int seaf_quota_manager_set_org_quota (SeafQuotaManager *mgr, int org_id, gint64 quota) { SeafDB *db = mgr->session->db; if (seaf_db_type(db) == SEAF_DB_TYPE_PGSQL) { gboolean exists, err; int rc; exists = seaf_db_statement_exists (db, "SELECT 1 FROM OrgQuota WHERE org_id=?", &err, 1, "int", org_id); if (err) return -1; if (exists) rc = seaf_db_statement_query (db, "UPDATE OrgQuota SET quota=? WHERE org_id=?", 2, "int64", quota, "int", org_id); else rc = seaf_db_statement_query (db, "INSERT INTO OrgQuota VALUES (?, ?)", 2, "int", org_id, "int64", quota); return rc; } else { int rc = seaf_db_statement_query (db, "REPLACE INTO OrgQuota VALUES (?, ?)", 2, "int", org_id, "int64", quota); return rc; } }
int seaf_repo_manager_set_repo_valid_since (SeafRepoManager *mgr, const char *repo_id, gint64 timestamp) { SeafDB *db = mgr->seaf->db; char sql[256]; if (seaf_db_type(db) == SEAF_DB_TYPE_PGSQL) { gboolean err; snprintf(sql, sizeof(sql), "SELECT repo_id FROM RepoValidSince WHERE " "repo_id='%s'", repo_id); if (seaf_db_check_for_existence(db, sql, &err)) snprintf(sql, sizeof(sql), "UPDATE RepoValidSince SET timestamp=%"G_GINT64_FORMAT " WHERE repo_id='%s'", timestamp, repo_id); else snprintf(sql, sizeof(sql), "INSERT INTO RepoValidSince VALUES " "('%s', %"G_GINT64_FORMAT")", repo_id, timestamp); if (err) return -1; if (seaf_db_query (db, sql) < 0) return -1; } else { snprintf (sql, sizeof(sql), "REPLACE INTO RepoValidSince VALUES ('%s', %"G_GINT64_FORMAT")", repo_id, timestamp); if (seaf_db_query (db, sql) < 0) return -1; } return 0; }
int seaf_quota_manager_set_user_quota (SeafQuotaManager *mgr, const char *user, gint64 quota) { SeafDB *db = mgr->session->db; if (seaf_db_type(db) == SEAF_DB_TYPE_PGSQL) { gboolean exists, err; int rc; exists = seaf_db_statement_exists (db, "SELECT 1 FROM UserQuota WHERE \"user\"=?", &err, 1, "string", user); if (err) return -1; if (exists) rc = seaf_db_statement_query (db, "UPDATE UserQuota SET quota=? " "WHERE \"user\"=?", 2, "int64", quota, "string", user); else rc = seaf_db_statement_query (db, "INSERT INTO UserQuota VALUES " "(?, ?)", 2, "string", user, "int64", quota); return rc; } else { int rc; rc = seaf_db_statement_query (db, "REPLACE INTO UserQuota VALUES (?, ?)", 2, "string", user, "int64", quota); return rc; } }
int seaf_quota_manager_set_org_user_quota (SeafQuotaManager *mgr, int org_id, const char *user, gint64 quota) { SeafDB *db = mgr->session->db; char sql[512]; if (seaf_db_type(db) == SEAF_DB_TYPE_PGSQL) { gboolean err; snprintf(sql, sizeof(sql), "SELECT 1 FROM OrgUserQuota WHERE org_id=%d AND user='******'", org_id, user); if (seaf_db_check_for_existence(db, sql, &err)) snprintf(sql, sizeof(sql), "UPDATE OrgUserQuota SET quota=%"G_GINT64_FORMAT " WHERE org_id=%d AND user='******'", quota, org_id, user); else snprintf(sql, sizeof(sql), "INSERT INTO OrgQuota VALUES " "(%d, '%s', %"G_GINT64_FORMAT")", org_id, user, quota); if (err) return -1; return seaf_db_query (db, sql); } else { snprintf (sql, sizeof(sql), "REPLACE INTO OrgUserQuota VALUES ('%d', '%s', %"G_GINT64_FORMAT")", org_id, user, quota); return seaf_db_query (mgr->session->db, sql); } }
int seaf_share_manager_start (SeafShareManager *mgr) { SeafDB *db = mgr->seaf->db; const char *sql; int db_type = seaf_db_type (db); if (db_type == SEAF_DB_TYPE_MYSQL) { sql = "CREATE TABLE IF NOT EXISTS SharedRepo " "(repo_id CHAR(37) , from_email VARCHAR(512), to_email VARCHAR(512), " "permission CHAR(15), INDEX (repo_id))"; if (seaf_db_query (db, sql) < 0) return -1; } else if (db_type == SEAF_DB_TYPE_SQLITE) { sql = "CREATE TABLE IF NOT EXISTS SharedRepo " "(repo_id CHAR(37) , from_email VARCHAR(512), to_email VARCHAR(512), " "permission CHAR(15))"; if (seaf_db_query (db, sql) < 0) return -1; sql = "CREATE INDEX IF NOT EXISTS RepoIdIndex on SharedRepo (repo_id)"; if (seaf_db_query (db, sql) < 0) return -1; } return 0; }
int seaf_share_manager_start (SeafShareManager *mgr) { SeafDB *db = mgr->seaf->db; const char *sql; int db_type = seaf_db_type (db); if (db_type == SEAF_DB_TYPE_MYSQL) { sql = "CREATE TABLE IF NOT EXISTS SharedRepo " "(id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT," "repo_id CHAR(37) , from_email VARCHAR(255), to_email VARCHAR(255), " "permission CHAR(15), INDEX (repo_id), " "INDEX(from_email), INDEX(to_email)) ENGINE=INNODB"; if (seaf_db_query (db, sql) < 0) return -1; } else if (db_type == SEAF_DB_TYPE_SQLITE) { sql = "CREATE TABLE IF NOT EXISTS SharedRepo " "(repo_id CHAR(37) , from_email VARCHAR(255), to_email VARCHAR(255), " "permission CHAR(15))"; if (seaf_db_query (db, sql) < 0) return -1; sql = "CREATE INDEX IF NOT EXISTS RepoIdIndex on SharedRepo (repo_id)"; if (seaf_db_query (db, sql) < 0) return -1; sql = "CREATE INDEX IF NOT EXISTS FromEmailIndex on SharedRepo (from_email)"; if (seaf_db_query (db, sql) < 0) return -1; sql = "CREATE INDEX IF NOT EXISTS ToEmailIndex on SharedRepo (to_email)"; if (seaf_db_query (db, sql) < 0) return -1; } else if (db_type == SEAF_DB_TYPE_PGSQL) { sql = "CREATE TABLE IF NOT EXISTS SharedRepo " "(repo_id CHAR(36) , from_email VARCHAR(255), to_email VARCHAR(255), " "permission VARCHAR(15))"; if (seaf_db_query (db, sql) < 0) return -1; if (!pgsql_index_exists (db, "sharedrepo_repoid_idx")) { sql = "CREATE INDEX sharedrepo_repoid_idx ON SharedRepo (repo_id)"; if (seaf_db_query (db, sql) < 0) return -1; } if (!pgsql_index_exists (db, "sharedrepo_from_email_idx")) { sql = "CREATE INDEX sharedrepo_from_email_idx ON SharedRepo (from_email)"; if (seaf_db_query (db, sql) < 0) return -1; } if (!pgsql_index_exists (db, "sharedrepo_to_email_idx")) { sql = "CREATE INDEX sharedrepo_to_email_idx ON SharedRepo (to_email)"; if (seaf_db_query (db, sql) < 0) return -1; } } return 0; }
static int open_db (SeafBranchManager *mgr) { #ifndef SEAFILE_SERVER char *db_path; const char *sql; db_path = g_build_filename (mgr->seaf->seaf_dir, BRANCH_DB, NULL); if (sqlite_open_db (db_path, &mgr->priv->db) < 0) { g_critical ("[Branch mgr] Failed to open branch db\n"); g_free (db_path); return -1; } g_free (db_path); sql = "CREATE TABLE IF NOT EXISTS Branch (" "name TEXT, repo_id TEXT, commit_id TEXT);"; if (sqlite_query_exec (mgr->priv->db, sql) < 0) return -1; sql = "CREATE INDEX IF NOT EXISTS branch_index ON Branch(repo_id, name);"; if (sqlite_query_exec (mgr->priv->db, sql) < 0) return -1; #elif defined FULL_FEATURE char *sql; switch (seaf_db_type (mgr->seaf->db)) { case SEAF_DB_TYPE_MYSQL: sql = "CREATE TABLE IF NOT EXISTS Branch (" "name VARCHAR(10), repo_id CHAR(41), commit_id CHAR(41)," "PRIMARY KEY (repo_id, name)) ENGINE = INNODB"; if (seaf_db_query (mgr->seaf->db, sql) < 0) return -1; break; case SEAF_DB_TYPE_PGSQL: sql = "CREATE TABLE IF NOT EXISTS Branch (" "name VARCHAR(10), repo_id CHAR(40), commit_id CHAR(40)," "PRIMARY KEY (repo_id, name))"; if (seaf_db_query (mgr->seaf->db, sql) < 0) return -1; break; case SEAF_DB_TYPE_SQLITE: sql = "CREATE TABLE IF NOT EXISTS Branch (" "name VARCHAR(10), repo_id CHAR(41), commit_id CHAR(41)," "PRIMARY KEY (repo_id, name))"; if (seaf_db_query (mgr->seaf->db, sql) < 0) return -1; break; } #endif return 0; }
int seaf_quota_manager_init (SeafQuotaManager *mgr) { SeafDB *db = mgr->session->db; const char *sql; switch (seaf_db_type(db)) { case SEAF_DB_TYPE_SQLITE: sql = "CREATE TABLE IF NOT EXISTS UserQuota (user VARCHAR(255) PRIMARY KEY," "quota BIGINT)"; if (seaf_db_query (db, sql) < 0) return -1; sql = "CREATE TABLE IF NOT EXISTS OrgQuota (org_id INTEGER PRIMARY KEY," "quota BIGINT)"; if (seaf_db_query (db, sql) < 0) return -1; sql = "CREATE TABLE IF NOT EXISTS OrgUserQuota (org_id INTEGER," "user VARCHAR(255), quota BIGINT, PRIMARY KEY (org_id, user))"; if (seaf_db_query (db, sql) < 0) return -1; break; case SEAF_DB_TYPE_MYSQL: sql = "CREATE TABLE IF NOT EXISTS UserQuota (user VARCHAR(255) PRIMARY KEY," "quota BIGINT) ENGINE=INNODB"; if (seaf_db_query (db, sql) < 0) return -1; sql = "CREATE TABLE IF NOT EXISTS OrgQuota (org_id INTEGER PRIMARY KEY," "quota BIGINT) ENGINE=INNODB"; if (seaf_db_query (db, sql) < 0) return -1; sql = "CREATE TABLE IF NOT EXISTS OrgUserQuota (org_id INTEGER," "user VARCHAR(255), quota BIGINT, PRIMARY KEY (org_id, user))" "ENGINE=INNODB"; if (seaf_db_query (db, sql) < 0) return -1; break; } return 0; }
gint64 seaf_quota_manager_get_user_quota (SeafQuotaManager *mgr, const char *user) { char *sql; gint64 quota; if (seaf_db_type(mgr->session->db) != SEAF_DB_TYPE_PGSQL) sql = "SELECT quota FROM UserQuota WHERE user=?"; else sql = "SELECT quota FROM UserQuota WHERE \"user\"=?"; quota = seaf_db_statement_get_int64 (mgr->session->db, sql, 1, "string", user); if (quota <= 0) quota = mgr->default_quota; return quota; }
int seaf_repo_manager_set_repo_history_limit (SeafRepoManager *mgr, const char *repo_id, int days) { SeafVirtRepo *vinfo; SeafDB *db = mgr->seaf->db; char sql[256]; vinfo = seaf_repo_manager_get_virtual_repo_info (mgr, repo_id); if (vinfo) { seaf_virtual_repo_info_free (vinfo); return 0; } if (seaf_db_type(db) == SEAF_DB_TYPE_PGSQL) { gboolean err; snprintf(sql, sizeof(sql), "SELECT repo_id FROM RepoHistoryLimit " "WHERE repo_id='%s'", repo_id); if (seaf_db_check_for_existence(db, sql, &err)) snprintf(sql, sizeof(sql), "UPDATE RepoHistoryLimit SET days=%d" "WHERE repo_id='%s'", days, repo_id); else snprintf(sql, sizeof(sql), "INSERT INTO RepoHistoryLimit VALUES " "('%s', %d)", repo_id, days); if (err) return -1; return seaf_db_query(db, sql); } else { snprintf (sql, sizeof(sql), "REPLACE INTO RepoHistoryLimit VALUES ('%s', %d)", repo_id, days); if (seaf_db_query (db, sql) < 0) return -1; } return 0; }
gint64 seaf_quota_manager_get_org_user_quota (SeafQuotaManager *mgr, int org_id, const char *user) { char *sql; gint64 quota; if (seaf_db_type(mgr->session->db) != SEAF_DB_TYPE_PGSQL) sql = "SELECT quota FROM OrgUserQuota WHERE org_id=? AND user=?"; else sql = "SELECT quota FROM OrgUserQuota WHERE org_id=? AND \"user\"=?"; quota = seaf_db_statement_get_int64 (mgr->session->db, sql, 2, "int", org_id, "string", user); /* return org quota if per user quota is not set. */ if (quota <= 0) quota = seaf_quota_manager_get_org_quota (mgr, org_id); return quota; }
int seaf_branch_manager_test_and_update_branch (SeafBranchManager *mgr, SeafBranch *branch, const char *old_commit_id) { SeafDBTrans *trans; char *sql; char commit_id[41] = { 0 }; trans = seaf_db_begin_transaction (mgr->seaf->db); if (!trans) return -1; switch (seaf_db_type (mgr->seaf->db)) { case SEAF_DB_TYPE_MYSQL: case SEAF_DB_TYPE_PGSQL: sql = "SELECT commit_id FROM Branch WHERE name=? " "AND repo_id=? FOR UPDATE"; break; case SEAF_DB_TYPE_SQLITE: sql = "SELECT commit_id FROM Branch WHERE name=? " "AND repo_id=?"; break; default: g_return_val_if_reached (-1); } if (seaf_db_trans_foreach_selected_row (trans, sql, get_commit_id, commit_id, 2, "string", branch->name, "string", branch->repo_id) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } if (strcmp (old_commit_id, commit_id) != 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } sql = "UPDATE Branch SET commit_id = ? " "WHERE name = ? AND repo_id = ?"; if (seaf_db_trans_query (trans, sql, 3, "string", branch->commit_id, "string", branch->name, "string", branch->repo_id) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } if (seaf_db_commit (trans) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } seaf_db_trans_close (trans); on_branch_updated (mgr, branch); return 0; }
int seaf_branch_manager_add_branch (SeafBranchManager *mgr, SeafBranch *branch) { #ifndef SEAFILE_SERVER char sql[256]; pthread_mutex_lock (&mgr->priv->db_lock); sqlite3_snprintf (sizeof(sql), sql, "SELECT 1 FROM Branch WHERE name=%Q and repo_id=%Q", branch->name, branch->repo_id); if (sqlite_check_for_existence (mgr->priv->db, sql)) sqlite3_snprintf (sizeof(sql), sql, "UPDATE Branch SET commit_id=%Q WHERE " "name=%Q and repo_id=%Q", branch->commit_id, branch->name, branch->repo_id); else sqlite3_snprintf (sizeof(sql), sql, "INSERT INTO Branch VALUES (%Q, %Q, %Q)", branch->name, branch->repo_id, branch->commit_id); sqlite_query_exec (mgr->priv->db, sql); pthread_mutex_unlock (&mgr->priv->db_lock); return 0; #else char *sql; SeafDB *db = mgr->seaf->db; if (seaf_db_type(db) == SEAF_DB_TYPE_PGSQL) { gboolean exists, err; int rc; sql = "SELECT repo_id FROM Branch WHERE name=? AND repo_id=?"; exists = seaf_db_statement_exists(db, sql, &err, 2, "string", branch->name, "string", branch->repo_id); if (err) return -1; if (exists) rc = seaf_db_statement_query (db, "UPDATE Branch SET commit_id=? " "WHERE name=? AND repo_id=?", 3, "string", branch->commit_id, "string", branch->name, "string", branch->repo_id); else rc = seaf_db_statement_query (db, "INSERT INTO Branch VALUES (?, ?, ?)", 3, "string", branch->name, "string", branch->repo_id, "string", branch->commit_id); if (rc < 0) return -1; } else { int rc = seaf_db_statement_query (db, "REPLACE INTO Branch VALUES (?, ?, ?)", 3, "string", branch->name, "string", branch->repo_id, "string", branch->commit_id); if (rc < 0) return -1; } return 0; #endif }
int seaf_branch_manager_test_and_update_branch (SeafBranchManager *mgr, SeafBranch *branch, const char *old_commit_id) { SeafDBTrans *trans; char sql[256]; char commit_id[41] = { 0 }; trans = seaf_db_begin_transaction (mgr->seaf->db); if (!trans) return -1; switch (seaf_db_type (mgr->seaf->db)) { case SEAF_DB_TYPE_MYSQL: snprintf (sql, sizeof(sql), "SELECT commit_id FROM Branch WHERE name='%s' " "AND repo_id='%s' FOR UPDATE", branch->name, branch->repo_id); break; case SEAF_DB_TYPE_SQLITE: snprintf (sql, sizeof(sql), "SELECT commit_id FROM Branch WHERE name='%s' " "AND repo_id='%s'", branch->name, branch->repo_id); break; } if (seaf_db_trans_foreach_selected_row (trans, sql, get_commit_id, commit_id) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } if (strcmp (old_commit_id, commit_id) != 0) { g_message ("[branch mgr] Branch update conflict for repo %s, rollback.\n", branch->repo_id); seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } snprintf (sql, sizeof(sql), "UPDATE Branch SET commit_id = '%s' " "WHERE name = '%s' AND repo_id = '%s'", branch->commit_id, branch->name, branch->repo_id); if (seaf_db_trans_query (trans, sql) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } if (seaf_db_commit (trans) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } seaf_db_trans_close (trans); on_branch_updated (mgr, branch); return 0; }
static int set_repo_size (SeafDB *db, const char *repo_id, const char *old_head_id, const char *new_head_id, gint64 size) { SeafDBTrans *trans; char *sql; char cached_head_id[41] = {0}; int ret = 0; trans = seaf_db_begin_transaction (db); if (!trans) return -1; switch (seaf_db_type (db)) { case SEAF_DB_TYPE_MYSQL: case SEAF_DB_TYPE_PGSQL: sql = "SELECT head_id FROM RepoSize WHERE repo_id=? FOR UPDATE"; break; case SEAF_DB_TYPE_SQLITE: sql = "SELECT head_id FROM RepoSize WHERE repo_id=?"; break; default: g_return_val_if_reached (-1); } int n = seaf_db_trans_foreach_selected_row (trans, sql, get_head_id, cached_head_id, 1, "string", repo_id); if (n < 0) { ret = SET_SIZE_ERROR; goto rollback; } if (n == 0) { /* Size not set before. */ sql = "INSERT INTO RepoSize VALUES (?, ?, ?)"; if (seaf_db_trans_query (trans, sql, 3, "string", repo_id, "int64", size, "string", new_head_id) < 0) { ret = SET_SIZE_ERROR; goto rollback; } } else { if (strcmp (old_head_id, cached_head_id) != 0) { g_message ("[size sched] Size update conflict for repo %s, rollback.\n", repo_id); ret = SET_SIZE_CONFLICT; goto rollback; } sql = "UPDATE RepoSize SET size = ?, head_id = ? WHERE repo_id = ?"; if (seaf_db_trans_query (trans, sql, 3, "int64", size, "string", new_head_id, "string", repo_id) < 0) { ret = SET_SIZE_ERROR; goto rollback; } } if (seaf_db_commit (trans) < 0) { ret = SET_SIZE_ERROR; goto rollback; } seaf_db_trans_close (trans); return ret; rollback: seaf_db_rollback (trans); seaf_db_trans_close (trans); return ret; }