diff --git a/ci/serverctl.py b/ci/serverctl.py index 03e6c09..e061b6d 100755 --- a/ci/serverctl.py +++ b/ci/serverctl.py @@ -62,6 +62,18 @@ class ServerCtl(object): shell(cmd) if self.db == 'mysql': self.add_ccnet_db_conf() + else: + self.add_ccnet_sqlite_db_conf() + + def add_ccnet_sqlite_db_conf(self): + ccnet_conf = join(self.central_conf_dir, 'ccnet.conf') + ccnet_db_conf = '''\ +[Database] +CREATE_TABLES = true +''' + with open(ccnet_conf, 'a+') as fp: + fp.write('\n') + fp.write(ccnet_db_conf) def add_ccnet_db_conf(self): ccnet_conf = join(self.central_conf_dir, 'ccnet.conf') @@ -74,6 +86,7 @@ USER = seafile PASSWD = seafile DB = ccnet CONNECTION_CHARSET = utf8 +CREATE_TABLES = true ''' with open(ccnet_conf, 'a+') as fp: fp.write('\n') @@ -93,6 +106,18 @@ CONNECTION_CHARSET = utf8 shell(cmd) if self.db == 'mysql': self.add_seafile_db_conf() + else: + self.add_seafile_sqlite_db_conf() + + def add_seafile_sqlite_db_conf(self): + seafile_conf = join(self.central_conf_dir, 'seafile.conf') + seafile_db_conf = '''\ +[database] +create_tables = true +''' + with open(seafile_conf, 'a+') as fp: + fp.write('\n') + fp.write(seafile_db_conf) def add_seafile_db_conf(self): seafile_conf = join(self.central_conf_dir, 'seafile.conf') @@ -105,6 +130,7 @@ user = seafile password = seafile db_name = seafile connection_charset = utf8 +create_tables = true ''' with open(seafile_conf, 'a+') as fp: fp.write('\n') diff --git a/common/branch-mgr.c b/common/branch-mgr.c index e3c0a5f..41391e7 100644 --- a/common/branch-mgr.c +++ b/common/branch-mgr.c @@ -127,7 +127,7 @@ seaf_branch_manager_init (SeafBranchManager *mgr) static int open_db (SeafBranchManager *mgr) { - if (!mgr->seaf->create_tables && seaf_db_type (mgr->seaf->db) == SEAF_DB_TYPE_MYSQL) + if (!mgr->seaf->create_tables && seaf_db_type (mgr->seaf->db) != SEAF_DB_TYPE_PGSQL) return 0; #ifndef SEAFILE_SERVER diff --git a/common/seaf-utils.c b/common/seaf-utils.c index b581cea..ef1c750 100644 --- a/common/seaf-utils.c +++ b/common/seaf-utils.c @@ -61,7 +61,6 @@ mysql_db_start (SeafileSession *session) char *host, *user, *passwd, *db, *unix_socket, *charset; int port; gboolean use_ssl = FALSE; - gboolean create_tables = TRUE; int max_connections = 0; GError *error = NULL; @@ -100,12 +99,6 @@ mysql_db_start (SeafileSession *session) use_ssl = g_key_file_get_boolean (session->config, "database", "use_ssl", NULL); - if (g_key_file_has_key (session->config, "database", "create_tables", NULL)) { - create_tables = g_key_file_get_boolean (session->config, - "database", "create_tables", NULL); - } - session->create_tables = create_tables; - charset = seaf_key_file_get_string (session->config, "database", "connection_charset", NULL); @@ -201,6 +194,7 @@ load_database_config (SeafileSession *session) char *type; GError *error = NULL; int ret = 0; + gboolean create_tables = FALSE; type = seaf_key_file_get_string (session->config, "database", "type", &error); /* Default to use sqlite if not set. */ @@ -221,6 +215,12 @@ load_database_config (SeafileSession *session) seaf_warning ("Unsupported db type %s.\n", type); ret = -1; } + if (ret == 0) { + if (g_key_file_has_key (session->config, "database", "create_tables", NULL)) + create_tables = g_key_file_get_boolean (session->config, + "database", "create_tables", NULL); + session->create_tables = create_tables; + } g_free (type); diff --git a/fuse/readdir.c b/fuse/readdir.c index 0e7a44e..c5bfc83 100644 --- a/fuse/readdir.c +++ b/fuse/readdir.c @@ -84,6 +84,9 @@ static int readdir_root(SeafileSession *seaf, users = g_hash_table_get_keys (user_hash); for (p = users; p; p = p->next) { email = p->data; + char *exclude = g_hash_table_lookup (seaf->excluded_users, email); + if (exclude) + continue; filler (buf, email, NULL, 0); } g_list_free (users); diff --git a/fuse/seafile-session.c b/fuse/seafile-session.c index 330777b..d560f67 100644 --- a/fuse/seafile-session.c +++ b/fuse/seafile-session.c @@ -13,6 +13,9 @@ #include "log.h" +static int +read_excluded_users (SeafileSession *session); + SeafileSession * seafile_session_new(const char *central_config_dir, const char *seafile_dir, @@ -64,12 +67,19 @@ seafile_session_new(const char *central_config_dir, session->tmp_file_dir = tmp_file_dir; session->session = ccnet_session; session->config = config; + session->excluded_users = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); if (load_database_config (session) < 0) { seaf_warning ("Failed to load database config.\n"); goto onerror; } + if (read_excluded_users (session) < 0) { + seaf_warning ("Failed to load excluded users.\n"); + goto onerror; + } + session->fs_mgr = seaf_fs_manager_new (session, abs_seafile_dir); if (!session->fs_mgr) goto onerror; @@ -95,6 +105,34 @@ onerror: return NULL; } +static int +read_excluded_users (SeafileSession *session) +{ + char *users; + int l, i; + char *hash_value; + + users = seaf_key_file_get_string (session->config, "fuse", "excluded_users", NULL); + if (!users) + return 0; + + char **parts = g_strsplit_set(users, " ,", 0); + l = g_strv_length(parts); + if (l > 0) + hash_value = g_new0(char, 1); + + for (i = 0; i < l; i++) { + if (g_strcmp0(parts[i], "") == 0) + continue; + g_hash_table_insert (session->excluded_users, g_strdup(parts[i]), hash_value); + } + + g_strfreev (parts); + g_free (users); + + return 0; +} + int seafile_session_init (SeafileSession *session) { diff --git a/fuse/seafile-session.h b/fuse/seafile-session.h index 30f6802..bb4a1a9 100644 --- a/fuse/seafile-session.h +++ b/fuse/seafile-session.h @@ -35,6 +35,8 @@ struct _SeafileSession { SeafCommitManager *commit_mgr; SeafRepoManager *repo_mgr; + GHashTable *excluded_users; + gboolean create_tables; }; diff --git a/scripts/build/build-server.py b/scripts/build/build-server.py index 9a18fae..5cb5a67 100755 --- a/scripts/build/build-server.py +++ b/scripts/build/build-server.py @@ -628,6 +628,14 @@ def copy_scripts_and_libs(): except Exception, e: error('failed to copy upgrade scripts: %s' % e) + # copy sql scripts + sql_scriptsdir = os.path.join(scripts_srcdir, 'sql') + dst_sql_scriptsdir = os.path.join(serverdir, 'sql') + try: + shutil.copytree(sql_scriptsdir, dst_sql_scriptsdir) + except Exception, e: + error('failed to copy sql scripts: %s' % e) + # copy runtime/seahub.conf runtimedir = os.path.join(serverdir, 'runtime') must_mkdir(runtimedir) diff --git a/scripts/setup-seafile-mysql.py b/scripts/setup-seafile-mysql.py index cafb95d..035befd 100644 --- a/scripts/setup-seafile-mysql.py +++ b/scripts/setup-seafile-mysql.py @@ -881,6 +881,41 @@ class CcnetConfigurator(AbstractConfigurator): default=default, validate=validate) + def do_syncdb(self): + print '----------------------------------------' + print 'Now creating ccnet database tables ...\n' + print '----------------------------------------' + + try: + conn = MySQLdb.connect(host=db_config.mysql_host, + port=db_config.mysql_port, + user=db_config.seafile_mysql_user, + passwd=db_config.seafile_mysql_password, + db=db_config.ccnet_db_name) + except Exception, e: + if isinstance(e, MySQLdb.OperationalError): + Utils.error('Failed to connect to mysql database %s: %s' % (db_config.ccnet_db_name, e.args[1])) + else: + Utils.error('Failed to connect to mysql database %s: %s' % (db_config.ccnet_db_name, e)) + + cursor = conn.cursor() + + sql_file = os.path.join(env_mgr.install_path, 'sql', 'mysql', 'ccnet.sql') + with open(sql_file, 'r') as fp: + content = fp.read() + + sqls = [line.strip() for line in content.split(';') if line.strip()] + for sql in sqls: + try: + cursor.execute(sql) + except Exception, e: + if isinstance(e, MySQLdb.OperationalError): + Utils.error('Failed to init ccnet database: %s' % e.args[1]) + else: + Utils.error('Failed to init ccnet database: %s' % e) + + conn.commit() + class SeafileConfigurator(AbstractConfigurator): def __init__(self): @@ -983,6 +1018,41 @@ class SeafileConfigurator(AbstractConfigurator): with open(seafile_ini, 'w') as fp: fp.write(self.seafile_dir) + def do_syncdb(self): + print '----------------------------------------' + print 'Now creating seafile database tables ...\n' + print '----------------------------------------' + + try: + conn = MySQLdb.connect(host=db_config.mysql_host, + port=db_config.mysql_port, + user=db_config.seafile_mysql_user, + passwd=db_config.seafile_mysql_password, + db=db_config.seafile_db_name) + except Exception, e: + if isinstance(e, MySQLdb.OperationalError): + Utils.error('Failed to connect to mysql database %s: %s' % (db_config.seafile_db_name, e.args[1])) + else: + Utils.error('Failed to connect to mysql database %s: %s' % (db_config.seafile_db_name, e)) + + cursor = conn.cursor() + + sql_file = os.path.join(env_mgr.install_path, 'sql', 'mysql', 'seafile.sql') + with open(sql_file, 'r') as fp: + content = fp.read() + + sqls = [line.strip() for line in content.split(';') if line.strip()] + for sql in sqls: + try: + cursor.execute(sql) + except Exception, e: + if isinstance(e, MySQLdb.OperationalError): + Utils.error('Failed to init seafile database: %s' % e.args[1]) + else: + Utils.error('Failed to init seafile database: %s' % e) + + conn.commit() + class SeahubConfigurator(AbstractConfigurator): def __init__(self): AbstractConfigurator.__init__(self) @@ -1465,6 +1535,8 @@ def main(): gunicorn_config.generate() seahub_config.generate() + ccnet_config.do_syncdb() + seafile_config.do_syncdb() seahub_config.do_syncdb() seahub_config.prepare_avatar_dir() # db_config.create_seahub_admin() diff --git a/scripts/setup-seafile.sh b/scripts/setup-seafile.sh index e4811a5..8c047b2 100755 --- a/scripts/setup-seafile.sh +++ b/scripts/setup-seafile.sh @@ -663,12 +663,48 @@ function get_seahub_admin_passwd () { # fi # fi -echo "Creating seahub database now, it may take one minute, please wait... " +echo "Creating database now, it may take one minute, please wait... " echo +cd ${TOPDIR}/ccnet && mkdir -m 0755 GroupMgr misc OrgMgr PeerMgr && cd - + +ccnet_group_db=${TOPDIR}/ccnet/GroupMgr/groupmgr.db +ccnet_group_sql=${INSTALLPATH}/sql/sqlite/groupmgr.sql +if ! sqlite3 ${ccnet_group_db} ".read ${ccnet_group_sql}" 2>/dev/null 1>&2; then + echo "Failed to sync ccnet groupmgr database." + err_and_quit; +fi + +ccnet_config_db=${TOPDIR}/ccnet/misc/config.db +ccnet_config_sql=${INSTALLPATH}/sql/sqlite/config.sql +if ! sqlite3 ${ccnet_config_db} ".read ${ccnet_config_sql}" 2>/dev/null 1>&2; then + echo "Failed to sync ccnet config database." + err_and_quit; +fi + +ccnet_org_db=${TOPDIR}/ccnet/OrgMgr/orgmgr.db +ccnet_org_sql=${INSTALLPATH}/sql/sqlite/org.sql +if ! sqlite3 ${ccnet_org_db} ".read ${ccnet_org_sql}" 2>/dev/null 1>&2; then + echo "Failed to sync ccnet org database." + err_and_quit; +fi + +ccnet_user_db=${TOPDIR}/ccnet/PeerMgr/usermgr.db +ccnet_user_sql=${INSTALLPATH}/sql/sqlite/user.sql +if ! sqlite3 ${ccnet_user_db} ".read ${ccnet_user_sql}" 2>/dev/null 1>&2; then + echo "Failed to sync ccnet user database." + err_and_quit; +fi + +seafile_db=${TOPDIR}/seafile-data/seafile.db +seafile_sql=${INSTALLPATH}/sql/sqlite/seafile.sql +if ! sqlite3 ${seafile_db} ".read ${seafile_sql}" 2>/dev/null 1>&2; then + echo "Failed to sync seafile database." + err_and_quit; +fi + seahub_db=${TOPDIR}/seahub.db seahub_sqls=${INSTALLPATH}/seahub/sql/sqlite3.sql - if ! sqlite3 ${seahub_db} ".read ${seahub_sqls}" 2>/dev/null 1>&2; then echo "Failed to sync seahub database." err_and_quit; diff --git a/scripts/sql/mysql/ccnet.sql b/scripts/sql/mysql/ccnet.sql new file mode 100644 index 0000000..7e09e85 --- /dev/null +++ b/scripts/sql/mysql/ccnet.sql @@ -0,0 +1,115 @@ +CREATE TABLE `Group` ( + `group_id` bigint(20) NOT NULL AUTO_INCREMENT, + `group_name` varchar(255) DEFAULT NULL, + `creator_name` varchar(255) DEFAULT NULL, + `timestamp` bigint(20) DEFAULT NULL, + `type` varchar(32) DEFAULT NULL, + `parent_group_id` int(11) DEFAULT NULL, + PRIMARY KEY (`group_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `GroupUser` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `group_id` bigint(20) DEFAULT NULL, + `user_name` varchar(255) DEFAULT NULL, + `is_staff` tinyint(4) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `group_id` (`group_id`,`user_name`), + KEY `user_name` (`user_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `GroupDNPair` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `group_id` int(11) DEFAULT NULL, + `dn` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `GroupStructure` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `group_id` int(11) DEFAULT NULL, + `path` varchar(1024) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `group_id` (`group_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `OrgGroup` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `org_id` int(11) DEFAULT NULL, + `group_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `org_id` (`org_id`,`group_id`), + KEY `group_id` (`group_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `Organization` ( + `org_id` bigint(20) NOT NULL AUTO_INCREMENT, + `org_name` varchar(255) DEFAULT NULL, + `url_prefix` varchar(255) DEFAULT NULL, + `creator` varchar(255) DEFAULT NULL, + `ctime` bigint(20) DEFAULT NULL, + PRIMARY KEY (`org_id`), + UNIQUE KEY `url_prefix` (`url_prefix`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `OrgUser` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `org_id` int(11) DEFAULT NULL, + `email` varchar(255) DEFAULT NULL, + `is_staff` tinyint(1) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `org_id` (`org_id`,`email`), + KEY `email` (`email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `Binding` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `email` varchar(255) DEFAULT NULL, + `peer_id` char(41) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `peer_id` (`peer_id`), + KEY `email` (`email`(20)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `EmailUser` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `email` varchar(255) DEFAULT NULL, + `passwd` varchar(256) DEFAULT NULL, + `is_staff` tinyint(1) NOT NULL, + `is_active` tinyint(1) NOT NULL, + `ctime` bigint(20) DEFAULT NULL, + `reference_id` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `email` (`email`), + UNIQUE KEY `reference_id` (`reference_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `LDAPConfig` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `cfg_group` varchar(255) NOT NULL, + `cfg_key` varchar(255) NOT NULL, + `value` varchar(255) DEFAULT NULL, + `property` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `LDAPUsers` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `email` varchar(255) NOT NULL, + `password` varchar(255) NOT NULL, + `is_staff` tinyint(1) NOT NULL, + `is_active` tinyint(1) NOT NULL, + `extra_attrs` text, + `reference_id` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `email` (`email`), + UNIQUE KEY `reference_id` (`reference_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `UserRole` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `email` varchar(255) DEFAULT NULL, + `role` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `email` (`email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/scripts/sql/mysql/seafile.sql b/scripts/sql/mysql/seafile.sql new file mode 100644 index 0000000..6aec92f --- /dev/null +++ b/scripts/sql/mysql/seafile.sql @@ -0,0 +1,228 @@ +CREATE TABLE `Branch` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `name` varchar(10) DEFAULT NULL, + `repo_id` char(41) DEFAULT NULL, + `commit_id` char(41) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`,`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `GarbageRepos` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(36) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `InnerPubRepo` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(37) DEFAULT NULL, + `permission` char(15) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `OrgQuota` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `org_id` int(11) DEFAULT NULL, + `quota` bigint(20) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `org_id` (`org_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `OrgUserQuota` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `org_id` int(11) DEFAULT NULL, + `user` varchar(255) DEFAULT NULL, + `quota` bigint(20) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `org_id` (`org_id`,`user`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `Repo` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(37) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `RepoFileCount` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(36) DEFAULT NULL, + `file_count` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `RepoGroup` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(37) DEFAULT NULL, + `group_id` int(11) DEFAULT NULL, + `user_name` varchar(255) DEFAULT NULL, + `permission` char(15) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `group_id` (`group_id`,`repo_id`), + KEY `repo_id` (`repo_id`), + KEY `user_name` (`user_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `RepoHead` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(37) DEFAULT NULL, + `branch_name` varchar(10) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `RepoHistoryLimit` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(37) DEFAULT NULL, + `days` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `RepoInfo` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(36) DEFAULT NULL, + `name` varchar(255) NOT NULL, + `update_time` bigint(20) DEFAULT NULL, + `version` int(11) DEFAULT NULL, + `is_encrypted` int(11) DEFAULT NULL, + `last_modifier` varchar(255) DEFAULT NULL, + `status` INTEGER DEFAULT 0, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `RepoOwner` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(37) DEFAULT NULL, + `owner_id` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`), + KEY `owner_id` (`owner_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `RepoSize` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(37) DEFAULT NULL, + `size` bigint(20) unsigned DEFAULT NULL, + `head_id` char(41) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `RepoTokenPeerInfo` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `token` char(41) DEFAULT NULL, + `peer_id` char(41) DEFAULT NULL, + `peer_ip` varchar(41) DEFAULT NULL, + `peer_name` varchar(255) DEFAULT NULL, + `sync_time` bigint(20) DEFAULT NULL, + `client_ver` varchar(20) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `token` (`token`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `RepoTrash` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(36) DEFAULT NULL, + `repo_name` varchar(255) DEFAULT NULL, + `head_id` char(40) DEFAULT NULL, + `owner_id` varchar(255) DEFAULT NULL, + `size` bigint(20) DEFAULT NULL, + `org_id` int(11) DEFAULT NULL, + `del_time` bigint(20) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`), + KEY `owner_id` (`owner_id`), + KEY `org_id` (`org_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `RepoUserToken` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(37) DEFAULT NULL, + `email` varchar(255) DEFAULT NULL, + `token` char(41) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`,`token`), + KEY `email` (`email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `RepoValidSince` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(37) DEFAULT NULL, + `timestamp` bigint(20) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `SeafileConf` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `cfg_group` varchar(255) NOT NULL, + `cfg_key` varchar(255) NOT NULL, + `value` varchar(255) DEFAULT NULL, + `property` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `SharedRepo` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(37) DEFAULT NULL, + `from_email` varchar(255) DEFAULT NULL, + `to_email` varchar(255) DEFAULT NULL, + `permission` char(15) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `repo_id` (`repo_id`), + KEY `from_email` (`from_email`), + KEY `to_email` (`to_email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `SystemInfo` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `info_key` varchar(256) DEFAULT NULL, + `info_value` varchar(1024) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `UserQuota` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `user` varchar(255) DEFAULT NULL, + `quota` bigint(20) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `user` (`user`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `UserShareQuota` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `user` varchar(255) DEFAULT NULL, + `quota` bigint(20) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `user` (`user`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `VirtualRepo` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(36) DEFAULT NULL, + `origin_repo` char(36) DEFAULT NULL, + `path` text, + `base_commit` char(40) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`), + KEY `origin_repo` (`origin_repo`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `WebAP` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `repo_id` char(37) DEFAULT NULL, + `access_property` char(10) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `repo_id` (`repo_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `WebUploadTempFiles` ( + `repo_id` char(40) NOT NULL, + `file_path` text NOT NULL, + `tmp_file_path` text NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/scripts/sql/sqlite/config.sql b/scripts/sql/sqlite/config.sql new file mode 100644 index 0000000..f96afb1 --- /dev/null +++ b/scripts/sql/sqlite/config.sql @@ -0,0 +1 @@ +CREATE TABLE Config (key TEXT PRIMARY KEY, value TEXT); diff --git a/scripts/sql/sqlite/groupmgr.sql b/scripts/sql/sqlite/groupmgr.sql new file mode 100644 index 0000000..fcae1de --- /dev/null +++ b/scripts/sql/sqlite/groupmgr.sql @@ -0,0 +1,9 @@ +CREATE TABLE `Group` (`group_id` INTEGER PRIMARY KEY AUTOINCREMENT, `group_name` VARCHAR(255), `creator_name` VARCHAR(255), `timestamp` BIGINT, `type` VARCHAR(32), `parent_group_id` INTEGER); + +CREATE TABLE `GroupUser` (`group_id` INTEGER, `user_name` VARCHAR(255), `is_staff` tinyint); +CREATE UNIQUE INDEX groupid_username_indx on `GroupUser` (`group_id`, `user_name`); +CREATE INDEX username_indx on `GroupUser` (`user_name`); + +CREATE TABLE GroupDNPair (group_id INTEGER, dn VARCHAR(255)); + +CREATE TABLE GroupStructure (group_id INTEGER PRIMARY KEY, path VARCHAR(1024)); diff --git a/scripts/sql/sqlite/org.sql b/scripts/sql/sqlite/org.sql new file mode 100644 index 0000000..555720d --- /dev/null +++ b/scripts/sql/sqlite/org.sql @@ -0,0 +1,10 @@ +CREATE TABLE OrgGroup (org_id INTEGER, group_id INTEGER); +CREATE INDEX groupid_indx on OrgGroup (group_id); +CREATE UNIQUE INDEX org_group_indx on OrgGroup (org_id, group_id); + +CREATE TABLE Organization (org_id INTEGER PRIMARY KEY AUTOINCREMENT, org_name VARCHAR(255), url_prefix VARCHAR(255), creator VARCHAR(255), ctime BIGINT); +CREATE UNIQUE INDEX url_prefix_indx on Organization (url_prefix); + +CREATE TABLE OrgUser (org_id INTEGER, email TEXT, is_staff bool NOT NULL); +CREATE INDEX email_indx on OrgUser (email); +CREATE UNIQUE INDEX orgid_email_indx on OrgUser (org_id, email); diff --git a/scripts/sql/sqlite/seafile.sql b/scripts/sql/sqlite/seafile.sql new file mode 100644 index 0000000..789829a --- /dev/null +++ b/scripts/sql/sqlite/seafile.sql @@ -0,0 +1,61 @@ +CREATE TABLE Branch (name VARCHAR(10), repo_id CHAR(41), commit_id CHAR(41),PRIMARY KEY (repo_id, name)); + +CREATE TABLE Repo (repo_id CHAR(37) PRIMARY KEY); + +CREATE TABLE RepoOwner (repo_id CHAR(37) PRIMARY KEY, owner_id TEXT); +CREATE INDEX OwnerIndex ON RepoOwner (owner_id); + +CREATE TABLE RepoGroup (repo_id CHAR(37), group_id INTEGER, user_name TEXT, permission CHAR(15)); +CREATE UNIQUE INDEX groupid_repoid_indx on RepoGroup (group_id, repo_id); +CREATE INDEX repogroup_repoid_index on RepoGroup (repo_id); +CREATE INDEX repogroup_username_indx on RepoGroup (user_name); + +CREATE TABLE InnerPubRepo (repo_id CHAR(37) PRIMARY KEY,permission CHAR(15)); + +CREATE TABLE RepoUserToken (repo_id CHAR(37), email VARCHAR(255), token CHAR(41)); +CREATE UNIQUE INDEX repo_token_indx on RepoUserToken (repo_id, token); +CREATE INDEX repo_token_email_indx on RepoUserToken (email); + +CREATE TABLE RepoTokenPeerInfo (token CHAR(41) PRIMARY KEY, peer_id CHAR(41), peer_ip VARCHAR(41), peer_name VARCHAR(255), sync_time BIGINT, client_ver VARCHAR(20)); + +CREATE TABLE RepoHead (repo_id CHAR(37) PRIMARY KEY, branch_name VARCHAR(10)); + +CREATE TABLE RepoSize (repo_id CHAR(37) PRIMARY KEY,size BIGINT UNSIGNED,head_id CHAR(41)); + +CREATE TABLE RepoHistoryLimit (repo_id CHAR(37) PRIMARY KEY, days INTEGER); + +CREATE TABLE RepoValidSince (repo_id CHAR(37) PRIMARY KEY, timestamp BIGINT); + +CREATE TABLE WebAP (repo_id CHAR(37) PRIMARY KEY, access_property CHAR(10)); + +CREATE TABLE VirtualRepo (repo_id CHAR(36) PRIMARY KEY,origin_repo CHAR(36), path TEXT, base_commit CHAR(40)); +CREATE INDEX virtualrepo_origin_repo_idx ON VirtualRepo (origin_repo); + +CREATE TABLE GarbageRepos (repo_id CHAR(36) PRIMARY KEY); + +CREATE TABLE RepoTrash (repo_id CHAR(36) PRIMARY KEY,repo_name VARCHAR(255), head_id CHAR(40), owner_id VARCHAR(255), size BIGINT UNSIGNED,org_id INTEGER, del_time BIGINT); +CREATE INDEX repotrash_owner_id_idx ON RepoTrash(owner_id); +CREATE INDEX repotrash_org_id_idx ON RepoTrash(org_id); + +CREATE TABLE RepoFileCount (repo_id CHAR(36) PRIMARY KEY,file_count BIGINT UNSIGNED); + +CREATE TABLE RepoInfo (repo_id CHAR(36) PRIMARY KEY, name VARCHAR(255) NOT NULL, update_time INTEGER, version INTEGER, is_encrypted INTEGER, last_modifier VARCHAR(255), status INTEGER DEFAULT 0); + +CREATE TABLE UserQuota (user VARCHAR(255) PRIMARY KEY,quota BIGINT); + +CREATE TABLE UserShareQuota (user VARCHAR(255) PRIMARY KEY,quota BIGINT); + +CREATE TABLE OrgQuota (org_id INTEGER PRIMARY KEY,quota BIGINT); + +CREATE TABLE OrgUserQuota (org_id INTEGER,user VARCHAR(255), quota BIGINT, PRIMARY KEY (org_id, user)); + +CREATE TABLE SeafileConf (cfg_group VARCHAR(255) NOT NULL,cfg_key VARCHAR(255) NOT NULL, value VARCHAR(255), property INTEGER); + +CREATE TABLE SharedRepo (repo_id CHAR(37) , from_email VARCHAR(255), to_email VARCHAR(255), permission CHAR(15)); +CREATE INDEX RepoIdIndex on SharedRepo (repo_id); +CREATE INDEX FromEmailIndex on SharedRepo (from_email); +CREATE INDEX ToEmailIndex on SharedRepo (to_email); + +CREATE TABLE SystemInfo( info_key VARCHAR(256), info_value VARCHAR(1024)); + +CREATE TABLE WebUploadTempFiles (repo_id CHAR(40) NOT NULL, file_path TEXT NOT NULL, tmp_file_path TEXT NOT NULL); diff --git a/scripts/sql/sqlite/user.sql b/scripts/sql/sqlite/user.sql new file mode 100644 index 0000000..2706c10 --- /dev/null +++ b/scripts/sql/sqlite/user.sql @@ -0,0 +1,16 @@ +CREATE TABLE Binding (email TEXT, peer_id TEXT); +CREATE UNIQUE INDEX peer_index on Binding (peer_id); + +CREATE TABLE EmailUser (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,email TEXT, passwd TEXT, is_staff bool NOT NULL, is_active bool NOT NULL, ctime INTEGER, reference_id TEXT); +CREATE UNIQUE INDEX email_index on EmailUser (email); +CREATE UNIQUE INDEX reference_id_index on EmailUser (reference_id); + +CREATE TABLE LDAPConfig (cfg_group VARCHAR(255) NOT NULL,cfg_key VARCHAR(255) NOT NULL, value VARCHAR(255), property INTEGER); + +CREATE TABLE LDAPUsers (id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT NOT NULL, password TEXT NOT NULL, is_staff BOOL NOT NULL, is_active BOOL NOT NULL, extra_attrs TEXT, reference_id TEXT); +CREATE UNIQUE INDEX ldapusers_email_index on LDAPUsers(email); +CREATE UNIQUE INDEX ldapusers_reference_id_index on LDAPUsers(reference_id); + +CREATE TABLE UserRole (email TEXT, role TEXT); +CREATE INDEX userrole_email_index on UserRole (email); +CREATE UNIQUE INDEX userrole_userrole_index on UserRole (email, role); diff --git a/server/http-server.c b/server/http-server.c index 438fc2c..424a835 100644 --- a/server/http-server.c +++ b/server/http-server.c @@ -1111,7 +1111,6 @@ put_update_branch_cb (evhtp_request_t *req, void *arg) goto out; } - seaf_repo_manager_cleanup_virtual_repos (seaf->repo_mgr, repo_id); seaf_repo_manager_merge_virtual_repo (seaf->repo_mgr, repo_id, NULL); schedule_repo_size_computation (seaf->size_sched, repo_id); diff --git a/server/processors/recvbranch-proc.c b/server/processors/recvbranch-proc.c index 1c55078..1171b88 100644 --- a/server/processors/recvbranch-proc.c +++ b/server/processors/recvbranch-proc.c @@ -204,7 +204,6 @@ update_repo (void *vprocessor) goto out; } - seaf_repo_manager_cleanup_virtual_repos (seaf->repo_mgr, repo_id); seaf_repo_manager_merge_virtual_repo (seaf->repo_mgr, repo_id, NULL); out: diff --git a/server/processors/recvbranch-v2-proc.c b/server/processors/recvbranch-v2-proc.c index 3990536..d46d1df 100644 --- a/server/processors/recvbranch-v2-proc.c +++ b/server/processors/recvbranch-v2-proc.c @@ -337,7 +337,6 @@ update_repo (void *vprocessor) goto out; } - seaf_repo_manager_cleanup_virtual_repos (seaf->repo_mgr, repo_id); seaf_repo_manager_merge_virtual_repo (seaf->repo_mgr, repo_id, NULL); out: diff --git a/server/quota-mgr.c b/server/quota-mgr.c index 9c20096..488659c 100644 --- a/server/quota-mgr.c +++ b/server/quota-mgr.c @@ -79,7 +79,7 @@ int seaf_quota_manager_init (SeafQuotaManager *mgr) { - if (!mgr->session->create_tables && seaf_db_type (mgr->session->db) == SEAF_DB_TYPE_MYSQL) + if (!mgr->session->create_tables && seaf_db_type (mgr->session->db) != SEAF_DB_TYPE_PGSQL) return 0; SeafDB *db = mgr->session->db; diff --git a/server/repo-mgr.c b/server/repo-mgr.c index abdd708..8b82573 100644 --- a/server/repo-mgr.c +++ b/server/repo-mgr.c @@ -1369,7 +1369,7 @@ create_tables_pgsql (SeafRepoManager *mgr) static int create_db_tables_if_not_exist (SeafRepoManager *mgr) { - if (!mgr->seaf->create_tables && seaf_db_type (mgr->seaf->db) == SEAF_DB_TYPE_MYSQL) + if (!mgr->seaf->create_tables && seaf_db_type (mgr->seaf->db) != SEAF_DB_TYPE_PGSQL) return 0; SeafDB *db = mgr->seaf->db; diff --git a/server/repo-op.c b/server/repo-op.c index b4ab86e..4f9097b 100644 --- a/server/repo-op.c +++ b/server/repo-op.c @@ -1495,7 +1495,8 @@ static char * del_file_recursive(SeafRepo *repo, const char *dir_id, const char *to_path, - const char *filename) + const char *filename, + int *mode, int *deleted_num, char **desc_file) { SeafDir *olddir, *newdir; SeafDirent *dent; @@ -1528,6 +1529,12 @@ del_file_recursive(SeafRepo *repo, for (i = 0; i < file_num; i++) { if (strcmp(old->name, file_names[i]) == 0) { found_flag = 1; + if (deleted_num) + (*deleted_num)++; + if (mode) + *mode = old->mode; + if (desc_file && *desc_file==NULL) + *desc_file = g_strdup(old->name); break; } } @@ -1543,6 +1550,13 @@ del_file_recursive(SeafRepo *repo, if (strcmp(old->name, filename) != 0) { new = seaf_dirent_dup (old); newentries = g_list_prepend (newentries, new); + } else { + if (deleted_num) + (*deleted_num)++; + if (mode) + *mode = old->mode; + if (desc_file && *desc_file==NULL) + *desc_file = g_strdup(old->name); } } } @@ -1572,7 +1586,8 @@ del_file_recursive(SeafRepo *repo, if (strcmp(dent->name, to_path_dup) != 0) continue; - id = del_file_recursive(repo, dent->id, remain, filename); + id = del_file_recursive(repo, dent->id, remain, filename, + mode, deleted_num, desc_file); if (id != NULL) { memcpy(dent->id, id, 40); dent->id[40] = '\0'; @@ -1604,13 +1619,15 @@ static char * do_del_file(SeafRepo *repo, const char *root_id, const char *parent_dir, - const char *file_name) + const char *file_name, + int *mode, int *deleted_num, char **desc_file) { /* if parent_dir is a absolutely path, we will remove the first '/' */ if (*parent_dir == '/') parent_dir = parent_dir + 1; - return del_file_recursive(repo, root_id, parent_dir, file_name); + return del_file_recursive(repo, root_id, parent_dir, file_name, + mode, deleted_num, desc_file); } int @@ -1623,15 +1640,14 @@ seaf_repo_manager_del_file (SeafRepoManager *mgr, { SeafRepo *repo = NULL; SeafCommit *head_commit = NULL; + SeafDir *dir = NULL; char *canon_path = NULL; - char **file_names; char buf[SEAF_PATH_MAX]; char *root_id = NULL; - char *desc_file; - int i = 0; + char *desc_file = NULL; int mode = 0; int ret = 0; - int file_num = 0, empty_num = 0; + int deleted_num = 0; GET_REPO_OR_FAIL(repo, repo_id); GET_COMMIT_OR_FAIL(head_commit, repo->id, repo->version, repo->head->commit_id); @@ -1639,39 +1655,19 @@ seaf_repo_manager_del_file (SeafRepoManager *mgr, if (!canon_path) canon_path = get_canonical_path (parent_dir); - if (strchr(file_name, '\t')) { - file_names = g_strsplit (file_name, "\t", -1); - file_num = g_strv_length (file_names); - - for (i = 0; i < file_num; i++) { - if (strcmp(file_names[i], "") == 0) { - empty_num++; - continue; - } - if (!check_file_exists(repo->store_id, repo->version, - head_commit->root_id, canon_path, file_names[i], &mode)) { - char *tmp_path; - if (strcmp(canon_path, "") == 0) - tmp_path = "/"; - else - tmp_path = canon_path; - seaf_warning ("[del file] File \'%s\' dosen't exist in %s in repo %s.\n", - file_names[i], tmp_path, repo->id); - empty_num++; - continue; - } - desc_file = file_names[i]; - } - file_num -= empty_num; - if (file_num <= 0) - goto out; - } else if (!check_file_exists(repo->store_id, repo->version, - head_commit->root_id, canon_path, file_name, &mode)) { + dir = seaf_fs_manager_get_seafdir_by_path (seaf->fs_mgr, + repo->store_id, repo->version, + head_commit->root_id, canon_path, NULL); + if (!dir) { + seaf_warning ("parent_dir %s doesn't exist in repo %s.\n", + canon_path, repo->store_id); + ret = -1; goto out; } root_id = do_del_file (repo, - head_commit->root_id, canon_path, file_name); + head_commit->root_id, canon_path, file_name, &mode, + &deleted_num, &desc_file); if (!root_id) { seaf_warning ("[del file] Failed to del file from %s in repo %s.\n", canon_path, repo->id); @@ -1680,15 +1676,23 @@ seaf_repo_manager_del_file (SeafRepoManager *mgr, ret = -1; goto out; } + if (deleted_num == 0) { + seaf_warning ("[del file] Nothing to be deleted in dir %s in repo %.8s.\n ", + parent_dir, repo->id); + g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, + "File doesn't exist"); + ret = -1; + goto out; + } /* Commit. */ - if (file_num > 1) { + if (deleted_num > 1) { snprintf(buf, SEAF_PATH_MAX, "Deleted \"%s\" and %d more files", - desc_file, file_num - 1); + desc_file, deleted_num - 1); } else if (S_ISDIR(mode)) { - snprintf(buf, SEAF_PATH_MAX, "Removed directory \"%s\"", file_name); + snprintf(buf, SEAF_PATH_MAX, "Removed directory \"%s\"", desc_file); } else { - snprintf(buf, SEAF_PATH_MAX, "Deleted \"%s\"", file_name); + snprintf(buf, SEAF_PATH_MAX, "Deleted \"%s\"", desc_file); } if (gen_new_commit (repo_id, head_commit, root_id, @@ -1697,8 +1701,6 @@ seaf_repo_manager_del_file (SeafRepoManager *mgr, goto out; } - seaf_repo_manager_cleanup_virtual_repos (mgr, repo_id); - seaf_repo_manager_merge_virtual_repo (mgr, repo_id, NULL); out: @@ -1706,10 +1708,11 @@ out: seaf_repo_unref (repo); if (head_commit) seaf_commit_unref(head_commit); - if (file_num) - g_strfreev (file_names); + if (dir) + seaf_dir_free (dir); g_free (root_id); g_free (canon_path); + g_free (desc_file); if (ret == 0) { update_repo_size (repo_id); @@ -2662,7 +2665,8 @@ move_file_same_repo (const char *repo_id, ret = -1; goto out; } - root_id = do_del_file (repo, root_id_after_put, src_path, filenames_str->str); + root_id = do_del_file (repo, root_id_after_put, src_path, filenames_str->str, + NULL, NULL, NULL); if (!root_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "move file failed"); @@ -2976,7 +2980,6 @@ seaf_repo_manager_move_file (SeafRepoManager *mgr, goto out; } - seaf_repo_manager_cleanup_virtual_repos (mgr, src_repo_id); seaf_repo_manager_merge_virtual_repo (mgr, src_repo_id, NULL); update_repo_size (dst_repo_id); @@ -3222,7 +3225,6 @@ seaf_repo_manager_move_multiple_files (SeafRepoManager *mgr, goto out; } } - seaf_repo_manager_cleanup_virtual_repos (mgr, src_repo_id); seaf_repo_manager_merge_virtual_repo (mgr, src_repo_id, NULL); update_repo_size (dst_repo_id); @@ -3786,7 +3788,6 @@ seaf_repo_manager_rename_file (SeafRepoManager *mgr, goto out; } - seaf_repo_manager_cleanup_virtual_repos (mgr, repo_id); seaf_repo_manager_merge_virtual_repo (mgr, repo_id, NULL); out: diff --git a/server/seafile-session.c b/server/seafile-session.c index 59f8f72..04155f5 100644 --- a/server/seafile-session.c +++ b/server/seafile-session.c @@ -207,7 +207,7 @@ seafile_session_init (SeafileSession *session) return -1; } - if ((session->create_tables || seaf_db_type(session->db) != SEAF_DB_TYPE_MYSQL) + if ((session->create_tables || seaf_db_type(session->db) == SEAF_DB_TYPE_PGSQL) && seaf_cfg_manager_init (session->cfg_mgr) < 0) { seaf_warning ("Failed to init config manager.\n"); return -1; @@ -444,7 +444,7 @@ schedule_create_system_default_repo (SeafileSession *session) sql = "CREATE TABLE IF NOT EXISTS SystemInfo( " "info_key VARCHAR(256), info_value VARCHAR(1024))"; - if ((session->create_tables || db_type != SEAF_DB_TYPE_MYSQL) + if ((session->create_tables || db_type == SEAF_DB_TYPE_PGSQL) && seaf_db_query (session->db, sql) < 0) return; diff --git a/server/share-mgr.c b/server/share-mgr.c index cba3a92..4f1a1a6 100644 --- a/server/share-mgr.c +++ b/server/share-mgr.c @@ -26,7 +26,7 @@ seaf_share_manager_new (SeafileSession *seaf) int seaf_share_manager_start (SeafShareManager *mgr) { - if (!mgr->seaf->create_tables && seaf_db_type (mgr->seaf->db) == SEAF_DB_TYPE_MYSQL) + if (!mgr->seaf->create_tables && seaf_db_type (mgr->seaf->db) != SEAF_DB_TYPE_PGSQL) return 0; SeafDB *db = mgr->seaf->db; diff --git a/server/virtual-repo.c b/server/virtual-repo.c index 2b03300..64948bf 100644 --- a/server/virtual-repo.c +++ b/server/virtual-repo.c @@ -607,7 +607,8 @@ seaf_repo_manager_merge_virtual_repo (SeafRepoManager *mgr, */ static void handle_missing_virtual_repo (SeafRepoManager *mgr, - SeafRepo *repo, SeafCommit *head, SeafVirtRepo *vinfo) + SeafRepo *repo, SeafCommit *head, SeafVirtRepo *vinfo, + char **return_new_path) { SeafCommit *parent = NULL; char *old_dir_id = NULL; @@ -655,9 +656,7 @@ handle_missing_virtual_repo (SeafRepoManager *mgr, } char de_id[41]; - char *new_path; - char *new_name; - char **parts = NULL; + char *new_path, *new_name; for (ptr = diff_res; ptr; ptr = ptr->next) { de = ptr->data; @@ -672,17 +671,23 @@ handle_missing_virtual_repo (SeafRepoManager *mgr, vinfo->repo_id, new_path); set_virtual_repo_base_commit_path (vinfo->repo_id, head->commit_id, new_path); - parts = g_strsplit(new_path, "/", 0); - new_name = parts[g_strv_length(parts) - 1]; - - seaf_repo_manager_edit_repo (vinfo->repo_id, - new_name, - "Changed library name", - NULL, - &error); - if (error) { - seaf_warning ("Failed to rename repo %s", de->new_name); - g_clear_error (&error); + if (return_new_path) + *return_new_path = g_strdup(new_path); + /* 'sub_path = NUll' means the virtual dir itself has been renamed, + * we need to make a new commit for the virtual repo + */ + if (sub_path == NULL) { + new_name = g_path_get_basename(new_path); + seaf_repo_manager_edit_repo (vinfo->repo_id, + new_name, + "Changed library name", + NULL, + &error); + if (error) { + seaf_warning ("Failed to rename repo %s", new_name); + g_clear_error (&error); + } + g_free(new_name); } is_renamed = TRUE; g_free (new_path); @@ -691,7 +696,6 @@ handle_missing_virtual_repo (SeafRepoManager *mgr, } } g_free (old_dir_id); - g_strfreev (parts); if (is_renamed) break; @@ -762,7 +766,7 @@ seaf_repo_manager_cleanup_virtual_repos (SeafRepoManager *mgr, &error); if (error) { if (error->code == SEAF_ERR_PATH_NO_EXIST) { - handle_missing_virtual_repo (mgr, repo, head, vinfo); + handle_missing_virtual_repo (mgr, repo, head, vinfo, NULL); } g_clear_error (&error); } else @@ -826,6 +830,31 @@ static void *merge_virtual_repo (void *vtask) goto out; } + orig_root = seaf_fs_manager_get_seafdir_id_by_path (seaf->fs_mgr, + orig_repo->store_id, + orig_repo->version, + orig_head->root_id, + vinfo->path, + NULL); + if (!orig_root) { + seaf_debug("Path %s not found in origin repo %.8s, delete or rename virtual repo %.8s\n", + vinfo->path, vinfo->origin_repo_id, repo_id); + + char *new_path = NULL; + handle_missing_virtual_repo (mgr, orig_repo, orig_head, vinfo, &new_path); + if (new_path != NULL) { + orig_root = seaf_fs_manager_get_seafdir_id_by_path (seaf->fs_mgr, + orig_repo->store_id, + orig_repo->version, + orig_head->root_id, + new_path, + NULL); + g_free (new_path); + } + if (!orig_root) + goto out; + } + base = seaf_commit_manager_get_commit (seaf->commit_mgr, orig_repo->id, orig_repo->version, vinfo->base_commit); @@ -852,19 +881,6 @@ static void *merge_virtual_repo (void *vtask) goto out; } - orig_root = seaf_fs_manager_get_seafdir_id_by_path (seaf->fs_mgr, - orig_repo->store_id, - orig_repo->version, - orig_head->root_id, - vinfo->path, - NULL); - if (!orig_root) { - seaf_warning ("Cannot find seafdir for repo %.10s path %s.\n", - vinfo->origin_repo_id, vinfo->path); - ret = -1; - goto out; - } - if (strcmp (root, orig_root) == 0) { /* Nothing to merge. */ seaf_debug ("Nothing to merge.\n"); diff --git a/server/zip-download-mgr.c b/server/zip-download-mgr.c index 84ef99d..eb4626d 100644 --- a/server/zip-download-mgr.c +++ b/server/zip-download-mgr.c @@ -266,15 +266,14 @@ parse_download_multi_data (DownloadObj *obj, const char *data) SeafRepo *repo = obj->repo; const char *tmp_parent_dir; char *parent_dir; - gboolean is_root_dir; json_t *name_array; json_error_t jerror; int i; int len; const char *file_name; - char *file_path; SeafDirent *dirent; - GList *dirent_list = NULL; + SeafDir *dir; + GList *dirent_list = NULL, *p = NULL; GError *error = NULL; jobj = json_loadb (data, strlen(data), 0, &jerror); @@ -304,7 +303,27 @@ parse_download_multi_data (DownloadObj *obj, const char *data) return -1; } parent_dir = format_dir_path (tmp_parent_dir); - is_root_dir = strcmp (parent_dir, "/") == 0; + + dir = seaf_fs_manager_get_seafdir_by_path (seaf->fs_mgr, repo->store_id, + repo->version, repo->root_id, parent_dir, &error); + if (!dir) { + if (error) { + seaf_warning ("Failed to get dir %s repo %.8s: %s.\n", + parent_dir, repo->store_id, error->message); + g_clear_error(&error); + } else { + seaf_warning ("dir %s doesn't exist in repo %.8s.\n", + parent_dir, repo->store_id); + } + g_free (parent_dir); + json_decref (jobj); + return -1; + } + GHashTable *dirent_hash = g_hash_table_new(g_str_hash, g_str_equal); + for (p = dir->entries; p; p = p->next) { + SeafDirent *d = p->data; + g_hash_table_insert(dirent_hash, d->name, d); + } for (i = 0; i < len; i++) { file_name = json_string_value (json_array_get (name_array, i)); @@ -317,25 +336,10 @@ parse_download_multi_data (DownloadObj *obj, const char *data) break; } - if (is_root_dir) { - file_path = g_strconcat (parent_dir, file_name, NULL); - } else { - file_path = g_strconcat (parent_dir, "/", file_name, NULL); - } - - dirent = seaf_fs_manager_get_dirent_by_path (seaf->fs_mgr, repo->store_id, - repo->version, repo->root_id, - file_path, &error); + dirent = g_hash_table_lookup (dirent_hash, file_name); if (!dirent) { - if (error) { - seaf_warning ("Failed to get dirent for %s: %s.\n", - file_path, error->message); - g_clear_error (&error); - } else { - seaf_warning ("Failed to get dirent for %s.\n", - file_path); - } - g_free (file_path); + seaf_warning ("Failed to get dirent for %s in dir %s in repo %.8s.\n", + file_name, parent_dir, repo->store_id); if (dirent_list) { g_list_free_full (dirent_list, (GDestroyNotify)seaf_dirent_free); dirent_list = NULL; @@ -343,12 +347,13 @@ parse_download_multi_data (DownloadObj *obj, const char *data) break; } - g_free (file_path); - dirent_list = g_list_prepend (dirent_list, dirent); + dirent_list = g_list_prepend (dirent_list, seaf_dirent_dup(dirent)); } + g_hash_table_unref(dirent_hash); g_free (parent_dir); json_decref (jobj); + seaf_dir_free (dir); if (!dirent_list) { return -1; diff --git a/tests/conf/ccnet.conf b/tests/conf/ccnet.conf index fe880e3..d1db59c 100644 --- a/tests/conf/ccnet.conf +++ b/tests/conf/ccnet.conf @@ -16,3 +16,4 @@ PORT = 9999 #USER = seafile #PASSWD = root #DB = ccnet-db +#CREATE_TABLES=true diff --git a/tests/test_share_and_perm/test_shared_repo_perm.py b/tests/test_share_and_perm/test_shared_repo_perm.py index 8c28cfd..0ca7332 100644 --- a/tests/test_share_and_perm/test_shared_repo_perm.py +++ b/tests/test_share_and_perm/test_shared_repo_perm.py @@ -1,4 +1,5 @@ import pytest +import time from seaserv import seafile_api as api from seaserv import ccnet_api @@ -114,6 +115,8 @@ def test_share_dir_to_user(repo, permission): assert api.del_file(repo.id, '/', 'dir1', USER) == 0 assert api.unshare_subdir_for_user(repo.id, '/dir2', USER, USER2) == 0 + time.sleep(1) + assert api.get_shared_repo_by_path(repo.id, '/dir1', USER2) is None assert api.get_shared_repo_by_path(repo.id, '/dir2', USER2) is None @@ -135,6 +138,8 @@ def test_share_dir_to_group(repo, group, permission): assert api.del_file(repo.id, '/', 'dir1', USER) == 0 assert api.unshare_subdir_for_group(repo.id, '/dir2', USER, group.id) == 0 + time.sleep(1) + assert api.check_permission(v_repo_id_1, USER2) is None assert api.check_permission(v_repo_id_2, USER2) is None