Initialize table from SQL query
This commit is contained in:
parent
faf4770c5d
commit
2cd66bdf50
|
@ -1,6 +1,6 @@
|
||||||
[metadata]
|
[metadata]
|
||||||
name = ProcruSQL
|
name = ProcruSQL
|
||||||
version = 0.0.6
|
version = 0.0.7
|
||||||
author = Peter J. Holzer
|
author = Peter J. Holzer
|
||||||
author_email = hjp@hjp.at
|
author_email = hjp@hjp.at
|
||||||
description = Make a database fit its description
|
description = Make a database fit its description
|
||||||
|
|
|
@ -115,6 +115,36 @@ class HaveData(Node):
|
||||||
# exception. Success with 0 rows should not happen.
|
# exception. Success with 0 rows should not happen.
|
||||||
raise RuntimeError("Unreachable code reached")
|
raise RuntimeError("Unreachable code reached")
|
||||||
|
|
||||||
|
class HaveInit(Node):
|
||||||
|
def __init__(self, name, depends, table, query):
|
||||||
|
super().__init__(name, depends)
|
||||||
|
self.table = table
|
||||||
|
self.query = query
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
log_check.info("Checking %s", self.name)
|
||||||
|
|
||||||
|
for w in want:
|
||||||
|
if isinstance(w, HaveTable) and w.table == self.table:
|
||||||
|
if not w.ok:
|
||||||
|
log_check.error("%s not yet ok", w.name)
|
||||||
|
raise RuntimeError(f"Cannot insert into table {w.table} from {w.name} which is not yet ok. Please add a dependency")
|
||||||
|
if w.new:
|
||||||
|
log_action.info("Executing %s", self.query)
|
||||||
|
csr = db.cursor(cursor_factory=extras.DictCursor)
|
||||||
|
csr.execute(self.query)
|
||||||
|
self.result = csr.fetchall()
|
||||||
|
log_action.info("Got %d rows", len(self.result))
|
||||||
|
self.set_order()
|
||||||
|
else:
|
||||||
|
log_check.info("Table %s already exists", w.table)
|
||||||
|
self.ok = True
|
||||||
|
log_state.info("%s is now ok", self.name)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise RuntimeError(f"Cannot find a rule which creates table {self.table}")
|
||||||
|
|
||||||
|
|
||||||
class HaveTable(Node):
|
class HaveTable(Node):
|
||||||
|
|
||||||
def __init__(self, name, depends, table, schema="public"):
|
def __init__(self, name, depends, table, schema="public"):
|
||||||
|
@ -136,6 +166,7 @@ class HaveTable(Node):
|
||||||
# Table exists, all ok
|
# Table exists, all ok
|
||||||
self.set_order()
|
self.set_order()
|
||||||
self.ok = True
|
self.ok = True
|
||||||
|
self.new = False
|
||||||
log_state.info("%s is now ok", self.name)
|
log_state.info("%s is now ok", self.name)
|
||||||
return
|
return
|
||||||
if len(r) > 1:
|
if len(r) > 1:
|
||||||
|
@ -151,6 +182,7 @@ class HaveTable(Node):
|
||||||
csr.execute(q)
|
csr.execute(q)
|
||||||
self.set_order()
|
self.set_order()
|
||||||
self.ok = True
|
self.ok = True
|
||||||
|
self.new = True
|
||||||
log_state.info("%s is now ok", self.name)
|
log_state.info("%s is now ok", self.name)
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -156,10 +156,7 @@ def parse_data_rule(ps):
|
||||||
table_name = ps3.ast[0]
|
table_name = ps3.ast[0]
|
||||||
ps2.position = ps3.position
|
ps2.position = ps3.position
|
||||||
|
|
||||||
ps3 = parse_dict(ps2)
|
if ps3 := parse_dict(ps2):
|
||||||
if not ps3:
|
|
||||||
ps.record_child_failure(ps2, "expected key data definition")
|
|
||||||
return
|
|
||||||
key_data = ps3.ast
|
key_data = ps3.ast
|
||||||
ps2.position = ps3.position
|
ps2.position = ps3.position
|
||||||
|
|
||||||
|
@ -180,6 +177,18 @@ def parse_data_rule(ps):
|
||||||
ps2.ast = procrusql.HaveData(label, [], table_name, key_data, extra_data)
|
ps2.ast = procrusql.HaveData(label, [], table_name, key_data, extra_data)
|
||||||
|
|
||||||
ps2.match_newlines()
|
ps2.match_newlines()
|
||||||
|
elif ps3 := parse_init_query(ps2):
|
||||||
|
# We have a bit of a problem here: The query extends to the end of the
|
||||||
|
# line so there is no room for a label. I really don't want to parse
|
||||||
|
# SQL here.
|
||||||
|
label = rulename()
|
||||||
|
ps2.position = ps3.position
|
||||||
|
ps2.ast = procrusql.HaveInit(label, [], table_name, ps3.ast)
|
||||||
|
|
||||||
|
ps2.match_newlines()
|
||||||
|
else:
|
||||||
|
ps.record_child_failure(ps2, "expected key data definition or insert query")
|
||||||
|
return
|
||||||
|
|
||||||
return ps2
|
return ps2
|
||||||
|
|
||||||
|
@ -347,6 +356,16 @@ def parse_dict(ps):
|
||||||
ps2.ast = d
|
ps2.ast = d
|
||||||
return ps2
|
return ps2
|
||||||
|
|
||||||
|
def parse_init_query(ps):
|
||||||
|
ps2 = ps.clone()
|
||||||
|
ps2.skip_whitespace_and_comments()
|
||||||
|
if m := ps2.match(r'(?i:with|insert)\b.*'):
|
||||||
|
ps2.ast = m.group(0)
|
||||||
|
return ps2
|
||||||
|
else:
|
||||||
|
ps.record_child_failure(ps2, "expected insert query")
|
||||||
|
return
|
||||||
|
|
||||||
def parse_label(ps):
|
def parse_label(ps):
|
||||||
ps2 = ps.clone()
|
ps2 = ps.clone()
|
||||||
if m := ps2.match(r"\s*>>\s*(\w+)"):
|
if m := ps2.match(r"\s*>>\s*(\w+)"):
|
||||||
|
|
Loading…
Reference in New Issue