db_setup.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. from game import CURRENCY_NAME
  2. from util import debug
  3. def setup(cursor):
  4. print('Database setup...')
  5. replace = False and debug
  6. if replace:
  7. drop_database(cursor)
  8. tables(cursor)
  9. integrity_checks(cursor)
  10. if replace: # TODO also seed new databases
  11. seed(cursor)
  12. def drop_database(cursor):
  13. print(' - Dropping old tables...')
  14. cursor.execute("DROP TABLE IF EXISTS users")
  15. cursor.execute("DROP TABLE IF EXISTS ownables")
  16. cursor.execute("DROP TABLE IF EXISTS ownership")
  17. cursor.execute("DROP TABLE IF EXISTS sessions")
  18. cursor.execute("DROP TABLE IF EXISTS orders")
  19. cursor.execute("DROP TABLE IF EXISTS transactions")
  20. cursor.execute("DROP TABLE IF EXISTS keys")
  21. cursor.execute("DROP TABLE IF EXISTS news")
  22. cursor.execute("DROP TRIGGER IF EXISTS owned_amount_not_negative_after_insert")
  23. cursor.execute("DROP TRIGGER IF EXISTS owned_amount_not_negative_after_update")
  24. cursor.execute("DROP TRIGGER IF EXISTS order_limit_not_negative_after_insert")
  25. cursor.execute("DROP TRIGGER IF EXISTS order_limit_not_negative_after_update")
  26. cursor.execute("DROP TRIGGER IF EXISTS order_amount_positive_after_insert")
  27. cursor.execute("DROP TRIGGER IF EXISTS order_amount_positive_after_update")
  28. def seed(cursor):
  29. print(' - Seeding initial data...')
  30. cursor.execute('''
  31. INSERT INTO ownables
  32. (name)
  33. VALUES (?)
  34. ''', (CURRENCY_NAME,))
  35. cursor.execute('''
  36. INSERT INTO users
  37. (username,password)
  38. VALUES ('bank','')
  39. ''')
  40. cursor.execute('''
  41. INSERT INTO ownership
  42. (user_id, ownable_id)
  43. VALUES ((SELECT rowid FROM users WHERE username = 'bank'),
  44. (SELECT rowid FROM ownables WHERE name = ?))
  45. ''', (CURRENCY_NAME,))
  46. def integrity_checks(cursor):
  47. print(' - Integrity checks...')
  48. cursor.execute('''
  49. CREATE TRIGGER IF NOT EXISTS owned_amount_not_negative_after_insert
  50. AFTER INSERT
  51. ON ownership
  52. WHEN NEW.amount < 0
  53. BEGIN
  54. SELECT RAISE(ROLLBACK, 'Can not own an amount less than 0.');
  55. END
  56. ''')
  57. cursor.execute('''
  58. CREATE TRIGGER IF NOT EXISTS owned_amount_not_negative_after_update
  59. AFTER UPDATE
  60. ON ownership
  61. WHEN NEW.amount < 0
  62. BEGIN
  63. SELECT RAISE(ROLLBACK, 'Can not own an amount less than 0.');
  64. END
  65. ''')
  66. cursor.execute('''
  67. CREATE TRIGGER IF NOT EXISTS amount_positive_after_insert
  68. AFTER INSERT
  69. ON transactions
  70. WHEN NEW.amount <= 0
  71. BEGIN
  72. SELECT RAISE(ROLLBACK, 'Can not perform empty transactions.');
  73. END
  74. ''')
  75. cursor.execute('''
  76. CREATE TRIGGER IF NOT EXISTS amount_positive_after_update
  77. AFTER UPDATE
  78. ON transactions
  79. WHEN NEW.amount <= 0
  80. BEGIN
  81. SELECT RAISE(ROLLBACK, 'Can not perform empty transactions.');
  82. END
  83. ''')
  84. cursor.execute('''
  85. CREATE TRIGGER IF NOT EXISTS order_limit_not_negative_after_insert
  86. AFTER INSERT
  87. ON orders
  88. WHEN NEW."limit" IS NOT NULL AND NEW."limit" < 0
  89. BEGIN
  90. SELECT RAISE(ROLLBACK, 'Can not set a limit less than 0.');
  91. END
  92. ''')
  93. cursor.execute('''
  94. CREATE TRIGGER IF NOT EXISTS order_limit_not_negative_after_update
  95. AFTER UPDATE
  96. ON orders
  97. WHEN NEW."limit" IS NOT NULL AND NEW."limit" < 0
  98. BEGIN
  99. SELECT RAISE(ROLLBACK, 'Can not set a limit less than 0.');
  100. END
  101. ''')
  102. cursor.execute('''
  103. CREATE TRIGGER IF NOT EXISTS order_amount_positive_after_insert
  104. AFTER INSERT
  105. ON orders
  106. WHEN NEW.ordered_amount <= 0 OR NEW.executed_amount < 0
  107. BEGIN
  108. SELECT RAISE(ROLLBACK, 'Can not order 0 or less.');
  109. END
  110. ''')
  111. cursor.execute('''
  112. CREATE TRIGGER IF NOT EXISTS order_amount_positive_after_update
  113. AFTER UPDATE
  114. ON orders
  115. WHEN NEW.ordered_amount <= 0 OR NEW.executed_amount < 0
  116. BEGIN
  117. SELECT RAISE(ROLLBACK, 'Can not order 0 or less.');
  118. END
  119. ''')
  120. cursor.execute('''
  121. CREATE TRIGGER IF NOT EXISTS not_more_executed_than_ordered_after_insert
  122. AFTER INSERT
  123. ON orders
  124. WHEN NEW.ordered_amount < NEW.executed_amount
  125. BEGIN
  126. SELECT RAISE(ROLLBACK, 'Can not execute more than ordered.');
  127. END
  128. ''')
  129. cursor.execute('''
  130. CREATE TRIGGER IF NOT EXISTS not_more_executed_than_ordered_after_update
  131. AFTER UPDATE
  132. ON orders
  133. WHEN NEW.ordered_amount < NEW.executed_amount
  134. BEGIN
  135. SELECT RAISE(ROLLBACK, 'Can not execute more than ordered.');
  136. END
  137. ''')
  138. def tables(cursor):
  139. print(' - Creating tables...')
  140. cursor.execute('''
  141. CREATE TABLE IF NOT EXISTS users(
  142. username VARCHAR(10) UNIQUE NOT NULL,
  143. password VARCHAR(200) NOT NULL)
  144. ''')
  145. cursor.execute('''
  146. CREATE TABLE IF NOT EXISTS ownables(
  147. name VARCHAR(10) UNIQUE NOT NULL)
  148. ''')
  149. cursor.execute('''
  150. CREATE TABLE IF NOT EXISTS ownership(
  151. user_id INTEGER NOT NULL,
  152. ownable_id INTEGER NOT NULL,
  153. amount CURRENCY NOT NULL DEFAULT 0,
  154. FOREIGN KEY (user_id) REFERENCES users(rowid),
  155. FOREIGN KEY (ownable_id) REFERENCES ownables(rowid),
  156. UNIQUE (user_id, ownable_id)
  157. )
  158. ''')
  159. cursor.execute('''
  160. CREATE TABLE IF NOT EXISTS sessions(
  161. user_id INTEGER NOT NULL,
  162. session_id STRING NOT NULL,
  163. FOREIGN KEY (user_id) REFERENCES users(rowid)
  164. )
  165. ''')
  166. cursor.execute('''
  167. CREATE TABLE IF NOT EXISTS orders(
  168. ownership_id INTEGER NOT NULL,
  169. buy BOOLEAN NOT NULL,
  170. "limit" CURRENCY,
  171. stop_loss BOOLEAN,
  172. ordered_amount CURRENCY NOT NULL,
  173. executed_amount CURRENCY DEFAULT 0 NOT NULL,
  174. FOREIGN KEY (ownership_id) REFERENCES ownership(rowid)
  175. )
  176. ''')
  177. cursor.execute('''
  178. CREATE TABLE IF NOT EXISTS transactions(
  179. dt DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  180. price CURRENCY NOT NULL,
  181. ownable_id INTEGER NOT NULL,
  182. amount CURRENCY NOT NULL,
  183. FOREIGN KEY (ownable_id) REFERENCES ownable(rowid)
  184. )
  185. ''')
  186. cursor.execute('''
  187. CREATE TABLE IF NOT EXISTS keys(
  188. key STRING UNIQUE NOT NULL,
  189. used_by_user_id INTEGER,
  190. FOREIGN KEY (used_by_user_id) REFERENCES user(rowid)
  191. )
  192. ''')
  193. cursor.execute('''
  194. CREATE TABLE IF NOT EXISTS news(
  195. dt DATETIME NOT NULL,
  196. title VARCHAR(50) NOT NULL
  197. )
  198. ''')