diff options
Diffstat (limited to 'subversion/libsvn_wc/wc-metadata.sql')
-rw-r--r-- | subversion/libsvn_wc/wc-metadata.sql | 951 |
1 files changed, 951 insertions, 0 deletions
diff --git a/subversion/libsvn_wc/wc-metadata.sql b/subversion/libsvn_wc/wc-metadata.sql new file mode 100644 index 0000000..d2a6161 --- /dev/null +++ b/subversion/libsvn_wc/wc-metadata.sql @@ -0,0 +1,951 @@ +/* wc-metadata.sql -- schema used in the wc-metadata SQLite database + * This is intended for use with SQLite 3 + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ + +/* + * the KIND column in these tables has one of the following values + * (documented in the corresponding C type #svn_kind_t): + * "file" + * "dir" + * "symlink" + * "unknown" + * + * the PRESENCE column in these tables has one of the following values + * (see also the C type #svn_wc__db_status_t): + * "normal" + * "server-excluded" -- server has declared it excluded (ie. authz failure) + * "excluded" -- administratively excluded (ie. sparse WC) + * "not-present" -- node not present at this REV + * "incomplete" -- state hasn't been filled in + * "base-deleted" -- node represents a delete of a BASE node + */ + +/* One big list of statements to create our (current) schema. */ +-- STMT_CREATE_SCHEMA + +/* ------------------------------------------------------------------------- */ + +CREATE TABLE REPOSITORY ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + /* The root URL of the repository. This value is URI-encoded. */ + root TEXT UNIQUE NOT NULL, + + /* the UUID of the repository */ + uuid TEXT NOT NULL + ); + +/* Note: a repository (identified by its UUID) may appear at multiple URLs. + For example, http://example.com/repos/ and https://example.com/repos/. */ +CREATE INDEX I_UUID ON REPOSITORY (uuid); +CREATE INDEX I_ROOT ON REPOSITORY (root); + + +/* ------------------------------------------------------------------------- */ + +CREATE TABLE WCROOT ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + /* absolute path in the local filesystem. NULL if storing metadata in + the wcroot itself. */ + local_abspath TEXT UNIQUE + ); + +CREATE UNIQUE INDEX I_LOCAL_ABSPATH ON WCROOT (local_abspath); + + +/* ------------------------------------------------------------------------- */ + +/* The PRISTINE table keeps track of pristine texts. Each row describes a + single pristine text. The text itself is stored in a file whose name is + derived from the 'checksum' column. Each pristine text is referenced by + any number of rows in the NODES and ACTUAL_NODE tables. + + In future, the pristine text file may be compressed. + */ +CREATE TABLE PRISTINE ( + /* The SHA-1 checksum of the pristine text. This is a unique key. The + SHA-1 checksum of a pristine text is assumed to be unique among all + pristine texts referenced from this database. */ + checksum TEXT NOT NULL PRIMARY KEY, + + /* Enumerated values specifying type of compression. The only value + supported so far is NULL, meaning that no compression has been applied + and the pristine text is stored verbatim in the file. */ + compression INTEGER, + + /* The size in bytes of the file in which the pristine text is stored. + Used to verify the pristine file is "proper". */ + size INTEGER NOT NULL, + + /* The number of rows in the NODES table that have a 'checksum' column + value that refers to this row. (References in other places, such as + in the ACTUAL_NODE table, are not counted.) */ + refcount INTEGER NOT NULL, + + /* Alternative MD5 checksum used for communicating with older + repositories. Not strictly guaranteed to be unique among table rows. */ + md5_checksum TEXT NOT NULL + ); + +CREATE INDEX I_PRISTINE_MD5 ON PRISTINE (md5_checksum); + +/* ------------------------------------------------------------------------- */ + +/* The ACTUAL_NODE table describes text changes and property changes + on each node in the WC, relative to the NODES table row for the + same path. (A NODES row must exist if this node exists, but an + ACTUAL_NODE row can exist on its own if it is just recording info + on a non-present node - a tree conflict or a changelist, for + example.) + + The ACTUAL_NODE table row for a given path exists if the node at that + path is known to have text or property changes relative to its + NODES row. ("Is known" because a text change on disk may not yet + have been discovered and recorded here.) + + The ACTUAL_NODE table row for a given path may also exist in other cases, + including if the "changelist" or any of the conflict columns have a + non-null value. + */ +CREATE TABLE ACTUAL_NODE ( + /* specifies the location of this node in the local filesystem */ + wc_id INTEGER NOT NULL REFERENCES WCROOT (id), + local_relpath TEXT NOT NULL, + + /* parent's local_relpath for aggregating children of a given parent. + this will be "" if the parent is the wcroot. NULL if this is the + wcroot node. */ + parent_relpath TEXT, + + /* serialized skel of this node's properties. NULL implies no change to + the properties, relative to WORKING/BASE as appropriate. */ + properties BLOB, + + /* relpaths of the conflict files. */ + /* ### These columns will eventually be merged into conflict_data below. */ + conflict_old TEXT, + conflict_new TEXT, + conflict_working TEXT, + prop_reject TEXT, + + /* if not NULL, this node is part of a changelist. */ + changelist TEXT, + + /* ### need to determine values. "unknown" (no info), "admin" (they + ### used something like 'svn edit'), "noticed" (saw a mod while + ### scanning the filesystem). */ + text_mod TEXT, + + /* if a directory, serialized data for all of tree conflicts therein. + ### This column will eventually be merged into the conflict_data column, + ### but within the ACTUAL node of the tree conflict victim itself, rather + ### than the node of the tree conflict victim's parent directory. */ + tree_conflict_data TEXT, + + /* A skel containing the conflict details. */ + conflict_data BLOB, + + /* Three columns containing the checksums of older, left and right conflict + texts. Stored in a column to allow storing them in the pristine store */ + /* stsp: This is meant for text conflicts, right? What about property + conflicts? Why do we need these in a column to refer to the + pristine store? Can't we just parse the checksums from + conflict_data as well? + rhuijben: Because that won't allow triggers to handle refcounts. + We would have to scan all conflict skels before cleaning up the + a single file from the pristine stor */ + older_checksum TEXT REFERENCES PRISTINE (checksum), + left_checksum TEXT REFERENCES PRISTINE (checksum), + right_checksum TEXT REFERENCES PRISTINE (checksum), + + PRIMARY KEY (wc_id, local_relpath) + ); + +CREATE UNIQUE INDEX I_ACTUAL_PARENT ON ACTUAL_NODE (wc_id, parent_relpath, + local_relpath); + + +/* ------------------------------------------------------------------------- */ + +/* This table is a cache of information about repository locks. */ +CREATE TABLE LOCK ( + /* what repository location is locked */ + repos_id INTEGER NOT NULL REFERENCES REPOSITORY (id), + repos_relpath TEXT NOT NULL, + + /* Information about the lock. Note: these values are just caches from + the server, and are not authoritative. */ + lock_token TEXT NOT NULL, + /* ### make the following fields NOT NULL ? */ + lock_owner TEXT, + lock_comment TEXT, + lock_date INTEGER, /* an APR date/time (usec since 1970) */ + + PRIMARY KEY (repos_id, repos_relpath) + ); + + +/* ------------------------------------------------------------------------- */ + +CREATE TABLE WORK_QUEUE ( + /* Work items are identified by this value. */ + id INTEGER PRIMARY KEY AUTOINCREMENT, + + /* A serialized skel specifying the work item. */ + work BLOB NOT NULL + ); + + +/* ------------------------------------------------------------------------- */ + +CREATE TABLE WC_LOCK ( + /* specifies the location of this node in the local filesystem */ + wc_id INTEGER NOT NULL REFERENCES WCROOT (id), + local_dir_relpath TEXT NOT NULL, + + locked_levels INTEGER NOT NULL DEFAULT -1, + + PRIMARY KEY (wc_id, local_dir_relpath) + ); + + +PRAGMA user_version = +-- define: SVN_WC__VERSION +; + + +/* ------------------------------------------------------------------------- */ + +/* The NODES table describes the way WORKING nodes are layered on top of + BASE nodes and on top of other WORKING nodes, due to nested tree structure + changes. The layers are modelled using the "op_depth" column. + + An 'operation depth' refers to the number of directory levels down from + the WC root at which a tree-change operation (delete, add?, copy, move) + was performed. A row's 'op_depth' does NOT refer to the depth of its own + 'local_relpath', but rather to the depth of the nearest tree change that + affects that node. + + The row with op_depth=0 for any given local relpath represents the "base" + node that is created and updated by checkout, update, switch and commit + post-processing. The row with the highest op_depth for a particular + local_relpath represents the working version. Any rows with intermediate + op_depth values are not normally visible to the user but may become + visible after reverting local changes. + + This table contains full node descriptions for nodes in either the BASE + or WORKING trees as described in notes/wc-ng/design. Fields relate + both to BASE and WORKING trees, unless documented otherwise. + + For illustration, with a scenario like this: + + # (0) + svn rm foo + svn cp ^/moo foo # (1) + svn rm foo/bar + touch foo/bar + svn add foo/bar # (2) + + , these are the NODES table rows for the path foo/bar: + + (0) "BASE" ---> NODES (op_depth == 0) + (1) NODES (op_depth == 1) + (2) NODES (op_depth == 2) + + 0 is the original data for foo/bar before 'svn rm foo' (if it existed). + 1 is the data for foo/bar copied in from ^/moo/bar. + 2 is the to-be-committed data for foo/bar, created by 'svn add foo/bar'. + + An 'svn revert foo/bar' would remove the NODES of (2). + + */ +-- STMT_CREATE_NODES +CREATE TABLE NODES ( + /* Working copy location related fields */ + + wc_id INTEGER NOT NULL REFERENCES WCROOT (id), + local_relpath TEXT NOT NULL, + + /* Contains the depth (= number of path segments) of the operation + modifying the working copy tree structure. All nodes below the root + of the operation (aka operation root, aka oproot) affected by the + operation will be assigned the same op_depth. + + op_depth == 0 designates the initial checkout; the BASE tree. + + */ + op_depth INTEGER NOT NULL, + + /* parent's local_relpath for aggregating children of a given parent. + this will be "" if the parent is the wcroot. Since a wcroot will + never have a WORKING node the parent_relpath will never be null, + except when op_depth == 0 and the node is a wcroot. */ + parent_relpath TEXT, + + + /* Repository location fields */ + + /* When op_depth == 0, these fields refer to the repository location of the + BASE node, the location of the initial checkout. + + When op_depth != 0, they indicate where this node was copied/moved from. + In this case, the fields are set for the root of the operation and for all + children. */ + repos_id INTEGER REFERENCES REPOSITORY (id), + repos_path TEXT, + revision INTEGER, + + + /* WC state fields */ + + /* The tree state of the node. + + In case 'op_depth' is equal to 0, this node is part of the 'BASE' + tree. The 'BASE' represents pristine nodes that are in the + repository; it is obtained and modified by commands such as + checkout/update/switch. + + In case 'op_depth' is greater than 0, this node is part of a + layer of working nodes. The 'WORKING' tree is obtained and + modified by commands like delete/copy/revert. + + The 'BASE' and 'WORKING' trees use the same literal values for + the 'presence' but the meaning of each value can vary depending + on the tree. + + normal: in the 'BASE' tree this is an ordinary node for which we + have full information. In the 'WORKING' tree it's an added or + copied node for which we have full information. + + not-present: in the 'BASE' tree this is a node that is implied to + exist by the parent node, but is not present in the working + copy. Typically obtained by delete/commit, or by update to + revision in which the node does not exist. In the 'WORKING' + tree this is a copy of a 'not-present' node from the 'BASE' + tree, and it will be deleted on commit. Such a node cannot be + copied directly, but can be copied as a descendant. + + incomplete: in the 'BASE' tree this is an ordinary node for which + we do not have full information. Only the name is guaranteed; + we may not have all its children, we may not have its checksum, + etc. In the 'WORKING' tree this is a copied node for which we + do not have the full information. This state is generally + obtained when an operation was interrupted. + + base-deleted: not valid in 'BASE' tree. In the 'WORKING' tree + this represents a node that is deleted from the tree below the + current 'op_depth'. This state is badly named, it should be + something like 'deleted'. + + server-excluded: in the 'BASE' tree this is a node that is excluded by + authz. The name of the node is known from the parent, but no + other information is available. Not valid in the 'WORKING' + tree as there is no way to commit such a node. + + excluded: in the 'BASE' tree this node is administratively + excluded by the user (sparse WC). In the 'WORKING' tree this + is a copy of an excluded node from the 'BASE' tree. Such a + node cannot be copied directly but can be copied as a + descendant. */ + + presence TEXT NOT NULL, + + /* ### JF: For an old-style move, "copyfrom" info stores its source, but a + new WC-NG "move" is intended to be a "true rename" so its copyfrom + revision is implicit, being in effect (new head - 1) at commit time. + For a (new) move, we need to store or deduce the copyfrom local-relpath; + perhaps add a column called "moved_from". */ + + /* Boolean value, specifying if this node was moved here (rather than just + copied). This is set on all the nodes in the moved tree. The source of + the move is implied by a different node with a moved_to column pointing + at the root node of the moved tree. */ + moved_here INTEGER, + + /* If the underlying node was moved away (rather than just deleted), this + specifies the local_relpath of where the node was moved to. + This is set only on the root of a move, and is NULL for all children. + + The op-depth of the moved-to node is not recorded. A moved_to path + always points at a node within the highest op-depth layer at the + destination. This invariant must be maintained by operations which + change existing move information. */ + moved_to TEXT, + + + /* Content fields */ + + /* the kind of the new node. may be "unknown" if the node is not present. */ + kind TEXT NOT NULL, + + /* serialized skel of this node's properties (when presence is 'normal' or + 'incomplete'); an empty skel or NULL indicates no properties. NULL if + we have no information about the properties (any other presence). + TODO: Choose & require a single representation for 'no properties'. + */ + properties BLOB, + + /* NULL depth means "default" (typically svn_depth_infinity) */ + /* ### depth on WORKING? seems this is a BASE-only concept. how do + ### you do "files" on an added-directory? can't really ignore + ### the subdirs! */ + /* ### maybe a WC-to-WC copy can retain a depth? */ + depth TEXT, + + /* The SHA-1 checksum of the pristine text, if this node is a file and was + moved here or copied here, else NULL. */ + checksum TEXT REFERENCES PRISTINE (checksum), + + /* for kind==symlink, this specifies the target. */ + symlink_target TEXT, + + + /* Last-Change fields */ + + /* If this node was moved here or copied here, then the following fields may + have information about their source node. changed_rev must be not-null + if this node has presence=="normal". changed_date and changed_author may + be null if the corresponding revprops are missing. + + For an added or not-present node, these are null. */ + changed_revision INTEGER, + changed_date INTEGER, /* an APR date/time (usec since 1970) */ + changed_author TEXT, + + + /* Various cache fields */ + + /* The size in bytes of the working file when it had no local text + modifications. This means the size of the text when translated from + repository-normal format to working copy format with EOL style + translated and keywords expanded according to the properties in the + "properties" column of this row. + + NULL if this node is not a file or if the size has not (yet) been + computed. */ + translated_size INTEGER, + + /* The mod-time of the working file when it was last determined to be + logically unmodified relative to its base, taking account of keywords + and EOL style. This value is used in the change detection heuristic + used by the status command. + + NULL if this node is not a file or if this info has not yet been + determined. + */ + last_mod_time INTEGER, /* an APR date/time (usec since 1970) */ + + /* serialized skel of this node's dav-cache. could be NULL if the + node does not have any dav-cache. */ + dav_cache BLOB, + + /* Is there a file external in this location. NULL if there + is no file external, otherwise '1' */ + /* ### Originally we had a wc-1.0 like skel in this place, so we + ### check for NULL. + ### In Subversion 1.7 we defined this column as TEXT, but Sqlite + ### only uses this information for deciding how to optimize + ### anyway. */ + file_external INTEGER, + + /* serialized skel of this node's inherited properties. NULL if this + is not the BASE of a WC root node. */ + inherited_props BLOB, + + PRIMARY KEY (wc_id, local_relpath, op_depth) + + ); + +CREATE UNIQUE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath, + local_relpath, op_depth); +/* I_NODES_MOVED is introduced in format 30 */ +CREATE UNIQUE INDEX I_NODES_MOVED ON NODES (wc_id, moved_to, op_depth); + +/* Many queries have to filter the nodes table to pick only that version + of each node with the highest (most "current") op_depth. This view + does the heavy lifting for such queries. + + Note that this view includes a row for each and every path that is known + in the WC, including, for example, paths that were children of a base- or + lower-op-depth directory that has been replaced by something else in the + current view. + */ +CREATE VIEW NODES_CURRENT AS + SELECT * FROM nodes AS n + WHERE op_depth = (SELECT MAX(op_depth) FROM nodes AS n2 + WHERE n2.wc_id = n.wc_id + AND n2.local_relpath = n.local_relpath); + +/* Many queries have to filter the nodes table to pick only that version + of each node with the BASE ("as checked out") op_depth. This view + does the heavy lifting for such queries. */ +CREATE VIEW NODES_BASE AS + SELECT * FROM nodes + WHERE op_depth = 0; + +-- STMT_CREATE_NODES_TRIGGERS + +CREATE TRIGGER nodes_insert_trigger +AFTER INSERT ON nodes +WHEN NEW.checksum IS NOT NULL +BEGIN + UPDATE pristine SET refcount = refcount + 1 + WHERE checksum = NEW.checksum; +END; + +CREATE TRIGGER nodes_delete_trigger +AFTER DELETE ON nodes +WHEN OLD.checksum IS NOT NULL +BEGIN + UPDATE pristine SET refcount = refcount - 1 + WHERE checksum = OLD.checksum; +END; + +CREATE TRIGGER nodes_update_checksum_trigger +AFTER UPDATE OF checksum ON nodes +WHEN NEW.checksum IS NOT OLD.checksum + /* AND (NEW.checksum IS NOT NULL OR OLD.checksum IS NOT NULL) */ +BEGIN + UPDATE pristine SET refcount = refcount + 1 + WHERE checksum = NEW.checksum; + UPDATE pristine SET refcount = refcount - 1 + WHERE checksum = OLD.checksum; +END; + +-- STMT_CREATE_EXTERNALS + +CREATE TABLE EXTERNALS ( + /* Working copy location related fields (like NODES)*/ + + wc_id INTEGER NOT NULL REFERENCES WCROOT (id), + local_relpath TEXT NOT NULL, + + /* The working copy root can't be recorded as an external in itself + so this will never be NULL. ### ATM only inserted, never queried */ + parent_relpath TEXT NOT NULL, + + /* Repository location fields */ + repos_id INTEGER NOT NULL REFERENCES REPOSITORY (id), + + /* Either MAP_NORMAL or MAP_EXCLUDED */ + presence TEXT NOT NULL, + + /* the kind of the external. */ + kind TEXT NOT NULL, + + /* The local relpath of the directory NODE defining this external + (Defaults to the parent directory of the file external after upgrade) */ + def_local_relpath TEXT NOT NULL, + + /* The url of the external as used in the definition */ + def_repos_relpath TEXT NOT NULL, + + /* The operational (peg) and node revision if this is a revision fixed + external; otherwise NULL. (Usually these will both have the same value) */ + def_operational_revision TEXT, + def_revision TEXT, + + PRIMARY KEY (wc_id, local_relpath) +); + +CREATE UNIQUE INDEX I_EXTERNALS_DEFINED ON EXTERNALS (wc_id, + def_local_relpath, + local_relpath); + +/* ------------------------------------------------------------------------- */ + +/* Format 20 introduces NODES and removes BASE_NODE and WORKING_NODE */ + +-- STMT_UPGRADE_TO_20 + +UPDATE BASE_NODE SET checksum = (SELECT checksum FROM pristine + WHERE md5_checksum = BASE_NODE.checksum) +WHERE EXISTS (SELECT 1 FROM pristine WHERE md5_checksum = BASE_NODE.checksum); + +UPDATE WORKING_NODE SET checksum = (SELECT checksum FROM pristine + WHERE md5_checksum = WORKING_NODE.checksum) +WHERE EXISTS (SELECT 1 FROM pristine + WHERE md5_checksum = WORKING_NODE.checksum); + +INSERT INTO NODES ( + wc_id, local_relpath, op_depth, parent_relpath, + repos_id, repos_path, revision, + presence, depth, moved_here, moved_to, kind, + changed_revision, changed_date, changed_author, + checksum, properties, translated_size, last_mod_time, + dav_cache, symlink_target, file_external ) +SELECT wc_id, local_relpath, 0 /*op_depth*/, parent_relpath, + repos_id, repos_relpath, revnum, + presence, depth, NULL /*moved_here*/, NULL /*moved_to*/, kind, + changed_rev, changed_date, changed_author, + checksum, properties, translated_size, last_mod_time, + dav_cache, symlink_target, file_external +FROM BASE_NODE; +INSERT INTO NODES ( + wc_id, local_relpath, op_depth, parent_relpath, + repos_id, repos_path, revision, + presence, depth, moved_here, moved_to, kind, + changed_revision, changed_date, changed_author, + checksum, properties, translated_size, last_mod_time, + dav_cache, symlink_target, file_external ) +SELECT wc_id, local_relpath, 2 /*op_depth*/, parent_relpath, + copyfrom_repos_id, copyfrom_repos_path, copyfrom_revnum, + presence, depth, NULL /*moved_here*/, NULL /*moved_to*/, kind, + changed_rev, changed_date, changed_author, + checksum, properties, translated_size, last_mod_time, + NULL /*dav_cache*/, symlink_target, NULL /*file_external*/ +FROM WORKING_NODE; + +DROP TABLE BASE_NODE; +DROP TABLE WORKING_NODE; + +PRAGMA user_version = 20; + + +/* ------------------------------------------------------------------------- */ + +/* Format 21 involves no schema changes, it moves the tree conflict victim + information to victime nodes, rather than parents. */ + +-- STMT_UPGRADE_TO_21 +PRAGMA user_version = 21; + +/* For format 21 bump code */ +-- STMT_UPGRADE_21_SELECT_OLD_TREE_CONFLICT +SELECT wc_id, local_relpath, tree_conflict_data +FROM actual_node +WHERE tree_conflict_data IS NOT NULL + +/* For format 21 bump code */ +-- STMT_UPGRADE_21_ERASE_OLD_CONFLICTS +UPDATE actual_node SET tree_conflict_data = NULL + +/* ------------------------------------------------------------------------- */ + +/* Format 22 simply moves the tree conflict information from the conflict_data + column to the tree_conflict_data column. */ + +-- STMT_UPGRADE_TO_22 +UPDATE actual_node SET tree_conflict_data = conflict_data; +UPDATE actual_node SET conflict_data = NULL; + +PRAGMA user_version = 22; + + +/* ------------------------------------------------------------------------- */ + +/* Format 23 involves no schema changes, it introduces multi-layer + op-depth processing for NODES. */ + +-- STMT_UPGRADE_TO_23 +PRAGMA user_version = 23; + +-- STMT_UPGRADE_23_HAS_WORKING_NODES +SELECT 1 FROM nodes WHERE op_depth > 0 +LIMIT 1 + +/* ------------------------------------------------------------------------- */ + +/* Format 24 involves no schema changes; it starts using the pristine + table's refcount column correctly. */ + +-- STMT_UPGRADE_TO_24 +UPDATE pristine SET refcount = + (SELECT COUNT(*) FROM nodes + WHERE checksum = pristine.checksum /*OR checksum = pristine.md5_checksum*/); + +PRAGMA user_version = 24; + +/* ------------------------------------------------------------------------- */ + +/* Format 25 introduces the NODES_CURRENT view. */ + +-- STMT_UPGRADE_TO_25 +DROP VIEW IF EXISTS NODES_CURRENT; +CREATE VIEW NODES_CURRENT AS + SELECT * FROM nodes + JOIN (SELECT wc_id, local_relpath, MAX(op_depth) AS op_depth FROM nodes + GROUP BY wc_id, local_relpath) AS filter + ON nodes.wc_id = filter.wc_id + AND nodes.local_relpath = filter.local_relpath + AND nodes.op_depth = filter.op_depth; + +PRAGMA user_version = 25; + +/* ------------------------------------------------------------------------- */ + +/* Format 26 introduces the NODES_BASE view. */ + +-- STMT_UPGRADE_TO_26 +DROP VIEW IF EXISTS NODES_BASE; +CREATE VIEW NODES_BASE AS + SELECT * FROM nodes + WHERE op_depth = 0; + +PRAGMA user_version = 26; + +/* ------------------------------------------------------------------------- */ + +/* Format 27 involves no schema changes, it introduces stores + conflict files as relpaths rather than names in ACTUAL_NODE. */ + +-- STMT_UPGRADE_TO_27 +PRAGMA user_version = 27; + +/* For format 27 bump code */ +-- STMT_UPGRADE_27_HAS_ACTUAL_NODES_CONFLICTS +SELECT 1 FROM actual_node +WHERE NOT ((prop_reject IS NULL) AND (conflict_old IS NULL) + AND (conflict_new IS NULL) AND (conflict_working IS NULL) + AND (tree_conflict_data IS NULL)) +LIMIT 1 + + +/* ------------------------------------------------------------------------- */ + +/* Format 28 involves no schema changes, it only converts MD5 pristine + references to SHA1. */ + +-- STMT_UPGRADE_TO_28 + +UPDATE NODES SET checksum = (SELECT checksum FROM pristine + WHERE md5_checksum = nodes.checksum) +WHERE EXISTS (SELECT 1 FROM pristine WHERE md5_checksum = nodes.checksum); + +PRAGMA user_version = 28; + +/* ------------------------------------------------------------------------- */ + +/* Format 29 introduces the EXTERNALS table (See STMT_CREATE_TRIGGERS) and + optimizes a few trigger definitions. ... */ + +-- STMT_UPGRADE_TO_29 + +DROP TRIGGER IF EXISTS nodes_update_checksum_trigger; +DROP TRIGGER IF EXISTS nodes_insert_trigger; +DROP TRIGGER IF EXISTS nodes_delete_trigger; + +CREATE TRIGGER nodes_update_checksum_trigger +AFTER UPDATE OF checksum ON nodes +WHEN NEW.checksum IS NOT OLD.checksum + /* AND (NEW.checksum IS NOT NULL OR OLD.checksum IS NOT NULL) */ +BEGIN + UPDATE pristine SET refcount = refcount + 1 + WHERE checksum = NEW.checksum; + UPDATE pristine SET refcount = refcount - 1 + WHERE checksum = OLD.checksum; +END; + +CREATE TRIGGER nodes_insert_trigger +AFTER INSERT ON nodes +WHEN NEW.checksum IS NOT NULL +BEGIN + UPDATE pristine SET refcount = refcount + 1 + WHERE checksum = NEW.checksum; +END; + +CREATE TRIGGER nodes_delete_trigger +AFTER DELETE ON nodes +WHEN OLD.checksum IS NOT NULL +BEGIN + UPDATE pristine SET refcount = refcount - 1 + WHERE checksum = OLD.checksum; +END; + +PRAGMA user_version = 29; + +/* ------------------------------------------------------------------------- */ + +/* Format 30 creates a new NODES index for move information, and a new + PRISTINE index for the md5_checksum column. It also activates use of + skel-based conflict storage -- see notes/wc-ng/conflict-storage-2.0. + It also renames the "absent" presence to "server-excluded". */ +-- STMT_UPGRADE_TO_30 +CREATE UNIQUE INDEX IF NOT EXISTS I_NODES_MOVED +ON NODES (wc_id, moved_to, op_depth); + +CREATE INDEX IF NOT EXISTS I_PRISTINE_MD5 ON PRISTINE (md5_checksum); + +UPDATE nodes SET presence = "server-excluded" WHERE presence = "absent"; + +/* Just to be sure clear out file external skels from pre 1.7.0 development + working copies that were never updated by 1.7.0+ style clients */ +UPDATE nodes SET file_external=1 WHERE file_external IS NOT NULL; + +-- STMT_UPGRADE_30_SELECT_CONFLICT_SEPARATE +SELECT wc_id, local_relpath, + conflict_old, conflict_working, conflict_new, prop_reject, tree_conflict_data +FROM actual_node +WHERE conflict_old IS NOT NULL + OR conflict_working IS NOT NULL + OR conflict_new IS NOT NULL + OR prop_reject IS NOT NULL + OR tree_conflict_data IS NOT NULL +ORDER by wc_id, local_relpath + +-- STMT_UPGRADE_30_SET_CONFLICT +UPDATE actual_node SET conflict_data = ?3, conflict_old = NULL, + conflict_working = NULL, conflict_new = NULL, prop_reject = NULL, + tree_conflict_data = NULL +WHERE wc_id = ?1 and local_relpath = ?2 + +/* ------------------------------------------------------------------------- */ + +/* Format 31 adds the inherited_props column to the NODES table. C code then + initializes the update/switch roots to make sure future updates fetch the + inherited properties */ +-- STMT_UPGRADE_TO_31_ALTER_TABLE +ALTER TABLE NODES ADD COLUMN inherited_props BLOB; +-- STMT_UPGRADE_TO_31_FINALIZE +DROP INDEX IF EXISTS I_ACTUAL_CHANGELIST; +DROP INDEX IF EXISTS I_EXTERNALS_PARENT; + +DROP INDEX I_NODES_PARENT; +CREATE UNIQUE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath, + local_relpath, op_depth); + +DROP INDEX I_ACTUAL_PARENT; +CREATE UNIQUE INDEX I_ACTUAL_PARENT ON ACTUAL_NODE (wc_id, parent_relpath, + local_relpath); + +PRAGMA user_version = 31; + +-- STMT_UPGRADE_31_SELECT_WCROOT_NODES +/* Select all base nodes which are the root of a WC, including + switched subtrees, but excluding those which map to the root + of the repos. + + ### IPROPS: Is this query horribly inefficient? Quite likely, + ### but it only runs during an upgrade, so do we care? */ +SELECT l.wc_id, l.local_relpath FROM nodes as l +LEFT OUTER JOIN nodes as r +ON l.wc_id = r.wc_id + AND r.local_relpath = l.parent_relpath + AND r.op_depth = 0 +WHERE l.op_depth = 0 + AND l.repos_path != '' + AND ((l.repos_id IS NOT r.repos_id) + OR (l.repos_path IS NOT RELPATH_SKIP_JOIN(r.local_relpath, r.repos_path, l.local_relpath))) + + +/* ------------------------------------------------------------------------- */ +/* Format 32 .... */ +-- STMT_UPGRADE_TO_32 + +/* Drop old index. ### Remove this part from the upgrade to 31 once bumped */ +DROP INDEX IF EXISTS I_ACTUAL_CHANGELIST; +DROP INDEX IF EXISTS I_EXTERNALS_PARENT; +CREATE INDEX I_EXTERNALS_PARENT ON EXTERNALS (wc_id, parent_relpath); + +DROP INDEX I_NODES_PARENT; +CREATE UNIQUE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath, + local_relpath, op_depth); + +DROP INDEX I_ACTUAL_PARENT; +CREATE UNIQUE INDEX I_ACTUAL_PARENT ON ACTUAL_NODE (wc_id, parent_relpath, + local_relpath); + +/* ------------------------------------------------------------------------- */ + +/* Format YYY introduces new handling for conflict information. */ +-- format: YYY + + +/* ------------------------------------------------------------------------- */ + +/* Format 99 drops all columns not needed due to previous format upgrades. + Before we release 1.7, these statements will be pulled into a format bump + and all the tables will be cleaned up. We don't know what that format + number will be, however, so we're just marking it as 99 for now. */ +-- format: 99 + +/* TODO: Un-confuse *_revision column names in the EXTERNALS table to + "-r<operative> foo@<peg>", as suggested by the patch attached to + http://svn.haxx.se/dev/archive-2011-09/0478.shtml */ +/* TODO: Remove column parent_relpath from EXTERNALS. We're not using it and + never will. It's not interesting like in the NODES table: the external's + parent path may be *anything*: unversioned, "behind" a another WC... */ + +/* Now "drop" the tree_conflict_data column from actual_node. */ +CREATE TABLE ACTUAL_NODE_BACKUP ( + wc_id INTEGER NOT NULL, + local_relpath TEXT NOT NULL, + parent_relpath TEXT, + properties BLOB, + conflict_old TEXT, + conflict_new TEXT, + conflict_working TEXT, + prop_reject TEXT, + changelist TEXT, + text_mod TEXT + ); + +INSERT INTO ACTUAL_NODE_BACKUP SELECT + wc_id, local_relpath, parent_relpath, properties, conflict_old, + conflict_new, conflict_working, prop_reject, changelist, text_mod +FROM ACTUAL_NODE; + +DROP TABLE ACTUAL_NODE; + +CREATE TABLE ACTUAL_NODE ( + wc_id INTEGER NOT NULL REFERENCES WCROOT (id), + local_relpath TEXT NOT NULL, + parent_relpath TEXT, + properties BLOB, + conflict_old TEXT, + conflict_new TEXT, + conflict_working TEXT, + prop_reject TEXT, + changelist TEXT, + text_mod TEXT, + + PRIMARY KEY (wc_id, local_relpath) + ); + +CREATE UNIQUE INDEX I_ACTUAL_PARENT ON ACTUAL_NODE (wc_id, parent_relpath, + local_relpath); + +INSERT INTO ACTUAL_NODE SELECT + wc_id, local_relpath, parent_relpath, properties, conflict_old, + conflict_new, conflict_working, prop_reject, changelist, text_mod +FROM ACTUAL_NODE_BACKUP; + +DROP TABLE ACTUAL_NODE_BACKUP; + +/* Note: Other differences between the schemas of an upgraded and a + * fresh WC. + * + * While format 22 was current, "NOT NULL" was added to the + * columns PRISTINE.size and PRISTINE.md5_checksum. The format was not + * bumped because it is a forward- and backward-compatible change. + * + * While format 23 was current, "REFERENCES PRISTINE" was added to the + * columns ACTUAL_NODE.older_checksum, ACTUAL_NODE.left_checksum, + * ACTUAL_NODE.right_checksum, NODES.checksum. + * + * The "NODES_BASE" view was originally implemented with a more complex (but + * functionally equivalent) statement using a 'JOIN'. WCs that were created + * at or upgraded to format 26 before it was changed will still have the old + * version. + */ + |