[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