diff --git a/libatalk/cnid/sqlite/cnid_sqlite.c b/libatalk/cnid/sqlite/cnid_sqlite.c index 5e6aebadfea..07f3dd92c4b 100644 --- a/libatalk/cnid/sqlite/cnid_sqlite.c +++ b/libatalk/cnid/sqlite/cnid_sqlite.c @@ -536,20 +536,23 @@ cnid_t cnid_sqlite_add(struct _cnid_db *cdb, "TRUNCATE TABLE %s;" "COMMIT;", db->cnid_sqlite_voluuid_str, - db->cnid_sqlite_voluuid_str, db->cnid_sqlite_voluuid_str)); db->cnid_sqlite_flags |= CNID_SQLITE_FLAG_DEPLETED; hint = CNID_INVALID; - // TODO: Do we really need to start from id 17? - if (cnid_sqlite_execute(db->cnid_sqlite_con, - "INSERT INTO sqlite_sequence (name, seq)" - "VALUES ('`%s`', 16)", - db->cnid_sqlite_voluuid_str)) { - LOG(log_error, logtype_cnid, "cnid_sqlite_open: sqlite query error: %s", - sqlite3_errmsg(db->cnid_sqlite_con)); - EC_FAIL; - } + if (cnid_sqlite_execute(db->cnid_sqlite_con, + "UPDATE sqlite_sequence SET seq = <16> WHERE name = '`%s`';" + "INSERT INTO sqlite_sequence (name,seq) SELECT '`%s`'," + "<16> WHERE NOT EXISTS" + "(SELECT changes() AS change" + "FROM sqlite_sequence WHERE change <> 0);" + "COMMIT;", + db->cnid_sqlite_voluuid_str, + db->cnid_sqlite_voluuid_str)) { + LOG(log_error, logtype_cnid, "cnid_sqlite_open: sqlite query error: %s", + sqlite3_errmsg(db->cnid_sqlite_con)); + EC_FAIL; + } #if 0 // again, really wrong do { result = @@ -762,12 +765,15 @@ int cnid_sqlite_wipe(struct _cnid_db *cdb) "TRUNCATE TABLE `%s`;" "COMMIT;", db->cnid_sqlite_voluuid_str, - db->cnid_sqlite_voluuid_str, db->cnid_sqlite_voluuid_str)); - // TODO: Do we really need to start from id 17? if (cnid_sqlite_execute(db->cnid_sqlite_con, - "INSERT INTO sqlite_sequence (name, seq)" - "VALUES ('`%s`', 16)", + "UPDATE sqlite_sequence SET seq = <16> WHERE name = '`%s`';" + "INSERT INTO sqlite_sequence (name,seq) SELECT '`%s`'," + "<16> WHERE NOT EXISTS" + "(SELECT changes() AS change" + "FROM sqlite_sequence WHERE change <> 0);" + "COMMIT;", + db->cnid_sqlite_voluuid_str, db->cnid_sqlite_voluuid_str)) { LOG(log_error, logtype_cnid, "cnid_sqlite_open: sqlite query error: %s", sqlite3_errmsg(db->cnid_sqlite_con)); @@ -839,7 +845,7 @@ struct _cnid_db *cnid_sqlite_open(struct cnid_open_args *args) (CNID_sqlite_private))); cdb->cnid_db_private = db; - EC_NULL(dbpath = bformat("%s/%s.sqlite", _PATH_STATEDIR "CNID", vol->v_localname)); + EC_NULL(dbpath = bformat("%s/%s.sqlite", _PATH_STATEDIR "CNID/sqlite", vol->v_localname)); EC_NULL(db->cnid_sqlite_voluuid_str = uuid_strip_dashes(vol->v_uuid)); /* Initialize and connect to sqlite3 database */ @@ -954,10 +960,25 @@ struct _cnid_db *cnid_sqlite_open(struct cnid_open_args *args) sqlite3_errmsg(db->cnid_sqlite_con)); EC_FAIL; } - // TODO: Do we really need to start from id 17? + + /* Directory IDs from 1 to 16 are reserved. + * The Directory ID of the root is always 2. + * The root’s Parent ID is always 1. + * (The root does not really have a parent; + * this value is returned only if an AFP command asks + * for the root’s Parent ID.) + * Zero (0) is not a valid Directory ID. + * + * https://developer.apple.com/library/archive/documentation/Networking/Conceptual/AFP/Concepts/Concepts.html + */ if (cnid_sqlite_execute(db->cnid_sqlite_con, - "INSERT INTO sqlite_sequence (name, seq)" - "VALUES ('`%s`', 16)", + "UPDATE sqlite_sequence SET seq = <16> WHERE name = '`%s`';" + "INSERT INTO sqlite_sequence (name,seq) SELECT '`%s`'," + "<16> WHERE NOT EXISTS" + "(SELECT changes() AS change" + "FROM sqlite_sequence WHERE change <> 0);" + "COMMIT;", + db->cnid_sqlite_voluuid_str, db->cnid_sqlite_voluuid_str)) { LOG(log_error, logtype_cnid, "cnid_sqlite_open: sqlite query error: %s", sqlite3_errmsg(db->cnid_sqlite_con)); diff --git a/libatalk/cnid/sqlite/meson.build b/libatalk/cnid/sqlite/meson.build index eda685ed082..bbab4314bb2 100644 --- a/libatalk/cnid/sqlite/meson.build +++ b/libatalk/cnid/sqlite/meson.build @@ -8,3 +8,5 @@ libcnid_sqlite = static_library( c_args: statedir, install: false, ) + +install_emptydir(localstatedir / 'netatalk/CNID/sqlite', install_mode: 'rwxrwxrwx')