#
# patch "ChangeLog"
# from [033b5fcc67eead39c3efad6b7314ef1c15525d6d]
# to [eae32b0ac132ce4c767df1c4697a43ff2898764a]
#
# patch "database.cc"
# from [c81a8c8cfaf1f6e1257d85470af1cd1f19b98e11]
# to [9fdad7cd836e53714c0a49fd1ac5510116525d72]
#
# patch "schema.sql"
# from [bd96fb52f2c501654f10445a6b8a7cfb6ea01019]
# to [ac99524347304a61fe2d857bc45d1bcca73adb6e]
#
# patch "schema_migration.cc"
# from [454fd869cecba6ce84ee4da05463441a2500f02b]
# to [dbe70c577761111a22e6bc47649411c335399bdf]
#
# patch "tests/t_migrate_schema.at"
# from [7e974a62fd0095b4a95d09eb1780d4744fe506e9]
# to [a5021d066df05e23620346dbc5cf480377af160f]
#
--- ChangeLog
+++ ChangeLog
@@ -1,7 +1,19 @@
+2005-07-09 Nathaniel Smith
+
+ * schema.sql (revision_ancestry__child, revision_certs__id,
+ revision_certs__name_value): New indexes.
+ * database.cc (dump, dump_table_cb, dump_index_cb): Include
+ indexes in dumps.
+ (database::database):
+ * schema_migration.cc (migrate_monotone_schema)
+ (migrate_client_to_add_indexes):
+ * tests/t_migrate_schema.at: Corresponding migration gunk.
+
2005-07-09 Jordan Breeding
* Makefile.am (monotone_CPPFLAGS, unit_tests_CPPFLAGS):
- * configure.ac (BOOST_FIX_VERSION):
+ * configure.ac (BOOST_FIX_VERSION): Restrict boost compile kluges
+ to boost 1.32.
2005-07-10 Matthew Gregan
--- database.cc
+++ database.cc
@@ -118,7 +118,7 @@
// non-alphabetic ordering of tables in sql source files. we could create
// a temporary db, write our intended schema into it, and read it back,
// but this seems like it would be too rude. possibly revisit this issue.
- schema("e372b508bea9b991816d1c74680f7ae10d2a6d94"),
+ schema("1509fd75019aebef5ac3da3a5edf1312393b70e9"),
__sql(NULL),
transaction_level(0)
{}
@@ -305,16 +305,30 @@
I(vals[1] != NULL);
I(vals[2] != NULL);
I(n == 3);
- if (string(vals[1]) == "table")
- {
- *(dump->out) << vals[2] << ";\n";
- dump->table_name = string(vals[0]);
- sqlite3_exec_printf(dump->sql, "SELECT * FROM '%q'",
- dump_row_cb, data, NULL, vals[0]);
- }
+ I(string(vals[1]) == "table");
+ *(dump->out) << vals[2] << ";\n";
+ dump->table_name = string(vals[0]);
+ sqlite3_exec_printf(dump->sql, "SELECT * FROM '%q'",
+ dump_row_cb, data, NULL, vals[0]);
return 0;
}
+static int
+dump_index_cb(void *data, int n, char **vals, char **cols)
+{
+ dump_request *dump = reinterpret_cast(data);
+ I(dump != NULL);
+ I(dump->sql != NULL);
+ I(vals != NULL);
+ I(vals[0] != NULL);
+ I(vals[1] != NULL);
+ I(vals[2] != NULL);
+ I(n == 3);
+ I(string(vals[1]) == "index");
+ *(dump->out) << vals[2] << ";\n";
+ return 0;
+}
+
void
database::dump(ostream & out)
{
@@ -322,12 +336,19 @@
req.out = &out;
req.sql = sql();
out << "BEGIN TRANSACTION;\n";
- int res = sqlite3_exec(req.sql,
+ int res;
+ res = sqlite3_exec(req.sql,
"SELECT name, type, sql FROM sqlite_master "
"WHERE type='table' AND sql NOT NULL "
- "ORDER BY substr(type,2,1), name",
+ "ORDER BY name",
dump_table_cb, &req, NULL);
I(res == SQLITE_OK);
+ res = sqlite3_exec(req.sql,
+ "SELECT name, type, sql FROM sqlite_master "
+ "WHERE type='index' AND sql NOT NULL "
+ "ORDER BY name",
+ dump_index_cb, &req, NULL);
+ I(res == SQLITE_OK);
out << "COMMIT;\n";
}
--- schema.sql
+++ schema.sql
@@ -58,6 +58,8 @@
unique(parent, child)
);
+CREATE INDEX revision_ancestry__child ON revision_ancestry (child);
+
-- structures for managing RSA keys and file / manifest certs
CREATE TABLE public_keys
@@ -96,6 +98,9 @@
unique(name, id, value, keypair, signature)
);
+CREATE INDEX revision_certs__id ON revision_certs (id);
+CREATE INDEX revision_certs__name_value ON revision_certs (name, value);
+
CREATE TABLE branch_epochs
(
hash not null unique, -- hash of remaining fields separated by ":"
--- schema_migration.cc
+++ schema_migration.cc
@@ -718,6 +718,36 @@
return true;
}
+static bool
+migrate_client_to_add_indexes(sqlite3 * sql,
+ char ** errmsg)
+{
+ int res;
+
+ res = sqlite3_exec_printf(sql,
+ "CREATE INDEX revision_ancestry__child "
+ "ON revision_ancestry (child)",
+ NULL, NULL, errmsg);
+ if (res != SQLITE_OK)
+ return false;
+
+ res = sqlite3_exec_printf(sql,
+ "CREATE INDEX revision_certs__id "
+ "ON revision_certs (id);",
+ NULL, NULL, errmsg);
+ if (res != SQLITE_OK)
+ return false;
+
+ res = sqlite3_exec_printf(sql,
+ "CREATE INDEX revision_certs__name_value "
+ "ON revision_certs (name, value);",
+ NULL, NULL, errmsg);
+ if (res != SQLITE_OK)
+ return false;
+
+ return true;
+}
+
void
migrate_monotone_schema(sqlite3 *sql)
{
@@ -739,11 +769,14 @@
m.add("40369a7bda66463c5785d160819ab6398b9d44f4",
&migrate_client_to_vars);
+ m.add("e372b508bea9b991816d1c74680f7ae10d2a6d94",
+ &migrate_client_to_add_indexes);
+
// IMPORTANT: whenever you modify this to add a new schema version, you must
// also add a new migration test for the new schema version. See
// tests/t_migrate_schema.at for details.
- m.migrate(sql, "e372b508bea9b991816d1c74680f7ae10d2a6d94");
+ m.migrate(sql, "1509fd75019aebef5ac3da3a5edf1312393b70e9");
if (sqlite3_exec(sql, "VACUUM", NULL, NULL, NULL) != SQLITE_OK)
throw runtime_error("error vacuuming after migration");
--- tests/t_migrate_schema.at
+++ tests/t_migrate_schema.at
@@ -19,10 +19,10 @@
# this will cause autotest to leave behind the temporary files the
# test generates. You want 'testsuite.dir/073/latest.db.dump'. Gzip
# it, base64 it, and stick it in this file with the id of its schema.
-# (E.g., gzip -c latest.db | mimencode > foo, then copy the contents
-# of foo into this file. Make sure when you do that that you put a
-# newline between the end of the base64'd text and the closing ], or
-# autotest will get very weirdly confused.)
+# (E.g., gzip -c latest.db.dump | mimencode > foo, then copy the
+# contents of foo into this file. Make sure when you do that that you
+# put a newline between the end of the base64'd text and the closing
+# ], or autotest will get very weirdly confused.)
######################################################################
## Do not touch this code; you'll have to regenerate all the test
@@ -555,4 +555,152 @@
dRaSpiDUOiwLrVwURaqtJBHUjCgUc8BscXJrLqC4yEX3CNWGT2AikQWB7a4bJTGEZKsmUwxz
ixPhjyXgfnuC3tA02frPzf8CKk8cw5M9AAA=
])
+
+CHECK_MIGRATE_FROM([1509fd75019aebef5ac3da3a5edf1312393b70e9],
+[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
+])
+
AT_CLEANUP