Browse Source

db: Implement SQL statement rewriting

We now have an abstract rewriter that will perform some common extractions and
replacements (type replacement for example), that can then be customized in
derived classes.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
travis-debug
Christian Decker 5 years ago
committed by Rusty Russell
parent
commit
2ddf168d59
  1. 1
      .gitignore
  2. 62
      devtools/sql-rewrite.py

1
.gitignore

@ -8,6 +8,7 @@
*.gcno
*.dSYM
*.rej
*.po
*.pyc
.cppcheck-suppress
TAGS

62
devtools/sql-rewrite.py

@ -2,16 +2,69 @@
from mako.template import Template
import re
import sys
class Sqlite3Rewriter(object):
def rewrite(self, query):
DEBUG = False
def eprint(*args, **kwargs):
if not DEBUG:
return
print(*args, **kwargs, file=sys.stderr)
class Rewriter(object):
def rewrite_types(self, query, mapping):
for old, new in mapping.items():
query = re.sub(old, new, query)
return query
def rewrite_single(self, query):
return query
def rewrite(self, queries):
for i, q in enumerate(queries):
org = q['query']
queries[i]['query'] = self.rewrite_single(org)
eprint("Rewritten statement\n\tfrom {}\n\t to {}".format(org, q['query']))
return queries
class Sqlite3Rewriter(Rewriter):
def rewrite_single(self, query):
typemapping = {
r'BIGINT': 'INTEGER',
r'BIGINTEGER': 'INTEGER',
r'BIGSERIAL': 'INTEGER',
r'CURRENT_TIMESTAMP\(\)': "strftime('%s', 'now')",
r'INSERT INTO[ \t]+(.*)[ \t]+ON CONFLICT.*DO NOTHING;': 'INSERT OR IGNORE INTO \\1;',
}
return self.rewrite_types(query, typemapping)
class PostgresRewriter(Rewriter):
def rewrite_single(self, q):
# Let's start by replacing any eventual '?' placeholders
q2 = ""
count = 1
for c in q:
if c == '?':
c = "${}".format(count)
count += 1
q2 += c
query = q2
typemapping = {
r'BLOB': 'BYTEA',
r'CURRENT_TIMESTAMP\(\)': "EXTRACT(epoch FROM now())",
}
query = self.rewrite_types(query, typemapping)
return query
class PostgresRewriter(Sqlite3Rewriter):
pass
rewriters = {
"sqlite3": Sqlite3Rewriter(),
@ -66,7 +119,6 @@ def extract_queries(pofile):
queries = []
for c in chunk(pofile):
name = c[0][3:]
# Skip other comments
i = 1

Loading…
Cancel
Save