108902b01SBrad Bishop# Copyright (C) 2018-2019 Garmin Ltd. 219323693SBrad Bishop# 3c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-only 419323693SBrad Bishop# 519323693SBrad Bishop 6*a34c030eSBrad Bishopfrom contextlib import closing 7*a34c030eSBrad Bishopimport re 819323693SBrad Bishopimport sqlite3 919323693SBrad Bishop 10*a34c030eSBrad BishopUNIX_PREFIX = "unix://" 1119323693SBrad Bishop 12*a34c030eSBrad BishopADDR_TYPE_UNIX = 0 13*a34c030eSBrad BishopADDR_TYPE_TCP = 1 1419323693SBrad Bishop 1508902b01SBrad Bishop 16*a34c030eSBrad Bishopdef setup_database(database, sync=True): 17*a34c030eSBrad Bishop db = sqlite3.connect(database) 1819323693SBrad Bishop db.row_factory = sqlite3.Row 1919323693SBrad Bishop 20*a34c030eSBrad Bishop with closing(db.cursor()) as cursor: 2119323693SBrad Bishop cursor.execute(''' 2208902b01SBrad Bishop CREATE TABLE IF NOT EXISTS tasks_v2 ( 2319323693SBrad Bishop id INTEGER PRIMARY KEY AUTOINCREMENT, 2419323693SBrad Bishop method TEXT NOT NULL, 2519323693SBrad Bishop outhash TEXT NOT NULL, 2619323693SBrad Bishop taskhash TEXT NOT NULL, 2719323693SBrad Bishop unihash TEXT NOT NULL, 2819323693SBrad Bishop created DATETIME, 2919323693SBrad Bishop 3019323693SBrad Bishop -- Optional fields 3119323693SBrad Bishop owner TEXT, 3219323693SBrad Bishop PN TEXT, 3319323693SBrad Bishop PV TEXT, 3419323693SBrad Bishop PR TEXT, 3519323693SBrad Bishop task TEXT, 3608902b01SBrad Bishop outhash_siginfo TEXT, 3708902b01SBrad Bishop 3808902b01SBrad Bishop UNIQUE(method, outhash, taskhash) 3919323693SBrad Bishop ) 4019323693SBrad Bishop ''') 41*a34c030eSBrad Bishop cursor.execute('PRAGMA journal_mode = WAL') 42*a34c030eSBrad Bishop cursor.execute('PRAGMA synchronous = %s' % ('NORMAL' if sync else 'OFF')) 4319323693SBrad Bishop 44*a34c030eSBrad Bishop # Drop old indexes 45*a34c030eSBrad Bishop cursor.execute('DROP INDEX IF EXISTS taskhash_lookup') 46*a34c030eSBrad Bishop cursor.execute('DROP INDEX IF EXISTS outhash_lookup') 4708902b01SBrad Bishop 48*a34c030eSBrad Bishop # Create new indexes 49*a34c030eSBrad Bishop cursor.execute('CREATE INDEX IF NOT EXISTS taskhash_lookup_v2 ON tasks_v2 (method, taskhash, created)') 50*a34c030eSBrad Bishop cursor.execute('CREATE INDEX IF NOT EXISTS outhash_lookup_v2 ON tasks_v2 (method, outhash)') 5108902b01SBrad Bishop 52*a34c030eSBrad Bishop return db 53*a34c030eSBrad Bishop 54*a34c030eSBrad Bishop 55*a34c030eSBrad Bishopdef parse_address(addr): 56*a34c030eSBrad Bishop if addr.startswith(UNIX_PREFIX): 57*a34c030eSBrad Bishop return (ADDR_TYPE_UNIX, (addr[len(UNIX_PREFIX):],)) 58*a34c030eSBrad Bishop else: 59*a34c030eSBrad Bishop m = re.match(r'\[(?P<host>[^\]]*)\]:(?P<port>\d+)$', addr) 60*a34c030eSBrad Bishop if m is not None: 61*a34c030eSBrad Bishop host = m.group('host') 62*a34c030eSBrad Bishop port = m.group('port') 63*a34c030eSBrad Bishop else: 64*a34c030eSBrad Bishop host, port = addr.split(':') 65*a34c030eSBrad Bishop 66*a34c030eSBrad Bishop return (ADDR_TYPE_TCP, (host, int(port))) 67*a34c030eSBrad Bishop 68*a34c030eSBrad Bishop 69*a34c030eSBrad Bishopdef create_server(addr, dbname, *, sync=True): 70*a34c030eSBrad Bishop from . import server 71*a34c030eSBrad Bishop db = setup_database(dbname, sync=sync) 72*a34c030eSBrad Bishop s = server.Server(db) 73*a34c030eSBrad Bishop 74*a34c030eSBrad Bishop (typ, a) = parse_address(addr) 75*a34c030eSBrad Bishop if typ == ADDR_TYPE_UNIX: 76*a34c030eSBrad Bishop s.start_unix_server(*a) 77*a34c030eSBrad Bishop else: 78*a34c030eSBrad Bishop s.start_tcp_server(*a) 79*a34c030eSBrad Bishop 80*a34c030eSBrad Bishop return s 81*a34c030eSBrad Bishop 82*a34c030eSBrad Bishop 83*a34c030eSBrad Bishopdef create_client(addr): 84*a34c030eSBrad Bishop from . import client 85*a34c030eSBrad Bishop c = client.Client() 86*a34c030eSBrad Bishop 87*a34c030eSBrad Bishop (typ, a) = parse_address(addr) 88*a34c030eSBrad Bishop if typ == ADDR_TYPE_UNIX: 89*a34c030eSBrad Bishop c.connect_unix(*a) 90*a34c030eSBrad Bishop else: 91*a34c030eSBrad Bishop c.connect_tcp(*a) 92*a34c030eSBrad Bishop 93*a34c030eSBrad Bishop return c 94