[Formed-commits] r328 - in trunk: . formed/formed/plugins/export
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Mon Apr 27 16:54:41 CEST 2009
Author: teichmann
Date: 2009-04-27 16:54:41 +0200 (Mon, 27 Apr 2009)
New Revision: 328
Modified:
trunk/ChangeLog
trunk/formed/formed/plugins/export/rg_sql.py
Log:
Added functions in repeat group schema generator to create datasets.
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2009-04-24 12:29:32 UTC (rev 327)
+++ trunk/ChangeLog 2009-04-27 14:54:41 UTC (rev 328)
@@ -1,5 +1,10 @@
2009-04-24 Sascha L. Teichmann <teichmann at intevation.de>
+ * formed/formed/plugins/export/rg_sql.py: Fixed $$$$ -> $$ template problems.
+ Add functions to create dataset.
+
+2009-04-24 Sascha L. Teichmann <teichmann at intevation.de>
+
* formed/formed/plugins/export/rg_sql.py: new plug-in to generate
tree structure functions in database.
Modified: trunk/formed/formed/plugins/export/rg_sql.py
===================================================================
--- trunk/formed/formed/plugins/export/rg_sql.py 2009-04-24 12:29:32 UTC (rev 327)
+++ trunk/formed/formed/plugins/export/rg_sql.py 2009-04-27 14:54:41 UTC (rev 328)
@@ -28,10 +28,39 @@
--
BEGIN;
--- need to be postgres because of untrusted language
+-- ------ This is static code and therefore may be put into a separate file. -------
+-- Used to track the structure changes of a case
+-- DROP TABLE case_structure CASCADE;
+
+CREATE TABLE case_structure (
+ id SERIAL PRIMARY KEY NOT NULL,
+ master_id int4 NOT NULL REFERENCES master_tbl(id) ON DELETE CASCADE,
+ modified boolean,
+ cache TEXT
+);
+
+-- each time a new case is created create a new entry in the strcuture table
+
+-- DROP TRIGGER case_insert_trigger ON master_tbl;
+-- DROP FUNCTION case_insert_func();
+
+CREATE OR REPLACE FUNCTION case_insert_func() RETURNS TRIGGER AS $$$$
+BEGIN
+ INSERT INTO case_structure (master_id, modified) VALUES (NEW.id, true);
+ RETURN NEW;
+END;
+$$$$ LANGUAGE plpgsql;
+
+CREATE TRIGGER case_insert_trigger AFTER INSERT ON master_tbl
+FOR EACH ROW EXECUTE PROCEDURE case_insert_func();
+
+-- ------ end of static code -------
+
+-- PLPython is an untrusted language. -> Need to be postgres.
+
-- DROP FUNCTION get_case_structure(int4);
-CREATE OR REPLACE FUNCTION get_case_structure(case_id int4) RETURNS TEXT AS $$
+CREATE OR REPLACE FUNCTION get_case_structure(case_id int4) RETURNS TEXT AS $$$$
class Node(object):
@@ -89,7 +118,7 @@
return r['cache']
-$$ LANGUAGE plpythonu;
+$$$$ LANGUAGE plpythonu;
--
-- These triggers are used to keep case_structure table in sync.
@@ -99,6 +128,8 @@
$TRIGGERS
+$CREATE_DELETE_FUNCTIONS
+
COMMIT;
''')
@@ -109,24 +140,24 @@
-- DROP TRIGGER ${RELATION}_delete_trigger ON master_tbl CASCADE;
-- DROP FUNCTION ${RELATION}_delete_func();
-CREATE OR REPLACE FUNCTION ${RELATION}_insert_func() RETURNS TRIGGER AS $$
+CREATE OR REPLACE FUNCTION ${RELATION}_insert_func() RETURNS TRIGGER AS $$$$
BEGIN
UPDATE case_structure SET modified = true WHERE master_id
${SUBSELECT_INSERT}
RETURN NEW;
END;
-$$ LANGUAGE plpgsql;
+$$$$ LANGUAGE plpgsql;
CREATE TRIGGER ${RELATION}_insert_trigger AFTER INSERT ON rg1_rg
FOR EACH ROW EXECUTE PROCEDURE ${RELATION}_insert_func();
-CREATE OR REPLACE FUNCTION ${RELATION}_delete_func() RETURNS TRIGGER AS $$
+CREATE OR REPLACE FUNCTION ${RELATION}_delete_func() RETURNS TRIGGER AS $$$$
BEGIN
UPDATE case_structure SET modified = true WHERE master_id
${SUBSELECT_DELETE}
RETURN OLD;
END;
-$$ LANGUAGE plpgsql;
+$$$$ LANGUAGE plpgsql;
CREATE TRIGGER ${RELATION}_delete_trigger AFTER DELETE ON rg1_rg
FOR EACH ROW EXECUTE PROCEDURE ${RELATION}_delete_func();
@@ -139,6 +170,74 @@
WHERE $RELATION.id = $NEW_OLD.id
)''')
+CREATE_DELETE_TMPL = Template(
+'''
+CREATE OR REPLACE FUNCTION create_${RELATION}(pid integer, nuuid char(36))
+RETURNS integer
+LANGUAGE 'plpgsql' VOLATILE EXTERNAL SECURITY DEFINER AS
+$$$$
+DECLARE
+ rid integer;
+ mid integer;
+BEGIN
+ ${SELECT_MASTER_ID}
+
+ IF NOT isEditorOrStandin(mid) THEN
+ RAISE EXCEPTION 'DS ID not session_user ID';
+ END IF;
+
+ INSERT INTO ${RELATION} (master_id) VALUES (pid);
+
+ SELECT INTO rid currval('${RELATION}_id_seq');
+
+ IF nuuid IS NOT NULL THEN
+ UPDATE ${RELATION}
+ SET uuid_id = nuuid
+ WHERE id = rid;
+ ELSE
+ PERFORM set_uuid('${RELATION}', rid);
+ END IF;
+
+ ${CREATE_CHILDREN}
+
+ RETURN rid;
+END;
+$$$$;
+''')
+
+CREATE_DELETE_MASTER_TMPL = Template('''
+CREATE OR REPLACE FUNCTION create_master_tbl(nuuid char(36))
+ RETURNS integer
+ LANGUAGE 'plpgsql' VOLATILE EXTERNAL SECURITY DEFINER AS
+$$$$
+DECLARE
+ standin integer;
+ rid integer;
+BEGIN
+ INSERT INTO master_tbl (bearbeiter_id) VALUES (getuserid());
+ SELECT INTO standin vertreter from ka_benutzer_tbl WHERE id = getuserid();
+
+ SELECT INTO rid currval('master_tbl_id_seq');
+
+ IF standin IS NOT NULL THEN
+ INSERT INTO nm_benutzer_master_tbl(benutzer_id, master_id) VALUES (standin, rid);
+ END IF;
+
+ IF nuuid IS NOT NULL THEN
+ UPDATE master_tbl SET uuid_id = nuuid WHERE id = rid;
+ ELSE
+ PERFORM set_uuid('master_tbl', mid);
+ END IF;
+
+ PERFORM create_status_ds(rid);
+
+ ${CREATE_CHILDREN}
+
+ RETURN rid;
+END;
+$$$$;
+''')
+
class RGNode(object):
def __init__(self, name, min = 1, children = None, parent = None):
@@ -161,6 +260,47 @@
out.append((idx < len(self.children) - 1) and ",\n" or "\n")
out.append("%s])" % ind)
+ def create_create_delete(self, out):
+ if self.children:
+ cout = []
+ for child in self.children:
+ for i in range(child.min):
+ cout.append("PERFORM create_%s(rid, NULL);" % child.name);
+ create_children = "\n ".join(cout);
+ else:
+ create_children = ""
+
+ if self.name == "master_tbl":
+ out.append(CREATE_DELETE_MASTER_TMPL.safe_substitute({
+ 'CREATE_CHILDREN': create_children
+ }))
+ else:
+ if self.parent.name == "master_tbl":
+ select_master = "mid := pid;"
+ else:
+ cout = ["SELECT INTO mid master_tbl.id FROM"]
+ current = self.parent
+ while current.parent:
+ cout.append("%(current)s INNER JOIN %(parent)s ON %(current)s.master_id = %(parent)s.id" % {
+ 'current': current.name,
+ 'parent' : current.parent.name
+ })
+ current = current.parent
+
+ cout.append("WHERE %s.id = pid;" % self.parent.name)
+
+ select_master = "\n ".join(cout)
+
+ out.append(CREATE_DELETE_TMPL.safe_substitute({
+ 'RELATION' : self.name,
+ 'CREATE_CHILDREN' : create_children,
+ 'SELECT_MASTER_ID': select_master
+ }))
+
+ for child in self.children:
+ child.create_create_delete(out)
+
+
def create_triggers(self, out):
if self.parent: # only when not master_tbl
current = self
@@ -210,7 +350,7 @@
@checkMode
def _createRepeatGroup(self, child):
min = child.getMin()
- if not min: min = 1
+ if not min: min = 0
min = int(min)
rg = RGNode(child.getName(), min, [], self.stack[-1])
self.stack.append(rg)
@@ -266,11 +406,16 @@
rg_root.create_triggers(out)
triggers = "".join(out)
+ out = []
+ rg_root.create_create_delete(out)
+ create_delete = "".join(out)
+
f = None
try:
out = SQL_TEMPLATE.safe_substitute({
- "TREE_STRUCTURE": tree_structure,
- "TRIGGERS" : triggers
+ "TREE_STRUCTURE" : tree_structure,
+ "TRIGGERS" : triggers,
+ "CREATE_DELETE_FUNCTIONS": create_delete
})
f = codecs.open(path, "w", "UTF-8")
print >> f, out
More information about the Formed-commits
mailing list