57 const float CatalogDatabase::kLatestSchema = 2.5;
58 const float CatalogDatabase::kLatestSupportedSchema = 2.5;
84 const unsigned CatalogDatabase::kLatestSchemaRevision = 7;
86 bool CatalogDatabase::CheckSchemaCompatibility() {
87 return !((schema_version() >= 2.0 - kSchemaEpsilon)
88 && (!IsEqualSchema(schema_version(), kLatestSupportedSchema))
89 && (!IsEqualSchema(schema_version(), 2.4)
90 || !IsEqualSchema(kLatestSupportedSchema, 2.5)));
94 bool CatalogDatabase::LiveSchemaUpgradeIfNecessary() {
97 if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 0)) {
100 SqlCatalog sql_upgrade(*
this,
"ALTER TABLE nested_catalogs "
101 "ADD size INTEGER;");
107 set_schema_revision(1);
108 if (!StoreSchemaRevision()) {
114 if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 1)) {
117 SqlCatalog sql_upgrade1(*
this,
"ALTER TABLE catalog ADD xattr BLOB;");
120 "INSERT INTO statistics (counter, value) VALUES ('self_xattr', 0);");
123 "INSERT INTO statistics (counter, value) VALUES ('subtree_xattr', 0);");
130 set_schema_revision(2);
131 if (!StoreSchemaRevision()) {
137 if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 2)) {
141 "INSERT INTO statistics (counter, value) VALUES "
142 "('self_external', 0);");
144 "INSERT INTO statistics (counter, value) VALUES "
145 "('self_external_file_size', 0);");
147 "INSERT INTO statistics (counter, value) VALUES "
148 "('subtree_external', 0);");
150 "INSERT INTO statistics (counter, value) VALUES "
151 "('subtree_external_file_size', 0);");
158 set_schema_revision(3);
159 if (!StoreSchemaRevision()) {
165 if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 3)) {
170 "CREATE TABLE bind_mountpoints (path TEXT, sha1 TEXT, size INTEGER, "
171 "CONSTRAINT pk_bind_mountpoints PRIMARY KEY (path));");
177 set_schema_revision(4);
178 if (!StoreSchemaRevision()) {
185 if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 4)) {
189 "INSERT INTO statistics (counter, value) VALUES "
190 "('self_special', 0);");
192 "INSERT INTO statistics (counter, value) VALUES "
193 "('subtree_special', 0);");
199 set_schema_revision(5);
200 if (!StoreSchemaRevision()) {
207 if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 5)) {
210 set_schema_revision(6);
211 if (!StoreSchemaRevision()) {
217 if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 6)) {
220 SqlCatalog sql_upgrade1(*
this,
"ALTER TABLE catalog ADD mtimens INTEGER;");
226 set_schema_revision(7);
227 if (!StoreSchemaRevision()) {
237 bool CatalogDatabase::CreateEmptyDatabase() {
243 "CREATE TABLE catalog "
244 "(md5path_1 INTEGER, md5path_2 INTEGER, parent_1 INTEGER, "
246 " hardlinks INTEGER, hash BLOB, size INTEGER, mode INTEGER, "
248 " mtimens INTEGER, flags INTEGER, name TEXT, symlink TEXT, "
250 " gid INTEGER, xattr BLOB, "
251 " CONSTRAINT pk_catalog PRIMARY KEY (md5path_1, md5path_2));")
254 "CREATE INDEX idx_catalog_parent "
255 "ON catalog (parent_1, parent_2);")
258 "CREATE TABLE chunks "
259 "(md5path_1 INTEGER, md5path_2 INTEGER, offset INTEGER, "
262 " CONSTRAINT pk_chunks PRIMARY KEY (md5path_1, md5path_2, "
264 " FOREIGN KEY (md5path_1, md5path_2) REFERENCES "
265 " catalog(md5path_1, md5path_2));")
268 "CREATE TABLE nested_catalogs (path TEXT, sha1 TEXT, size "
270 "CONSTRAINT pk_nested_catalogs PRIMARY KEY (path));")
283 "CREATE TABLE bind_mountpoints (path TEXT, sha1 TEXT, size INTEGER, "
284 "CONSTRAINT pk_bind_mountpoints PRIMARY KEY (path));")
287 "CREATE TABLE statistics (counter TEXT, value INTEGER, "
288 "CONSTRAINT pk_statistics PRIMARY KEY (counter));")
292 PrintSqlError(
"failed to create catalog database tables.");
299 bool CatalogDatabase::InsertInitialValues(
const std::string &root_path,
300 const bool volatile_content,
301 const std::string &voms_authz,
308 shash::Md5 root_parent_hash = (root_path ==
"")
314 retval = BeginTransaction();
316 PrintSqlError(
"failed to enter initial filling transaction");
321 if (!this->SetProperty(
"revision", 0)) {
323 "failed to insert default initial values into the newly created "
328 if (volatile_content) {
329 if (!this->SetProperty(
"volatile", 1)) {
330 PrintSqlError(
"failed to insert volatile flag into the newly created "
336 if (!voms_authz.empty()) {
337 if (!SetVOMSAuthz(voms_authz)) {
338 PrintSqlError(
"failed to insert VOMS authz flag into the newly created "
354 PrintSqlError(
"failed to insert root entry into newly created catalog.");
359 counters.
self.directories = 1;
364 PrintSqlError(
"failed to insert initial catalog statistics counters.");
369 if (!root_path.empty()) {
370 if (!this->SetProperty(
"root_prefix", root_path)) {
372 "failed to store root prefix in the newly created catalog.");
378 if (!this->SetProperty(
"last_modified", static_cast<uint64_t>(time(NULL)))) {
379 PrintSqlError(
"failed to store creation timestamp in the new catalog.");
384 retval = CommitTransaction();
386 PrintSqlError(
"failed to commit initial filling transaction");
394 bool CatalogDatabase::SetVOMSAuthz(
const std::string &voms_authz) {
395 return this->SetProperty(
"voms_authz", voms_authz);
399 double CatalogDatabase::GetRowIdWasteRatio()
const {
402 "SELECT 1.0 - CAST(COUNT(*) AS DOUBLE) / MAX(rowid) "
403 "AS ratio FROM catalog;");
404 const bool retval = rowid_waste_ratio_query.
FetchRow();
430 bool CatalogDatabase::CompactDatabase()
const {
434 && BeginTransaction()
435 &&
SqlCatalog(*
this,
"CREATE TEMPORARY TABLE duplicate AS "
436 " SELECT * FROM catalog "
437 " ORDER BY rowid ASC;")
441 " SELECT * FROM duplicate "
445 && CommitTransaction()
454 unsigned int database_flags = 0;
457 database_flags |= kFlagDirNestedRoot;
459 database_flags |= kFlagDirNestedMountpoint;
461 database_flags |= kFlagDirBindMountpoint;
464 database_flags |= kFlagDir;
465 }
else if (entry.
IsLink()) {
466 database_flags |= kFlagFile | kFlagLink;
468 database_flags |= kFlagFile | kFlagFileSpecial;
470 database_flags |= kFlagFile;
473 database_flags |= kFlagFileChunk;
475 database_flags |= kFlagFileExternal;
477 database_flags |= kFlagDirectIo;
484 database_flags |= kFlagHidden;
486 return database_flags;
491 unsigned *flags)
const {
494 *flags |= (algo - 1) << kFlagPosHash;
499 unsigned in_flags = ((7 << kFlagPosHash) & flags) >> kFlagPosHash;
508 const unsigned flags)
const {
510 unsigned in_flags = ((7 << kFlagPosCompression) & flags)
511 >> kFlagPosCompression;
516 uint32_t SqlDirent::Hardlinks2Linkcount(
const uint64_t hardlinks)
const {
517 return (hardlinks << 32) >> 32;
521 uint32_t SqlDirent::Hardlinks2HardlinkGroup(
const uint64_t hardlinks)
const {
522 return hardlinks >> 32;
526 uint64_t SqlDirent::MakeHardlinks(
const uint32_t hardlink_group,
527 const uint32_t linkcount)
const {
529 return (static_cast<uint64_t>(hardlink_group) << 32) | linkcount;
537 void SqlDirent::ExpandSymlink(
LinkString *raw_symlink)
const {
538 const char *c = raw_symlink->
GetChars();
539 const char *cEnd = c + raw_symlink->
GetLength();
540 for (; c < cEnd; ++c) {
548 for (c = raw_symlink->
GetChars(); c < cEnd; ++c) {
549 if ((*c ==
'$') && (c < cEnd - 2) && (*(c + 1) ==
'(')) {
551 const char *rpar = c;
552 while (rpar < cEnd) {
554 goto expand_symlink_getenv;
562 expand_symlink_getenv:
564 const char *default_separator = c;
565 const char *default_value = rpar;
566 while (default_separator != rpar) {
567 if ((*default_separator ==
':') && (*(default_separator + 1) ==
'-')) {
568 default_value = default_separator + 2;
574 const unsigned environ_var_length = default_separator - c;
575 char environ_var[environ_var_length + 1];
576 environ_var[environ_var_length] =
'\0';
577 memcpy(environ_var, c, environ_var_length);
578 const char *environ_value = getenv(environ_var);
580 result.
Append(environ_value, strlen(environ_value));
582 const unsigned default_length = rpar - default_value;
583 result.
Append(default_value, default_length);
590 raw_symlink->
Assign(result);
598 bool SqlDirentWrite::BindDirentFields(
const int hash_idx,
599 const int hardlinks_idx,
603 const int mtimens_idx,
606 const int symlink_idx,
613 bool result = BindHashBlob(hash_idx, entry.
checksum_)
614 && BindInt64(hardlinks_idx, hardlinks)
615 && BindInt64(size_idx, entry.
size_)
616 && BindInt(mode_idx, entry.
mode_)
617 && BindInt64(uid_idx, entry.
uid_)
618 && BindInt64(gid_idx, entry.
gid_)
619 && BindInt64(mtime_idx, entry.
mtime_)
620 && BindInt(flags_idx, CreateDatabaseFlags(entry))
626 result &= BindInt(mtimens_idx, entry.
mtime_ns_);
628 result &= BindNull(mtimens_idx);
639 static const char *stmt_lt_2_4 =
"SELECT hash, flags, 0 "
641 " WHERE length(hash) > 0;";
644 *stmt_ge_2_4 =
"SELECT hash, flags, 0 "
646 " WHERE (length(catalog.hash) > 0) AND "
647 " ((flags & 128) = 0) "
649 "SELECT chunks.hash, catalog.flags, 1 "
652 " ON catalog.md5path_1 = chunks.md5path_1 AND "
653 " catalog.md5path_2 = chunks.md5path_2 "
654 " WHERE (catalog.flags & 128) = 0;";
656 if (database.
schema_version() < 2.4 - CatalogDatabase::kSchemaEpsilon) {
657 DeferredInit(database.
sqlite_db(), stmt_lt_2_4);
659 DeferredInit(database.
sqlite_db(), stmt_ge_2_4);
665 const unsigned int db_flags = RetrieveInt(1);
667 shash::Any hash = RetrieveHashBlob(0, hash_algorithm);
668 if (RetrieveInt(2) == 1) {
678 #define DB_FIELDS_LT_V2_1 \
679 "catalog.hash, catalog.inode, catalog.size, " \
680 "catalog.mode, catalog.mtime, catalog.flags, " \
681 "catalog.name, catalog.symlink, catalog.md5path_1, " \
682 "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \
684 #define DB_FIELDS_GE_V2_1_LT_R2 \
685 "catalog.hash, catalog.hardlinks, catalog.size, " \
686 "catalog.mode, catalog.mtime, catalog.flags, " \
687 "catalog.name, catalog.symlink, catalog.md5path_1, " \
688 "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \
689 "catalog.rowid, catalog.uid, catalog.gid, " \
691 #define DB_FIELDS_GE_V2_1_LT_R7 \
692 "catalog.hash, catalog.hardlinks, catalog.size, " \
693 "catalog.mode, catalog.mtime, catalog.flags, " \
694 "catalog.name, catalog.symlink, catalog.md5path_1, " \
695 "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \
696 "catalog.rowid, catalog.uid, catalog.gid, " \
697 "catalog.xattr IS NOT NULL, NULL"
698 #define DB_FIELDS_GE_V2_1_GE_R7 \
699 "catalog.hash, catalog.hardlinks, catalog.size, " \
700 "catalog.mode, catalog.mtime, catalog.flags, " \
701 "catalog.name, catalog.symlink, catalog.md5path_1, " \
702 "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \
703 "catalog.rowid, catalog.uid, catalog.gid, " \
704 "catalog.xattr IS NOT NULL, catalog.mtimens"
706 #define MAKE_STATEMENT(STMT_TMPL, REV) \
707 static const std::string REV = ReplaceAll(STMT_TMPL, "@DB_FIELDS@", \
710 #define MAKE_STATEMENTS(STMT_TMPL) \
711 MAKE_STATEMENT(STMT_TMPL, LT_V2_1); \
712 MAKE_STATEMENT(STMT_TMPL, GE_V2_1_LT_R2); \
713 MAKE_STATEMENT(STMT_TMPL, GE_V2_1_LT_R7); \
714 MAKE_STATEMENT(STMT_TMPL, GE_V2_1_GE_R7)
716 #define DEFERRED_INIT(DB, REV) DeferredInit((DB).sqlite_db(), (REV).c_str())
718 #define DEFERRED_INITS(DB) \
719 if ((DB).schema_version() < 2.1 - CatalogDatabase::kSchemaEpsilon) { \
720 DEFERRED_INIT((DB), LT_V2_1); \
721 } else if ((DB).schema_revision() < 2) { \
722 DEFERRED_INIT((DB), GE_V2_1_LT_R2); \
723 } else if ((DB).schema_revision() < 7) { \
724 DEFERRED_INIT((DB), GE_V2_1_LT_R7); \
726 DEFERRED_INIT((DB), GE_V2_1_GE_R7); \
730 shash::Md5 SqlLookup::GetPathHash()
const {
return RetrieveMd5(8, 9); }
733 shash::Md5 SqlLookup::GetParentPathHash()
const {
return RetrieveMd5(10, 11); }
740 const bool expand_symlink)
const {
743 const unsigned database_flags = RetrieveInt(5);
746 & kFlagDirNestedMountpoint);
747 const char *name =
reinterpret_cast<const char *
>(RetrieveText(6));
748 const char *symlink =
reinterpret_cast<const char *
>(RetrieveText(7));
751 if (catalog->
schema() < 2.1 - CatalogDatabase::kSchemaEpsilon) {
761 const uint64_t hardlinks = RetrieveInt64(1);
762 result.
linkcount_ = Hardlinks2Linkcount(hardlinks);
768 result.
is_hidden_ = (database_flags & kFlagHidden);
772 result.
mtime_ns_ = RetrieveNullableInt(16, -1);
774 RetrieveHashAlgorithm(database_flags));
782 result.
uid_ = catalog->
MapUid(RetrieveInt64(13));
783 result.
gid_ = catalog->
MapGid(RetrieveInt64(14));
787 result.
mode_ = RetrieveInt(3);
788 result.
size_ = RetrieveInt64(2);
789 result.
mtime_ = RetrieveInt64(4);
796 if (S_ISDIR(result.
mode_)) {
797 result.
mode_ |= 0555;
799 result.
mode_ |= 0444;
812 "WHERE (parent_1 = :p_1) AND (parent_2 = :p_2);");
817 bool SqlListing::BindPathHash(
const struct shash::Md5 &hash) {
818 return BindMd5(1, 2, hash);
827 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
831 bool SqlLookupPathHash::BindPathHash(
const struct shash::Md5 &hash) {
832 return BindMd5(1, 2, hash);
840 MAKE_STATEMENTS(
"SELECT @DB_FIELDS@ FROM catalog WHERE rowid = :rowid;");
845 bool SqlLookupInode::BindRowId(
const uint64_t inode) {
846 return BindInt64(1, inode);
853 SqlLookupDanglingMountpoints::SqlLookupDanglingMountpoints(
856 "JOIN catalog AS c2 "
857 "ON catalog.md5path_1 = c2.parent_1 AND "
858 " catalog.md5path_2 = c2.parent_2 "
859 "WHERE catalog.flags & :nested_mountpoint_flag");
864 const bool success = BindInt64(1, SqlDirent::kFlagDirNestedMountpoint);
875 "SET hash = :hash, size = :size, mode = :mode, mtime = :mtime, "
877 "name = :name, symlink = :symlink, uid = :uid, gid = :gid, "
880 "mtimens = :mtimens "
882 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
888 bool result = BindHashBlob(1, entry.
checksum_) && BindInt64(2, entry.
size_)
889 && BindInt(3, entry.
mode_) && BindInt64(4, entry.
mtime_)
893 && BindInt64(7, entry.
uid_) && BindInt64(8, entry.
gid_);
897 result &= BindNull(10);
904 return BindMd5(11, 12, hash);
908 bool SqlDirentTouch::BindXattr(
const XattrList &xattrs) {
909 unsigned char *packed_xattrs;
912 if (packed_xattrs == NULL)
914 return BindBlobTransient(9, packed_xattrs, size);
918 bool SqlDirentTouch::BindXattrEmpty() {
return BindNull(9); }
924 SqlNestedCatalogLookup::SqlNestedCatalogLookup(
927 static const char *stmt_0_9 =
"SELECT '', 0 FROM nested_catalogs;";
928 static const char *stmt_2_5_ge_4 =
929 "SELECT sha1, size FROM nested_catalogs WHERE path=:path "
930 "UNION ALL SELECT sha1, size FROM bind_mountpoints WHERE path=:path;";
931 static const char *stmt_2_5_ge_1_lt_4 =
"SELECT sha1, size FROM "
932 "nested_catalogs WHERE path=:path;";
935 *stmt_2_5_lt_1 =
"SELECT sha1, 0 FROM nested_catalogs WHERE path=:path;";
939 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_4);
942 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_1_lt_4);
945 DeferredInit(database.
sqlite_db(), stmt_0_9);
947 DeferredInit(database.
sqlite_db(), stmt_2_5_lt_1);
953 bool SqlNestedCatalogLookup::BindSearchPath(
const PathString &path) {
959 const string hash = string(reinterpret_cast<const char *>(RetrieveText(0)));
960 return (hash.empty())
966 uint64_t SqlNestedCatalogLookup::GetSize()
const {
return RetrieveInt64(1); }
972 SqlNestedCatalogListing::SqlNestedCatalogListing(
975 static const char *stmt_0_9 =
"SELECT '', '', 0 FROM nested_catalogs;";
976 static const char *stmt_2_5_ge_4 =
977 "SELECT path, sha1, size FROM nested_catalogs "
978 "UNION ALL SELECT path, sha1, size FROM bind_mountpoints;";
980 *stmt_2_5_ge_1_lt_4 =
"SELECT path, sha1, size FROM nested_catalogs;";
983 *stmt_2_5_lt_1 =
"SELECT path, sha1, 0 FROM nested_catalogs;";
987 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_4);
990 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_1_lt_4);
993 DeferredInit(database.
sqlite_db(), stmt_0_9);
995 DeferredInit(database.
sqlite_db(), stmt_2_5_lt_1);
1002 const char *path =
reinterpret_cast<const char *
>(RetrieveText(0));
1008 const string hash = string(reinterpret_cast<const char *>(RetrieveText(1)));
1009 return (hash.empty())
1015 uint64_t SqlNestedCatalogListing::GetSize()
const {
return RetrieveInt64(2); }
1021 SqlOwnNestedCatalogListing::SqlOwnNestedCatalogListing(
1024 static const char *stmt_0_9 =
"SELECT '', '', 0 FROM nested_catalogs;";
1026 *stmt_2_5_ge_1 =
"SELECT path, sha1, size FROM nested_catalogs;";
1029 *stmt_2_5_lt_1 =
"SELECT path, sha1, 0 FROM nested_catalogs;";
1033 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_1);
1036 DeferredInit(database.
sqlite_db(), stmt_0_9);
1038 DeferredInit(database.
sqlite_db(), stmt_2_5_lt_1);
1045 const char *path =
reinterpret_cast<const char *
>(RetrieveText(0));
1051 const string hash = string(reinterpret_cast<const char *>(RetrieveText(1)));
1052 return (hash.empty())
1058 uint64_t SqlOwnNestedCatalogListing::GetSize()
const {
1059 return RetrieveInt64(2);
1069 "INSERT INTO catalog "
1070 "(md5path_1, md5path_2, parent_1, parent_2, hash, hardlinks, size, mode,"
1072 "mtime, flags, name, symlink, uid, gid, xattr, mtimens) "
1074 "VALUES (:md5_1, :md5_2, :p_1, :p_2, :hash, :links, :size, :mode, :mtime,"
1075 " :flags, :name, :symlink, :uid, :gid, :xattr, :mtimens);");
1080 return BindMd5(1, 2, hash);
1084 bool SqlDirentInsert::BindParentPathHash(
const shash::Md5 &hash) {
1085 return BindMd5(3, 4, hash);
1090 return BindDirentFields(5, 6, 7, 8, 9, 16, 10, 11, 12, 13, 14, entry);
1095 unsigned char *packed_xattrs;
1097 xattrs.
Serialize(&packed_xattrs, &size);
1098 if (packed_xattrs == NULL)
1099 return BindNull(15);
1100 return BindBlobTransient(15, packed_xattrs, size);
1104 bool SqlDirentInsert::BindXattrEmpty() {
return BindNull(15); }
1113 "SET hash = :hash, size = :size, mode = :mode, mtime = :mtime, "
1115 "flags = :flags, name = :name, symlink = :symlink, hardlinks = "
1118 "uid = :uid, gid = :gid, mtimens = :mtimens "
1120 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
1126 return BindMd5(12, 13, hash);
1131 return BindDirentFields(1, 8, 2, 3, 4, 11, 5, 6, 7, 9, 10, entry);
1140 "DELETE FROM catalog "
1141 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
1145 return BindMd5(1, 2, hash);
1161 "UPDATE catalog SET hardlinks = hardlinks + :delta "
1162 "WHERE hardlinks = (SELECT hardlinks from catalog "
1163 "WHERE md5path_1 = :md5_1 AND md5path_2 = :md5_2);");
1168 return BindMd5(2, 3, hash);
1172 bool SqlIncLinkcount::BindDelta(
const int delta) {
return BindInt(1, delta); }
1180 "INSERT INTO chunks (md5path_1, md5path_2, offset, size, hash) "
1182 "VALUES (:md5_1, :md5_2, :offset, :size, :hash);");
1187 return BindMd5(1, 2, hash);
1191 bool SqlChunkInsert::BindFileChunk(
const FileChunk &chunk) {
1192 return BindInt64(3, chunk.
offset()) && BindInt64(4, chunk.
size())
1202 "DELETE FROM chunks "
1203 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
1208 return BindMd5(1, 2, hash);
1217 "SELECT offset, size, hash FROM chunks "
1219 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2) "
1221 "ORDER BY offset ASC;");
1226 return BindMd5(1, 2, hash);
1244 "SELECT count(*) FROM chunks "
1246 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2)");
1252 return BindMd5(1, 2, hash);
1256 int SqlChunksCount::GetChunkCount()
const {
return RetrieveInt64(0); }
1263 DeferredInit(database.
sqlite_db(),
"SELECT max(hardlinks) FROM catalog;");
1267 uint32_t SqlMaxHardlinkGroup::GetMaxGroupId()
const {
1268 return RetrieveInt64(0) >> 32;
1277 *stmt_ge_2_4 =
"SELECT value from statistics WHERE counter = :counter;";
1278 static const char *stmt_lt_2_4 =
"SELECT 0;";
1280 if (database.
schema_version() >= 2.4 - CatalogDatabase::kSchemaEpsilon) {
1282 DeferredInit(database.
sqlite_db(), stmt_ge_2_4);
1285 DeferredInit(database.
sqlite_db(), stmt_lt_2_4);
1290 bool SqlGetCounter::BindCounter(
const std::string &counter) {
1293 return BindText(1, counter);
1297 uint64_t SqlGetCounter::GetCounter()
const {
1300 return RetrieveInt64(0);
1310 "UPDATE statistics SET value=value+:val WHERE counter=:counter;");
1314 bool SqlUpdateCounter::BindCounter(
const std::string &counter) {
1315 return BindText(2, counter);
1319 bool SqlUpdateCounter::BindDelta(
const int64_t delta) {
1320 return BindInt64(1, delta);
1329 "INSERT OR REPLACE INTO statistics (counter, value) "
1330 "VALUES (:counter, :value);");
1334 bool SqlCreateCounter::BindCounter(
const std::string &counter) {
1335 return BindText(1, counter);
1339 bool SqlCreateCounter::BindInitialValue(
const int64_t value) {
1340 return BindInt64(2, value);
1348 int hash_mask = 7 << SqlDirent::kFlagPosHash;
1349 string flags2hash =
" ((flags&" +
StringifyInt(hash_mask) +
") >> "
1351 +
")+1 AS hash_algorithm ";
1353 int compression_mask = 7 << SqlDirent::kFlagPosCompression;
1354 string flags2compression =
" ((flags&" +
StringifyInt(compression_mask)
1357 +
") " +
"AS compression_algorithm ";
1363 string sql =
"SELECT DISTINCT hash, "
1364 "CASE WHEN flags & "
1369 +
"AS chunk_type, " + flags2hash +
"," + flags2compression
1370 +
"FROM catalog WHERE (hash IS NOT NULL) AND "
1372 +
StringifyInt(SqlDirent::kFlagFileExternal) +
" = 0)";
1373 if (database.
schema_version() >= 2.4 - CatalogDatabase::kSchemaEpsilon) {
1375 "SELECT DISTINCT chunks.hash, "
1378 +
"FROM chunks, catalog WHERE "
1379 "chunks.md5path_1=catalog.md5path_1 AND "
1380 "chunks.md5path_2=catalog.md5path_2 AND "
1382 +
StringifyInt(SqlDirent::kFlagFileExternal) +
" = 0)";
1397 *hash = RetrieveHashBlob(0, static_cast<shash::Algorithms>(RetrieveInt(2)),
1398 static_cast<shash::Suffix>(RetrieveInt(1)));
1404 bool SqlAllChunks::Close() {
return Reset(); }
1412 "SELECT xattr FROM catalog "
1413 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
1418 return BindMd5(1, 2, hash);
1423 const unsigned char *packed_xattrs =
reinterpret_cast<const unsigned char *
>(
1425 if (packed_xattrs == NULL)
1428 int size = RetrieveBytes(0);
bool InsertIntoDatabase(const CatalogDatabase &database) const
bool IsExternalFile() const
uint64_t MapUid(const uint64_t uid) const
bool IsChunkedFile() const
bool BindDirent(const DirectoryEntry &entry)
void Assign(const char *chars, const unsigned length)
double RetrieveDouble(const int idx_column) const
const char kSuffixMicroCatalog
const shash::Any & content_hash() const
assert((mem||(size==0))&&"Out Of Memory")
float schema_version() const
#define MAKE_STATEMENTS(STMT_TMPL)
unsigned schema_revision() const
#define DEFERRED_INITS(DB)
bool IsNestedCatalogMountpoint() const
bool BindPathHash(const shash::Md5 &hash)
bool IsNestedCatalogRoot() const
zlib::Algorithms compression_algorithm_
const char kSuffixPartial
void Serialize(unsigned char **outbuf, unsigned *size, const std::vector< std::string > *blacklist=NULL) const
const char kSuffixCatalog
bool is_nested_catalog_mountpoint_
zlib::Algorithms compression_algorithm() const
static int Init(const loader::LoaderExports *loader_exports)
void Append(const char *chars, const unsigned length)
string StringifyInt(const int64_t value)
sqlite3 * sqlite_db() const
bool IsBindMountpoint() const
bool IsEqualSchema(const float value, const float compare) const
inode_t GetMangledInode(const uint64_t row_id, const uint64_t hardlink_group) const
static XattrList * Deserialize(const unsigned char *inbuf, const unsigned size)
ShortString< kDefaultMaxPath, 0 > PathString
PathString GetParentPath(const PathString &path)
Any MkFromHexPtr(const HexPtr hex, const char suffix)
unsigned GetLength() const
bool is_nested_catalog_root_
const char * GetChars() const
bool BindParentPathHash(const shash::Md5 &hash)
const shash::Any * checksum_ptr() const
uint64_t MapGid(const uint64_t gid) const
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)