database.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. # This file is part of jwmud, written by Helmut Pozimski in 2014.
  2. #
  3. # jwmud is free software: you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation, version 2 of the License.
  6. #
  7. # jwmud is distributed in the hope that it will be useful,
  8. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. # GNU General Public License for more details.
  11. #
  12. # You should have received a copy of the GNU General Public License
  13. # along with jwmud. If not, see <http://www.gnu.org/licenses/>.
  14. # -*- coding: utf8 -*-
  15. import sqlite3
  16. from jwmudlib import jwmu_exceptions
  17. class db:
  18. def __init__(self, db_path):
  19. """Constructor, establishes the initial connection to the database."""
  20. try:
  21. self.__connection = sqlite3.connect(db_path)
  22. except sqlite3.OperationalError:
  23. raise jwmu_exceptions.DataBaseAccessFailed()
  24. else:
  25. self.__cursor = self.__connection.cursor()
  26. def __del__(self):
  27. """Destructor, closes the connection to the database"""
  28. self.__connection.close()
  29. def __ExecuteQuery(self, query, arguments=None):
  30. """Executes any query and returns the result"""
  31. if arguments is None:
  32. query_result = self.__cursor.execute(query)
  33. else:
  34. query_result = self.__cursor.execute(query, arguments)
  35. return query_result
  36. def __ExecuteStatement(self, statement, arguments=None):
  37. """Executes any statements that perform a write access to the
  38. database
  39. """
  40. try:
  41. if arguments is None:
  42. self.__cursor.execute(statement)
  43. else:
  44. self.__cursor.execute(statement, arguments)
  45. except sqlite3.OperationalError:
  46. raise jwmu_exceptions.DataBaseWriteFailed()
  47. else:
  48. self.__connection.commit()
  49. def Populate(self):
  50. """Creates the initial database structure with all the necessary
  51. tables.
  52. """
  53. create_weekdays = """CREATE TABLE weekdays(
  54. day_id INTEGER PRIMARY KEY NOT NULL,
  55. alarm_time TEXT,
  56. name TEXT
  57. );"""
  58. create_categories = """CREATE TABLE categories(
  59. category_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
  60. name TEXT NOT NULL,
  61. alarm_time TEXT
  62. );"""
  63. create_alarmdays = """CREATE TABLE alarmdays(
  64. date TEXT NOT NULL,
  65. alarm_time TEXT,
  66. category INTEGER DEFAULT NULL,
  67. FOREIGN KEY(category) REFERENCES category(category_id),
  68. PRIMARY KEY(date, alarm_time)
  69. );"""
  70. # create the empty tables
  71. self.__ExecuteStatement(create_weekdays)
  72. self.__ExecuteStatement(create_categories)
  73. self.__ExecuteStatement(create_alarmdays)
  74. # fill the weekdays table with the existing 7 days of the week,
  75. # these are always hardcoded
  76. self.__ExecuteStatement("INSERT INTO weekdays (day_id, alarm_time, "
  77. "name) VALUES (1, 'undefined', 'Monday');")
  78. self.__ExecuteStatement("INSERT INTO weekdays (day_id, alarm_time, "
  79. "name) VALUES (2, 'undefined', 'Tuesday');")
  80. self.__ExecuteStatement("INSERT INTO weekdays (day_id, alarm_time, "
  81. "name) VALUES (3, 'undefined', 'Wednesday');")
  82. self.__ExecuteStatement("INSERT INTO weekdays (day_id, alarm_time, "
  83. "name) VALUES (4, 'undefined', 'Thursday');")
  84. self.__ExecuteStatement("INSERT INTO weekdays (day_id, alarm_time, "
  85. "name) VALUES (5, 'undefined', 'Friday');")
  86. self.__ExecuteStatement("INSERT INTO weekdays (day_id, alarm_time, "
  87. "name) VALUES (6, 'undefined', 'Saturday');")
  88. self.__ExecuteStatement("INSERT INTO weekdays (day_id, alarm_time, "
  89. "name) VALUES (7, 'undefined', 'Sunday');")
  90. def FetchCategoryId(self, category_name):
  91. """Fetches the id of a category with a given name from the database
  92. and returns it.
  93. """
  94. query = "SELECT category_id FROM categories WHERE name=?;"
  95. result = self.__ExecuteQuery(query, (category_name,))
  96. category_id = result.fetchone()
  97. try:
  98. return int(category_id[0])
  99. except TypeError:
  100. raise jwmu_exceptions.CategoryNotFound()
  101. def ChangeAlarmTimeWeekdays(self, alarm_time, start=None, end=None, day=None):
  102. """Changes the alarm time either for a single day or a range of days,
  103. like 1-5 for regular work days or 6-7 for week end. What mode is
  104. chosen depends on the parameters defined when the function is called.
  105. """
  106. statement = "UPDATE weekdays SET alarm_time = ? WHERE day_id = ?;"
  107. if day is not None:
  108. self.__ExecuteStatement(statement, (alarm_time, day))
  109. elif start is not None and end is not None:
  110. for day in range(start, end+1):
  111. self.__ExecuteStatement(statement, (alarm_time, day))
  112. else:
  113. raise jwmu_exceptions.WrongParameters()
  114. def CreateCategory(self, category_name):
  115. """Inserts a new category into the database and returns the newly
  116. assigned category id.
  117. """
  118. statement = "INSERT INTO categories (name) VALUES (?);"
  119. self.__ExecuteStatement(statement, (category_name,))
  120. category_id = self.FetchCategoryId(category_name)
  121. return category_id
  122. def DeleteCategory(self, category_id):
  123. """Deletes a category with the given ID from the database."""
  124. statement = "UPDATE alarmdays SET category=NULL WHERE category = ?;"
  125. self.__ExecuteStatement(statement, (category_id,))
  126. statement = "DELETE FROM categories WHERE category_id = ?;"
  127. self.__ExecuteStatement(statement, (category_id,))
  128. def InsertDay(self, date, alarm_time, category_id=None):
  129. """Inserts an additional day with the given parameters and optionally
  130. a category into the database.
  131. """
  132. try:
  133. if category_id is not None:
  134. statement = "INSERT INTO alarmdays (date, alarm_time, category) " \
  135. "VALUES (? , ?, ?);"
  136. self.__ExecuteStatement(statement, (date, alarm_time, category_id))
  137. else:
  138. statement = "INSERT INTO alarmdays (date, alarm_time) VALUES " \
  139. "(?, ?);"
  140. self.__ExecuteStatement(statement, (date, alarm_time))
  141. except sqlite3.IntegrityError:
  142. raise jwmu_exceptions.DayAlreadyInDatabase()
  143. def ModifyAlarmTime(self, date, alarm_time):
  144. """Changes the alarm time for a given day in the database."""
  145. statement = "UPDATE alarmdays SET alarm_time = ? WHERE date = ?;"
  146. self.__ExecuteStatement(statement, (alarm_time, date))
  147. def DeleteDay(self, date):
  148. """Deletes a specified day from the database."""
  149. statement = "DELETE FROM alarmdays WHERE date = ?;"
  150. self.__ExecuteStatement(statement, (date,))
  151. def FetchDays(self):
  152. """Retrieves a list of all the days with their corresponding
  153. categories from the database.
  154. """
  155. query = "SELECT date, alarmdays.alarm_time, name FROM alarmdays LEFT " \
  156. "JOIN categories ON alarmdays.category=categories.category_id;"
  157. result = self.__ExecuteQuery(query).fetchall()
  158. return result
  159. def FetchWeekDays(self):
  160. """Retrieves a list of all the week days and their alarm times from
  161. the database.
  162. """
  163. query = "SELECT * FROM weekdays;"
  164. result = self.__ExecuteQuery(query).fetchall()
  165. return result