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;");
119 "INSERT INTO statistics (counter, value) VALUES ('self_xattr', 0);");
121 "INSERT INTO statistics (counter, value) VALUES ('subtree_xattr', 0);");
129 set_schema_revision(2);
130 if (!StoreSchemaRevision()) {
136 if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 2)) {
140 "INSERT INTO statistics (counter, value) VALUES "
141 "('self_external', 0);");
143 "INSERT INTO statistics (counter, value) VALUES "
144 "('self_external_file_size', 0);");
146 "INSERT INTO statistics (counter, value) VALUES "
147 "('subtree_external', 0);");
149 "INSERT INTO statistics (counter, value) VALUES "
150 "('subtree_external_file_size', 0);");
158 set_schema_revision(3);
159 if (!StoreSchemaRevision()) {
165 if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 3)) {
169 "CREATE TABLE bind_mountpoints (path TEXT, sha1 TEXT, size INTEGER, "
170 "CONSTRAINT pk_bind_mountpoints PRIMARY KEY (path));");
176 set_schema_revision(4);
177 if (!StoreSchemaRevision()) {
184 if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 4)) {
188 "INSERT INTO statistics (counter, value) VALUES "
189 "('self_special', 0);");
191 "INSERT INTO statistics (counter, value) VALUES "
192 "('subtree_special', 0);");
198 set_schema_revision(5);
199 if (!StoreSchemaRevision()) {
206 if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 5)) {
209 set_schema_revision(6);
210 if (!StoreSchemaRevision()) {
216 if (IsEqualSchema(schema_version(), 2.5) && (schema_revision() == 6)) {
219 SqlCatalog sql_upgrade1(*
this,
"ALTER TABLE catalog ADD mtimens INTEGER;");
225 set_schema_revision(7);
226 if (!StoreSchemaRevision()) {
236 bool CatalogDatabase::CreateEmptyDatabase() {
242 "CREATE TABLE catalog "
243 "(md5path_1 INTEGER, md5path_2 INTEGER, parent_1 INTEGER, parent_2 INTEGER,"
244 " hardlinks INTEGER, hash BLOB, size INTEGER, mode INTEGER, mtime INTEGER,"
245 " mtimens INTEGER, flags INTEGER, name TEXT, symlink TEXT, uid INTEGER,"
246 " gid INTEGER, xattr BLOB, "
247 " CONSTRAINT pk_catalog PRIMARY KEY (md5path_1, md5path_2));").
Execute() &&
249 "CREATE INDEX idx_catalog_parent "
250 "ON catalog (parent_1, parent_2);") .
Execute() &&
252 "CREATE TABLE chunks "
253 "(md5path_1 INTEGER, md5path_2 INTEGER, offset INTEGER, size INTEGER, "
255 " CONSTRAINT pk_chunks PRIMARY KEY (md5path_1, md5path_2, offset, size), "
256 " FOREIGN KEY (md5path_1, md5path_2) REFERENCES "
257 " catalog(md5path_1, md5path_2));") .
Execute() &&
259 "CREATE TABLE nested_catalogs (path TEXT, sha1 TEXT, size INTEGER, "
260 "CONSTRAINT pk_nested_catalogs PRIMARY KEY (path));") .
Execute() &&
269 "CREATE TABLE bind_mountpoints (path TEXT, sha1 TEXT, size INTEGER, "
270 "CONSTRAINT pk_bind_mountpoints PRIMARY KEY (path));") .
Execute() &&
272 "CREATE TABLE statistics (counter TEXT, value INTEGER, "
273 "CONSTRAINT pk_statistics PRIMARY KEY (counter));") .
Execute();
276 PrintSqlError(
"failed to create catalog database tables.");
283 bool CatalogDatabase::InsertInitialValues(
284 const std::string &root_path,
285 const bool volatile_content,
286 const std::string &voms_authz,
294 shash::Md5 root_parent_hash = (root_path ==
"")
299 retval = BeginTransaction();
301 PrintSqlError(
"failed to enter initial filling transaction");
306 if (!this->SetProperty(
"revision", 0)) {
308 "failed to insert default initial values into the newly created "
313 if (volatile_content) {
314 if (!this->SetProperty(
"volatile", 1)) {
315 PrintSqlError(
"failed to insert volatile flag into the newly created "
321 if (!voms_authz.empty()) {
322 if (!SetVOMSAuthz(voms_authz)) {
323 PrintSqlError(
"failed to insert VOMS authz flag into the newly created "
340 PrintSqlError(
"failed to insert root entry into newly created catalog.");
345 counters.
self.directories = 1;
350 PrintSqlError(
"failed to insert initial catalog statistics counters.");
355 if (!root_path.empty()) {
356 if (!this->SetProperty(
"root_prefix", root_path)) {
358 "failed to store root prefix in the newly created catalog.");
364 if (!this->SetProperty(
"last_modified", static_cast<uint64_t>(time(NULL)))) {
365 PrintSqlError(
"failed to store creation timestamp in the new catalog.");
370 retval = CommitTransaction();
372 PrintSqlError(
"failed to commit initial filling transaction");
381 CatalogDatabase::SetVOMSAuthz(
const std::string &voms_authz) {
382 return this->SetProperty(
"voms_authz", voms_authz);
386 double CatalogDatabase::GetRowIdWasteRatio()
const {
388 "SELECT 1.0 - CAST(COUNT(*) AS DOUBLE) / MAX(rowid) "
389 "AS ratio FROM catalog;");
390 const bool retval = rowid_waste_ratio_query.
FetchRow();
416 bool CatalogDatabase::CompactDatabase()
const {
420 BeginTransaction() &&
421 SqlCatalog(*
this,
"CREATE TEMPORARY TABLE duplicate AS "
422 " SELECT * FROM catalog "
423 " ORDER BY rowid ASC;").
Execute() &&
426 " SELECT * FROM duplicate "
427 " ORDER BY rowid").
Execute() &&
429 CommitTransaction() &&
438 unsigned int database_flags = 0;
441 database_flags |= kFlagDirNestedRoot;
443 database_flags |= kFlagDirNestedMountpoint;
445 database_flags |= kFlagDirBindMountpoint;
448 database_flags |= kFlagDir;
449 }
else if (entry.
IsLink()) {
450 database_flags |= kFlagFile | kFlagLink;
452 database_flags |= kFlagFile | kFlagFileSpecial;
454 database_flags |= kFlagFile;
457 database_flags |= kFlagFileChunk;
459 database_flags |= kFlagFileExternal;
461 database_flags |= kFlagDirectIo;
468 database_flags |= kFlagHidden;
470 return database_flags;
475 unsigned *flags)
const
479 *flags |= (algo - 1) << kFlagPosHash;
484 unsigned in_flags = ((7 << kFlagPosHash) & flags) >> kFlagPosHash;
497 ((7 << kFlagPosCompression) & flags) >> kFlagPosCompression;
502 uint32_t SqlDirent::Hardlinks2Linkcount(
const uint64_t hardlinks)
const {
503 return (hardlinks << 32) >> 32;
507 uint32_t SqlDirent::Hardlinks2HardlinkGroup(
const uint64_t hardlinks)
const {
508 return hardlinks >> 32;
512 uint64_t SqlDirent::MakeHardlinks(
const uint32_t hardlink_group,
513 const uint32_t linkcount)
const
516 return (static_cast<uint64_t>(hardlink_group) << 32) | linkcount;
524 void SqlDirent::ExpandSymlink(
LinkString *raw_symlink)
const {
525 const char *c = raw_symlink->
GetChars();
526 const char *cEnd = c+raw_symlink->
GetLength();
527 for (; c < cEnd; ++c) {
535 for (c = raw_symlink->
GetChars(); c < cEnd; ++c) {
536 if ((*c ==
'$') && (c < cEnd-2) && (*(c+1) ==
'(')) {
538 const char *rpar = c;
539 while (rpar < cEnd) {
541 goto expand_symlink_getenv;
549 expand_symlink_getenv:
551 const char *default_separator = c;
552 const char *default_value = rpar;
553 while (default_separator != rpar) {
554 if ((*default_separator ==
':') && (*(default_separator + 1) ==
'-')) {
555 default_value = default_separator+2;
561 const unsigned environ_var_length = default_separator-c;
562 char environ_var[environ_var_length+1];
563 environ_var[environ_var_length] =
'\0';
564 memcpy(environ_var, c, environ_var_length);
565 const char *environ_value = getenv(environ_var);
567 result.
Append(environ_value, strlen(environ_value));
569 const unsigned default_length = rpar-default_value;
570 result.
Append(default_value, default_length);
577 raw_symlink->
Assign(result);
585 bool SqlDirentWrite::BindDirentFields(
const int hash_idx,
586 const int hardlinks_idx,
590 const int mtimens_idx,
593 const int symlink_idx,
598 const uint64_t hardlinks =
603 BindHashBlob(hash_idx, entry.
checksum_) &&
604 BindInt64(hardlinks_idx, hardlinks) &&
605 BindInt64(size_idx, entry.
size_) &&
606 BindInt(mode_idx, entry.
mode_) &&
607 BindInt64(uid_idx, entry.
uid_) &&
608 BindInt64(gid_idx, entry.
gid_) &&
609 BindInt64(mtime_idx, entry.
mtime_) &&
610 BindInt(flags_idx, CreateDatabaseFlags(entry)) &&
616 result &= BindInt(mtimens_idx, entry.
mtime_ns_);
618 result &= BindNull(mtimens_idx);
629 static const char *stmt_lt_2_4 =
630 "SELECT hash, flags, 0 "
632 " WHERE length(hash) > 0;";
634 static const char *stmt_ge_2_4 =
635 "SELECT hash, flags, 0 "
637 " WHERE (length(catalog.hash) > 0) AND "
638 " ((flags & 128) = 0) "
640 "SELECT chunks.hash, catalog.flags, 1 "
643 " ON catalog.md5path_1 = chunks.md5path_1 AND "
644 " catalog.md5path_2 = chunks.md5path_2 "
645 " WHERE (catalog.flags & 128) = 0;";
647 if (database.
schema_version() < 2.4-CatalogDatabase::kSchemaEpsilon) {
648 DeferredInit(database.
sqlite_db(), stmt_lt_2_4);
650 DeferredInit(database.
sqlite_db(), stmt_ge_2_4);
656 const unsigned int db_flags = RetrieveInt(1);
658 shash::Any hash = RetrieveHashBlob(0, hash_algorithm);
659 if (RetrieveInt(2) == 1) {
669 #define DB_FIELDS_LT_V2_1 \
670 "catalog.hash, catalog.inode, catalog.size, " \
671 "catalog.mode, catalog.mtime, catalog.flags, " \
672 "catalog.name, catalog.symlink, catalog.md5path_1, " \
673 "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \
675 #define DB_FIELDS_GE_V2_1_LT_R2 \
676 "catalog.hash, catalog.hardlinks, catalog.size, " \
677 "catalog.mode, catalog.mtime, catalog.flags, " \
678 "catalog.name, catalog.symlink, catalog.md5path_1, " \
679 "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \
680 "catalog.rowid, catalog.uid, catalog.gid, " \
682 #define DB_FIELDS_GE_V2_1_LT_R7 \
683 "catalog.hash, catalog.hardlinks, catalog.size, " \
684 "catalog.mode, catalog.mtime, catalog.flags, " \
685 "catalog.name, catalog.symlink, catalog.md5path_1, " \
686 "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \
687 "catalog.rowid, catalog.uid, catalog.gid, " \
688 "catalog.xattr IS NOT NULL, NULL"
689 #define DB_FIELDS_GE_V2_1_GE_R7 \
690 "catalog.hash, catalog.hardlinks, catalog.size, " \
691 "catalog.mode, catalog.mtime, catalog.flags, " \
692 "catalog.name, catalog.symlink, catalog.md5path_1, " \
693 "catalog.md5path_2, catalog.parent_1, catalog.parent_2, " \
694 "catalog.rowid, catalog.uid, catalog.gid, " \
695 "catalog.xattr IS NOT NULL, catalog.mtimens"
697 #define MAKE_STATEMENT(STMT_TMPL, REV) \
698 static const std::string REV = \
699 ReplaceAll(STMT_TMPL, "@DB_FIELDS@", DB_FIELDS_ ## REV)
701 #define MAKE_STATEMENTS(STMT_TMPL) \
702 MAKE_STATEMENT(STMT_TMPL, LT_V2_1); \
703 MAKE_STATEMENT(STMT_TMPL, GE_V2_1_LT_R2); \
704 MAKE_STATEMENT(STMT_TMPL, GE_V2_1_LT_R7); \
705 MAKE_STATEMENT(STMT_TMPL, GE_V2_1_GE_R7)
707 #define DEFERRED_INIT(DB, REV) \
708 DeferredInit((DB).sqlite_db(), (REV).c_str())
710 #define DEFERRED_INITS(DB) \
711 if ((DB).schema_version() < 2.1 - CatalogDatabase::kSchemaEpsilon) { \
712 DEFERRED_INIT((DB), LT_V2_1); \
713 } else if ((DB).schema_revision() < 2) { \
714 DEFERRED_INIT((DB), GE_V2_1_LT_R2); \
715 } else if ((DB).schema_revision() < 7) { \
716 DEFERRED_INIT((DB), GE_V2_1_LT_R7); \
718 DEFERRED_INIT((DB), GE_V2_1_GE_R7); \
723 return RetrieveMd5(8, 9);
728 return RetrieveMd5(10, 11);
736 const bool expand_symlink)
const
740 const unsigned database_flags = RetrieveInt(5);
743 (database_flags & kFlagDirNestedMountpoint);
744 const char *name =
reinterpret_cast<const char *
>(RetrieveText(6));
745 const char *symlink =
reinterpret_cast<const char *
>(RetrieveText(7));
748 if (catalog->
schema() < 2.1 - CatalogDatabase::kSchemaEpsilon) {
758 const uint64_t hardlinks = RetrieveInt64(1);
759 result.
linkcount_ = Hardlinks2Linkcount(hardlinks);
765 result.
is_hidden_ = (database_flags & kFlagHidden);
769 result.
mtime_ns_ = RetrieveNullableInt(16, -1);
771 RetrieveHashBlob(0, RetrieveHashAlgorithm(database_flags));
773 RetrieveCompressionAlgorithm(database_flags);
779 result.
uid_ = catalog->
MapUid(RetrieveInt64(13));
780 result.
gid_ = catalog->
MapGid(RetrieveInt64(14));
784 result.
mode_ = RetrieveInt(3);
785 result.
size_ = RetrieveInt64(2);
786 result.
mtime_ = RetrieveInt64(4);
793 if (S_ISDIR(result.
mode_)) {
794 result.
mode_ |= 0555;
796 result.
mode_ |= 0444;
809 "WHERE (parent_1 = :p_1) AND (parent_2 = :p_2);");
814 bool SqlListing::BindPathHash(
const struct shash::Md5 &hash) {
815 return BindMd5(1, 2, hash);
824 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
828 bool SqlLookupPathHash::BindPathHash(
const struct shash::Md5 &hash) {
829 return BindMd5(1, 2, hash);
837 MAKE_STATEMENTS(
"SELECT @DB_FIELDS@ FROM catalog WHERE rowid = :rowid;");
842 bool SqlLookupInode::BindRowId(
const uint64_t inode) {
843 return BindInt64(1, inode);
850 SqlLookupDanglingMountpoints::SqlLookupDanglingMountpoints(
853 "JOIN catalog AS c2 "
854 "ON catalog.md5path_1 = c2.parent_1 AND "
855 " catalog.md5path_2 = c2.parent_2 "
856 "WHERE catalog.flags & :nested_mountpoint_flag");
861 const bool success = BindInt64(1, SqlDirent::kFlagDirNestedMountpoint);
872 "SET hash = :hash, size = :size, mode = :mode, mtime = :mtime, "
874 "name = :name, symlink = :symlink, uid = :uid, gid = :gid, xattr = :xattr, "
876 "mtimens = :mtimens "
878 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
886 BindInt64(2, entry.
size_) &&
887 BindInt(3, entry.
mode_) &&
888 BindInt64(4, entry.
mtime_) &&
891 BindInt64(7, entry.
uid_) &&
892 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() {
928 static const char *stmt_0_9 =
929 "SELECT '', 0 FROM nested_catalogs;";
930 static const char *stmt_2_5_ge_4 =
931 "SELECT sha1, size FROM nested_catalogs WHERE path=:path "
932 "UNION ALL SELECT sha1, size FROM bind_mountpoints WHERE path=:path;";
933 static const char *stmt_2_5_ge_1_lt_4 =
934 "SELECT sha1, size FROM nested_catalogs WHERE path=:path;";
936 static const char *stmt_2_5_lt_1 =
937 "SELECT sha1, 0 FROM nested_catalogs WHERE path=:path;";
942 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_4);
946 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_1_lt_4);
949 DeferredInit(database.
sqlite_db(), stmt_0_9);
951 DeferredInit(database.
sqlite_db(), stmt_2_5_lt_1);
957 bool SqlNestedCatalogLookup::BindSearchPath(
const PathString &path) {
963 const string hash = string(reinterpret_cast<const char *>(RetrieveText(0)));
970 uint64_t SqlNestedCatalogLookup::GetSize()
const {
971 return RetrieveInt64(1);
978 SqlNestedCatalogListing::SqlNestedCatalogListing(
982 static const char *stmt_0_9 =
983 "SELECT '', '', 0 FROM nested_catalogs;";
984 static const char *stmt_2_5_ge_4 =
985 "SELECT path, sha1, size FROM nested_catalogs "
986 "UNION ALL SELECT path, sha1, size FROM bind_mountpoints;";
987 static const char *stmt_2_5_ge_1_lt_4 =
988 "SELECT path, sha1, size FROM nested_catalogs;";
990 static const char *stmt_2_5_lt_1 =
991 "SELECT path, sha1, 0 FROM nested_catalogs;";
996 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_4);
1000 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_1_lt_4);
1003 DeferredInit(database.
sqlite_db(), stmt_0_9);
1005 DeferredInit(database.
sqlite_db(), stmt_2_5_lt_1);
1012 const char *path =
reinterpret_cast<const char *
>(RetrieveText(0));
1018 const string hash = string(reinterpret_cast<const char *>(RetrieveText(1)));
1025 uint64_t SqlNestedCatalogListing::GetSize()
const {
1026 return RetrieveInt64(2);
1033 SqlOwnNestedCatalogListing::SqlOwnNestedCatalogListing(
1037 static const char *stmt_0_9 =
1038 "SELECT '', '', 0 FROM nested_catalogs;";
1039 static const char *stmt_2_5_ge_1 =
1040 "SELECT path, sha1, size FROM nested_catalogs;";
1042 static const char *stmt_2_5_lt_1 =
1043 "SELECT path, sha1, 0 FROM nested_catalogs;";
1048 DeferredInit(database.
sqlite_db(), stmt_2_5_ge_1);
1051 DeferredInit(database.
sqlite_db(), stmt_0_9);
1053 DeferredInit(database.
sqlite_db(), stmt_2_5_lt_1);
1060 const char *path =
reinterpret_cast<const char *
>(RetrieveText(0));
1066 const string hash = string(reinterpret_cast<const char *>(RetrieveText(1)));
1073 uint64_t SqlOwnNestedCatalogListing::GetSize()
const {
1074 return RetrieveInt64(2);
1083 "INSERT INTO catalog "
1084 "(md5path_1, md5path_2, parent_1, parent_2, hash, hardlinks, size, mode,"
1086 "mtime, flags, name, symlink, uid, gid, xattr, mtimens) "
1088 "VALUES (:md5_1, :md5_2, :p_1, :p_2, :hash, :links, :size, :mode, :mtime,"
1089 " :flags, :name, :symlink, :uid, :gid, :xattr, :mtimens);");
1094 return BindMd5(1, 2, hash);
1098 bool SqlDirentInsert::BindParentPathHash(
const shash::Md5 &hash) {
1099 return BindMd5(3, 4, hash);
1104 return BindDirentFields(5, 6, 7, 8, 9, 16, 10, 11, 12, 13, 14, entry);
1109 unsigned char *packed_xattrs;
1111 xattrs.
Serialize(&packed_xattrs, &size);
1112 if (packed_xattrs == NULL)
1113 return BindNull(15);
1114 return BindBlobTransient(15, packed_xattrs, size);
1118 bool SqlDirentInsert::BindXattrEmpty() {
1119 return BindNull(15);
1129 "SET hash = :hash, size = :size, mode = :mode, mtime = :mtime, "
1131 "flags = :flags, name = :name, symlink = :symlink, hardlinks = :hardlinks, "
1133 "uid = :uid, gid = :gid, mtimens = :mtimens "
1135 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
1141 return BindMd5(12, 13, hash);
1146 return BindDirentFields(1, 8, 2, 3, 4, 11, 5, 6, 7, 9, 10, entry);
1155 "DELETE FROM catalog "
1156 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
1160 return BindMd5(1, 2, hash);
1176 "UPDATE catalog SET hardlinks = hardlinks + :delta "
1177 "WHERE hardlinks = (SELECT hardlinks from catalog "
1178 "WHERE md5path_1 = :md5_1 AND md5path_2 = :md5_2);");
1183 return BindMd5(2, 3, hash);
1187 bool SqlIncLinkcount::BindDelta(
const int delta) {
1188 return BindInt(1, delta);
1197 "INSERT INTO chunks (md5path_1, md5path_2, offset, size, hash) "
1199 "VALUES (:md5_1, :md5_2, :offset, :size, :hash);");
1204 return BindMd5(1, 2, hash);
1208 bool SqlChunkInsert::BindFileChunk(
const FileChunk &chunk) {
1210 BindInt64(3, chunk.
offset()) &&
1211 BindInt64(4, chunk.
size()) &&
1221 "DELETE FROM chunks "
1222 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
1227 return BindMd5(1, 2, hash);
1236 "SELECT offset, size, hash FROM chunks "
1238 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2) "
1240 "ORDER BY offset ASC;");
1245 return BindMd5(1, 2, hash);
1264 "SELECT count(*) FROM chunks "
1266 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2)");
1272 return BindMd5(1, 2, hash);
1276 int SqlChunksCount::GetChunkCount()
const {
1277 return RetrieveInt64(0);
1285 DeferredInit(database.
sqlite_db(),
"SELECT max(hardlinks) FROM catalog;");
1289 uint32_t SqlMaxHardlinkGroup::GetMaxGroupId()
const {
1290 return RetrieveInt64(0) >> 32;
1298 static const char *stmt_ge_2_4 =
1299 "SELECT value from statistics WHERE counter = :counter;";
1300 static const char *stmt_lt_2_4 =
1303 if (database.
schema_version() >= 2.4 - CatalogDatabase::kSchemaEpsilon) {
1305 DeferredInit(database.
sqlite_db(), stmt_ge_2_4);
1308 DeferredInit(database.
sqlite_db(), stmt_lt_2_4);
1313 bool SqlGetCounter::BindCounter(
const std::string &counter) {
1314 if (compat_)
return true;
1315 return BindText(1, counter);
1319 uint64_t SqlGetCounter::GetCounter()
const {
1320 if (compat_)
return 0;
1321 return RetrieveInt64(0);
1330 "UPDATE statistics SET value=value+:val WHERE counter=:counter;");
1334 bool SqlUpdateCounter::BindCounter(
const std::string &counter) {
1335 return BindText(2, counter);
1339 bool SqlUpdateCounter::BindDelta(
const int64_t delta) {
1340 return BindInt64(1, delta);
1349 "INSERT OR REPLACE INTO statistics (counter, value) "
1350 "VALUES (:counter, :value);");
1354 bool SqlCreateCounter::BindCounter(
const std::string &counter) {
1355 return BindText(1, counter);
1359 bool SqlCreateCounter::BindInitialValue(
const int64_t value) {
1360 return BindInt64(2, value);
1368 int hash_mask = 7 << SqlDirent::kFlagPosHash;
1371 StringifyInt(SqlDirent::kFlagPosHash) +
")+1 AS hash_algorithm ";
1373 int compression_mask = 7 << SqlDirent::kFlagPosCompression;
1374 string flags2compression =
1375 " ((flags&" +
StringifyInt(compression_mask) +
") >> " +
1377 "AS compression_algorithm ";
1383 string sql =
"SELECT DISTINCT hash, "
1384 "CASE WHEN flags & " +
StringifyInt(SqlDirent::kFlagFile) +
" THEN " +
1386 "WHEN flags & " +
StringifyInt(SqlDirent::kFlagDir) +
" THEN " +
1388 "AS chunk_type, " + flags2hash +
"," + flags2compression +
1389 "FROM catalog WHERE (hash IS NOT NULL) AND "
1390 "(flags & " +
StringifyInt(SqlDirent::kFlagFileExternal) +
" = 0)";
1391 if (database.
schema_version() >= 2.4 - CatalogDatabase::kSchemaEpsilon) {
1395 ", " + flags2hash +
"," + flags2compression +
1396 "FROM chunks, catalog WHERE "
1397 "chunks.md5path_1=catalog.md5path_1 AND "
1398 "chunks.md5path_2=catalog.md5path_2 AND "
1399 "(catalog.flags & " +
StringifyInt(SqlDirent::kFlagFileExternal) +
1417 *hash = RetrieveHashBlob(0, static_cast<shash::Algorithms>(RetrieveInt(2)),
1418 static_cast<shash::Suffix>(RetrieveInt(1)));
1424 bool SqlAllChunks::Close() {
1434 "SELECT xattr FROM catalog "
1435 "WHERE (md5path_1 = :md5_1) AND (md5path_2 = :md5_2);");
1440 return BindMd5(1, 2, hash);
1445 const unsigned char *packed_xattrs =
1446 reinterpret_cast<const unsigned char *
>(RetrieveBlob(0));
1447 if (packed_xattrs == NULL)
1450 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,...)