from server import * if config['DB_ENGINE'] == 'sqlite': import sqlite3 # From sqlite3 module, but with error catching def convert_timestamp(val): try: datepart, timepart = val.split(b" ") year, month, day = map(int, datepart.split(b"-")) timepart_full = timepart.split(b".") hours, minutes, seconds = map(int, timepart_full[0].split(b":")) val = datetime(year, month, day, hours, minutes, seconds, 0) except ValueError: val = datetime.fromtimestamp(0) return val sqlite3.register_converter('datetime', convert_timestamp) sqlite3.register_converter('timestamp', convert_timestamp) if config['DB_ENGINE'] == 'sqlite': created = not os.path.exists(config['SQLITE_DB']) db = sqlite3.connect(config['SQLITE_DB']) cur = db.cursor() if config['SQLITE_INIT_SCHEMA']: print('Init db schema') cur.executescript(open(config['DB_SCHEMA']).read()) if config['SQLITE_INIT_DATA'] and created: print('Init db data') cur.executescript(open(config['DB_DATA']).read()) db.commit() db.close() def get_dbcursor(): if 'db' not in g: g.db = sqlite3.connect(config['SQLITE_DB'], detect_types=sqlite3.PARSE_DECLTYPES) g.db.isolation_level = None if not hasattr(request, 'db'): request.db = g.db.cursor() return request.db def fix_query(operation, params): params = [(p.replace(microsecond=0) if isinstance(p, datetime) else p) for p in params] return operation, params def show(operation, host=None): return {} elif config['DB_ENGINE'] == 'mysql': import mysql.connector def get_dbcursor(): if 'db' not in g or not g.db.is_connected(): g.db = mysql.connector.connect(user=config['MYSQL_USER'], password=config['MYSQL_PASSWD'], host=config.get('MYSQL_HOST', None), port=config.get('MYSQL_PORT', 3306), unix_socket=config.get('MYSQL_UNIX', None), database=config['MYSQL_DB']) if not hasattr(request, 'db'): request.db = g.db.cursor() return request.db def fix_query(operation, params): operation = operation.replace('?', '%s') params = [(p.replace(microsecond=0) if isinstance(p, datetime) else p) for p in params] return operation, params def show(operation, host=config.get('MYSQL_HOST', None)): if host: db = mysql.connector.connect(user=config['MYSQL_USER'], password=config['MYSQL_PASSWD'], host=host, port=config.get('MYSQL_PORT', 3306)) else: db = mysql.connector.connect(user=config['MYSQL_USER'], password=config['MYSQL_PASSWD'], unix_socket=config.get('MYSQL_UNIX', None)) cur = db.cursor() cur.execute(operation) rows = [] try: rows = cur.fetchall() except mysql.connector.errors.InterfaceError as ie: if ie.msg == 'No result set to fetch from.': # no problem, we were just at the end of the result set pass else: raise res = {} for row in rows: res[row[0]] = row[1] cur.close() db.close() return res def query(operation, *params, delim="sep", nlfix=True): operation, params = fix_query(operation, params) tries = 0 while (tries < 10): try: cur = get_dbcursor() cur.execute(operation, params) except mysql.connector.errors.InternalError as e: if e.msg == 'Deadlock found when trying to get lock; try restarting transaction': tries += 1 continue else: raise break rows = [] try: rows = cur.fetchall() except mysql.connector.errors.InterfaceError as ie: if ie.msg == 'No result set to fetch from.': # no problem, we were just at the end of the result set pass else: raise res = [] for row in rows: res.append({}) ptr = res[-1] for col, desc in zip(row, cur.description): name = desc[0].split('.')[-1].split(':')[0] if name == delim: ptr = res[-1][col] = {} continue if type(col) == str and nlfix: col = col.replace('\\n', '\n').replace('\\r', '\r') ptr[name] = col return res def modify(operation, *params): operation, params = fix_query(operation, params) cur = get_dbcursor() cur.execute(operation, params) return cur.lastrowid @app.teardown_request def commit_db(*args): if hasattr(request, 'db'): request.db.close() g.db.commit() @app.teardown_appcontext def close_db(*args): if 'db' in g: g.db.close() del g.db def searchquery(text, columns, match, tables, suffix, *suffixparams): params = [] subexprs = [] words = text.split(' ') prio = len(words)+1 for word in words: if word == '' or word.isspace(): continue matchexpr = ' OR '.join(['%s LIKE ?'%column for column in match]) subexprs.append('SELECT %s, %s AS _prio FROM %s WHERE %s'%(columns, str(prio), tables, matchexpr)) params += ['%'+word+'%']*len(match) prio -= 1 if subexprs == []: return [] expr = 'SELECT *,SUM(_prio) AS _score FROM (%s) AS _tmp %s'%(' UNION '.join(subexprs), suffix) return query(expr, *(list(params)+list(suffixparams)))