Fossil SCM
On-the-fly schema updates. No "fossil rebuild" needed when moving to Fossil 2.0.
Commit
94f4c0aab5678f83f82e5ee44876acd606a48d7c
Parent
89077b05bf0a906…
2 files changed
+5
-23
+69
-81
M
src/db.c
+5
-23
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -1486,33 +1486,15 @@ | ||
| 1486 | 1486 | /* Cache "allow-symlinks" option, because we'll need it on every stat call */ |
| 1487 | 1487 | g.allowSymlinks = db_get_boolean("allow-symlinks", |
| 1488 | 1488 | db_allow_symlinks_by_default()); |
| 1489 | 1489 | g.zAuxSchema = db_get("aux-schema",""); |
| 1490 | 1490 | |
| 1491 | - /* Verify that the PLINK table has a new column added by the | |
| 1492 | - ** 2014-11-28 schema change. Create it if necessary. This code | |
| 1493 | - ** can be removed in the future, once all users have upgraded to the | |
| 1494 | - ** 2014-11-28 or later schema. | |
| 1495 | - */ | |
| 1496 | - if( !db_table_has_column("repository","plink","baseid") ){ | |
| 1497 | - db_multi_exec( | |
| 1498 | - "ALTER TABLE repository.plink ADD COLUMN baseid;" | |
| 1499 | - ); | |
| 1500 | - } | |
| 1501 | - | |
| 1502 | - /* Verify that the MLINK table has the newer columns added by the | |
| 1503 | - ** 2015-01-24 schema change. Create them if necessary. This code | |
| 1504 | - ** can be removed in the future, once all users have upgraded to the | |
| 1505 | - ** 2015-01-24 or later schema. | |
| 1506 | - */ | |
| 1507 | - if( !db_table_has_column("repository","mlink","isaux") ){ | |
| 1508 | - db_begin_transaction(); | |
| 1509 | - db_multi_exec( | |
| 1510 | - "ALTER TABLE repository.mlink ADD COLUMN pmid INTEGER DEFAULT 0;" | |
| 1511 | - "ALTER TABLE repository.mlink ADD COLUMN isaux BOOLEAN DEFAULT 0;" | |
| 1512 | - ); | |
| 1513 | - db_end_transaction(0); | |
| 1491 | + /* If the ALIAS table is not present, then some on-the-fly schema | |
| 1492 | + ** updates might be required. | |
| 1493 | + */ | |
| 1494 | + if( !db_table_exists("repository","alias") ){ | |
| 1495 | + rebuild_schema_update_2_0(); /* Do the Fossil-2.0 schema updates */ | |
| 1514 | 1496 | } |
| 1515 | 1497 | } |
| 1516 | 1498 | |
| 1517 | 1499 | /* |
| 1518 | 1500 | ** Flags for the db_find_and_open_repository() function. |
| 1519 | 1501 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1486,33 +1486,15 @@ | |
| 1486 | /* Cache "allow-symlinks" option, because we'll need it on every stat call */ |
| 1487 | g.allowSymlinks = db_get_boolean("allow-symlinks", |
| 1488 | db_allow_symlinks_by_default()); |
| 1489 | g.zAuxSchema = db_get("aux-schema",""); |
| 1490 | |
| 1491 | /* Verify that the PLINK table has a new column added by the |
| 1492 | ** 2014-11-28 schema change. Create it if necessary. This code |
| 1493 | ** can be removed in the future, once all users have upgraded to the |
| 1494 | ** 2014-11-28 or later schema. |
| 1495 | */ |
| 1496 | if( !db_table_has_column("repository","plink","baseid") ){ |
| 1497 | db_multi_exec( |
| 1498 | "ALTER TABLE repository.plink ADD COLUMN baseid;" |
| 1499 | ); |
| 1500 | } |
| 1501 | |
| 1502 | /* Verify that the MLINK table has the newer columns added by the |
| 1503 | ** 2015-01-24 schema change. Create them if necessary. This code |
| 1504 | ** can be removed in the future, once all users have upgraded to the |
| 1505 | ** 2015-01-24 or later schema. |
| 1506 | */ |
| 1507 | if( !db_table_has_column("repository","mlink","isaux") ){ |
| 1508 | db_begin_transaction(); |
| 1509 | db_multi_exec( |
| 1510 | "ALTER TABLE repository.mlink ADD COLUMN pmid INTEGER DEFAULT 0;" |
| 1511 | "ALTER TABLE repository.mlink ADD COLUMN isaux BOOLEAN DEFAULT 0;" |
| 1512 | ); |
| 1513 | db_end_transaction(0); |
| 1514 | } |
| 1515 | } |
| 1516 | |
| 1517 | /* |
| 1518 | ** Flags for the db_find_and_open_repository() function. |
| 1519 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1486,33 +1486,15 @@ | |
| 1486 | /* Cache "allow-symlinks" option, because we'll need it on every stat call */ |
| 1487 | g.allowSymlinks = db_get_boolean("allow-symlinks", |
| 1488 | db_allow_symlinks_by_default()); |
| 1489 | g.zAuxSchema = db_get("aux-schema",""); |
| 1490 | |
| 1491 | /* If the ALIAS table is not present, then some on-the-fly schema |
| 1492 | ** updates might be required. |
| 1493 | */ |
| 1494 | if( !db_table_exists("repository","alias") ){ |
| 1495 | rebuild_schema_update_2_0(); /* Do the Fossil-2.0 schema updates */ |
| 1496 | } |
| 1497 | } |
| 1498 | |
| 1499 | /* |
| 1500 | ** Flags for the db_find_and_open_repository() function. |
| 1501 |
+69
-81
| --- src/rebuild.c | ||
| +++ src/rebuild.c | ||
| @@ -20,90 +20,40 @@ | ||
| 20 | 20 | #include "config.h" |
| 21 | 21 | #include "rebuild.h" |
| 22 | 22 | #include <assert.h> |
| 23 | 23 | #include <errno.h> |
| 24 | 24 | |
| 25 | -/* | |
| 26 | -** Make changes to the stable part of the schema (the part that is not | |
| 27 | -** simply deleted and reconstructed on a rebuild) to bring the schema | |
| 28 | -** up to the latest. | |
| 29 | -*/ | |
| 30 | -static const char zSchemaUpdates1[] = | |
| 31 | -@ -- Index on the delta table | |
| 32 | -@ -- | |
| 33 | -@ CREATE INDEX IF NOT EXISTS delta_i1 ON delta(srcid); | |
| 34 | -@ | |
| 35 | -@ -- Artifacts that should not be processed are identified in the | |
| 36 | -@ -- "shun" table. Artifacts that are control-file forgeries or | |
| 37 | -@ -- spam or artifacts whose contents violate administrative policy | |
| 38 | -@ -- can be shunned in order to prevent them from contaminating | |
| 39 | -@ -- the repository. | |
| 40 | -@ -- | |
| 41 | -@ -- Shunned artifacts do not exist in the blob table. Hence they | |
| 42 | -@ -- have not artifact ID (rid) and we thus must store their full | |
| 43 | -@ -- UUID. | |
| 44 | -@ -- | |
| 45 | -@ CREATE TABLE IF NOT EXISTS shun( | |
| 46 | -@ uuid UNIQUE, -- UUID of artifact to be shunned. Canonical form | |
| 47 | -@ mtime INTEGER, -- When added. Seconds since 1970 | |
| 48 | -@ scom TEXT -- Optional text explaining why the shun occurred | |
| 49 | -@ ); | |
| 50 | -@ | |
| 51 | -@ -- Artifacts that should not be pushed are stored in the "private" | |
| 52 | -@ -- table. | |
| 53 | -@ -- | |
| 54 | -@ CREATE TABLE IF NOT EXISTS private(rid INTEGER PRIMARY KEY); | |
| 55 | -@ | |
| 56 | -@ -- Some ticket content (such as the originators email address or contact | |
| 57 | -@ -- information) needs to be obscured to protect privacy. This is achieved | |
| 58 | -@ -- by storing an SHA1 hash of the content. For display, the hash is | |
| 59 | -@ -- mapped back into the original text using this table. | |
| 60 | -@ -- | |
| 61 | -@ -- This table contains sensitive information and should not be shared | |
| 62 | -@ -- with unauthorized users. | |
| 63 | -@ -- | |
| 64 | -@ CREATE TABLE IF NOT EXISTS concealed( | |
| 65 | -@ hash TEXT PRIMARY KEY, -- The SHA1 hash of content | |
| 66 | -@ mtime INTEGER, -- Time created. Seconds since 1970 | |
| 67 | -@ content TEXT -- Content intended to be concealed | |
| 68 | -@ ); | |
| 69 | -; | |
| 70 | -static const char zSchemaUpdates2[] = | |
| 71 | -@ -- An entry in this table describes a database query that generates a | |
| 72 | -@ -- table of tickets. | |
| 73 | -@ -- | |
| 74 | -@ CREATE TABLE IF NOT EXISTS reportfmt( | |
| 75 | -@ rn INTEGER PRIMARY KEY, -- Report number | |
| 76 | -@ owner TEXT, -- Owner of this report format (not used) | |
| 77 | -@ title TEXT UNIQUE, -- Title of this report | |
| 78 | -@ mtime INTEGER, -- Time last modified. Seconds since 1970 | |
| 79 | -@ cols TEXT, -- A color-key specification | |
| 80 | -@ sqlcode TEXT -- An SQL SELECT statement for this report | |
| 81 | -@ ); | |
| 82 | -; | |
| 83 | -static const char zSchemaUpdate3[] = | |
| 84 | -@ -- Make sure the alias table exists. | |
| 85 | -@ -- | |
| 86 | -@ CREATE TABLE repository.alias( | |
| 87 | -@ hval TEXT, -- Hex-encoded hash value | |
| 88 | -@ htype ANY, -- Type of hash. | |
| 89 | -@ rid INTEGER REFERENCES blob, -- Blob that this hash names | |
| 90 | -@ PRIMARY KEY(hval,htype,rid) | |
| 91 | -@ ) WITHOUT ROWID; | |
| 92 | -@ CREATE INDEX alias_rid ON alias(rid); | |
| 93 | -; | |
| 94 | - | |
| 95 | 25 | /* |
| 96 | 26 | ** Update the schema as necessary |
| 97 | 27 | */ |
| 98 | 28 | static void rebuild_update_schema(void){ |
| 99 | - int rc; | |
| 100 | - char *z; | |
| 101 | - db_multi_exec("%s", zSchemaUpdates1 /*safe-for-%s*/); | |
| 102 | - db_multi_exec("%s", zSchemaUpdates2 /*safe-for-%s*/); | |
| 29 | + /* Verify that the PLINK table has a new column added by the | |
| 30 | + ** 2014-11-28 schema change. Create it if necessary. This code | |
| 31 | + ** can be removed in the future, once all users have upgraded to the | |
| 32 | + ** 2014-11-28 or later schema. | |
| 33 | + */ | |
| 34 | + if( !db_table_has_column("repository","plink","baseid") ){ | |
| 35 | + db_multi_exec( | |
| 36 | + "ALTER TABLE repository.plink ADD COLUMN baseid;" | |
| 37 | + ); | |
| 38 | + } | |
| 39 | + | |
| 40 | + /* Verify that the MLINK table has the newer columns added by the | |
| 41 | + ** 2015-01-24 schema change. Create them if necessary. This code | |
| 42 | + ** can be removed in the future, once all users have upgraded to the | |
| 43 | + ** 2015-01-24 or later schema. | |
| 44 | + */ | |
| 45 | + if( !db_table_has_column("repository","mlink","isaux") ){ | |
| 46 | + db_begin_transaction(); | |
| 47 | + db_multi_exec( | |
| 48 | + "ALTER TABLE repository.mlink ADD COLUMN pmid INTEGER DEFAULT 0;" | |
| 49 | + "ALTER TABLE repository.mlink ADD COLUMN isaux BOOLEAN DEFAULT 0;" | |
| 50 | + ); | |
| 51 | + db_end_transaction(0); | |
| 52 | + } | |
| 103 | 53 | |
| 104 | - /* Add the user.mtime column if it is missing. | |
| 54 | + /* Add the user.mtime column if it is missing. (2011-04-27) | |
| 105 | 55 | */ |
| 106 | 56 | if( !db_table_has_column("repository", "user", "mtime") ){ |
| 107 | 57 | db_multi_exec( |
| 108 | 58 | "CREATE TEMP TABLE temp_user AS SELECT * FROM user;" |
| 109 | 59 | "DROP TABLE user;" |
| @@ -124,58 +74,97 @@ | ||
| 124 | 74 | " ipaddr, cexpire, info, now(), photo FROM temp_user;" |
| 125 | 75 | "DROP TABLE temp_user;" |
| 126 | 76 | ); |
| 127 | 77 | } |
| 128 | 78 | |
| 129 | - /* Add the config.mtime column if it is missing. | |
| 79 | + /* Add the config.mtime column if it is missing. (2011-04-27) | |
| 130 | 80 | */ |
| 131 | 81 | if( !db_table_has_column("repository", "config", "mtime") ){ |
| 132 | 82 | db_multi_exec( |
| 133 | 83 | "ALTER TABLE config ADD COLUMN mtime INTEGER;" |
| 134 | 84 | "UPDATE config SET mtime=now();" |
| 135 | 85 | ); |
| 136 | 86 | } |
| 137 | 87 | |
| 138 | 88 | /* Add the shun.mtime and shun.scom columns if they are missing. |
| 89 | + ** (2011-04-27) | |
| 139 | 90 | */ |
| 140 | 91 | if( !db_table_has_column("repository", "shun", "mtime") ){ |
| 141 | 92 | db_multi_exec( |
| 142 | 93 | "ALTER TABLE shun ADD COLUMN mtime INTEGER;" |
| 143 | 94 | "ALTER TABLE shun ADD COLUMN scom TEXT;" |
| 144 | 95 | "UPDATE shun SET mtime=now();" |
| 145 | 96 | ); |
| 146 | 97 | } |
| 147 | 98 | |
| 148 | - /* Add the reportfmt.mtime column if it is missing. | |
| 99 | + /* Add the reportfmt.mtime column if it is missing. (2011-04-27) | |
| 149 | 100 | */ |
| 150 | 101 | if( !db_table_has_column("repository", "reportfmt", "mtime") ){ |
| 102 | + static const char zCreateReportFmtTable[] = | |
| 103 | + @ -- An entry in this table describes a database query that generates a | |
| 104 | + @ -- table of tickets. | |
| 105 | + @ -- | |
| 106 | + @ CREATE TABLE IF NOT EXISTS reportfmt( | |
| 107 | + @ rn INTEGER PRIMARY KEY, -- Report number | |
| 108 | + @ owner TEXT, -- Owner of this report format (not used) | |
| 109 | + @ title TEXT UNIQUE, -- Title of this report | |
| 110 | + @ mtime INTEGER, -- Time last modified. Seconds since 1970 | |
| 111 | + @ cols TEXT, -- A color-key specification | |
| 112 | + @ sqlcode TEXT -- An SQL SELECT statement for this report | |
| 113 | + @ ); | |
| 114 | + ; | |
| 151 | 115 | db_multi_exec( |
| 152 | 116 | "CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;" |
| 153 | 117 | "DROP TABLE reportfmt;" |
| 154 | 118 | ); |
| 155 | - db_multi_exec("%s", zSchemaUpdates2/*safe-for-%s*/); | |
| 119 | + db_multi_exec("%s", zCreateReportFmtTable/*safe-for-%s*/); | |
| 156 | 120 | db_multi_exec( |
| 157 | 121 | "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)" |
| 158 | 122 | " SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;" |
| 159 | 123 | "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)" |
| 160 | 124 | " SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()" |
| 161 | 125 | " FROM old_fmt;" |
| 162 | 126 | ); |
| 163 | 127 | } |
| 164 | 128 | |
| 165 | - /* Add the concealed.mtime column if it is missing. | |
| 129 | + /* Add the concealed.mtime column if it is missing. (2011-04-27) | |
| 166 | 130 | */ |
| 167 | 131 | if( !db_table_has_column("repository", "concealed", "mtime") ){ |
| 168 | 132 | db_multi_exec( |
| 169 | 133 | "ALTER TABLE concealed ADD COLUMN mtime INTEGER;" |
| 170 | 134 | "UPDATE concealed SET mtime=now();" |
| 171 | 135 | ); |
| 172 | 136 | } |
| 173 | 137 | |
| 138 | + /* Do the fossil-2.0 updates to the schema. (2017-02-28) | |
| 139 | + */ | |
| 140 | + rebuild_schema_update_2_0(); | |
| 141 | +} | |
| 142 | + | |
| 143 | +/* | |
| 144 | +** Update the repository schema for Fossil version 2.0. (2017-02-28) | |
| 145 | +** (1) Create the ALIAS table | |
| 146 | +** (2) Change the CHECK constraint on BLOB.UUID so that the length | |
| 147 | +** is greater than or equal to 40, not exactly equal to 40. | |
| 148 | +*/ | |
| 149 | +void rebuild_schema_update_2_0(void){ | |
| 150 | + static const char zCreateAliasTable[] = | |
| 151 | + @ -- Make sure the alias table exists. | |
| 152 | + @ -- | |
| 153 | + @ CREATE TABLE repository.alias( | |
| 154 | + @ hval TEXT, -- Hex-encoded hash value | |
| 155 | + @ htype ANY, -- Type of hash. | |
| 156 | + @ rid INTEGER REFERENCES blob, -- Blob that this hash names | |
| 157 | + @ PRIMARY KEY(hval,htype,rid) | |
| 158 | + @ ) WITHOUT ROWID; | |
| 159 | + @ CREATE INDEX repository.alias_rid ON alias(rid); | |
| 160 | + ; | |
| 161 | + char *z; | |
| 162 | + | |
| 174 | 163 | /* If the alias table is missing, create it. */ |
| 175 | 164 | if( !db_table_exists("repository", "alias") ){ |
| 176 | - db_multi_exec("%s", zSchemaUpdate3/*safe-for-%s*/); | |
| 165 | + db_multi_exec("%s", zCreateAliasTable/*safe-for-%s*/); | |
| 177 | 166 | } |
| 178 | 167 | |
| 179 | 168 | /* Make sure the CHECK constraint on the BLOB table says "length(uuid)>=40" |
| 180 | 169 | ** instead of "length(uuid)==40". */ |
| 181 | 170 | z = db_text(0, "SELECT sql FROM repository.sqlite_master WHERE" |
| @@ -196,11 +185,10 @@ | ||
| 196 | 185 | break; |
| 197 | 186 | } |
| 198 | 187 | } |
| 199 | 188 | fossil_free(z); |
| 200 | 189 | } |
| 201 | - | |
| 202 | 190 | } |
| 203 | 191 | |
| 204 | 192 | /* |
| 205 | 193 | ** Variables used to store state information about an on-going "rebuild" |
| 206 | 194 | ** or "deconstruct". |
| 207 | 195 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -20,90 +20,40 @@ | |
| 20 | #include "config.h" |
| 21 | #include "rebuild.h" |
| 22 | #include <assert.h> |
| 23 | #include <errno.h> |
| 24 | |
| 25 | /* |
| 26 | ** Make changes to the stable part of the schema (the part that is not |
| 27 | ** simply deleted and reconstructed on a rebuild) to bring the schema |
| 28 | ** up to the latest. |
| 29 | */ |
| 30 | static const char zSchemaUpdates1[] = |
| 31 | @ -- Index on the delta table |
| 32 | @ -- |
| 33 | @ CREATE INDEX IF NOT EXISTS delta_i1 ON delta(srcid); |
| 34 | @ |
| 35 | @ -- Artifacts that should not be processed are identified in the |
| 36 | @ -- "shun" table. Artifacts that are control-file forgeries or |
| 37 | @ -- spam or artifacts whose contents violate administrative policy |
| 38 | @ -- can be shunned in order to prevent them from contaminating |
| 39 | @ -- the repository. |
| 40 | @ -- |
| 41 | @ -- Shunned artifacts do not exist in the blob table. Hence they |
| 42 | @ -- have not artifact ID (rid) and we thus must store their full |
| 43 | @ -- UUID. |
| 44 | @ -- |
| 45 | @ CREATE TABLE IF NOT EXISTS shun( |
| 46 | @ uuid UNIQUE, -- UUID of artifact to be shunned. Canonical form |
| 47 | @ mtime INTEGER, -- When added. Seconds since 1970 |
| 48 | @ scom TEXT -- Optional text explaining why the shun occurred |
| 49 | @ ); |
| 50 | @ |
| 51 | @ -- Artifacts that should not be pushed are stored in the "private" |
| 52 | @ -- table. |
| 53 | @ -- |
| 54 | @ CREATE TABLE IF NOT EXISTS private(rid INTEGER PRIMARY KEY); |
| 55 | @ |
| 56 | @ -- Some ticket content (such as the originators email address or contact |
| 57 | @ -- information) needs to be obscured to protect privacy. This is achieved |
| 58 | @ -- by storing an SHA1 hash of the content. For display, the hash is |
| 59 | @ -- mapped back into the original text using this table. |
| 60 | @ -- |
| 61 | @ -- This table contains sensitive information and should not be shared |
| 62 | @ -- with unauthorized users. |
| 63 | @ -- |
| 64 | @ CREATE TABLE IF NOT EXISTS concealed( |
| 65 | @ hash TEXT PRIMARY KEY, -- The SHA1 hash of content |
| 66 | @ mtime INTEGER, -- Time created. Seconds since 1970 |
| 67 | @ content TEXT -- Content intended to be concealed |
| 68 | @ ); |
| 69 | ; |
| 70 | static const char zSchemaUpdates2[] = |
| 71 | @ -- An entry in this table describes a database query that generates a |
| 72 | @ -- table of tickets. |
| 73 | @ -- |
| 74 | @ CREATE TABLE IF NOT EXISTS reportfmt( |
| 75 | @ rn INTEGER PRIMARY KEY, -- Report number |
| 76 | @ owner TEXT, -- Owner of this report format (not used) |
| 77 | @ title TEXT UNIQUE, -- Title of this report |
| 78 | @ mtime INTEGER, -- Time last modified. Seconds since 1970 |
| 79 | @ cols TEXT, -- A color-key specification |
| 80 | @ sqlcode TEXT -- An SQL SELECT statement for this report |
| 81 | @ ); |
| 82 | ; |
| 83 | static const char zSchemaUpdate3[] = |
| 84 | @ -- Make sure the alias table exists. |
| 85 | @ -- |
| 86 | @ CREATE TABLE repository.alias( |
| 87 | @ hval TEXT, -- Hex-encoded hash value |
| 88 | @ htype ANY, -- Type of hash. |
| 89 | @ rid INTEGER REFERENCES blob, -- Blob that this hash names |
| 90 | @ PRIMARY KEY(hval,htype,rid) |
| 91 | @ ) WITHOUT ROWID; |
| 92 | @ CREATE INDEX alias_rid ON alias(rid); |
| 93 | ; |
| 94 | |
| 95 | /* |
| 96 | ** Update the schema as necessary |
| 97 | */ |
| 98 | static void rebuild_update_schema(void){ |
| 99 | int rc; |
| 100 | char *z; |
| 101 | db_multi_exec("%s", zSchemaUpdates1 /*safe-for-%s*/); |
| 102 | db_multi_exec("%s", zSchemaUpdates2 /*safe-for-%s*/); |
| 103 | |
| 104 | /* Add the user.mtime column if it is missing. |
| 105 | */ |
| 106 | if( !db_table_has_column("repository", "user", "mtime") ){ |
| 107 | db_multi_exec( |
| 108 | "CREATE TEMP TABLE temp_user AS SELECT * FROM user;" |
| 109 | "DROP TABLE user;" |
| @@ -124,58 +74,97 @@ | |
| 124 | " ipaddr, cexpire, info, now(), photo FROM temp_user;" |
| 125 | "DROP TABLE temp_user;" |
| 126 | ); |
| 127 | } |
| 128 | |
| 129 | /* Add the config.mtime column if it is missing. |
| 130 | */ |
| 131 | if( !db_table_has_column("repository", "config", "mtime") ){ |
| 132 | db_multi_exec( |
| 133 | "ALTER TABLE config ADD COLUMN mtime INTEGER;" |
| 134 | "UPDATE config SET mtime=now();" |
| 135 | ); |
| 136 | } |
| 137 | |
| 138 | /* Add the shun.mtime and shun.scom columns if they are missing. |
| 139 | */ |
| 140 | if( !db_table_has_column("repository", "shun", "mtime") ){ |
| 141 | db_multi_exec( |
| 142 | "ALTER TABLE shun ADD COLUMN mtime INTEGER;" |
| 143 | "ALTER TABLE shun ADD COLUMN scom TEXT;" |
| 144 | "UPDATE shun SET mtime=now();" |
| 145 | ); |
| 146 | } |
| 147 | |
| 148 | /* Add the reportfmt.mtime column if it is missing. |
| 149 | */ |
| 150 | if( !db_table_has_column("repository", "reportfmt", "mtime") ){ |
| 151 | db_multi_exec( |
| 152 | "CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;" |
| 153 | "DROP TABLE reportfmt;" |
| 154 | ); |
| 155 | db_multi_exec("%s", zSchemaUpdates2/*safe-for-%s*/); |
| 156 | db_multi_exec( |
| 157 | "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)" |
| 158 | " SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;" |
| 159 | "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)" |
| 160 | " SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()" |
| 161 | " FROM old_fmt;" |
| 162 | ); |
| 163 | } |
| 164 | |
| 165 | /* Add the concealed.mtime column if it is missing. |
| 166 | */ |
| 167 | if( !db_table_has_column("repository", "concealed", "mtime") ){ |
| 168 | db_multi_exec( |
| 169 | "ALTER TABLE concealed ADD COLUMN mtime INTEGER;" |
| 170 | "UPDATE concealed SET mtime=now();" |
| 171 | ); |
| 172 | } |
| 173 | |
| 174 | /* If the alias table is missing, create it. */ |
| 175 | if( !db_table_exists("repository", "alias") ){ |
| 176 | db_multi_exec("%s", zSchemaUpdate3/*safe-for-%s*/); |
| 177 | } |
| 178 | |
| 179 | /* Make sure the CHECK constraint on the BLOB table says "length(uuid)>=40" |
| 180 | ** instead of "length(uuid)==40". */ |
| 181 | z = db_text(0, "SELECT sql FROM repository.sqlite_master WHERE" |
| @@ -196,11 +185,10 @@ | |
| 196 | break; |
| 197 | } |
| 198 | } |
| 199 | fossil_free(z); |
| 200 | } |
| 201 | |
| 202 | } |
| 203 | |
| 204 | /* |
| 205 | ** Variables used to store state information about an on-going "rebuild" |
| 206 | ** or "deconstruct". |
| 207 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -20,90 +20,40 @@ | |
| 20 | #include "config.h" |
| 21 | #include "rebuild.h" |
| 22 | #include <assert.h> |
| 23 | #include <errno.h> |
| 24 | |
| 25 | /* |
| 26 | ** Update the schema as necessary |
| 27 | */ |
| 28 | static void rebuild_update_schema(void){ |
| 29 | /* Verify that the PLINK table has a new column added by the |
| 30 | ** 2014-11-28 schema change. Create it if necessary. This code |
| 31 | ** can be removed in the future, once all users have upgraded to the |
| 32 | ** 2014-11-28 or later schema. |
| 33 | */ |
| 34 | if( !db_table_has_column("repository","plink","baseid") ){ |
| 35 | db_multi_exec( |
| 36 | "ALTER TABLE repository.plink ADD COLUMN baseid;" |
| 37 | ); |
| 38 | } |
| 39 | |
| 40 | /* Verify that the MLINK table has the newer columns added by the |
| 41 | ** 2015-01-24 schema change. Create them if necessary. This code |
| 42 | ** can be removed in the future, once all users have upgraded to the |
| 43 | ** 2015-01-24 or later schema. |
| 44 | */ |
| 45 | if( !db_table_has_column("repository","mlink","isaux") ){ |
| 46 | db_begin_transaction(); |
| 47 | db_multi_exec( |
| 48 | "ALTER TABLE repository.mlink ADD COLUMN pmid INTEGER DEFAULT 0;" |
| 49 | "ALTER TABLE repository.mlink ADD COLUMN isaux BOOLEAN DEFAULT 0;" |
| 50 | ); |
| 51 | db_end_transaction(0); |
| 52 | } |
| 53 | |
| 54 | /* Add the user.mtime column if it is missing. (2011-04-27) |
| 55 | */ |
| 56 | if( !db_table_has_column("repository", "user", "mtime") ){ |
| 57 | db_multi_exec( |
| 58 | "CREATE TEMP TABLE temp_user AS SELECT * FROM user;" |
| 59 | "DROP TABLE user;" |
| @@ -124,58 +74,97 @@ | |
| 74 | " ipaddr, cexpire, info, now(), photo FROM temp_user;" |
| 75 | "DROP TABLE temp_user;" |
| 76 | ); |
| 77 | } |
| 78 | |
| 79 | /* Add the config.mtime column if it is missing. (2011-04-27) |
| 80 | */ |
| 81 | if( !db_table_has_column("repository", "config", "mtime") ){ |
| 82 | db_multi_exec( |
| 83 | "ALTER TABLE config ADD COLUMN mtime INTEGER;" |
| 84 | "UPDATE config SET mtime=now();" |
| 85 | ); |
| 86 | } |
| 87 | |
| 88 | /* Add the shun.mtime and shun.scom columns if they are missing. |
| 89 | ** (2011-04-27) |
| 90 | */ |
| 91 | if( !db_table_has_column("repository", "shun", "mtime") ){ |
| 92 | db_multi_exec( |
| 93 | "ALTER TABLE shun ADD COLUMN mtime INTEGER;" |
| 94 | "ALTER TABLE shun ADD COLUMN scom TEXT;" |
| 95 | "UPDATE shun SET mtime=now();" |
| 96 | ); |
| 97 | } |
| 98 | |
| 99 | /* Add the reportfmt.mtime column if it is missing. (2011-04-27) |
| 100 | */ |
| 101 | if( !db_table_has_column("repository", "reportfmt", "mtime") ){ |
| 102 | static const char zCreateReportFmtTable[] = |
| 103 | @ -- An entry in this table describes a database query that generates a |
| 104 | @ -- table of tickets. |
| 105 | @ -- |
| 106 | @ CREATE TABLE IF NOT EXISTS reportfmt( |
| 107 | @ rn INTEGER PRIMARY KEY, -- Report number |
| 108 | @ owner TEXT, -- Owner of this report format (not used) |
| 109 | @ title TEXT UNIQUE, -- Title of this report |
| 110 | @ mtime INTEGER, -- Time last modified. Seconds since 1970 |
| 111 | @ cols TEXT, -- A color-key specification |
| 112 | @ sqlcode TEXT -- An SQL SELECT statement for this report |
| 113 | @ ); |
| 114 | ; |
| 115 | db_multi_exec( |
| 116 | "CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;" |
| 117 | "DROP TABLE reportfmt;" |
| 118 | ); |
| 119 | db_multi_exec("%s", zCreateReportFmtTable/*safe-for-%s*/); |
| 120 | db_multi_exec( |
| 121 | "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)" |
| 122 | " SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;" |
| 123 | "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)" |
| 124 | " SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()" |
| 125 | " FROM old_fmt;" |
| 126 | ); |
| 127 | } |
| 128 | |
| 129 | /* Add the concealed.mtime column if it is missing. (2011-04-27) |
| 130 | */ |
| 131 | if( !db_table_has_column("repository", "concealed", "mtime") ){ |
| 132 | db_multi_exec( |
| 133 | "ALTER TABLE concealed ADD COLUMN mtime INTEGER;" |
| 134 | "UPDATE concealed SET mtime=now();" |
| 135 | ); |
| 136 | } |
| 137 | |
| 138 | /* Do the fossil-2.0 updates to the schema. (2017-02-28) |
| 139 | */ |
| 140 | rebuild_schema_update_2_0(); |
| 141 | } |
| 142 | |
| 143 | /* |
| 144 | ** Update the repository schema for Fossil version 2.0. (2017-02-28) |
| 145 | ** (1) Create the ALIAS table |
| 146 | ** (2) Change the CHECK constraint on BLOB.UUID so that the length |
| 147 | ** is greater than or equal to 40, not exactly equal to 40. |
| 148 | */ |
| 149 | void rebuild_schema_update_2_0(void){ |
| 150 | static const char zCreateAliasTable[] = |
| 151 | @ -- Make sure the alias table exists. |
| 152 | @ -- |
| 153 | @ CREATE TABLE repository.alias( |
| 154 | @ hval TEXT, -- Hex-encoded hash value |
| 155 | @ htype ANY, -- Type of hash. |
| 156 | @ rid INTEGER REFERENCES blob, -- Blob that this hash names |
| 157 | @ PRIMARY KEY(hval,htype,rid) |
| 158 | @ ) WITHOUT ROWID; |
| 159 | @ CREATE INDEX repository.alias_rid ON alias(rid); |
| 160 | ; |
| 161 | char *z; |
| 162 | |
| 163 | /* If the alias table is missing, create it. */ |
| 164 | if( !db_table_exists("repository", "alias") ){ |
| 165 | db_multi_exec("%s", zCreateAliasTable/*safe-for-%s*/); |
| 166 | } |
| 167 | |
| 168 | /* Make sure the CHECK constraint on the BLOB table says "length(uuid)>=40" |
| 169 | ** instead of "length(uuid)==40". */ |
| 170 | z = db_text(0, "SELECT sql FROM repository.sqlite_master WHERE" |
| @@ -196,11 +185,10 @@ | |
| 185 | break; |
| 186 | } |
| 187 | } |
| 188 | fossil_free(z); |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | /* |
| 193 | ** Variables used to store state information about an on-going "rebuild" |
| 194 | ** or "deconstruct". |
| 195 |