sqlite_authors: add missing expansion
[sqlite-export.git] / patches / export_topo_patch_diff.txt
blob88b3387f7e79b242f341593e086b8189667620a3
1 diff --git a/src/createtopo.cql b/src/createtopo.cql
2 new file mode 100644
3 index 00000000..7f0e31f3
4 --- /dev/null
5 +++ b/src/createtopo.cql
6 @@ -0,0 +1,69 @@
7 +/*
9 +createtopo.cql -- provide topological ordering for fossil export
10 +Copyright (C) 2016 Kyle J. McKay.  All rights reserved.
12 +This program is free software; you can redistribute it and/or
13 +modify it under the terms of the GNU General Public License
14 +as published by the Free Software Foundation; either version 2
15 +of the License, or (at your option) any later version.
17 +This program is distributed in the hope that it will be useful,
18 +but WITHOUT ANY WARRANTY; without even the implied warranty of
19 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 +GNU General Public License for more details.
22 +You should have received a copy of the GNU General Public License
23 +along with this program; if not, write to the Free Software
24 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26 +*/
27 +"BEGIN;\n"
28 +"  DROP TABLE IF EXISTS temp.t_nodes;\n"
29 +"  CREATE TEMP TABLE t_nodes(n INTEGER PRIMARY KEY);\n"
30 +"  DROP TABLE IF EXISTS temp.t_edges;\n"
31 +"  CREATE TEMP TABLE t_edges(rid INTEGER PRIMARY KEY,\n"
32 +"    c INTEGER, p INTEGER, UNIQUE(c, p));\n"
33 +"  CREATE INDEX t_edges_parents ON t_edges(p, c);\n"
34 +"  DROP TABLE IF EXISTS temp.topo_order;\n"
35 +"  CREATE TEMP TABLE topo_order(n INTEGER PRIMARY KEY, ordering INTEGER);\n"
36 +"  CREATE INDEX topo_order_ordering ON topo_order(ordering);\n"
37 +"  DROP TABLE IF EXISTS temp.v_counter;\n"
38 +"  CREATE TEMP TABLE v_counter (v INTEGER DEFAULT 0);\n"
39 +"  INSERT INTO v_counter DEFAULT VALUES;\n"
40 +"  DROP TABLE IF EXISTS temp.v_curnode;\n"
41 +"  CREATE TEMP TABLE v_curnode (v INTEGER DEFAULT 0);\n"
42 +"  INSERT INTO v_curnode DEFAULT VALUES;\n"
43 +"  INSERT INTO t_nodes\n"
44 +"  SELECT objid FROM event JOIN blob ON objid = rid WHERE type = 'ci';\n"
45 +"  INSERT INTO t_edges (c, p)\n"
46 +"  SELECT plink.cid, plink.pid FROM t_nodes t1, t_nodes t2, plink\n"
47 +"  WHERE t1.n = plink.cid AND t2.n = plink.pid AND plink.cid != plink.pid;\n"
48 +"  INSERT INTO topo_order\n"
49 +"  SELECT n, NULL FROM t_nodes LEFT JOIN t_edges ON n = c WHERE p IS NULL;\n"
50 +"  DROP VIEW IF EXISTS temp.t_tsort;\n"
51 +"  CREATE TEMP VIEW t_tsort AS SELECT NULL;\n"
52 +"  CREATE TRIGGER t_tsort_code INSTEAD OF INSERT ON t_tsort\n"
53 +"  WHEN EXISTS (SELECT n FROM topo_order WHERE ordering IS NULL LIMIT 1)\n"
54 +"  BEGIN\n"
55 +"    UPDATE v_curnode SET v =\n"
56 +"    (SELECT n FROM topo_order WHERE ordering IS NULL LIMIT 1);\n"
57 +"    UPDATE v_counter SET v = v + 1;\n"
58 +"    UPDATE topo_order SET ordering = (SELECT v FROM v_counter)\n"
59 +"    WHERE n = (SELECT v FROM v_curnode);\n"
60 +"    INSERT INTO topo_order (n, ordering)\n"
61 +"    SELECT n, NULL\n"
62 +"    FROM t_nodes t\n"
63 +"    JOIN t_edges e1 ON t.n = e1.c\n"
64 +"    WHERE e1.p = (SELECT v FROM v_curnode) AND\n"
65 +"      NOT EXISTS (SELECT NULL FROM t_edges e2\n"
66 +"        WHERE e2.c = t.n AND e2.p != (SELECT v FROM v_curnode LIMIT 1));\n"
67 +"    DELETE FROM t_edges WHERE p = (SELECT v FROM v_curnode);\n"
68 +"  END;\n"
69 +"  INSERT INTO t_tsort SELECT n FROM t_nodes;\n"
70 +"  DROP VIEW temp.t_tsort;\n"
71 +"  DROP TABLE temp.v_curnode;\n"
72 +"  DROP TABLE temp.v_counter;\n"
73 +"  DROP TABLE temp.t_edges;\n"
74 +"  DROP TABLE temp.t_nodes;\n"
75 +"COMMIT;\n"
76 diff --git a/src/export.c b/src/export.c
77 index d7b48774..abda76c7 100644
78 --- a/src/export.c
79 +++ b/src/export.c
80 @@ -444,6 +444,10 @@ static void massage_refname(char *ref)
81    }
82  }
84 +static const char zCreateTopoOrder[] =
85 +#include "createtopo.cql"
88  /*
89  ** COMMAND: export
90  **
91 @@ -558,6 +562,10 @@ void export_cmd(void){
92    if( done_flag )
93      printf("feature done\n");
95 +  /* Step 0:  Create a proper topological ordering of the DAG
96 +  */
97 +  db_multi_exec(zCreateTopoOrder/*works-like:""*/);
99    /* Step 1:  Generate "blob" records for every artifact that is part
100    ** of a check-in
101    */
102 @@ -618,9 +626,9 @@ void export_cmd(void){
103      "SELECT strftime('%%s',mtime), objid, coalesce(ecomment,comment),"
104      "       coalesce(euser,user),"
105      "       (SELECT value FROM tagxref WHERE rid=objid AND tagid=%d)"
106 -    "  FROM event"
107 +    "  FROM event JOIN topo_order ON objid = n"
108      " WHERE type='ci' AND NOT EXISTS (SELECT 1 FROM oldcommit WHERE objid=rid)"
109 -    " ORDER BY mtime ASC",
110 +    " ORDER BY ordering ASC, mtime ASC",
111      TAG_BRANCH
112    );
113    db_prepare(&q2, "INSERT INTO oldcommit VALUES (:rid)");
114 @@ -665,9 +673,9 @@ void export_cmd(void){
115        printf("data %d\n%s\n\n", (int)strlen(zComment)+1, zComment);
116      }
117      db_prepare(&q3,
118 -      "SELECT pid FROM plink"
119 +      "SELECT pid FROM plink, event"
120        " WHERE cid=%d AND isprim"
121 -      "   AND pid IN (SELECT objid FROM event)",
122 +      "   AND pid=objid AND type='ci'",
123        ckinId
124      );
125      if( db_step(&q3) == SQLITE_ROW ){
126 @@ -676,9 +684,9 @@ void export_cmd(void){
127        printf("from %s\n", zMark);
128        free(zMark);
129        db_prepare(&q4,
130 -        "SELECT pid FROM plink"
131 +        "SELECT pid FROM plink, event"
132          " WHERE cid=%d AND NOT isprim"
133 -        "   AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)"
134 +        "   AND pid=objid AND type='ci'"
135          " ORDER BY pid",
136          ckinId);
137        while( db_step(&q4)==SQLITE_ROW ){