Directory: | cvmfs/ |
---|---|
File: | cvmfs/catalog_sql.cc |
Date: | 2024-04-28 02:33:07 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 439 | 584 | 75.2% |
Branches: | 539 | 1408 | 38.3% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * This file is part of the CernVM file system. | ||
3 | */ | ||
4 | |||
5 | #include "cvmfs_config.h" | ||
6 | #include "catalog_sql.h" | ||
7 | |||
8 | #include <cstdlib> | ||
9 | #include <cstring> | ||
10 | |||
11 | #include "catalog.h" | ||
12 | #include "globals.h" | ||
13 | #include "util/logging.h" | ||
14 | #include "util/posix.h" | ||
15 | #include "xattr.h" | ||
16 | |||
17 | using namespace std; // NOLINT | ||
18 | |||
19 | namespace catalog { | ||
20 | |||
21 | /** | ||
22 | * NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE | ||
23 | * Always remember to update the legacy catalog migration classes to produce a | ||
24 | * compatible catalog structure when updating the schema revisions here! | ||
25 | * | ||
26 | * Repository rollbacks to an outdated catalog schema is not supported. Have a | ||
27 | * look into CVM-252 if that becomes necessary at some point. | ||
28 | * | ||
29 | * If the statistics counters get modified, the swissknife migration 'stats' | ||
30 | * tools needs to be modified, too. | ||
31 | * NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE | ||
32 | */ | ||
33 | |||
34 | // ChangeLog | ||
35 | // 2.5 (Jun 26 2013 - Git: e79baec22c6abd6ddcdf8f8d7d33921027a052ab) | ||
36 | // * add (backward compatible) schema revision - see below | ||
37 | // * add statistics counters for chunked files | ||
38 | // Note: this was retrofitted and needed a catalog migration step | ||
39 | // | ||
40 | // 2.4 (Aug 15 2012 - Git: 17de8fc782b5b8dc4404dda925627b5ec2b552e1) | ||
41 | // 2.3 (Aug 15 2012 - Git: ab77688cdb2f851af3fe983bf3694dc2465e65be) | ||
42 | // 2.2 (never existed) | ||
43 | // 2.1 (Aug 7 2012 - Git: beba36c12d2b1123ffbb169f865a861e570adc68) | ||
44 | // * add 'chunks' table for file chunks | ||
45 | // * add 'statistics' table for accumulative counters | ||
46 | // * rename 'inode' field to 'hardlinks' | ||
47 | // * containing both hardlink group ID and linkcount | ||
48 | // * .cvmfscatalog files become first-class entries in the catalogs | ||
49 | // | ||
50 | // 2.0 (Aug 6 2012 - Git: c8a81ede603e57fbe4324b6ab6bc8c41e3a2fa5f) | ||
51 | // * beginning of CernVM-FS 2.1.x branch ('modern' era) | ||
52 | // | ||
53 | // 1.x (earlier - code base still in SVN) | ||
54 | // * pre-historic times | ||
55 | // 0.9 (some time 2011, artificial version) | ||
56 | // * 1.0 catalogs that lack the SHA-1 value for nested catalogs | ||
57 | const float CatalogDatabase::kLatestSchema = 2.5; | ||
58 | const float CatalogDatabase::kLatestSupportedSchema = 2.5; // + 1.X (r/o) | ||
59 | |||
60 | // ChangeLog | ||
61 | // 0 --> 1: (Jan 6 2014 - Git: 3667fe7a669d0d65e07275b753a7c6f23fc267df) | ||
62 | // * add size column to nested catalog table, | ||
63 | // * add schema_revision property | ||
64 | // 1 --> 2: (Jan 22 2014 - Git: 85e6680e52cfe56dc1213a5ad74a5cc62fd50ead): | ||
65 | // * add xattr column to catalog table | ||
66 | // * add self_xattr and subtree_xattr statistics counters | ||
67 | // 2 --> 3: (Sep 28 2015 - Git: f4171234b13ea448589820c1524ee52eae141bb4): | ||
68 | // * add kFlagFileExternal to entries in catalog table | ||
69 | // * add self_external and subtree_external statistics counters | ||
70 | // * store compression algorithm in flags | ||
71 | // 3 --> 4: (Nov 11 2016 - Git): | ||
72 | // * add kFlagDirBindMountpoint | ||
73 | // * add kFlagHidden | ||
74 | // * add table bind_mountpoints | ||
75 | // 4 --> 5: (Dec 07 2017): | ||
76 | // * add kFlagFileSpecial (rebranded unused kFlagFileStat) | ||
77 | // * add self_special and subtree_special statistics counters | ||
78 | // 5 --> 6: (Jul 01 2021): | ||
79 | // * Add kFlagDirectIo | ||
80 | const unsigned CatalogDatabase::kLatestSchemaRevision = 6; | ||
81 | |||
82 | 146 | bool CatalogDatabase::CheckSchemaCompatibility() { | |
83 |
3/6✓ Branch 1 taken 144 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 144 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
290 | return !( (schema_version() >= 2.0-kSchemaEpsilon) && |
84 | 144 | (!IsEqualSchema(schema_version(), kLatestSupportedSchema)) && | |
85 | ✗ | (!IsEqualSchema(schema_version(), 2.4) || | |
86 | 146 | !IsEqualSchema(kLatestSupportedSchema, 2.5)) ); | |
87 | } | ||
88 | |||
89 | |||
90 | 91 | bool CatalogDatabase::LiveSchemaUpgradeIfNecessary() { | |
91 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 91 times.
|
91 | assert(read_write()); |
92 | |||
93 |
6/6✓ Branch 2 taken 89 times.
✓ Branch 3 taken 2 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 88 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 90 times.
|
91 | if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 0)) { |
94 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | LogCvmfs(kLogCatalog, kLogDebug, "upgrading schema revision (0 --> 1)"); |
95 | |||
96 | SqlCatalog sql_upgrade(*this, "ALTER TABLE nested_catalogs " | ||
97 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
2 | "ADD size INTEGER;"); |
98 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
|
1 | if (!sql_upgrade.Execute()) { |
99 | ✗ | LogCvmfs(kLogCatalog, kLogDebug, "failed to upgrade nested_catalogs"); | |
100 | ✗ | return false; | |
101 | } | ||
102 | |||
103 | 1 | set_schema_revision(1); | |
104 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
|
1 | if (!StoreSchemaRevision()) { |
105 | ✗ | LogCvmfs(kLogCatalog, kLogDebug, "failed to upgrade schema revision"); | |
106 | ✗ | return false; | |
107 | } | ||
108 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | } |
109 | |||
110 |
6/6✓ Branch 2 taken 89 times.
✓ Branch 3 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 87 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 89 times.
|
91 | if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 1)) { |
111 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | LogCvmfs(kLogCatalog, kLogDebug, "upgrading schema revision (1 --> 2)"); |
112 | |||
113 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | SqlCatalog sql_upgrade1(*this, "ALTER TABLE catalog ADD xattr BLOB;"); |
114 | SqlCatalog sql_upgrade2(*this, | ||
115 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | "INSERT INTO statistics (counter, value) VALUES ('self_xattr', 0);"); |
116 | SqlCatalog sql_upgrade3(*this, | ||
117 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | "INSERT INTO statistics (counter, value) VALUES ('subtree_xattr', 0);"); |
118 |
5/11✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
|
4 | if (!sql_upgrade1.Execute() || !sql_upgrade2.Execute() || |
119 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
|
2 | !sql_upgrade3.Execute()) |
120 | { | ||
121 | ✗ | LogCvmfs(kLogCatalog, kLogDebug, "failed to upgrade catalogs (1 --> 2)"); | |
122 | ✗ | return false; | |
123 | } | ||
124 | |||
125 | 2 | set_schema_revision(2); | |
126 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
|
2 | if (!StoreSchemaRevision()) { |
127 | ✗ | LogCvmfs(kLogCatalog, kLogDebug, "failed to upgrade schema revision"); | |
128 | ✗ | return false; | |
129 | } | ||
130 |
3/6✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
|
2 | } |
131 | |||
132 |
6/6✓ Branch 2 taken 89 times.
✓ Branch 3 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 87 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 89 times.
|
91 | if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 2)) { |
133 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | LogCvmfs(kLogCatalog, kLogDebug, "upgrading schema revision (2 --> 3)"); |
134 | |||
135 | SqlCatalog sql_upgrade4(*this, | ||
136 | "INSERT INTO statistics (counter, value) VALUES " | ||
137 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | "('self_external', 0);"); |
138 | SqlCatalog sql_upgrade5(*this, | ||
139 | "INSERT INTO statistics (counter, value) VALUES " | ||
140 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | "('self_external_file_size', 0);"); |
141 | SqlCatalog sql_upgrade6(*this, | ||
142 | "INSERT INTO statistics (counter, value) VALUES " | ||
143 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | "('subtree_external', 0);"); |
144 | SqlCatalog sql_upgrade7(*this, | ||
145 | "INSERT INTO statistics (counter, value) VALUES " | ||
146 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | "('subtree_external_file_size', 0);"); |
147 |
3/7✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
4 | if (!sql_upgrade4.Execute() || !sql_upgrade5.Execute() || |
148 |
6/13✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
|
4 | !sql_upgrade6.Execute() || !sql_upgrade7.Execute()) |
149 | { | ||
150 | ✗ | LogCvmfs(kLogCatalog, kLogDebug, "failed to upgrade catalogs (2 --> 3)"); | |
151 | ✗ | return false; | |
152 | } | ||
153 | |||
154 | 2 | set_schema_revision(3); | |
155 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
|
2 | if (!StoreSchemaRevision()) { |
156 | ✗ | LogCvmfs(kLogCatalog, kLogDebug, "failed to upgrade schema revision"); | |
157 | ✗ | return false; | |
158 | } | ||
159 |
4/8✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
|
2 | } |
160 | |||
161 |
6/6✓ Branch 2 taken 89 times.
✓ Branch 3 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 87 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 89 times.
|
91 | if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 3)) { |
162 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | LogCvmfs(kLogCatalog, kLogDebug, "upgrading schema revision (3 --> 4)"); |
163 | |||
164 | SqlCatalog sql_upgrade8(*this, | ||
165 | "CREATE TABLE bind_mountpoints (path TEXT, sha1 TEXT, size INTEGER, " | ||
166 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | "CONSTRAINT pk_bind_mountpoints PRIMARY KEY (path));"); |
167 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
|
2 | if (!sql_upgrade8.Execute()) { |
168 | ✗ | LogCvmfs(kLogCatalog, kLogDebug, "failed to upgrade catalogs (3 --> 4)"); | |
169 | ✗ | return false; | |
170 | } | ||
171 | |||
172 | 2 | set_schema_revision(4); | |
173 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
|
2 | if (!StoreSchemaRevision()) { |
174 | ✗ | LogCvmfs(kLogCatalog, kLogDebug, "failed to upgrade schema revision"); | |
175 | ✗ | return false; | |
176 | } | ||
177 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | } |
178 | |||
179 | |||
180 |
6/6✓ Branch 2 taken 89 times.
✓ Branch 3 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 87 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 89 times.
|
91 | if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 4)) { |
181 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | LogCvmfs(kLogCatalog, kLogDebug, "upgrading schema revision (4 --> 5)"); |
182 | |||
183 | SqlCatalog sql_upgrade9(*this, | ||
184 | "INSERT INTO statistics (counter, value) VALUES " | ||
185 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | "('self_special', 0);"); |
186 | SqlCatalog sql_upgrade10(*this, | ||
187 | "INSERT INTO statistics (counter, value) VALUES " | ||
188 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | "('subtree_special', 0);"); |
189 |
5/11✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
|
2 | if (!sql_upgrade9.Execute() || !sql_upgrade10.Execute()) { |
190 | ✗ | LogCvmfs(kLogCatalog, kLogDebug, "failed to upgrade catalogs (4 --> 5)"); | |
191 | ✗ | return false; | |
192 | } | ||
193 | |||
194 | 2 | set_schema_revision(5); | |
195 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
|
2 | if (!StoreSchemaRevision()) { |
196 | ✗ | LogCvmfs(kLogCatalog, kLogDebug, "failed to upgrade schema revision"); | |
197 | ✗ | return false; | |
198 | } | ||
199 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | } |
200 | |||
201 | |||
202 |
6/6✓ Branch 2 taken 89 times.
✓ Branch 3 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 87 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 89 times.
|
91 | if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 5)) { |
203 | 2 | LogCvmfs(kLogCatalog, kLogDebug, "upgrading schema revision (5 --> 6)"); | |
204 | |||
205 | 2 | set_schema_revision(6); | |
206 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (!StoreSchemaRevision()) { |
207 | ✗ | LogCvmfs(kLogCatalog, kLogDebug, "failed to upgrade schema revision"); | |
208 | ✗ | return false; | |
209 | } | ||
210 | } | ||
211 | |||
212 | 91 | return true; | |
213 | } | ||
214 | |||
215 | |||
216 | 92 | bool CatalogDatabase::CreateEmptyDatabase() { | |
217 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 92 times.
|
92 | assert(read_write()); |
218 | |||
219 | // generate the catalog table and index structure | ||
220 | const bool retval = | ||
221 |
4/16✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 92 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 92 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 92 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
184 | SqlCatalog(*this, |
222 | "CREATE TABLE catalog " | ||
223 | "(md5path_1 INTEGER, md5path_2 INTEGER, parent_1 INTEGER, parent_2 INTEGER," | ||
224 | " hardlinks INTEGER, hash BLOB, size INTEGER, mode INTEGER, mtime INTEGER," | ||
225 | " flags INTEGER, name TEXT, symlink TEXT, uid INTEGER, gid INTEGER, " | ||
226 | " xattr BLOB, " | ||
227 |
0/2✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
368 | " CONSTRAINT pk_catalog PRIMARY KEY (md5path_1, md5path_2));").Execute() && |
228 |
5/19✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 92 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 92 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 92 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 92 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
184 | SqlCatalog(*this, |
229 | "CREATE INDEX idx_catalog_parent " | ||
230 |
2/4✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 92 times.
✗ Branch 4 not taken.
|
92 | "ON catalog (parent_1, parent_2);") .Execute() && |
231 |
5/19✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 92 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 92 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 92 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 92 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
184 | SqlCatalog(*this, |
232 | "CREATE TABLE chunks " | ||
233 | "(md5path_1 INTEGER, md5path_2 INTEGER, offset INTEGER, size INTEGER, " | ||
234 | " hash BLOB, " | ||
235 | " CONSTRAINT pk_chunks PRIMARY KEY (md5path_1, md5path_2, offset, size), " | ||
236 | " FOREIGN KEY (md5path_1, md5path_2) REFERENCES " | ||
237 |
2/4✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 92 times.
✗ Branch 4 not taken.
|
92 | " catalog(md5path_1, md5path_2));") .Execute() && |
238 |
5/19✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 92 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 92 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 92 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 92 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
184 | SqlCatalog(*this, |
239 | "CREATE TABLE nested_catalogs (path TEXT, sha1 TEXT, size INTEGER, " | ||
240 |
2/4✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 92 times.
✗ Branch 4 not taken.
|
92 | "CONSTRAINT pk_nested_catalogs PRIMARY KEY (path));") .Execute() && |
241 | // Bind mountpoints and nested catalogs are almost the same. We put them in | ||
242 | // separate tables to | ||
243 | // - not confuse previous client versions, which would crash on bind | ||
244 | // mountpoints | ||
245 | // - prevent catalogs referenced as bind mountpoints from being replicated, | ||
246 | // which would cause exhaustive recursive catalog tree walking | ||
247 | // - don't walk into bind mountpoints in catalog traversal (e.g. GC) | ||
248 |
5/19✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 92 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 92 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 92 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 92 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
184 | SqlCatalog(*this, |
249 | "CREATE TABLE bind_mountpoints (path TEXT, sha1 TEXT, size INTEGER, " | ||
250 |
4/9✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 92 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 92 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 92 times.
✗ Branch 10 not taken.
|
368 | "CONSTRAINT pk_bind_mountpoints PRIMARY KEY (path));") .Execute() && |
251 |
5/19✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 92 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 92 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 92 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 92 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
184 | SqlCatalog(*this, |
252 | "CREATE TABLE statistics (counter TEXT, value INTEGER, " | ||
253 |
3/6✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 92 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 92 times.
✗ Branch 6 not taken.
|
184 | "CONSTRAINT pk_statistics PRIMARY KEY (counter));") .Execute(); |
254 | |||
255 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
|
92 | if (!retval) { |
256 | ✗ | PrintSqlError("failed to create catalog database tables."); | |
257 | } | ||
258 | |||
259 | 92 | return retval; | |
260 | } | ||
261 | |||
262 | |||
263 | 91 | bool CatalogDatabase::InsertInitialValues( | |
264 | const std::string &root_path, | ||
265 | const bool volatile_content, | ||
266 | const std::string &voms_authz, | ||
267 | const DirectoryEntry &root_entry) | ||
268 | { | ||
269 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 91 times.
|
91 | assert(read_write()); |
270 | 91 | bool retval = false; | |
271 | |||
272 | // Path hashes | ||
273 |
1/2✓ Branch 2 taken 91 times.
✗ Branch 3 not taken.
|
91 | shash::Md5 root_path_hash = shash::Md5(shash::AsciiPtr(root_path)); |
274 | 91 | shash::Md5 root_parent_hash = (root_path == "") | |
275 | ? shash::Md5() | ||
276 |
7/12✓ Branch 0 taken 52 times.
✓ Branch 1 taken 39 times.
✓ Branch 3 taken 52 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 39 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 39 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 39 times.
✓ Branch 13 taken 52 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
91 | : shash::Md5(shash::AsciiPtr(GetParentPath(root_path))); |
277 | |||
278 | // Start initial filling transaction | ||
279 |
1/2✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
|
91 | retval = BeginTransaction(); |
280 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 91 times.
|
91 | if (!retval) { |
281 | ✗ | PrintSqlError("failed to enter initial filling transaction"); | |
282 | ✗ | return false; | |
283 | } | ||
284 | |||
285 | // Insert initial values to properties | ||
286 |
3/6✓ Branch 2 taken 91 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 91 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 91 times.
|
91 | if (!this->SetProperty("revision", 0)) { |
287 | ✗ | PrintSqlError( | |
288 | "failed to insert default initial values into the newly created " | ||
289 | "catalog tables."); | ||
290 | ✗ | return false; | |
291 | } | ||
292 | |||
293 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 91 times.
|
91 | if (volatile_content) { |
294 | ✗ | if (!this->SetProperty("volatile", 1)) { | |
295 | ✗ | PrintSqlError("failed to insert volatile flag into the newly created " | |
296 | "catalog tables."); | ||
297 | ✗ | return false; | |
298 | } | ||
299 | } | ||
300 | |||
301 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 91 times.
|
91 | if (!voms_authz.empty()) { |
302 | ✗ | if (!SetVOMSAuthz(voms_authz)) { | |
303 | ✗ | PrintSqlError("failed to insert VOMS authz flag into the newly created " | |
304 | "catalog tables."); | ||
305 | ✗ | return false; | |
306 | } | ||
307 | } | ||
308 | |||
309 | // Create initial statistics counters | ||
310 |
1/2✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
|
91 | catalog::Counters counters; |
311 | |||
312 | // Insert root entry (when given) | ||
313 |
2/2✓ Branch 1 taken 71 times.
✓ Branch 2 taken 20 times.
|
91 | if (!root_entry.IsNegative()) { |
314 |
1/2✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
|
71 | SqlDirentInsert sql_insert(*this); |
315 |
1/2✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
|
71 | retval = sql_insert.BindPathHash(root_path_hash) && |
316 |
2/4✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
✗ Branch 4 not taken.
|
71 | sql_insert.BindParentPathHash(root_parent_hash) && |
317 |
3/6✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 71 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 71 times.
✗ Branch 6 not taken.
|
213 | sql_insert.BindDirent(root_entry) && |
318 |
2/4✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
✗ Branch 4 not taken.
|
71 | sql_insert.Execute(); |
319 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 71 times.
|
71 | if (!retval) { |
320 | ✗ | PrintSqlError("failed to insert root entry into newly created catalog."); | |
321 | ✗ | return false; | |
322 | } | ||
323 | |||
324 | // account for the created root entry | ||
325 | 71 | counters.self.directories = 1; | |
326 |
1/2✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
|
71 | } |
327 | |||
328 | // Save initial statistics counters | ||
329 |
2/4✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 91 times.
|
91 | if (!counters.InsertIntoDatabase(*this)) { |
330 | ✗ | PrintSqlError("failed to insert initial catalog statistics counters."); | |
331 | ✗ | return false; | |
332 | } | ||
333 | |||
334 | // Insert root path (when given) | ||
335 |
2/2✓ Branch 1 taken 39 times.
✓ Branch 2 taken 52 times.
|
91 | if (!root_path.empty()) { |
336 |
4/9✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 39 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 39 times.
✗ Branch 9 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 39 times.
|
39 | if (!this->SetProperty("root_prefix", root_path)) { |
337 | ✗ | PrintSqlError( | |
338 | "failed to store root prefix in the newly created catalog."); | ||
339 | ✗ | return false; | |
340 | } | ||
341 | } | ||
342 | |||
343 | // Set creation timestamp | ||
344 |
3/6✓ Branch 3 taken 91 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 91 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 91 times.
|
91 | if (!this->SetProperty("last_modified", static_cast<uint64_t>(time(NULL)))) { |
345 | ✗ | PrintSqlError("failed to store creation timestamp in the new catalog."); | |
346 | ✗ | return false; | |
347 | } | ||
348 | |||
349 | // Commit initial filling transaction | ||
350 |
1/2✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
|
91 | retval = CommitTransaction(); |
351 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 91 times.
|
91 | if (!retval) { |
352 | ✗ | PrintSqlError("failed to commit initial filling transaction"); | |
353 | ✗ | return false; | |
354 | } | ||
355 | |||
356 | 91 | return true; | |
357 | } | ||
358 | |||
359 | |||
360 | bool | ||
361 | ✗ | CatalogDatabase::SetVOMSAuthz(const std::string &voms_authz) { | |
362 | ✗ | return this->SetProperty("voms_authz", voms_authz); | |
363 | } | ||
364 | |||
365 | |||
366 | 46 | double CatalogDatabase::GetRowIdWasteRatio() const { | |
367 | SqlCatalog rowid_waste_ratio_query(*this, | ||
368 | "SELECT 1.0 - CAST(COUNT(*) AS DOUBLE) / MAX(rowid) " | ||
369 |
2/4✓ Branch 2 taken 46 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 46 times.
✗ Branch 6 not taken.
|
92 | "AS ratio FROM catalog;"); |
370 |
1/2✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
|
46 | const bool retval = rowid_waste_ratio_query.FetchRow(); |
371 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
|
46 | assert(retval); |
372 | |||
373 |
1/2✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
|
92 | return rowid_waste_ratio_query.RetrieveDouble(0); |
374 | 46 | } | |
375 | |||
376 | /** | ||
377 | * Cleanup unused database space | ||
378 | * | ||
379 | * This copies the entire catalog content into a temporary SQLite table, sweeps | ||
380 | * the original data from the 'catalog' table and reinserts everything from the | ||
381 | * temporary table afterwards. That way the implicit rowid field of 'catalog' is | ||
382 | * defragmented. | ||
383 | * | ||
384 | * Since the 'chunks' table has a foreign key relationship to the 'catalog' we | ||
385 | * need to temporarily switch off the foreign key checks. Otherwise the clearing | ||
386 | * of the 'catalog' table would fail due to foreign key violations. Note that it | ||
387 | * is a NOOP to change the foreign key setting during a transaction! | ||
388 | * | ||
389 | * Note: VACUUM used to have a similar behaviour but it was dropped from SQLite | ||
390 | * at some point. Since we compute client-inodes from the rowIDs, we are | ||
391 | * probably one of the few use cases where a defragmented rowID is indeed | ||
392 | * beneficial. | ||
393 | * | ||
394 | * See: http://www.sqlite.org/lang_vacuum.html | ||
395 | */ | ||
396 | 12 | bool CatalogDatabase::CompactDatabase() const { | |
397 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
|
12 | assert(read_write()); |
398 | |||
399 |
4/17✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
24 | return SqlCatalog(*this, "PRAGMA foreign_keys = OFF;").Execute() && |
400 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
|
12 | BeginTransaction() && |
401 |
5/19✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 12 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 12 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
24 | SqlCatalog(*this, "CREATE TEMPORARY TABLE duplicate AS " |
402 | " SELECT * FROM catalog " | ||
403 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
|
12 | " ORDER BY rowid ASC;").Execute() && |
404 |
7/22✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 12 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 12 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
|
24 | SqlCatalog(*this, "DELETE FROM catalog;").Execute() && |
405 |
5/19✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 12 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 12 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
24 | SqlCatalog(*this, "INSERT INTO catalog " |
406 | " SELECT * FROM duplicate " | ||
407 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
|
12 | " ORDER BY rowid").Execute() && |
408 |
7/22✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 12 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 12 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
|
24 | SqlCatalog(*this, "DROP TABLE duplicate;").Execute() && |
409 |
4/9✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 12 times.
✗ Branch 10 not taken.
|
48 | CommitTransaction() && |
410 |
8/25✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 12 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 12 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 12 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 12 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
|
36 | SqlCatalog(*this, "PRAGMA foreign_keys = ON;").Execute(); |
411 | } | ||
412 | |||
413 | |||
414 | //------------------------------------------------------------------------------ | ||
415 | |||
416 | |||
417 | 709 | unsigned SqlDirent::CreateDatabaseFlags(const DirectoryEntry &entry) const { | |
418 | 709 | unsigned int database_flags = 0; | |
419 | |||
420 |
2/2✓ Branch 1 taken 32 times.
✓ Branch 2 taken 677 times.
|
709 | if (entry.IsNestedCatalogRoot()) |
421 | 32 | database_flags |= kFlagDirNestedRoot; | |
422 |
2/2✓ Branch 1 taken 35 times.
✓ Branch 2 taken 642 times.
|
677 | else if (entry.IsNestedCatalogMountpoint()) |
423 | 35 | database_flags |= kFlagDirNestedMountpoint; | |
424 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 642 times.
|
642 | else if (entry.IsBindMountpoint()) |
425 | ✗ | database_flags |= kFlagDirBindMountpoint; | |
426 | |||
427 |
2/2✓ Branch 1 taken 399 times.
✓ Branch 2 taken 310 times.
|
709 | if (entry.IsDirectory()) { |
428 | 399 | database_flags |= kFlagDir; | |
429 |
2/2✓ Branch 1 taken 13 times.
✓ Branch 2 taken 297 times.
|
310 | } else if (entry.IsLink()) { |
430 | 13 | database_flags |= kFlagFile | kFlagLink; | |
431 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 297 times.
|
297 | } else if (entry.IsSpecial()) { |
432 | ✗ | database_flags |= kFlagFile | kFlagFileSpecial; | |
433 | } else { | ||
434 | 297 | database_flags |= kFlagFile; | |
435 | 297 | database_flags |= entry.compression_algorithm() << kFlagPosCompression; | |
436 |
2/2✓ Branch 1 taken 10 times.
✓ Branch 2 taken 287 times.
|
297 | if (entry.IsChunkedFile()) |
437 | 10 | database_flags |= kFlagFileChunk; | |
438 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 297 times.
|
297 | if (entry.IsExternalFile()) |
439 | ✗ | database_flags |= kFlagFileExternal; | |
440 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 297 times.
|
297 | if (entry.IsDirectIo()) |
441 | ✗ | database_flags |= kFlagDirectIo; | |
442 | } | ||
443 | |||
444 |
5/6✓ Branch 2 taken 432 times.
✓ Branch 3 taken 277 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 432 times.
✓ Branch 7 taken 277 times.
✓ Branch 8 taken 432 times.
|
709 | if (!entry.checksum_ptr()->IsNull() || entry.IsChunkedFile()) |
445 | 277 | StoreHashAlgorithm(entry.checksum_ptr()->algorithm, &database_flags); | |
446 | |||
447 |
2/2✓ Branch 1 taken 10 times.
✓ Branch 2 taken 699 times.
|
709 | if (entry.IsHidden()) |
448 | 10 | database_flags |= kFlagHidden; | |
449 | |||
450 | 709 | return database_flags; | |
451 | } | ||
452 | |||
453 | |||
454 | 277 | void SqlDirent::StoreHashAlgorithm(const shash::Algorithms algo, | |
455 | unsigned *flags) const | ||
456 | { | ||
457 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 277 times.
|
277 | assert(algo != shash::kAny); |
458 | // Md5 unusable for content hashes | ||
459 | 277 | *flags |= (algo - 1) << kFlagPosHash; | |
460 | 277 | } | |
461 | |||
462 | |||
463 | 720 | shash::Algorithms SqlDirent::RetrieveHashAlgorithm(const unsigned flags) const { | |
464 | 720 | unsigned in_flags = ((7 << kFlagPosHash) & flags) >> kFlagPosHash; | |
465 | // Skip Md5 | ||
466 | 720 | in_flags++; | |
467 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 720 times.
|
720 | assert(in_flags < shash::kAny); |
468 | 720 | return static_cast<shash::Algorithms>(in_flags); | |
469 | } | ||
470 | |||
471 | |||
472 | 707 | zlib::Algorithms SqlDirent::RetrieveCompressionAlgorithm(const unsigned flags) | |
473 | const | ||
474 | { | ||
475 | // 3 bits, so use 7 (111) to only pull out the flags we want | ||
476 | 707 | unsigned in_flags = | |
477 | 707 | ((7 << kFlagPosCompression) & flags) >> kFlagPosCompression; | |
478 | 707 | return static_cast<zlib::Algorithms>(in_flags); | |
479 | } | ||
480 | |||
481 | |||
482 | 707 | uint32_t SqlDirent::Hardlinks2Linkcount(const uint64_t hardlinks) const { | |
483 | 707 | return (hardlinks << 32) >> 32; | |
484 | } | ||
485 | |||
486 | |||
487 | 707 | uint32_t SqlDirent::Hardlinks2HardlinkGroup(const uint64_t hardlinks) const { | |
488 | 707 | return hardlinks >> 32; | |
489 | } | ||
490 | |||
491 | |||
492 | 709 | uint64_t SqlDirent::MakeHardlinks(const uint32_t hardlink_group, | |
493 | const uint32_t linkcount) const | ||
494 | { | ||
495 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 709 times.
|
709 | assert(linkcount > 0); |
496 | 709 | return (static_cast<uint64_t>(hardlink_group) << 32) | linkcount; | |
497 | } | ||
498 | |||
499 | |||
500 | /** | ||
501 | * Expands variant symlinks containing $(VARIABLE) string. Uses the environment | ||
502 | * variables of the current process (cvmfs2) | ||
503 | */ | ||
504 | 583 | void SqlDirent::ExpandSymlink(LinkString *raw_symlink) const { | |
505 | 583 | const char *c = raw_symlink->GetChars(); | |
506 | 583 | const char *cEnd = c+raw_symlink->GetLength(); | |
507 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 583 times.
|
613 | for (; c < cEnd; ++c) { |
508 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
|
30 | if (*c == '$') |
509 | ✗ | goto expand_symlink; | |
510 | } | ||
511 | 583 | return; | |
512 | |||
513 | ✗ | expand_symlink: | |
514 | ✗ | LinkString result; | |
515 | ✗ | for (c = raw_symlink->GetChars(); c < cEnd; ++c) { | |
516 | ✗ | if ((*c == '$') && (c < cEnd-2) && (*(c+1) == '(')) { | |
517 | ✗ | c += 2; | |
518 | ✗ | const char *rpar = c; | |
519 | ✗ | while (rpar < cEnd) { | |
520 | ✗ | if (*rpar == ')') | |
521 | ✗ | goto expand_symlink_getenv; | |
522 | ✗ | rpar++; | |
523 | } | ||
524 | // right parenthesis missing | ||
525 | ✗ | result.Append("$(", 2); | |
526 | ✗ | result.Append(c, 1); | |
527 | ✗ | continue; | |
528 | |||
529 | ✗ | expand_symlink_getenv: | |
530 | // Check for default value | ||
531 | ✗ | const char *default_separator = c; | |
532 | ✗ | const char *default_value = rpar; | |
533 | ✗ | while (default_separator != rpar) { | |
534 | ✗ | if ((*default_separator == ':') && (*(default_separator + 1) == '-')) { | |
535 | ✗ | default_value = default_separator+2; | |
536 | ✗ | break; | |
537 | } | ||
538 | ✗ | default_separator++; | |
539 | } | ||
540 | |||
541 | ✗ | const unsigned environ_var_length = default_separator-c; | |
542 | ✗ | char environ_var[environ_var_length+1]; | |
543 | ✗ | environ_var[environ_var_length] = '\0'; | |
544 | ✗ | memcpy(environ_var, c, environ_var_length); | |
545 | ✗ | const char *environ_value = getenv(environ_var); // Don't free! | |
546 | ✗ | if (environ_value) { | |
547 | ✗ | result.Append(environ_value, strlen(environ_value)); | |
548 | } else { | ||
549 | ✗ | const unsigned default_length = rpar-default_value; | |
550 | ✗ | result.Append(default_value, default_length); | |
551 | } | ||
552 | ✗ | c = rpar; | |
553 | ✗ | continue; | |
554 | } | ||
555 | ✗ | result.Append(c, 1); | |
556 | } | ||
557 | ✗ | raw_symlink->Assign(result); | |
558 | ✗ | return; | |
559 | } | ||
560 | |||
561 | |||
562 | //------------------------------------------------------------------------------ | ||
563 | |||
564 | |||
565 | 709 | bool SqlDirentWrite::BindDirentFields(const int hash_idx, | |
566 | const int hardlinks_idx, | ||
567 | const int size_idx, | ||
568 | const int mode_idx, | ||
569 | const int mtime_idx, | ||
570 | const int flags_idx, | ||
571 | const int name_idx, | ||
572 | const int symlink_idx, | ||
573 | const int uid_idx, | ||
574 | const int gid_idx, | ||
575 | const DirectoryEntry &entry) | ||
576 | { | ||
577 | const uint64_t hardlinks = | ||
578 | 709 | MakeHardlinks(entry.hardlink_group_, | |
579 | 709 | entry.linkcount_); | |
580 | |||
581 | return ( | ||
582 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
709 | BindHashBlob(hash_idx, entry.checksum_) && |
583 |
1/2✓ Branch 1 taken 709 times.
✗ Branch 2 not taken.
|
709 | BindInt64(hardlinks_idx, hardlinks) && |
584 |
1/2✓ Branch 1 taken 709 times.
✗ Branch 2 not taken.
|
709 | BindInt64(size_idx, entry.size_) && |
585 |
1/2✓ Branch 1 taken 709 times.
✗ Branch 2 not taken.
|
709 | BindInt(mode_idx, entry.mode_) && |
586 |
1/2✓ Branch 1 taken 709 times.
✗ Branch 2 not taken.
|
709 | BindInt64(uid_idx, entry.uid_) && |
587 |
1/2✓ Branch 1 taken 709 times.
✗ Branch 2 not taken.
|
709 | BindInt64(gid_idx, entry.gid_) && |
588 |
1/2✓ Branch 1 taken 709 times.
✗ Branch 2 not taken.
|
709 | BindInt64(mtime_idx, entry.mtime_) && |
589 |
1/2✓ Branch 2 taken 709 times.
✗ Branch 3 not taken.
|
709 | BindInt(flags_idx, CreateDatabaseFlags(entry)) && |
590 |
2/4✓ Branch 0 taken 709 times.
✗ Branch 1 not taken.
✓ Branch 5 taken 709 times.
✗ Branch 6 not taken.
|
2127 | BindText(name_idx, entry.name_.GetChars(), entry.name_.GetLength()) && |
591 |
1/2✓ Branch 3 taken 709 times.
✗ Branch 4 not taken.
|
709 | BindText(symlink_idx, entry.symlink_.GetChars(), entry.symlink_.GetLength()) |
592 | 709 | ); // NOLINT | |
593 | } | ||
594 | |||
595 | |||
596 | //------------------------------------------------------------------------------ | ||
597 | |||
598 | |||
599 | 2 | SqlListContentHashes::SqlListContentHashes(const CatalogDatabase &database) { | |
600 | static const char *stmt_lt_2_4 = | ||
601 | "SELECT hash, flags, 0 " | ||
602 | " FROM catalog " | ||
603 | " WHERE length(hash) > 0;"; | ||
604 | |||
605 | static const char *stmt_ge_2_4 = | ||
606 | "SELECT hash, flags, 0 " | ||
607 | " FROM catalog " | ||
608 | " WHERE (length(catalog.hash) > 0) AND " | ||
609 | " ((flags & 128) = 0) " // kFlagFileExternal | ||
610 | "UNION " | ||
611 | "SELECT chunks.hash, catalog.flags, 1 " | ||
612 | " FROM catalog " | ||
613 | " LEFT JOIN chunks " | ||
614 | " ON catalog.md5path_1 = chunks.md5path_1 AND " | ||
615 | " catalog.md5path_2 = chunks.md5path_2 " | ||
616 | " WHERE (catalog.flags & 128) = 0;"; // kFlagFileExternal | ||
617 | |||
618 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | if (database.schema_version() < 2.4-CatalogDatabase::kSchemaEpsilon) { |
619 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | DeferredInit(database.sqlite_db(), stmt_lt_2_4); |
620 | } else { | ||
621 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | DeferredInit(database.sqlite_db(), stmt_ge_2_4); |
622 | } | ||
623 | 2 | } | |
624 | |||
625 | |||
626 | 13 | shash::Any SqlListContentHashes::GetHash() const { | |
627 | 13 | const unsigned int db_flags = RetrieveInt(1); | |
628 | 13 | const shash::Algorithms hash_algorithm = RetrieveHashAlgorithm(db_flags); | |
629 | 13 | shash::Any hash = RetrieveHashBlob(0, hash_algorithm); | |
630 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 2 taken 8 times.
|
13 | if (RetrieveInt(2) == 1) { |
631 | 5 | hash.suffix = shash::kSuffixPartial; | |
632 | } | ||
633 | |||
634 | 13 | return hash; | |
635 | } | ||
636 | |||
637 | |||
638 | //------------------------------------------------------------------------------ | ||
639 | |||
640 | #define DB_FIELDS_LT_V2_1 \ | ||
641 | "catalog.hash, catalog.inode, catalog.size, " \ | ||
642 | "catalog.mode, catalog.mtime, catalog.flags, " \ | ||
643 | "catalog.name, catalog.symlink, catalog.md5path_1, " \ | ||
644 | "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \ | ||
645 | "catalog.rowid" | ||
646 | #define DB_FIELDS_GE_V2_1_LT_R2 \ | ||
647 | "catalog.hash, catalog.hardlinks, catalog.size, " \ | ||
648 | "catalog.mode, catalog.mtime, catalog.flags, " \ | ||
649 | "catalog.name, catalog.symlink, catalog.md5path_1, " \ | ||
650 | "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \ | ||
651 | "catalog.rowid, catalog.uid, catalog.gid, " \ | ||
652 | "0" | ||
653 | #define DB_FIELDS_GE_V2_1_GE_R2 \ | ||
654 | "catalog.hash, catalog.hardlinks, catalog.size, " \ | ||
655 | "catalog.mode, catalog.mtime, catalog.flags, " \ | ||
656 | "catalog.name, catalog.symlink, catalog.md5path_1, " \ | ||
657 | "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \ | ||
658 | "catalog.rowid, catalog.uid, catalog.gid, " \ | ||
659 | "catalog.xattr IS NOT NULL" | ||
660 | |||
661 | #define MAKE_STATEMENT(STMT_TMPL, REV) \ | ||
662 | static const std::string REV = \ | ||
663 | ReplaceAll(STMT_TMPL, "@DB_FIELDS@", DB_FIELDS_ ## REV) | ||
664 | |||
665 | #define MAKE_STATEMENTS(STMT_TMPL) \ | ||
666 | MAKE_STATEMENT(STMT_TMPL, LT_V2_1); \ | ||
667 | MAKE_STATEMENT(STMT_TMPL, GE_V2_1_LT_R2); \ | ||
668 | MAKE_STATEMENT(STMT_TMPL, GE_V2_1_GE_R2) | ||
669 | |||
670 | #define DEFERRED_INIT(DB, REV) \ | ||
671 | DeferredInit((DB).sqlite_db(), (REV).c_str()) | ||
672 | |||
673 | #define DEFERRED_INITS(DB) \ | ||
674 | if ((DB).schema_version() < 2.1 - CatalogDatabase::kSchemaEpsilon) { \ | ||
675 | DEFERRED_INIT((DB), LT_V2_1); \ | ||
676 | } else if ((DB).schema_revision() < 2) { \ | ||
677 | DEFERRED_INIT((DB), GE_V2_1_LT_R2); \ | ||
678 | } else { \ | ||
679 | DEFERRED_INIT((DB), GE_V2_1_GE_R2); \ | ||
680 | } | ||
681 | |||
682 | |||
683 | ✗ | shash::Md5 SqlLookup::GetPathHash() const { | |
684 | ✗ | return RetrieveMd5(8, 9); | |
685 | } | ||
686 | |||
687 | |||
688 | ✗ | shash::Md5 SqlLookup::GetParentPathHash() const { | |
689 | ✗ | return RetrieveMd5(10, 11); | |
690 | } | ||
691 | |||
692 | |||
693 | /** | ||
694 | * This method is a friend of DirectoryEntry. | ||
695 | */ | ||
696 | 707 | DirectoryEntry SqlLookup::GetDirent(const Catalog *catalog, | |
697 | const bool expand_symlink) const | ||
698 | { | ||
699 | 707 | DirectoryEntry result; | |
700 | |||
701 |
1/2✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
|
707 | const unsigned database_flags = RetrieveInt(5); |
702 | 707 | result.is_nested_catalog_root_ = (database_flags & kFlagDirNestedRoot); | |
703 | 707 | result.is_nested_catalog_mountpoint_ = | |
704 | 707 | (database_flags & kFlagDirNestedMountpoint); | |
705 |
1/2✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
|
707 | const char *name = reinterpret_cast<const char *>(RetrieveText(6)); |
706 |
1/2✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
|
707 | const char *symlink = reinterpret_cast<const char *>(RetrieveText(7)); |
707 | |||
708 | // Retrieve the hardlink information from the hardlinks database field | ||
709 |
2/4✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 707 times.
|
707 | if (catalog->schema() < 2.1 - CatalogDatabase::kSchemaEpsilon) { |
710 | ✗ | result.linkcount_ = 1; | |
711 | ✗ | result.hardlink_group_ = 0; | |
712 | ✗ | result.inode_ = catalog->GetMangledInode(RetrieveInt64(12), 0); | |
713 | ✗ | result.is_chunked_file_ = false; | |
714 | ✗ | result.has_xattrs_ = false; | |
715 | ✗ | result.checksum_ = RetrieveHashBlob(0, shash::kSha1); | |
716 | ✗ | result.uid_ = g_uid; | |
717 | ✗ | result.gid_ = g_gid; | |
718 | } else { | ||
719 |
1/2✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
|
707 | const uint64_t hardlinks = RetrieveInt64(1); |
720 | 707 | result.linkcount_ = Hardlinks2Linkcount(hardlinks); | |
721 | 707 | result.hardlink_group_ = Hardlinks2HardlinkGroup(hardlinks); | |
722 | 707 | result.inode_ = | |
723 |
2/4✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 707 times.
✗ Branch 5 not taken.
|
707 | catalog->GetMangledInode(RetrieveInt64(12), result.hardlink_group_); |
724 | 707 | result.is_bind_mountpoint_ = (database_flags & kFlagDirBindMountpoint); | |
725 | 707 | result.is_chunked_file_ = (database_flags & kFlagFileChunk); | |
726 | 707 | result.is_hidden_ = (database_flags & kFlagHidden); | |
727 | 707 | result.is_direct_io_ = (database_flags & kFlagDirectIo); | |
728 | 707 | result.is_external_file_ = (database_flags & kFlagFileExternal); | |
729 |
1/2✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
|
707 | result.has_xattrs_ = RetrieveInt(15) != 0; |
730 | 707 | result.checksum_ = | |
731 |
1/2✓ Branch 2 taken 707 times.
✗ Branch 3 not taken.
|
707 | RetrieveHashBlob(0, RetrieveHashAlgorithm(database_flags)); |
732 | 707 | result.compression_algorithm_ = | |
733 | 707 | RetrieveCompressionAlgorithm(database_flags); | |
734 | |||
735 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 707 times.
|
707 | if (g_claim_ownership) { |
736 | ✗ | result.uid_ = g_uid; | |
737 | ✗ | result.gid_ = g_gid; | |
738 | } else { | ||
739 |
2/4✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 707 times.
✗ Branch 5 not taken.
|
707 | result.uid_ = catalog->MapUid(RetrieveInt64(13)); |
740 |
2/4✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 707 times.
✗ Branch 5 not taken.
|
707 | result.gid_ = catalog->MapGid(RetrieveInt64(14)); |
741 | } | ||
742 | } | ||
743 | |||
744 |
1/2✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
|
707 | result.mode_ = RetrieveInt(3); |
745 |
1/2✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
|
707 | result.size_ = RetrieveInt64(2); |
746 |
1/2✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
|
707 | result.mtime_ = RetrieveInt64(4); |
747 |
1/2✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
|
707 | result.name_.Assign(name, strlen(name)); |
748 |
1/2✓ Branch 1 taken 707 times.
✗ Branch 2 not taken.
|
707 | result.symlink_.Assign(symlink, strlen(symlink)); |
749 |
3/4✓ Branch 0 taken 583 times.
✓ Branch 1 taken 124 times.
✓ Branch 2 taken 583 times.
✗ Branch 3 not taken.
|
707 | if (expand_symlink && !g_raw_symlinks) |
750 |
1/2✓ Branch 1 taken 583 times.
✗ Branch 2 not taken.
|
583 | ExpandSymlink(&result.symlink_); |
751 | |||
752 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 707 times.
|
707 | if (g_world_readable) { |
753 | ✗ | if (S_ISDIR(result.mode_)) { | |
754 | ✗ | result.mode_ |= 0555; | |
755 | } else { | ||
756 | ✗ | result.mode_ |= 0444; | |
757 | } | ||
758 | } | ||
759 | |||
760 | 707 | return result; | |
761 | } | ||
762 | |||
763 | |||
764 | //------------------------------------------------------------------------------ | ||
765 | |||
766 | |||
767 | 143 | SqlListing::SqlListing(const CatalogDatabase &database) { | |
768 |
21/47✓ Branch 0 taken 1 times.
✓ Branch 1 taken 142 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 28 taken 1 times.
✓ Branch 29 taken 142 times.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 35 taken 1 times.
✗ Branch 36 not taken.
✓ Branch 39 taken 1 times.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 56 taken 1 times.
✓ Branch 57 taken 142 times.
✓ Branch 59 taken 1 times.
✗ Branch 60 not taken.
✓ Branch 63 taken 1 times.
✗ Branch 64 not taken.
✓ Branch 67 taken 1 times.
✗ Branch 68 not taken.
✓ Branch 71 taken 1 times.
✗ Branch 72 not taken.
✓ Branch 74 taken 1 times.
✗ Branch 75 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
|
143 | MAKE_STATEMENTS("SELECT @DB_FIELDS@ FROM catalog " |
769 | "WHERE (parent_1 = :p_1) AND (parent_2 = :p_2);"); | ||
770 |
7/17✓ Branch 1 taken 2 times.
✓ Branch 2 taken 141 times.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 141 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 22 taken 141 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 141 times.
✗ Branch 26 not taken.
|
143 | DEFERRED_INITS(database); |
771 | 143 | } | |
772 | |||
773 | |||
774 | 88 | bool SqlListing::BindPathHash(const struct shash::Md5 &hash) { | |
775 | 88 | return BindMd5(1, 2, hash); | |
776 | } | ||
777 | |||
778 | |||
779 | //------------------------------------------------------------------------------ | ||
780 | |||
781 | |||
782 | 143 | SqlLookupPathHash::SqlLookupPathHash(const CatalogDatabase &database) { | |
783 |
21/47✓ Branch 0 taken 1 times.
✓ Branch 1 taken 142 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 28 taken 1 times.
✓ Branch 29 taken 142 times.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 35 taken 1 times.
✗ Branch 36 not taken.
✓ Branch 39 taken 1 times.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 56 taken 1 times.
✓ Branch 57 taken 142 times.
✓ Branch 59 taken 1 times.
✗ Branch 60 not taken.
✓ Branch 63 taken 1 times.
✗ Branch 64 not taken.
✓ Branch 67 taken 1 times.
✗ Branch 68 not taken.
✓ Branch 71 taken 1 times.
✗ Branch 72 not taken.
✓ Branch 74 taken 1 times.
✗ Branch 75 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
|
143 | MAKE_STATEMENTS("SELECT @DB_FIELDS@ FROM catalog " |
784 | "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);"); | ||
785 |
7/17✓ Branch 1 taken 2 times.
✓ Branch 2 taken 141 times.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 141 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 22 taken 141 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 141 times.
✗ Branch 26 not taken.
|
143 | DEFERRED_INITS(database); |
786 | 143 | } | |
787 | |||
788 | 561 | bool SqlLookupPathHash::BindPathHash(const struct shash::Md5 &hash) { | |
789 | 561 | return BindMd5(1, 2, hash); | |
790 | } | ||
791 | |||
792 | |||
793 | //------------------------------------------------------------------------------ | ||
794 | |||
795 | |||
796 | ✗ | SqlLookupInode::SqlLookupInode(const CatalogDatabase &database) { | |
797 | ✗ | MAKE_STATEMENTS("SELECT @DB_FIELDS@ FROM catalog WHERE rowid = :rowid;"); | |
798 | ✗ | DEFERRED_INITS(database); | |
799 | } | ||
800 | |||
801 | |||
802 | ✗ | bool SqlLookupInode::BindRowId(const uint64_t inode) { | |
803 | ✗ | return BindInt64(1, inode); | |
804 | } | ||
805 | |||
806 | |||
807 | //------------------------------------------------------------------------------ | ||
808 | |||
809 | |||
810 | ✗ | SqlLookupDanglingMountpoints::SqlLookupDanglingMountpoints( | |
811 | ✗ | const catalog::CatalogDatabase &database) { | |
812 | ✗ | MAKE_STATEMENTS("SELECT DISTINCT @DB_FIELDS@ FROM catalog " | |
813 | "JOIN catalog AS c2 " | ||
814 | "ON catalog.md5path_1 = c2.parent_1 AND " | ||
815 | " catalog.md5path_2 = c2.parent_2 " | ||
816 | "WHERE catalog.flags & :nested_mountpoint_flag"); | ||
817 | ✗ | DEFERRED_INITS(database); | |
818 | |||
819 | // this pretty much removes the advantage of a deferred init but the statement | ||
820 | // is anyway only used directly. | ||
821 | ✗ | const bool success = BindInt64(1, SqlDirent::kFlagDirNestedMountpoint); | |
822 | ✗ | assert(success); | |
823 | } | ||
824 | |||
825 | |||
826 | //------------------------------------------------------------------------------ | ||
827 | |||
828 | |||
829 | 88 | SqlDirentTouch::SqlDirentTouch(const CatalogDatabase &database) { | |
830 |
2/4✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
|
88 | DeferredInit(database.sqlite_db(), |
831 | "UPDATE catalog " | ||
832 | "SET hash = :hash, size = :size, mode = :mode, mtime = :mtime, " | ||
833 | // 1 2 3 4 | ||
834 | "name = :name, symlink = :symlink, uid = :uid, gid = :gid, xattr = :xattr " | ||
835 | // 5 6 7 8 9 | ||
836 | "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);"); | ||
837 | // 10 11 | ||
838 | 88 | } | |
839 | |||
840 | |||
841 | 4 | bool SqlDirentTouch::BindDirentBase(const DirectoryEntryBase &entry) { | |
842 | return ( | ||
843 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
4 | BindHashBlob(1, entry.checksum_) && |
844 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | BindInt64(2, entry.size_) && |
845 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | BindInt(3, entry.mode_) && |
846 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | BindInt64(4, entry.mtime_) && |
847 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | BindText(5, entry.name_.GetChars(), entry.name_.GetLength()) && |
848 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | BindText(6, entry.symlink_.GetChars(), entry.symlink_.GetLength()) && |
849 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
12 | BindInt64(7, entry.uid_) && |
850 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
8 | BindInt64(8, entry.gid_)); |
851 | } | ||
852 | |||
853 | |||
854 | 4 | bool SqlDirentTouch::BindPathHash(const shash::Md5 &hash) { | |
855 | 4 | return BindMd5(10, 11, hash); | |
856 | } | ||
857 | |||
858 | |||
859 | ✗ | bool SqlDirentTouch::BindXattr(const XattrList &xattrs) { | |
860 | unsigned char *packed_xattrs; | ||
861 | unsigned size; | ||
862 | ✗ | xattrs.Serialize(&packed_xattrs, &size); | |
863 | ✗ | if (packed_xattrs == NULL) | |
864 | ✗ | return BindNull(9); | |
865 | ✗ | return BindBlobTransient(9, packed_xattrs, size); | |
866 | } | ||
867 | |||
868 | |||
869 | 4 | bool SqlDirentTouch::BindXattrEmpty() { | |
870 | 4 | return BindNull(9); | |
871 | } | ||
872 | |||
873 | |||
874 | //------------------------------------------------------------------------------ | ||
875 | |||
876 | |||
877 | 143 | SqlNestedCatalogLookup::SqlNestedCatalogLookup(const CatalogDatabase &database) | |
878 | { | ||
879 | // We cannot access nested catalogs where the content hash is missing | ||
880 | static const char *stmt_0_9 = | ||
881 | "SELECT '', 0 FROM nested_catalogs;"; | ||
882 | static const char *stmt_2_5_ge_4 = | ||
883 | "SELECT sha1, size FROM nested_catalogs WHERE path=:path " | ||
884 | "UNION ALL SELECT sha1, size FROM bind_mountpoints WHERE path=:path;"; | ||
885 | static const char *stmt_2_5_ge_1_lt_4 = | ||
886 | "SELECT sha1, size FROM nested_catalogs WHERE path=:path;"; | ||
887 | // Internally converts NULL to 0 for size | ||
888 | static const char *stmt_2_5_lt_1 = | ||
889 | "SELECT sha1, 0 FROM nested_catalogs WHERE path=:path;"; | ||
890 | |||
891 |
5/6✓ Branch 2 taken 141 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 141 times.
✓ Branch 7 taken 2 times.
|
284 | if (database.IsEqualSchema(database.schema_version(), 2.5) && |
892 | 141 | (database.schema_revision() >= 4)) | |
893 | { | ||
894 |
2/4✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
|
141 | DeferredInit(database.sqlite_db(), stmt_2_5_ge_4); |
895 |
2/6✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
|
2 | } else if (database.IsEqualSchema(database.schema_version(), 2.5) && |
896 | ✗ | (database.schema_revision() >= 1)) | |
897 | { | ||
898 | ✗ | DeferredInit(database.sqlite_db(), stmt_2_5_ge_1_lt_4); | |
899 | } else { | ||
900 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
|
2 | if (database.IsEqualSchema(database.schema_version(), 0.9)) { |
901 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | DeferredInit(database.sqlite_db(), stmt_0_9); |
902 | } else { | ||
903 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | DeferredInit(database.sqlite_db(), stmt_2_5_lt_1); |
904 | } | ||
905 | } | ||
906 | 143 | } | |
907 | |||
908 | |||
909 | 50 | bool SqlNestedCatalogLookup::BindSearchPath(const PathString &path) { | |
910 | 50 | return BindText(1, path.GetChars(), path.GetLength()); | |
911 | } | ||
912 | |||
913 | |||
914 | 48 | shash::Any SqlNestedCatalogLookup::GetContentHash() const { | |
915 |
2/4✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 48 times.
✗ Branch 6 not taken.
|
48 | const string hash = string(reinterpret_cast<const char *>(RetrieveText(0))); |
916 | 48 | return (hash.empty()) ? shash::Any(shash::kAny) : | |
917 |
1/2✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
|
22 | shash::MkFromHexPtr(shash::HexPtr(hash), |
918 |
3/4✓ Branch 0 taken 26 times.
✓ Branch 1 taken 22 times.
✓ Branch 3 taken 26 times.
✗ Branch 4 not taken.
|
96 | shash::kSuffixCatalog); |
919 | 48 | } | |
920 | |||
921 | |||
922 | 48 | uint64_t SqlNestedCatalogLookup::GetSize() const { | |
923 | 48 | return RetrieveInt64(1); | |
924 | } | ||
925 | |||
926 | |||
927 | //------------------------------------------------------------------------------ | ||
928 | |||
929 | |||
930 | 143 | SqlNestedCatalogListing::SqlNestedCatalogListing( | |
931 | 143 | const CatalogDatabase &database) | |
932 | { | ||
933 | // We cannot access nested catalogs where the content hash is missing | ||
934 | static const char *stmt_0_9 = | ||
935 | "SELECT '', '', 0 FROM nested_catalogs;"; | ||
936 | static const char *stmt_2_5_ge_4 = | ||
937 | "SELECT path, sha1, size FROM nested_catalogs " | ||
938 | "UNION ALL SELECT path, sha1, size FROM bind_mountpoints;"; | ||
939 | static const char *stmt_2_5_ge_1_lt_4 = | ||
940 | "SELECT path, sha1, size FROM nested_catalogs;"; | ||
941 | // Internally converts NULL to 0 for size | ||
942 | static const char *stmt_2_5_lt_1 = | ||
943 | "SELECT path, sha1, 0 FROM nested_catalogs;"; | ||
944 | |||
945 |
5/6✓ Branch 2 taken 141 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 141 times.
✓ Branch 7 taken 2 times.
|
284 | if (database.IsEqualSchema(database.schema_version(), 2.5) && |
946 | 141 | (database.schema_revision() >= 4)) | |
947 | { | ||
948 |
2/4✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
|
141 | DeferredInit(database.sqlite_db(), stmt_2_5_ge_4); |
949 |
2/6✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
|
2 | } else if (database.IsEqualSchema(database.schema_version(), 2.5) && |
950 | ✗ | (database.schema_revision() >= 1)) | |
951 | { | ||
952 | ✗ | DeferredInit(database.sqlite_db(), stmt_2_5_ge_1_lt_4); | |
953 | } else { | ||
954 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
|
2 | if (database.IsEqualSchema(database.schema_version(), 0.9)) { |
955 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | DeferredInit(database.sqlite_db(), stmt_0_9); |
956 | } else { | ||
957 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | DeferredInit(database.sqlite_db(), stmt_2_5_lt_1); |
958 | } | ||
959 | } | ||
960 | 143 | } | |
961 | |||
962 | |||
963 | 46 | PathString SqlNestedCatalogListing::GetPath() const { | |
964 | 46 | const char *path = reinterpret_cast<const char *>(RetrieveText(0)); | |
965 | 46 | return PathString(path, strlen(path)); | |
966 | } | ||
967 | |||
968 | |||
969 | 46 | shash::Any SqlNestedCatalogListing::GetContentHash() const { | |
970 |
2/4✓ Branch 2 taken 46 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 46 times.
✗ Branch 6 not taken.
|
46 | const string hash = string(reinterpret_cast<const char *>(RetrieveText(1))); |
971 | 46 | return (hash.empty()) ? shash::Any(shash::kAny) : | |
972 |
1/2✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
|
34 | shash::MkFromHexPtr(shash::HexPtr(hash), |
973 |
3/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 34 times.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
|
92 | shash::kSuffixCatalog); |
974 | 46 | } | |
975 | |||
976 | |||
977 | 46 | uint64_t SqlNestedCatalogListing::GetSize() const { | |
978 | 46 | return RetrieveInt64(2); | |
979 | } | ||
980 | |||
981 | |||
982 | //------------------------------------------------------------------------------ | ||
983 | |||
984 | |||
985 | 143 | SqlOwnNestedCatalogListing::SqlOwnNestedCatalogListing( | |
986 | 143 | const CatalogDatabase &database) | |
987 | { | ||
988 | // We cannot access nested catalogs where the content hash is missing | ||
989 | static const char *stmt_0_9 = | ||
990 | "SELECT '', '', 0 FROM nested_catalogs;"; | ||
991 | static const char *stmt_2_5_ge_1 = | ||
992 | "SELECT path, sha1, size FROM nested_catalogs;"; | ||
993 | // Internally converts NULL to 0 for size | ||
994 | static const char *stmt_2_5_lt_1 = | ||
995 | "SELECT path, sha1, 0 FROM nested_catalogs;"; | ||
996 | |||
997 |
5/6✓ Branch 2 taken 141 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 141 times.
✓ Branch 7 taken 2 times.
|
284 | if (database.IsEqualSchema(database.schema_version(), 2.5) && |
998 | 141 | (database.schema_revision() >= 1)) | |
999 | { | ||
1000 |
2/4✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
|
141 | DeferredInit(database.sqlite_db(), stmt_2_5_ge_1); |
1001 | } else { | ||
1002 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
|
2 | if (database.IsEqualSchema(database.schema_version(), 0.9)) { |
1003 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | DeferredInit(database.sqlite_db(), stmt_0_9); |
1004 | } else { | ||
1005 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | DeferredInit(database.sqlite_db(), stmt_2_5_lt_1); |
1006 | } | ||
1007 | } | ||
1008 | 143 | } | |
1009 | |||
1010 | |||
1011 | 5 | PathString SqlOwnNestedCatalogListing::GetPath() const { | |
1012 | 5 | const char *path = reinterpret_cast<const char *>(RetrieveText(0)); | |
1013 | 5 | return PathString(path, strlen(path)); | |
1014 | } | ||
1015 | |||
1016 | |||
1017 | 5 | shash::Any SqlOwnNestedCatalogListing::GetContentHash() const { | |
1018 |
2/4✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
|
5 | const string hash = string(reinterpret_cast<const char *>(RetrieveText(1))); |
1019 | 5 | return (hash.empty()) ? shash::Any(shash::kAny) : | |
1020 |
1/2✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
5 | shash::MkFromHexPtr(shash::HexPtr(hash), |
1021 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
10 | shash::kSuffixCatalog); |
1022 | 5 | } | |
1023 | |||
1024 | |||
1025 | 5 | uint64_t SqlOwnNestedCatalogListing::GetSize() const { | |
1026 | 5 | return RetrieveInt64(2); | |
1027 | } | ||
1028 | |||
1029 | |||
1030 | //------------------------------------------------------------------------------ | ||
1031 | |||
1032 | |||
1033 | 159 | SqlDirentInsert::SqlDirentInsert(const CatalogDatabase &database) { | |
1034 |
2/4✓ Branch 1 taken 159 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 159 times.
✗ Branch 5 not taken.
|
159 | DeferredInit(database.sqlite_db(), |
1035 | "INSERT INTO catalog " | ||
1036 | "(md5path_1, md5path_2, parent_1, parent_2, hash, hardlinks, size, mode," | ||
1037 | // 1 2 3 4 5 6 7 8 | ||
1038 | "mtime, flags, name, symlink, uid, gid, xattr) " | ||
1039 | // 9, 10 11 12 13 14 15 | ||
1040 | "VALUES (:md5_1, :md5_2, :p_1, :p_2, :hash, :links, :size, :mode, :mtime," | ||
1041 | " :flags, :name, :symlink, :uid, :gid, :xattr);"); | ||
1042 | 159 | } | |
1043 | |||
1044 | |||
1045 | 532 | bool SqlDirentInsert::BindPathHash(const shash::Md5 &hash) { | |
1046 | 532 | return BindMd5(1, 2, hash); | |
1047 | } | ||
1048 | |||
1049 | |||
1050 | 532 | bool SqlDirentInsert::BindParentPathHash(const shash::Md5 &hash) { | |
1051 | 532 | return BindMd5(3, 4, hash); | |
1052 | } | ||
1053 | |||
1054 | |||
1055 | 532 | bool SqlDirentInsert::BindDirent(const DirectoryEntry &entry) { | |
1056 | 532 | return BindDirentFields(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, entry); | |
1057 | } | ||
1058 | |||
1059 | |||
1060 | ✗ | bool SqlDirentInsert::BindXattr(const XattrList &xattrs) { | |
1061 | unsigned char *packed_xattrs; | ||
1062 | unsigned size; | ||
1063 | ✗ | xattrs.Serialize(&packed_xattrs, &size); | |
1064 | ✗ | if (packed_xattrs == NULL) | |
1065 | ✗ | return BindNull(15); | |
1066 | ✗ | return BindBlobTransient(15, packed_xattrs, size); | |
1067 | } | ||
1068 | |||
1069 | |||
1070 | 461 | bool SqlDirentInsert::BindXattrEmpty() { | |
1071 | 461 | return BindNull(15); | |
1072 | } | ||
1073 | |||
1074 | |||
1075 | //------------------------------------------------------------------------------ | ||
1076 | |||
1077 | |||
1078 | 88 | SqlDirentUpdate::SqlDirentUpdate(const CatalogDatabase &database) { | |
1079 |
2/4✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
|
88 | DeferredInit(database.sqlite_db(), |
1080 | "UPDATE catalog " | ||
1081 | "SET hash = :hash, size = :size, mode = :mode, mtime = :mtime, " | ||
1082 | // 1 2 3 4 | ||
1083 | "flags = :flags, name = :name, symlink = :symlink, hardlinks = :hardlinks, " | ||
1084 | // 5 6 7 8 | ||
1085 | "uid = :uid, gid = :gid " | ||
1086 | // 9 10 | ||
1087 | "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);"); | ||
1088 | // 11 12 | ||
1089 | 88 | } | |
1090 | |||
1091 | |||
1092 | 177 | bool SqlDirentUpdate::BindPathHash(const shash::Md5 &hash) { | |
1093 | 177 | return BindMd5(11, 12, hash); | |
1094 | } | ||
1095 | |||
1096 | |||
1097 | 177 | bool SqlDirentUpdate::BindDirent(const DirectoryEntry &entry) { | |
1098 | 177 | return BindDirentFields(1, 8, 2, 3, 4, 5, 6, 7, 9, 10, entry); | |
1099 | } | ||
1100 | |||
1101 | |||
1102 | //------------------------------------------------------------------------------ | ||
1103 | |||
1104 | |||
1105 | 88 | SqlDirentUnlink::SqlDirentUnlink(const CatalogDatabase &database) { | |
1106 |
2/4✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
|
88 | DeferredInit(database.sqlite_db(), |
1107 | "DELETE FROM catalog " | ||
1108 | "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);"); | ||
1109 | 88 | } | |
1110 | |||
1111 | 113 | bool SqlDirentUnlink::BindPathHash(const shash::Md5 &hash) { | |
1112 | 113 | return BindMd5(1, 2, hash); | |
1113 | } | ||
1114 | |||
1115 | |||
1116 | //------------------------------------------------------------------------------ | ||
1117 | |||
1118 | |||
1119 | 88 | SqlIncLinkcount::SqlIncLinkcount(const CatalogDatabase &database) { | |
1120 | // This command changes the linkcount of a whole hardlink group at once! | ||
1121 | // We can do this, since the 'hardlinks'-field contains the hardlink group ID | ||
1122 | // in the higher 32bit as well as the 'linkcount' in the lower 32bit. | ||
1123 | // This field will be equal for all entries belonging to the same hardlink | ||
1124 | // group while adding/subtracting small values from it will only effect the | ||
1125 | // linkcount in the lower 32bit. | ||
1126 | // Take a deep breath! | ||
1127 |
2/4✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
|
88 | DeferredInit(database.sqlite_db(), |
1128 | "UPDATE catalog SET hardlinks = hardlinks + :delta " | ||
1129 | "WHERE hardlinks = (SELECT hardlinks from catalog " | ||
1130 | "WHERE md5path_1 = :md5_1 AND md5path_2 = :md5_2);"); | ||
1131 | 88 | } | |
1132 | |||
1133 | |||
1134 | ✗ | bool SqlIncLinkcount::BindPathHash(const shash::Md5 &hash) { | |
1135 | ✗ | return BindMd5(2, 3, hash); | |
1136 | } | ||
1137 | |||
1138 | |||
1139 | ✗ | bool SqlIncLinkcount::BindDelta(const int delta) { | |
1140 | ✗ | return BindInt(1, delta); | |
1141 | } | ||
1142 | |||
1143 | |||
1144 | //------------------------------------------------------------------------------ | ||
1145 | |||
1146 | |||
1147 | 88 | SqlChunkInsert::SqlChunkInsert(const CatalogDatabase &database) { | |
1148 |
2/4✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
|
88 | DeferredInit(database.sqlite_db(), |
1149 | "INSERT INTO chunks (md5path_1, md5path_2, offset, size, hash) " | ||
1150 | // 1 2 3 4 5 | ||
1151 | "VALUES (:md5_1, :md5_2, :offset, :size, :hash);"); | ||
1152 | 88 | } | |
1153 | |||
1154 | |||
1155 | 10 | bool SqlChunkInsert::BindPathHash(const shash::Md5 &hash) { | |
1156 | 10 | return BindMd5(1, 2, hash); | |
1157 | } | ||
1158 | |||
1159 | |||
1160 | 10 | bool SqlChunkInsert::BindFileChunk(const FileChunk &chunk) { | |
1161 | return | ||
1162 |
0/2✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
10 | BindInt64(3, chunk.offset()) && |
1163 |
2/4✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
|
20 | BindInt64(4, chunk.size()) && |
1164 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
20 | BindHashBlob(5, chunk.content_hash()); |
1165 | } | ||
1166 | |||
1167 | |||
1168 | //------------------------------------------------------------------------------ | ||
1169 | |||
1170 | |||
1171 | 88 | SqlChunksRemove::SqlChunksRemove(const CatalogDatabase &database) { | |
1172 |
2/4✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
|
88 | DeferredInit(database.sqlite_db(), |
1173 | "DELETE FROM chunks " | ||
1174 | "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);"); | ||
1175 | 88 | } | |
1176 | |||
1177 | |||
1178 | ✗ | bool SqlChunksRemove::BindPathHash(const shash::Md5 &hash) { | |
1179 | ✗ | return BindMd5(1, 2, hash); | |
1180 | } | ||
1181 | |||
1182 | |||
1183 | //------------------------------------------------------------------------------ | ||
1184 | |||
1185 | |||
1186 | 143 | SqlChunksListing::SqlChunksListing(const CatalogDatabase &database) { | |
1187 |
2/4✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
|
143 | DeferredInit(database.sqlite_db(), |
1188 | "SELECT offset, size, hash FROM chunks " | ||
1189 | // 0 1 2 | ||
1190 | "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2) " | ||
1191 | // 1 2 | ||
1192 | "ORDER BY offset ASC;"); | ||
1193 | 143 | } | |
1194 | |||
1195 | |||
1196 | 1 | bool SqlChunksListing::BindPathHash(const shash::Md5 &hash) { | |
1197 | 1 | return BindMd5(1, 2, hash); | |
1198 | } | ||
1199 | |||
1200 | |||
1201 | 1 | FileChunk SqlChunksListing::GetFileChunk( | |
1202 | const shash::Algorithms interpret_hash_as) const | ||
1203 | { | ||
1204 | return FileChunk( | ||
1205 | 1 | RetrieveHashBlob(2, interpret_hash_as, shash::kSuffixPartial), | |
1206 | 1 | RetrieveInt64(0), | |
1207 | 2 | RetrieveInt64(1)); | |
1208 | } | ||
1209 | |||
1210 | |||
1211 | //------------------------------------------------------------------------------ | ||
1212 | |||
1213 | |||
1214 | 88 | SqlChunksCount::SqlChunksCount(const CatalogDatabase &database) { | |
1215 |
2/4✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
|
88 | DeferredInit(database.sqlite_db(), |
1216 | "SELECT count(*) FROM chunks " | ||
1217 | // 0 | ||
1218 | "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2)"); | ||
1219 | // 1 2 | ||
1220 | 88 | } | |
1221 | |||
1222 | |||
1223 | ✗ | bool SqlChunksCount::BindPathHash(const shash::Md5 &hash) { | |
1224 | ✗ | return BindMd5(1, 2, hash); | |
1225 | } | ||
1226 | |||
1227 | |||
1228 | ✗ | int SqlChunksCount::GetChunkCount() const { | |
1229 | ✗ | return RetrieveInt64(0); | |
1230 | } | ||
1231 | |||
1232 | |||
1233 | //------------------------------------------------------------------------------ | ||
1234 | |||
1235 | |||
1236 | 88 | SqlMaxHardlinkGroup::SqlMaxHardlinkGroup(const CatalogDatabase &database) { | |
1237 |
2/4✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
|
88 | DeferredInit(database.sqlite_db(), "SELECT max(hardlinks) FROM catalog;"); |
1238 | 88 | } | |
1239 | |||
1240 | |||
1241 | 1 | uint32_t SqlMaxHardlinkGroup::GetMaxGroupId() const { | |
1242 | 1 | return RetrieveInt64(0) >> 32; | |
1243 | } | ||
1244 | |||
1245 | |||
1246 | //------------------------------------------------------------------------------ | ||
1247 | |||
1248 | |||
1249 | 218 | SqlGetCounter::SqlGetCounter(const CatalogDatabase &database) { | |
1250 | static const char *stmt_ge_2_4 = | ||
1251 | "SELECT value from statistics WHERE counter = :counter;"; | ||
1252 | static const char *stmt_lt_2_4 = | ||
1253 | "SELECT 0;"; | ||
1254 | |||
1255 |
2/2✓ Branch 1 taken 216 times.
✓ Branch 2 taken 2 times.
|
218 | if (database.schema_version() >= 2.4 - CatalogDatabase::kSchemaEpsilon) { |
1256 | 216 | compat_ = false; | |
1257 |
2/4✓ Branch 1 taken 216 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 216 times.
✗ Branch 5 not taken.
|
216 | DeferredInit(database.sqlite_db(), stmt_ge_2_4); |
1258 | } else { | ||
1259 | 2 | compat_ = true; | |
1260 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | DeferredInit(database.sqlite_db(), stmt_lt_2_4); |
1261 | } | ||
1262 | 218 | } | |
1263 | |||
1264 | |||
1265 | 5232 | bool SqlGetCounter::BindCounter(const std::string &counter) { | |
1266 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 5184 times.
|
5232 | if (compat_) return true; |
1267 | 5184 | return BindText(1, counter); | |
1268 | } | ||
1269 | |||
1270 | |||
1271 | 5232 | uint64_t SqlGetCounter::GetCounter() const { | |
1272 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 5184 times.
|
5232 | if (compat_) return 0; |
1273 | 5184 | return RetrieveInt64(0); | |
1274 | } | ||
1275 | |||
1276 | |||
1277 | //------------------------------------------------------------------------------ | ||
1278 | |||
1279 | |||
1280 | 75 | SqlUpdateCounter::SqlUpdateCounter(const CatalogDatabase &database) { | |
1281 |
2/4✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 75 times.
✗ Branch 5 not taken.
|
75 | DeferredInit(database.sqlite_db(), |
1282 | "UPDATE statistics SET value=value+:val WHERE counter=:counter;"); | ||
1283 | 75 | } | |
1284 | |||
1285 | |||
1286 | 1800 | bool SqlUpdateCounter::BindCounter(const std::string &counter) { | |
1287 | 1800 | return BindText(2, counter); | |
1288 | } | ||
1289 | |||
1290 | |||
1291 | 1800 | bool SqlUpdateCounter::BindDelta(const int64_t delta) { | |
1292 | 1800 | return BindInt64(1, delta); | |
1293 | } | ||
1294 | |||
1295 | |||
1296 | //------------------------------------------------------------------------------ | ||
1297 | |||
1298 | |||
1299 | 92 | SqlCreateCounter::SqlCreateCounter(const CatalogDatabase &database) { | |
1300 |
2/4✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 92 times.
✗ Branch 5 not taken.
|
92 | DeferredInit(database.sqlite_db(), |
1301 | "INSERT OR REPLACE INTO statistics (counter, value) " | ||
1302 | "VALUES (:counter, :value);"); | ||
1303 | 92 | } | |
1304 | |||
1305 | |||
1306 | 2208 | bool SqlCreateCounter::BindCounter(const std::string &counter) { | |
1307 | 2208 | return BindText(1, counter); | |
1308 | } | ||
1309 | |||
1310 | |||
1311 | 2208 | bool SqlCreateCounter::BindInitialValue(const int64_t value) { | |
1312 | 2208 | return BindInt64(2, value); | |
1313 | } | ||
1314 | |||
1315 | |||
1316 | //------------------------------------------------------------------------------ | ||
1317 | |||
1318 | |||
1319 | 143 | SqlAllChunks::SqlAllChunks(const CatalogDatabase &database) { | |
1320 | 143 | int hash_mask = 7 << SqlDirent::kFlagPosHash; | |
1321 | string flags2hash = | ||
1322 |
4/8✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 143 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 143 times.
✗ Branch 11 not taken.
|
286 | " ((flags&" + StringifyInt(hash_mask) + ") >> " + |
1323 |
2/4✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
|
286 | StringifyInt(SqlDirent::kFlagPosHash) + ")+1 AS hash_algorithm "; |
1324 | |||
1325 | 143 | int compression_mask = 7 << SqlDirent::kFlagPosCompression; | |
1326 | string flags2compression = | ||
1327 |
4/8✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 143 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 143 times.
✗ Branch 11 not taken.
|
286 | " ((flags&" + StringifyInt(compression_mask) + ") >> " + |
1328 |
2/4✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
|
429 | StringifyInt(SqlDirent::kFlagPosCompression) + ") " + |
1329 |
1/2✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
|
143 | "AS compression_algorithm "; |
1330 | |||
1331 | // TODO(reneme): this depends on shash::kSuffix* being a char! | ||
1332 | // it should be more generic or replaced entirely | ||
1333 | // TODO(reneme): this is practically the same as SqlListContentHashes and | ||
1334 | // should be consolidated | ||
1335 | string sql = "SELECT DISTINCT hash, " | ||
1336 |
4/8✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 143 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 143 times.
✗ Branch 11 not taken.
|
286 | "CASE WHEN flags & " + StringifyInt(SqlDirent::kFlagFile) + " THEN " + |
1337 |
3/6✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 143 times.
✗ Branch 8 not taken.
|
572 | StringifyInt(shash::kSuffixNone) + " " + |
1338 |
4/8✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 143 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 143 times.
✗ Branch 11 not taken.
|
572 | "WHEN flags & " + StringifyInt(SqlDirent::kFlagDir) + " THEN " + |
1339 |
3/6✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 143 times.
✗ Branch 8 not taken.
|
572 | StringifyInt(shash::kSuffixMicroCatalog) + " END " + |
1340 |
4/8✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 143 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 143 times.
✗ Branch 11 not taken.
|
286 | "AS chunk_type, " + flags2hash + "," + flags2compression + |
1341 | "FROM catalog WHERE (hash IS NOT NULL) AND " | ||
1342 |
3/6✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 143 times.
✗ Branch 8 not taken.
|
429 | "(flags & " + StringifyInt(SqlDirent::kFlagFileExternal) + " = 0)"; |
1343 |
2/2✓ Branch 1 taken 141 times.
✓ Branch 2 taken 2 times.
|
143 | if (database.schema_version() >= 2.4 - CatalogDatabase::kSchemaEpsilon) { |
1344 | sql += | ||
1345 | " UNION " | ||
1346 |
3/6✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 141 times.
✗ Branch 8 not taken.
|
282 | "SELECT DISTINCT chunks.hash, " + StringifyInt(shash::kSuffixPartial) + |
1347 |
4/8✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 141 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 141 times.
✗ Branch 11 not taken.
|
282 | ", " + flags2hash + "," + flags2compression + |
1348 | "FROM chunks, catalog WHERE " | ||
1349 | "chunks.md5path_1=catalog.md5path_1 AND " | ||
1350 | "chunks.md5path_2=catalog.md5path_2 AND " | ||
1351 |
3/6✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 141 times.
✗ Branch 8 not taken.
|
564 | "(catalog.flags & " + StringifyInt(SqlDirent::kFlagFileExternal) + |
1352 |
1/2✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
|
141 | " = 0)"; |
1353 | } | ||
1354 |
1/2✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
|
143 | sql += ";"; |
1355 |
2/4✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
|
143 | Init(database.sqlite_db(), sql); |
1356 | 143 | } | |
1357 | |||
1358 | |||
1359 | 2 | bool SqlAllChunks::Open() { | |
1360 | 2 | return true; | |
1361 | } | ||
1362 | |||
1363 | |||
1364 | 11 | bool SqlAllChunks::Next(shash::Any *hash, zlib::Algorithms *compression_alg) { | |
1365 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 9 times.
|
11 | if (!FetchRow()) { |
1366 | 2 | return false; | |
1367 | } | ||
1368 | |||
1369 | 9 | *hash = RetrieveHashBlob(0, static_cast<shash::Algorithms>(RetrieveInt(2)), | |
1370 | 9 | static_cast<shash::Suffix>(RetrieveInt(1))); | |
1371 | 9 | *compression_alg = static_cast<zlib::Algorithms>(RetrieveInt(3)); | |
1372 | 9 | return true; | |
1373 | } | ||
1374 | |||
1375 | |||
1376 | 2 | bool SqlAllChunks::Close() { | |
1377 | 2 | return Reset(); | |
1378 | } | ||
1379 | |||
1380 | |||
1381 | //------------------------------------------------------------------------------ | ||
1382 | |||
1383 | |||
1384 | 143 | SqlLookupXattrs::SqlLookupXattrs(const CatalogDatabase &database) { | |
1385 |
2/4✓ Branch 1 taken 143 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143 times.
✗ Branch 5 not taken.
|
143 | DeferredInit(database.sqlite_db(), |
1386 | "SELECT xattr FROM catalog " | ||
1387 | "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);"); | ||
1388 | 143 | } | |
1389 | |||
1390 | |||
1391 | 1 | bool SqlLookupXattrs::BindPathHash(const shash::Md5 &hash) { | |
1392 | 1 | return BindMd5(1, 2, hash); | |
1393 | } | ||
1394 | |||
1395 | |||
1396 | 1 | XattrList SqlLookupXattrs::GetXattrs() { | |
1397 | const unsigned char *packed_xattrs = | ||
1398 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | reinterpret_cast<const unsigned char *>(RetrieveBlob(0)); |
1399 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (packed_xattrs == NULL) |
1400 | 1 | return XattrList(); | |
1401 | |||
1402 | ✗ | int size = RetrieveBytes(0); | |
1403 | ✗ | assert(size >= 0); | |
1404 | ✗ | UniquePtr<XattrList> xattrs(XattrList::Deserialize(packed_xattrs, size)); | |
1405 | ✗ | if (!xattrs.IsValid()) { | |
1406 | ✗ | LogCvmfs(kLogCatalog, kLogDebug, "corrupted xattr data"); | |
1407 | ✗ | return XattrList(); | |
1408 | } | ||
1409 | ✗ | return *xattrs; | |
1410 | } | ||
1411 | |||
1412 | } // namespace catalog | ||
1413 |