module.mk 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. # database/module.mk
  2. # Part of Lorica, a cash ordering system.
  3. #
  4. # Copyright © 2007–2008 Cybersource Pty. Ltd.
  5. #
  6. # This is free software: see the grant of license at end of this file.
  7. # Makefile module for Lorica database.
  8. MODULE_DIR = database
  9. SQL_SUFFIX = .sql
  10. APPLY_STAMP_SUFFIX = -apply
  11. DATABASE_REVISIONS_DIR = ${DATABASE_DIR}/revisions
  12. database_revision_files_regex = [[:digit:]]\+-[^/]\+${SQL_SUFFIX}
  13. database_revision_files = $(shell \
  14. ls -1 ${DATABASE_REVISIONS_DIR}/*${SQL_SUFFIX} \
  15. | grep '${database_revision_files_regex}$$')
  16. database_revision_targets = $(addsuffix ${APPLY_STAMP_SUFFIX},${database_revision_files})
  17. DATABASE_REVISION_SETUP_DIR = ${DATABASE_REVISIONS_DIR}/setup
  18. database_revision_setup_files = $(wildcard ${DATABASE_REVISION_SETUP_DIR}/*${SQL_SUFFIX})
  19. database_revision_setup_targets = $(addsuffix ${APPLY_STAMP_SUFFIX},${database_revision_setup_files})
  20. DATABASE_STAMP_FILES += ${DATABASE_REVISIONS_DIR}/*${APPLY_STAMP_SUFFIX}
  21. DATABASE_STAMP_FILES += ${DATABASE_REVISION_SETUP_DIR}/*${APPLY_STAMP_SUFFIX}
  22. PG_TMP_ROOT_DIR ?= ${DATABASE_DIR}/postgres-tmp
  23. pg_sock_link = ${PG_TMP_ROOT_DIR}/run
  24. PG_SOCK_DIR ?= $(shell \
  25. readlink ${pg_sock_link} || echo "/nonexistent" \
  26. )
  27. PG_LOG_DIR ?= ${PG_TMP_ROOT_DIR}/log
  28. PG_LOG_NAME ?= postgresql.log
  29. pg_log_file = ${PG_LOG_DIR}/${PG_LOG_NAME}
  30. PG_START_TIMEOUT_SECS = 10
  31. PG_DATABASE_COMMENT = "Lorica cash ordering system database"
  32. export PGDATABASE ?= lorica
  33. export PGDATA ?= ${PG_TMP_ROOT_DIR}/data
  34. export PGHOST ?= ${PG_SOCK_DIR}
  35. DATABASE_ENV_FILE = ${DATABASE_DIR}/pg_env.sh
  36. pg_pid_file = ${PGDATA}/postmaster.pid
  37. DATABASE_TEST_DIR = $(DATABASE_DIR)/test
  38. DATABASE_TEST_INWAIT_FILES = ${DATABASE_REVISIONS_DIR} ${DATABASE_TEST_DIR}
  39. INSTALL = install
  40. RM = rm
  41. # Update this as necessary.
  42. PG_VERSION = 8.3
  43. # This format required on Debian-based systems.
  44. #PG_BIN_DIR = /usr/lib/postgresql/$(PG_VERSION)/bin
  45. # Most other systems.
  46. PG_BIN_DIR = /usr/bin
  47. INITDB = ${PG_BIN_DIR}/initdb
  48. INITDB_OPTS = -A "ident sameuser"
  49. PG_CTL = ${PG_BIN_DIR}/pg_ctl
  50. PG_CTL_START_OPTS = -w -o "-h \"\" -k ${PG_SOCK_DIR}" -l ${pg_log_file}
  51. PG_CTL_STOP_OPTS = -w -m fast
  52. CREATEDB = ${PG_BIN_DIR}/createdb
  53. CREATELANG = ${PG_BIN_DIR}/createlang
  54. DROPDB = ${PG_BIN_DIR}/dropdb
  55. PSQL = ${PG_BIN_DIR}/psql
  56. APPLY_REVISION = ${CODE_PROGRAM_DIR}/apply-schema-revision
  57. DATABASE_NOSETESTS_OPTS =
  58. .PHONY: database-build-test
  59. database-build-test: database-setup-stamp database-build-stamp database-test database-clean
  60. ${PGDATA}:
  61. $(INITDB) ${INITDB_OPTS}
  62. GENERATED_FILES += database-setup-stamp
  63. .PHONY: database-setup
  64. database-setup: database-setup-stamp
  65. database-setup-stamp: ${PGDATA} database-start
  66. touch $@
  67. # usage: $(call database-test-server-started)
  68. define database-test-server-started
  69. ( $(PG_CTL) status > /dev/null )
  70. endef
  71. # usage: $(call database-start-server)
  72. define database-start-server
  73. $(PG_CTL) ${PG_CTL_START_OPTS} start
  74. endef
  75. # usage: $(call database-wait-sever-started,message)
  76. define database-wait-server-started
  77. echo -n ${1} ; \
  78. for (( sec=0 ; $$sec < ${PG_START_TIMEOUT_SECS} ; sec++ )) ; do \
  79. $(call database-test-server-started) && break ; \
  80. echo -n "." ; \
  81. sleep 1 ; \
  82. done ; \
  83. echo
  84. endef
  85. ifeq (${PGHOST},${PG_SOCK_DIR})
  86. database-start: ${pg_pid_file}
  87. ${pg_pid_file}: PGHOST =
  88. ${pg_pid_file}: ${PG_SOCK_DIR} ${PG_LOG_DIR}
  89. endif
  90. .PHONY: database-start
  91. database-start:
  92. if ( $(call database-test-server-started) ; test $$? -ne 0 ) ; then \
  93. $(PG_CTL) ${PG_CTL_START_OPTS} start ; \
  94. sleep 2 ; \
  95. fi
  96. $(call database-wait-server-started, \
  97. "waiting for server to be active: ")
  98. $(PG_CTL) status
  99. .PHONY: database-stop
  100. database-stop: | database-drop
  101. if $(call database-test-server-started) ; then \
  102. $(PG_CTL) ${PG_CTL_STOP_OPTS} stop ; \
  103. fi
  104. $(RM) -rf ${PG_SOCK_DIR} ${pg_sock_link}
  105. ${PG_SOCK_DIR}: ${PGDATA} ${pg_sock_link}
  106. ${pg_sock_link}:
  107. ln -s $$(mktemp -td "postgres-${PGDATABASE}.XXXXXXXX") $@
  108. ${PG_LOG_DIR}:
  109. $(INSTALL) -d $@
  110. # usage: $(call database-test-database-created)
  111. define database-test-database-created
  112. ( $(PSQL) -f /dev/null > /dev/null 2>&1)
  113. endef
  114. # usage: $(call database-write-env-file)
  115. define database-write-env-file
  116. echo "# ${DATABASE_ENV_FILE}" > ${DATABASE_ENV_FILE}
  117. echo "# Database connection environment settings" >> ${DATABASE_ENV_FILE}
  118. echo "# Usage:" >> ${DATABASE_ENV_FILE}
  119. echo "# $$ source ${DATABASE_ENV_FILE}" >> ${DATABASE_ENV_FILE}
  120. echo "# $$ psql" >> ${DATABASE_ENV_FILE}
  121. echo >> ${DATABASE_ENV_FILE}
  122. echo "export PGDATABASE=${PGDATABASE}" >> ${DATABASE_ENV_FILE}
  123. echo "export PGDATA=${PGDATA}" >> ${DATABASE_ENV_FILE}
  124. echo "export PGHOST=${PGHOST}" >> ${DATABASE_ENV_FILE}
  125. echo "export PGPORT=${PGPORT}" >> ${DATABASE_ENV_FILE}
  126. endef
  127. ${DATABASE_ENV_FILE}:
  128. $(call database-write-env-file)
  129. GENERATED_FILES += database-create-stamp
  130. .PHONY: database-create
  131. database-create: database-create-stamp
  132. database-create-stamp: ${DATABASE_ENV_FILE} | database-drop
  133. if ( $(call database-test-database-created) ; test $$? -ne 0 ) ; then \
  134. $(CREATEDB) ${PGDATABASE} ${PG_DATABASE_COMMENT} ; \
  135. $(CREATELANG) plpgsql ${PGDATABASE} ; \
  136. fi
  137. touch $@
  138. ${database_revision_setup_targets}: database-drop database-create
  139. ${DATABASE_REVISION_SETUP_DIR}/%${APPLY_STAMP_SUFFIX}: ${DATABASE_REVISION_SETUP_DIR}/%
  140. $(PSQL) -f $<
  141. touch $@
  142. ${database_revision_targets}: ${database_revision_setup_targets}
  143. ${DATABASE_REVISIONS_DIR}/%${APPLY_STAMP_SUFFIX}: ${DATABASE_REVISIONS_DIR}/%
  144. $(APPLY_REVISION) ${PGDATABASE} $<
  145. touch $@
  146. GENERATED_FILES += database-build-stamp
  147. .PHONY: database-build
  148. database-build: database-build-stamp
  149. database-build-stamp: ${database_revision_targets}
  150. touch $@
  151. build: database-build
  152. .PHONY: database-nosetests
  153. database-nosetests: NOSETESTS_OPTS += ${DATABASE_NOSETESTS_OPTS}
  154. database-nosetests: NOSETESTS_FILES = ${DATABASE_TEST_DIR}
  155. database-nosetests: database-build-stamp
  156. $(call test-output-banner, "Database test run: ")
  157. $(nosetests_cmd)
  158. .PHONY: database-test
  159. database-test: database-nosetests
  160. .PHONY: database-build-test-continuous
  161. database-build-test-continuous: TEST_INWAIT_FILES = ${DATABASE_TEST_INWAIT_FILES}
  162. database-build-test-continuous:
  163. while true ; do \
  164. clear ; \
  165. $(MAKE) database-build-test ; \
  166. $(call test-wait) ; \
  167. done
  168. # Continuous rebuild of the test database.
  169. #
  170. # Note: The touch on database/test/stamp-IGNORE.py is a kludge -
  171. # intended to signal a continuous 'make database-test' loop (hopefully
  172. # running in another window) to rerun the database tests.
  173. .PHONY: database-build-continuous
  174. database-build-continuous:
  175. while true ; do \
  176. clear ; \
  177. unset PGDATABASE ; \
  178. unset PGDATA ; \
  179. unset PGHOST ; \
  180. echo -n "Database build run: " ; \
  181. $(DATE) +${DATE_FORMAT} ; \
  182. $(MAKE) clean && \
  183. $(MAKE) database-build && \
  184. echo '===> Database successfully rebuilt.' && \
  185. TEST_FILE_STAMP='database/test/stamp-IGNORE.py' && \
  186. echo > "$$TEST_FILE_STAMP" && \
  187. rm -f "$$TEST_FILE_STAMP" ; \
  188. $(INWAIT) ${INWAIT_OPTS} ${DATABASE_REVISIONS_DIR} ; \
  189. done
  190. build: database-test
  191. %.png: %.dot
  192. $(DOT) -Tpng -o $@ $<
  193. # Requires the environment variables set up to access the database.
  194. $(PGDATABASE).dot: database-build
  195. $(POSTGRESQL_AUTODOC) -t dot
  196. database-diagram: $(PGDATABASE).png
  197. @echo "Generated $<"
  198. @if [ ! -z "$(DISPLAY)" ] ; then display $< ; fi
  199. .PHONY: database-drop
  200. database-drop: database-clean
  201. if ( $(call database-test-database-created) ) ; then \
  202. $(DROPDB) ${PGDATABASE} ; \
  203. fi
  204. $(RM) -f database-create-stamp
  205. .PHONY: database-teardown
  206. database-teardown: database-drop database-stop
  207. $(RM) -rf ${PG_TMP_ROOT_DIR}
  208. database-clean: database-drop
  209. $(RM) -f ${DATABASE_STAMP_FILES}
  210. clean: database-clean
  211. # This is free software: you may copy, modify, and/or distribute this work
  212. # under the terms of the GNU General Public License as published by the
  213. # Free Software Foundation; version 3 of that license or any later version.
  214. #
  215. # No warranty expressed or implied. See the file ‘LICENSE.GPL-3’ for details,
  216. # or view it online at <URL:https://www.gnu.org/licenses/gpl-3.0.html>.
  217. # Local variables:
  218. # coding: utf-8
  219. # mode: makefile
  220. # End:
  221. # vim: fileencoding=utf-8 filetype=make :