| 79 | |
| 80 | # API objects |
| 81 | class Database(object): |
| 82 | filepath = None |
| 83 | |
| 84 | def __init__(self, database=None): |
| 85 | self.database = self.filepath if database is None else database |
| 86 | self.connection = None |
| 87 | self.cursor = None |
| 88 | |
| 89 | def connect(self, who="server"): |
| 90 | self.connection = sqlite3.connect(self.database, timeout=3, isolation_level=None, check_same_thread=False) |
| 91 | self.cursor = self.connection.cursor() |
| 92 | self.lock = threading.Lock() |
| 93 | logger.debug("REST-JSON API %s connected to IPC database" % who) |
| 94 | |
| 95 | def disconnect(self): |
| 96 | if self.cursor: |
| 97 | self.cursor.close() |
| 98 | |
| 99 | if self.connection: |
| 100 | self.connection.close() |
| 101 | |
| 102 | def commit(self): |
| 103 | self.connection.commit() |
| 104 | |
| 105 | def execute(self, statement, arguments=None): |
| 106 | with self.lock: |
| 107 | while True: |
| 108 | try: |
| 109 | if arguments: |
| 110 | self.cursor.execute(statement, arguments) |
| 111 | else: |
| 112 | self.cursor.execute(statement) |
| 113 | except sqlite3.OperationalError as ex: |
| 114 | if "locked" not in getSafeExString(ex): |
| 115 | raise |
| 116 | else: |
| 117 | time.sleep(1) |
| 118 | else: |
| 119 | break |
| 120 | |
| 121 | if statement.lstrip().upper().startswith("SELECT"): |
| 122 | return self.cursor.fetchall() |
| 123 | |
| 124 | def init(self): |
| 125 | self.execute("CREATE TABLE IF NOT EXISTS logs(id INTEGER PRIMARY KEY AUTOINCREMENT, taskid INTEGER, time TEXT, level TEXT, message TEXT)") |
| 126 | self.execute("CREATE TABLE IF NOT EXISTS data(id INTEGER PRIMARY KEY AUTOINCREMENT, taskid INTEGER, status INTEGER, content_type INTEGER, value TEXT)") |
| 127 | self.execute("CREATE TABLE IF NOT EXISTS errors(id INTEGER PRIMARY KEY AUTOINCREMENT, taskid INTEGER, error TEXT)") |
| 128 | |
| 129 | class Task(object): |
| 130 | def __init__(self, taskid, remote_addr): |
no outgoing calls
no test coverage detected
searching dependent graphs…