1 /* node-origins-sqlite-index.c
3 * ====================================================================
4 * Copyright (c) 2006-2007 CollabNet. All rights reserved.
6 * This software is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at http://subversion.tigris.org/license-1.html.
9 * If newer versions of this license are posted there, you may use a
10 * newer version instead, at your option.
12 * This software consists of voluntary contributions made by many
13 * individuals. For exact contribution history, see the revision
14 * history and logs, available at http://subversion.tigris.org/.
15 * ====================================================================
24 #include <apr_general.h>
25 #include <apr_pools.h>
31 #include "svn_pools.h"
33 #include "private/svn_fs_sqlite.h"
34 #include "private/svn_fs_node_origins.h"
35 #include "../libsvn_fs/fs-loader.h"
36 #include "svn_private_config.h"
38 #include "sqlite-util.h"
41 /* A flow-control helper macro for sending processing to the 'cleanup'
42 label when the local variable 'err' is not SVN_NO_ERROR. */
43 #define MAYBE_CLEANUP if (err) goto cleanup
46 get_origin(const char **node_rev_id
,
51 svn_fs__sqlite_stmt_t
*stmt
;
52 svn_boolean_t got_row
;
54 SVN_ERR(svn_fs__sqlite_prepare(&stmt
, db
,
55 "SELECT node_rev_id FROM node_origins "
56 "WHERE node_id = ?", pool
));
57 SVN_ERR(svn_fs__sqlite_bind_text(stmt
, 1, node_id
));
58 SVN_ERR(svn_fs__sqlite_step(&got_row
, stmt
));
60 *node_rev_id
= got_row
61 ? apr_pstrdup(pool
, svn_fs__sqlite_column_text(stmt
, 0))
64 SVN_ERR(svn_fs__sqlite_finalize(stmt
));
70 set_origin(sqlite3
*db
,
72 const svn_string_t
*node_rev_id
,
75 svn_fs__sqlite_stmt_t
*stmt
;
76 const char *old_node_rev_id
;
78 /* First figure out if it's already there. (Don't worry, we're in a
80 SVN_ERR(get_origin(&old_node_rev_id
, db
, node_id
, pool
));
81 if (old_node_rev_id
!= NULL
)
83 if (!strcmp(node_rev_id
->data
, old_node_rev_id
))
86 return svn_error_createf
87 (SVN_ERR_FS_CORRUPT
, NULL
,
88 _("Node origin for '%s' exists with a different "
89 "value (%s) than what we were about to store (%s)"),
90 node_id
, old_node_rev_id
, node_rev_id
->data
);
93 SVN_ERR(svn_fs__sqlite_prepare(&stmt
, db
,
94 "INSERT INTO node_origins (node_id, "
95 "node_rev_id) VALUES (?, ?);", pool
));
96 SVN_ERR(svn_fs__sqlite_bind_text(stmt
, 1, node_id
));
97 SVN_ERR(svn_fs__sqlite_bind_text(stmt
, 2, node_rev_id
->data
));
99 SVN_ERR(svn_fs__sqlite_step_done(stmt
));
101 SVN_ERR(svn_fs__sqlite_finalize(stmt
));
108 svn_fs__set_node_origins(svn_fs_t
*fs
,
109 apr_hash_t
*node_origins
,
113 apr_hash_index_t
*hi
;
115 apr_pool_t
*subpool
= svn_pool_create(pool
);
116 apr_pool_t
*iterpool
= svn_pool_create(subpool
);
118 SVN_ERR(svn_fs__sqlite_open(&db
, fs
->path
, subpool
));
119 err
= svn_fs__sqlite_exec(db
, "BEGIN TRANSACTION;");
122 for (hi
= apr_hash_first(subpool
, node_origins
);
124 hi
= apr_hash_next(hi
))
129 const svn_fs_id_t
*node_rev_id
;
131 svn_pool_clear(iterpool
);
133 apr_hash_this(hi
, &key
, NULL
, &val
);
137 err
= set_origin(db
, node_id
,
138 svn_fs_unparse_id(node_rev_id
, iterpool
),
143 err
= svn_fs__sqlite_exec(db
, "COMMIT TRANSACTION;");
147 /* It's just an "optional" cache, so it's OK if the database is
149 /* ### Instead of checking twice here, maybe add an IGNORE_READONLY
150 ### argument to svn_fs__sqlite_close? */
151 if (err
&& err
->apr_err
== SVN_ERR_FS_SQLITE_READONLY
)
153 svn_error_clear(err
);
156 err
= svn_fs__sqlite_close(db
, err
);
157 if (err
&& err
->apr_err
== SVN_ERR_FS_SQLITE_READONLY
)
159 svn_error_clear(err
);
162 svn_pool_destroy(iterpool
);
163 svn_pool_destroy(subpool
);
168 svn_fs__set_node_origin(svn_fs_t
*fs
,
170 const svn_fs_id_t
*node_rev_id
,
173 apr_hash_t
*origins
= apr_hash_make(pool
);
175 apr_hash_set(origins
, node_id
, APR_HASH_KEY_STRING
, node_rev_id
);
177 return svn_fs__set_node_origins(fs
, origins
, pool
);
181 svn_fs__get_node_origin(const char **origin_id
,
189 SVN_ERR(svn_fs__sqlite_open(&db
, fs
->path
, pool
));
191 err
= get_origin(origin_id
, db
, node_id
, pool
);
193 return svn_fs__sqlite_close(db
, err
);