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,
313 retval = BeginTransaction();
315 PrintSqlError(
"failed to enter initial filling transaction");
320 if (!this->SetProperty(
"revision", 0)) {
322 "failed to insert default initial values into the newly created "
327 if (volatile_content) {
328 if (!this->SetProperty(
"volatile", 1)) {
329 PrintSqlError(
"failed to insert volatile flag into the newly created "
335 if (!voms_authz.empty()) {
336 if (!SetVOMSAuthz(voms_authz)) {
337 PrintSqlError(
"failed to insert VOMS authz flag into the newly created "
353 PrintSqlError(
"failed to insert root entry into newly created catalog.");
358 counters.
self.directories = 1;
363 PrintSqlError(
"failed to insert initial catalog statistics counters.");
368 if (!root_path.empty()) {
369 if (!this->SetProperty(
"root_prefix", root_path)) {
371 "failed to store root prefix in the newly created catalog.");
377 if (!this->SetProperty(
"last_modified", static_cast<uint64_t>(time(NULL)))) {
378 PrintSqlError(
"failed to store creation timestamp in the new catalog.");
383 retval = CommitTransaction();
385 PrintSqlError(
"failed to commit initial filling transaction");
393 bool CatalogDatabase::SetVOMSAuthz(
const std::string &voms_authz) {
394 return this->SetProperty(
"voms_authz", voms_authz);
398 double CatalogDatabase::GetRowIdWasteRatio()
const {
401 "SELECT 1.0 - CAST(COUNT(*) AS DOUBLE) / MAX(rowid) "
402 "AS ratio FROM catalog;");
403 const bool retval = rowid_waste_ratio_query.
FetchRow();
429 bool CatalogDatabase::CompactDatabase()
const {
433 && BeginTransaction()
434 &&
SqlCatalog(*
this,
"CREATE TEMPORARY TABLE duplicate AS "
435 " SELECT * FROM catalog "
436 " ORDER BY rowid ASC;")
440 " SELECT * FROM duplicate "
444 && CommitTransaction()
453 unsigned int database_flags = 0;
456 database_flags |= kFlagDirNestedRoot;
458 database_flags |= kFlagDirNestedMountpoint;
460 database_flags |= kFlagDirBindMountpoint;
463 database_flags |= kFlagDir;
464 }
else if (entry.
IsLink()) {
465 database_flags |= kFlagFile | kFlagLink;
467 database_flags |= kFlagFile | kFlagFileSpecial;
469 database_flags |= kFlagFile;
472 database_flags |= kFlagFileChunk;
474 database_flags |= kFlagFileExternal;
476 database_flags |= kFlagDirectIo;
483 database_flags |= kFlagHidden;
485 return database_flags;
490 unsigned *flags)
const {
493 *flags |= (algo - 1) << kFlagPosHash;
498 unsigned in_flags = ((7 << kFlagPosHash) & flags) >> kFlagPosHash;
507 const unsigned flags)
const {
509 const unsigned in_flags =
510 ((7 << kFlagPosCompression) & flags) >> kFlagPosCompression;
515 uint32_t SqlDirent::Hardlinks2Linkcount(
const uint64_t hardlinks)
const {
516 return (hardlinks << 32) >> 32;
520 uint32_t SqlDirent::Hardlinks2HardlinkGroup(
const uint64_t hardlinks)
const {
521 return hardlinks >> 32;
525 uint64_t SqlDirent::MakeHardlinks(
const uint32_t hardlink_group,
526 const uint32_t linkcount)
const {
528 return (static_cast<uint64_t>(hardlink_group) << 32) | linkcount;
536 void SqlDirent::ExpandSymlink(
LinkString *raw_symlink)
const {
537 const char *c = raw_symlink->
GetChars();
538 const char *cEnd = c + raw_symlink->
GetLength();
539 for (; c < cEnd; ++c) {
547 for (c = raw_symlink->
GetChars(); c < cEnd; ++c) {
548 if ((*c ==
'$') && (c < cEnd - 2) && (*(c + 1) ==
'(')) {
550 const char *rpar = c;
551 while (rpar < cEnd) {
553 goto expand_symlink_getenv;
561 expand_symlink_getenv:
563 const char *default_separator = c;
564 const char *default_value = rpar;
565 while (default_separator != rpar) {
566 if ((*default_separator ==
':') && (*(default_separator + 1) ==
'-')) {
567 default_value = default_separator + 2;
573 const unsigned environ_var_length = default_separator - c;
574 char environ_var[environ_var_length + 1];
575 environ_var[environ_var_length] =
'\0';
576 memcpy(environ_var, c, environ_var_length);
577 const char *environ_value = getenv(environ_var);
579 result.
Append(environ_value, strlen(environ_value));
581 const unsigned default_length = rpar - default_value;
582 result.
Append(default_value, default_length);
589 raw_symlink->
Assign(result);
597 bool SqlDirentWrite::BindDirentFields(
const int hash_idx,
598 const int hardlinks_idx,
602 const int mtimens_idx,
605 const int symlink_idx,
612 bool result = BindHashBlob(hash_idx, entry.
checksum_)
613 && BindInt64(hardlinks_idx, hardlinks)
614 && BindInt64(size_idx, entry.
size_)
615 && BindInt(mode_idx, entry.
mode_)
616 && BindInt64(uid_idx, entry.
uid_)
617 && BindInt64(gid_idx, entry.
gid_)
618 && BindInt64(mtime_idx, entry.
mtime_)
619 && BindInt(flags_idx, CreateDatabaseFlags(entry))
625 result &= BindInt(mtimens_idx, entry.
mtime_ns_);
627 result &= BindNull(mtimens_idx);
638 static const char *stmt_lt_2_4 =
"SELECT hash, flags, 0 "
640 " WHERE length(hash) > 0;";
643 *stmt_ge_2_4 =
"SELECT hash, flags, 0 "
645 " WHERE (length(catalog.hash) > 0) AND "
646 " ((flags & 128) = 0) "
648 "SELECT chunks.hash, catalog.flags, 1 "
651 " ON catalog.md5path_1 = chunks.md5path_1 AND "
652 " catalog.md5path_2 = chunks.md5path_2 "
653 " WHERE (catalog.flags & 128) = 0;";
655 if (database.
schema_version() < 2.4 - CatalogDatabase::kSchemaEpsilon) {
656 DeferredInit(database.
sqlite_db(), stmt_lt_2_4);
658 DeferredInit(database.
sqlite_db(), stmt_ge_2_4);
664 const unsigned int db_flags = RetrieveInt(1);
666 shash::Any hash = RetrieveHashBlob(0, hash_algorithm);
667 if (RetrieveInt(2) == 1) {
677 #define DB_FIELDS_LT_V2_1 \
678 "catalog.hash, catalog.inode, catalog.size, " \
679 "catalog.mode, catalog.mtime, catalog.flags, " \
680 "catalog.name, catalog.symlink, catalog.md5path_1, " \
681 "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \
683 #define DB_FIELDS_GE_V2_1_LT_R2 \
684 "catalog.hash, catalog.hardlinks, catalog.size, " \
685 "catalog.mode, catalog.mtime, catalog.flags, " \
686 "catalog.name, catalog.symlink, catalog.md5path_1, " \
687 "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \
688 "catalog.rowid, catalog.uid, catalog.gid, " \
690 #define DB_FIELDS_GE_V2_1_LT_R7 \
691 "catalog.hash, catalog.hardlinks, catalog.size, " \
692 "catalog.mode, catalog.mtime, catalog.flags, " \
693 "catalog.name, catalog.symlink, catalog.md5path_1, " \
694 "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \
695 "catalog.rowid, catalog.uid, catalog.gid, " \
696 "catalog.xattr IS NOT NULL, NULL"
697 #define DB_FIELDS_GE_V2_1_GE_R7 \
698 "catalog.hash, catalog.hardlinks, catalog.size, " \
699 "catalog.mode, catalog.mtime, catalog.flags, " \
700 "catalog.name, catalog.symlink, catalog.md5path_1, " \
701 "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \
702 "catalog.rowid, catalog.uid, catalog.gid, " \
703 "catalog.xattr IS NOT NULL, catalog.mtimens"
705 #define MAKE_STATEMENT(STMT_TMPL, REV) \
706 static const std::string REV = ReplaceAll(STMT_TMPL, "@DB_FIELDS@", \
709 #define MAKE_STATEMENTS(STMT_TMPL) \
710 MAKE_STATEMENT(STMT_TMPL, LT_V2_1); \
711 MAKE_STATEMENT(STMT_TMPL, GE_V2_1_LT_R2); \
712 MAKE_STATEMENT(STMT_TMPL, GE_V2_1_LT_R7); \
713 MAKE_STATEMENT(STMT_TMPL, GE_V2_1_GE_R7)
715 #define DEFERRED_INIT(DB, REV) DeferredInit((DB).sqlite_db(), (REV).c_str())
717 #define DEFERRED_INITS(DB) \
718 if ((DB).schema_version() < 2.1 - CatalogDatabase::kSchemaEpsilon) { \
719 DEFERRED_INIT((DB), LT_V2_1); \
720 } else if ((DB).schema_revision() < 2) { \
721 DEFERRED_INIT((DB), GE_V2_1_LT_R2); \
722 } else if ((DB).schema_revision() < 7) { \
723 DEFERRED_INIT((DB), GE_V2_1_LT_R7); \
725 DEFERRED_INIT((DB), GE_V2_1_GE_R7); \
729 shash::Md5 SqlLookup::GetPathHash()
const {
return RetrieveMd5(8, 9); }
732 shash::Md5 SqlLookup::GetParentPathHash()
const {
return RetrieveMd5(10, 11); }
739 const bool expand_symlink)
const {
742 const unsigned database_flags = RetrieveInt(5);
745 & kFlagDirNestedMountpoint);
746 const char *name =
reinterpret_cast<const char *
>(RetrieveText(6));
747 const char *symlink =
reinterpret_cast<const char *
>(RetrieveText(7));
750 if (catalog->
schema() < 2.1 - CatalogDatabase::kSchemaEpsilon) {
760 const uint64_t hardlinks = RetrieveInt64(1);
761 result.
linkcount_ = Hardlinks2Linkcount(hardlinks);
767 result.
is_hidden_ = (database_flags & kFlagHidden);
771 result.
mtime_ns_ = RetrieveNullableInt(16, -1);
773 RetrieveHashAlgorithm(database_flags));
781 result.
uid_ = catalog->
MapUid(RetrieveInt64(13));
782 result.
gid_ = catalog->
MapGid(RetrieveInt64(14));
786 result.
mode_ = RetrieveInt(3);
787 result.
size_ = RetrieveInt64(2);
788 result.
mtime_ = RetrieveInt64(4);
795 if (S_ISDIR(result.
mode_)) {
796 result.
mode_ |= 0555;
798 result.
mode_ |= 0444;
811 "WHERE (parent_1 = :p_1) AND (parent_2 = :p_2);");
816 bool SqlListing::BindPathHash(
const struct shash::Md5 &hash) {
817 return BindMd5(1, 2, hash);
826 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
830 bool SqlLookupPathHash::BindPathHash(
const struct shash::Md5 &hash) {
831 return BindMd5(1, 2, hash);
839 MAKE_STATEMENTS(
"SELECT @DB_FIELDS@ FROM catalog WHERE rowid = :rowid;");
844 bool SqlLookupInode::BindRowId(
const uint64_t inode) {
845 return BindInt64(1, inode);
852 SqlLookupDanglingMountpoints::SqlLookupDanglingMountpoints(
855 "JOIN catalog AS c2 "
856 "ON catalog.md5path_1 = c2.parent_1 AND "
857 " catalog.md5path_2 = c2.parent_2 "
858 "WHERE catalog.flags & :nested_mountpoint_flag");
863 const bool success = BindInt64(1, SqlDirent::kFlagDirNestedMountpoint);
874 "SET hash = :hash, size = :size, mode = :mode, mtime = :mtime, "
876 "name = :name, symlink = :symlink, uid = :uid, gid = :gid, "
879 "mtimens = :mtimens "
881 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
887 bool result = BindHashBlob(1, entry.
checksum_) && BindInt64(2, entry.
size_)
888 && BindInt(3, entry.
mode_) && BindInt64(4, entry.
mtime_)
892 && BindInt64(7, entry.
uid_) && BindInt64(8, entry.
gid_);
896 result &= BindNull(10);
903 return BindMd5(11, 12, hash);
907 bool SqlDirentTouch::BindXattr(
const XattrList &xattrs) {
908 unsigned char *packed_xattrs;
911 if (packed_xattrs == NULL)
913 return BindBlobTransient(9, packed_xattrs, size);
917 bool SqlDirentTouch::BindXattrEmpty() {
return BindNull(9); }
923 SqlNestedCatalogLookup::SqlNestedCatalogLookup(
926 static const char *stmt_0_9 =
"SELECT '', 0 FROM nested_catalogs;";
927 static const char *stmt_2_5_ge_4 =
928 "SELECT sha1, size FROM nested_catalogs WHERE path=:path "
929 "UNION ALL SELECT sha1, size FROM bind_mountpoints WHERE path=:path;";
930 static const char *stmt_2_5_ge_1_lt_4 =
"SELECT sha1, size FROM "
931 "nested_catalogs WHERE path=:path;";
934 *stmt_2_5_lt_1 =
"SELECT sha1, 0 FROM nested_catalogs WHERE path=:path;";
938 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_4);
941 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_1_lt_4);
944 DeferredInit(database.
sqlite_db(), stmt_0_9);
946 DeferredInit(database.
sqlite_db(), stmt_2_5_lt_1);
952 bool SqlNestedCatalogLookup::BindSearchPath(
const PathString &path) {
958 const string hash = string(reinterpret_cast<const char *>(RetrieveText(0)));
959 return (hash.empty())
965 uint64_t SqlNestedCatalogLookup::GetSize()
const {
return RetrieveInt64(1); }
971 SqlNestedCatalogListing::SqlNestedCatalogListing(
974 static const char *stmt_0_9 =
"SELECT '', '', 0 FROM nested_catalogs;";
975 static const char *stmt_2_5_ge_4 =
976 "SELECT path, sha1, size FROM nested_catalogs "
977 "UNION ALL SELECT path, sha1, size FROM bind_mountpoints;";
979 *stmt_2_5_ge_1_lt_4 =
"SELECT path, sha1, size FROM nested_catalogs;";
982 *stmt_2_5_lt_1 =
"SELECT path, sha1, 0 FROM nested_catalogs;";
986 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_4);
989 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_1_lt_4);
992 DeferredInit(database.
sqlite_db(), stmt_0_9);
994 DeferredInit(database.
sqlite_db(), stmt_2_5_lt_1);
1001 const char *path =
reinterpret_cast<const char *
>(RetrieveText(0));
1007 const string hash = string(reinterpret_cast<const char *>(RetrieveText(1)));
1008 return (hash.empty())
1014 uint64_t SqlNestedCatalogListing::GetSize()
const {
return RetrieveInt64(2); }
1020 SqlOwnNestedCatalogListing::SqlOwnNestedCatalogListing(
1023 static const char *stmt_0_9 =
"SELECT '', '', 0 FROM nested_catalogs;";
1025 *stmt_2_5_ge_1 =
"SELECT path, sha1, size FROM nested_catalogs;";
1028 *stmt_2_5_lt_1 =
"SELECT path, sha1, 0 FROM nested_catalogs;";
1032 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_1);
1035 DeferredInit(database.
sqlite_db(), stmt_0_9);
1037 DeferredInit(database.
sqlite_db(), stmt_2_5_lt_1);
1044 const char *path =
reinterpret_cast<const char *
>(RetrieveText(0));
1050 const string hash = string(reinterpret_cast<const char *>(RetrieveText(1)));
1051 return (hash.empty())
1057 uint64_t SqlOwnNestedCatalogListing::GetSize()
const {
1058 return RetrieveInt64(2);
1068 "INSERT INTO catalog "
1069 "(md5path_1, md5path_2, parent_1, parent_2, hash, hardlinks, size, mode,"
1071 "mtime, flags, name, symlink, uid, gid, xattr, mtimens) "
1073 "VALUES (:md5_1, :md5_2, :p_1, :p_2, :hash, :links, :size, :mode, :mtime,"
1074 " :flags, :name, :symlink, :uid, :gid, :xattr, :mtimens);");
1079 return BindMd5(1, 2, hash);
1083 bool SqlDirentInsert::BindParentPathHash(
const shash::Md5 &hash) {
1084 return BindMd5(3, 4, hash);
1089 return BindDirentFields(5, 6, 7, 8, 9, 16, 10, 11, 12, 13, 14, entry);
1094 unsigned char *packed_xattrs;
1096 xattrs.
Serialize(&packed_xattrs, &size);
1097 if (packed_xattrs == NULL)
1098 return BindNull(15);
1099 return BindBlobTransient(15, packed_xattrs, size);
1103 bool SqlDirentInsert::BindXattrEmpty() {
return BindNull(15); }
1112 "SET hash = :hash, size = :size, mode = :mode, mtime = :mtime, "
1114 "flags = :flags, name = :name, symlink = :symlink, hardlinks = "
1117 "uid = :uid, gid = :gid, mtimens = :mtimens "
1119 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
1125 return BindMd5(12, 13, hash);
1130 return BindDirentFields(1, 8, 2, 3, 4, 11, 5, 6, 7, 9, 10, entry);
1139 "DELETE FROM catalog "
1140 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
1144 return BindMd5(1, 2, hash);
1160 "UPDATE catalog SET hardlinks = hardlinks + :delta "
1161 "WHERE hardlinks = (SELECT hardlinks from catalog "
1162 "WHERE md5path_1 = :md5_1 AND md5path_2 = :md5_2);");
1167 return BindMd5(2, 3, hash);
1171 bool SqlIncLinkcount::BindDelta(
const int delta) {
return BindInt(1, delta); }
1179 "INSERT INTO chunks (md5path_1, md5path_2, offset, size, hash) "
1181 "VALUES (:md5_1, :md5_2, :offset, :size, :hash);");
1186 return BindMd5(1, 2, hash);
1190 bool SqlChunkInsert::BindFileChunk(
const FileChunk &chunk) {
1191 return BindInt64(3, chunk.
offset()) && BindInt64(4, chunk.
size())
1201 "DELETE FROM chunks "
1202 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
1207 return BindMd5(1, 2, hash);
1216 "SELECT offset, size, hash FROM chunks "
1218 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2) "
1220 "ORDER BY offset ASC;");
1225 return BindMd5(1, 2, hash);
1243 "SELECT count(*) FROM chunks "
1245 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2)");
1251 return BindMd5(1, 2, hash);
1255 int SqlChunksCount::GetChunkCount()
const {
return RetrieveInt64(0); }
1262 DeferredInit(database.
sqlite_db(),
"SELECT max(hardlinks) FROM catalog;");
1266 uint32_t SqlMaxHardlinkGroup::GetMaxGroupId()
const {
1267 return RetrieveInt64(0) >> 32;
1276 *stmt_ge_2_4 =
"SELECT value from statistics WHERE counter = :counter;";
1277 static const char *stmt_lt_2_4 =
"SELECT 0;";
1279 if (database.
schema_version() >= 2.4 - CatalogDatabase::kSchemaEpsilon) {
1281 DeferredInit(database.
sqlite_db(), stmt_ge_2_4);
1284 DeferredInit(database.
sqlite_db(), stmt_lt_2_4);
1289 bool SqlGetCounter::BindCounter(
const std::string &counter) {
1292 return BindText(1, counter);
1296 uint64_t SqlGetCounter::GetCounter()
const {
1299 return RetrieveInt64(0);
1309 "UPDATE statistics SET value=value+:val WHERE counter=:counter;");
1313 bool SqlUpdateCounter::BindCounter(
const std::string &counter) {
1314 return BindText(2, counter);
1318 bool SqlUpdateCounter::BindDelta(
const int64_t delta) {
1319 return BindInt64(1, delta);
1328 "INSERT OR REPLACE INTO statistics (counter, value) "
1329 "VALUES (:counter, :value);");
1333 bool SqlCreateCounter::BindCounter(
const std::string &counter) {
1334 return BindText(1, counter);
1338 bool SqlCreateCounter::BindInitialValue(
const int64_t value) {
1339 return BindInt64(2, value);
1347 const int hash_mask = 7 << SqlDirent::kFlagPosHash;
1348 const string flags2hash =
" ((flags&" +
StringifyInt(hash_mask) +
") >> " +
1350 ")+1 AS hash_algorithm ";
1352 const int compression_mask = 7 << SqlDirent::kFlagPosCompression;
1353 const string flags2compression =
1354 " ((flags&" +
StringifyInt(compression_mask) +
") >> " +
1356 "AS compression_algorithm ";
1362 string sql =
"SELECT DISTINCT hash, "
1363 "CASE WHEN flags & "
1368 +
"AS chunk_type, " + flags2hash +
"," + flags2compression
1369 +
"FROM catalog WHERE (hash IS NOT NULL) AND "
1371 +
StringifyInt(SqlDirent::kFlagFileExternal) +
" = 0)";
1372 if (database.
schema_version() >= 2.4 - CatalogDatabase::kSchemaEpsilon) {
1374 "SELECT DISTINCT chunks.hash, "
1377 +
"FROM chunks, catalog WHERE "
1378 "chunks.md5path_1=catalog.md5path_1 AND "
1379 "chunks.md5path_2=catalog.md5path_2 AND "
1381 +
StringifyInt(SqlDirent::kFlagFileExternal) +
" = 0)";
1396 *hash = RetrieveHashBlob(0, static_cast<shash::Algorithms>(RetrieveInt(2)),
1397 static_cast<shash::Suffix>(RetrieveInt(1)));
1403 bool SqlAllChunks::Close() {
return Reset(); }
1411 "SELECT xattr FROM catalog "
1412 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
1417 return BindMd5(1, 2, hash);
1422 const unsigned char *packed_xattrs =
reinterpret_cast<const unsigned char *
>(
1424 if (packed_xattrs == NULL)
1427 const 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,...)