1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 #include "common.h"
4 
5 #include "seafile-session.h"
6 #include "seaf-db.h"
7 #include "org-mgr.h"
8 #include "seaf-utils.h"
9 
10 #include "utils.h"
11 #include "log.h"
12 
13 #define DEFAULT_MAX_CONNECTIONS 100
14 
15 struct _CcnetOrgManagerPriv
16 {
17     CcnetDB	*db;
18 };
19 
20 static int open_db (CcnetOrgManager *manager);
21 static int check_db_table (CcnetDB *db);
22 
ccnet_org_manager_new(SeafileSession * session)23 CcnetOrgManager* ccnet_org_manager_new (SeafileSession *session)
24 {
25     CcnetOrgManager *manager = g_new0 (CcnetOrgManager, 1);
26 
27     manager->session = session;
28     manager->priv = g_new0 (CcnetOrgManagerPriv, 1);
29 
30     return manager;
31 }
32 
33 int
ccnet_org_manager_init(CcnetOrgManager * manager)34 ccnet_org_manager_init (CcnetOrgManager *manager)
35 {
36     return 0;
37 }
38 
39 int
ccnet_org_manager_prepare(CcnetOrgManager * manager)40 ccnet_org_manager_prepare (CcnetOrgManager *manager)
41 {
42     return open_db (manager);
43 }
44 
45 static CcnetDB *
open_sqlite_db(CcnetOrgManager * manager)46 open_sqlite_db (CcnetOrgManager *manager)
47 {
48     CcnetDB *db = NULL;
49     char *db_dir;
50     char *db_path;
51 
52     db_dir = g_build_filename (manager->session->ccnet_dir, "OrgMgr", NULL);
53     if (checkdir_with_mkdir(db_dir) < 0) {
54         ccnet_error ("Cannot open db dir %s: %s\n", db_dir,
55                      strerror(errno));
56         g_free (db_dir);
57         return NULL;
58     }
59     g_free (db_dir);
60 
61     db_path = g_build_filename (manager->session->ccnet_dir, "OrgMgr",
62                                 "orgmgr.db", NULL);
63     db = seaf_db_new_sqlite (db_path, DEFAULT_MAX_CONNECTIONS);
64 
65     g_free (db_path);
66 
67     return db;
68 }
69 
70 static int
open_db(CcnetOrgManager * manager)71 open_db (CcnetOrgManager *manager)
72 {
73     CcnetDB *db = NULL;
74 
75     switch (seaf_db_type(manager->session->ccnet_db)) {
76     case SEAF_DB_TYPE_SQLITE:
77         db = open_sqlite_db (manager);
78         break;
79     case SEAF_DB_TYPE_PGSQL:
80     case SEAF_DB_TYPE_MYSQL:
81         db = manager->session->ccnet_db;
82         break;
83     }
84 
85     if (!db)
86         return -1;
87 
88     manager->priv->db = db;
89     if ((manager->session->create_tables || seaf_db_type(db) == SEAF_DB_TYPE_PGSQL)
90          && check_db_table (db) < 0) {
91         ccnet_warning ("Failed to create org db tables.\n");
92         return -1;
93     }
94 
95     return 0;
96 }
97 
ccnet_org_manager_start(CcnetOrgManager * manager)98 void ccnet_org_manager_start (CcnetOrgManager *manager)
99 {
100 }
101 
102 /* -------- Group Database Management ---------------- */
103 
check_db_table(CcnetDB * db)104 static int check_db_table (CcnetDB *db)
105 {
106     char *sql;
107 
108     int db_type = seaf_db_type (db);
109     if (db_type == SEAF_DB_TYPE_MYSQL) {
110         sql = "CREATE TABLE IF NOT EXISTS Organization (org_id BIGINT"
111             " PRIMARY KEY AUTO_INCREMENT, org_name VARCHAR(255),"
112             " url_prefix VARCHAR(255), creator VARCHAR(255), ctime BIGINT,"
113             " UNIQUE INDEX (url_prefix))"
114             "ENGINE=INNODB";
115         if (seaf_db_query (db, sql) < 0)
116             return -1;
117 
118         sql = "CREATE TABLE IF NOT EXISTS OrgUser ( "
119             "id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT, org_id INTEGER, "
120             "email VARCHAR(255), is_staff BOOL NOT NULL, "
121             "INDEX (email), UNIQUE INDEX(org_id, email))"
122             "ENGINE=INNODB";
123         if (seaf_db_query (db, sql) < 0)
124             return -1;
125 
126         sql = "CREATE TABLE IF NOT EXISTS OrgGroup ("
127             "id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT, org_id INTEGER, "
128             "group_id INTEGER, INDEX (group_id), "
129             "UNIQUE INDEX(org_id, group_id))"
130             "ENGINE=INNODB";
131         if (seaf_db_query (db, sql) < 0)
132             return -1;
133 
134     } else if (db_type == SEAF_DB_TYPE_SQLITE) {
135         sql = "CREATE TABLE IF NOT EXISTS Organization (org_id INTEGER"
136             " PRIMARY KEY AUTOINCREMENT, org_name VARCHAR(255),"
137             " url_prefix VARCHAR(255), "
138             " creator VARCHAR(255), ctime BIGINT)";
139         if (seaf_db_query (db, sql) < 0)
140             return -1;
141 
142         sql = "CREATE UNIQUE INDEX IF NOT EXISTS url_prefix_indx on "
143             "Organization (url_prefix)";
144         if (seaf_db_query (db, sql) < 0)
145             return -1;
146 
147         sql = "CREATE TABLE IF NOT EXISTS OrgUser (org_id INTEGER, "
148             "email TEXT, is_staff bool NOT NULL)";
149         if (seaf_db_query (db, sql) < 0)
150             return -1;
151 
152         sql = "CREATE INDEX IF NOT EXISTS email_indx on "
153             "OrgUser (email)";
154         if (seaf_db_query (db, sql) < 0)
155             return -1;
156 
157         sql = "CREATE UNIQUE INDEX IF NOT EXISTS orgid_email_indx on "
158             "OrgUser (org_id, email)";
159         if (seaf_db_query (db, sql) < 0)
160             return -1;
161 
162         sql = "CREATE TABLE IF NOT EXISTS OrgGroup (org_id INTEGER, "
163             "group_id INTEGER)";
164         if (seaf_db_query (db, sql) < 0)
165             return -1;
166 
167         sql = "CREATE INDEX IF NOT EXISTS groupid_indx on OrgGroup (group_id)";
168         if (seaf_db_query (db, sql) < 0)
169             return -1;
170 
171         sql = "CREATE UNIQUE INDEX IF NOT EXISTS org_group_indx on "
172             "OrgGroup (org_id, group_id)";
173         if (seaf_db_query (db, sql) < 0)
174             return -1;
175     } else if (db_type == SEAF_DB_TYPE_PGSQL) {
176         sql = "CREATE TABLE IF NOT EXISTS Organization (org_id SERIAL"
177             " PRIMARY KEY, org_name VARCHAR(255),"
178             " url_prefix VARCHAR(255), creator VARCHAR(255), ctime BIGINT,"
179             " UNIQUE (url_prefix))";
180         if (seaf_db_query (db, sql) < 0)
181             return -1;
182 
183         sql = "CREATE TABLE IF NOT EXISTS OrgUser (org_id INTEGER, "
184             "email VARCHAR(255), is_staff INTEGER NOT NULL, "
185             "UNIQUE (org_id, email))";
186         if (seaf_db_query (db, sql) < 0)
187             return -1;
188 
189         //if (!pgsql_index_exists (db, "orguser_email_idx")) {
190         //    sql = "CREATE INDEX orguser_email_idx ON OrgUser (email)";
191         //    if (seaf_db_query (db, sql) < 0)
192         //        return -1;
193         //}
194 
195         sql = "CREATE TABLE IF NOT EXISTS OrgGroup (org_id INTEGER, "
196             "group_id INTEGER, "
197             "UNIQUE (org_id, group_id))";
198         if (seaf_db_query (db, sql) < 0)
199             return -1;
200 
201         //if (!pgsql_index_exists (db, "orggroup_groupid_idx")) {
202         //    sql = "CREATE INDEX orggroup_groupid_idx ON OrgGroup (group_id)";
203         //    if (seaf_db_query (db, sql) < 0)
204         //        return -1;
205         //}
206     }
207 
208     return 0;
209 }
210 
ccnet_org_manager_create_org(CcnetOrgManager * mgr,const char * org_name,const char * url_prefix,const char * creator,GError ** error)211 int ccnet_org_manager_create_org (CcnetOrgManager *mgr,
212                                   const char *org_name,
213                                   const char *url_prefix,
214                                   const char *creator,
215                                   GError **error)
216 {
217     CcnetDB *db = mgr->priv->db;
218     gint64 now = get_current_time();
219     int rc;
220 
221     rc = seaf_db_statement_query (db,
222                                    "INSERT INTO Organization(org_name, url_prefix,"
223                                    " creator, ctime) VALUES (?, ?, ?, ?)",
224                                    4, "string", org_name, "string", url_prefix,
225                                    "string", creator, "int64", now);
226 
227     if (rc < 0) {
228         g_set_error (error, CCNET_DOMAIN, 0, "Failed to create organization");
229         return -1;
230     }
231 
232     int org_id = seaf_db_statement_get_int (db,
233                                              "SELECT org_id FROM Organization WHERE "
234                                              "url_prefix = ?", 1, "string", url_prefix);
235     if (org_id < 0) {
236         g_set_error (error, CCNET_DOMAIN, 0, "Failed to create organization");
237         return -1;
238     }
239 
240     rc = seaf_db_statement_query (db, "INSERT INTO OrgUser (org_id, email, is_staff) values (?, ?, ?)",
241                                    3, "int", org_id, "string", creator, "int", 1);
242     if (rc < 0) {
243         seaf_db_statement_query (db, "DELETE FROM Organization WHERE org_id=?",
244                                   1, "int", org_id);
245         g_set_error (error, CCNET_DOMAIN, 0, "Failed to create organization");
246         return -1;
247     }
248 
249     return org_id;
250 }
251 
252 int
ccnet_org_manager_remove_org(CcnetOrgManager * mgr,int org_id,GError ** error)253 ccnet_org_manager_remove_org (CcnetOrgManager *mgr,
254                               int org_id,
255                               GError **error)
256 {
257     CcnetDB *db = mgr->priv->db;
258 
259     seaf_db_statement_query (db, "DELETE FROM Organization WHERE org_id = ?",
260                               1, "int", org_id);
261 
262     seaf_db_statement_query (db, "DELETE FROM OrgUser WHERE org_id = ?",
263                               1, "int", org_id);
264 
265     seaf_db_statement_query (db, "DELETE FROM OrgGroup WHERE org_id = ?",
266                               1, "int", org_id);
267 
268     return 0;
269 }
270 
271 
272 static gboolean
get_all_orgs_cb(CcnetDBRow * row,void * data)273 get_all_orgs_cb (CcnetDBRow *row, void *data)
274 {
275     GList **p_list = data;
276     CcnetOrganization *org = NULL;
277     int org_id;
278     const char *org_name;
279     const char *url_prefix;
280     const char *creator;
281     gint64 ctime;
282 
283     org_id = seaf_db_row_get_column_int (row, 0);
284     org_name = seaf_db_row_get_column_text (row, 1);
285     url_prefix = seaf_db_row_get_column_text (row, 2);
286     creator = seaf_db_row_get_column_text (row, 3);
287     ctime = seaf_db_row_get_column_int64 (row, 4);
288 
289     org = g_object_new (CCNET_TYPE_ORGANIZATION,
290                         "org_id", org_id,
291                         "org_name", org_name,
292                         "url_prefix", url_prefix,
293                         "creator", creator,
294                         "ctime", ctime,
295                         NULL);
296 
297     *p_list = g_list_prepend (*p_list, org);
298 
299     return TRUE;
300 }
301 
302 GList *
ccnet_org_manager_get_all_orgs(CcnetOrgManager * mgr,int start,int limit)303 ccnet_org_manager_get_all_orgs (CcnetOrgManager *mgr,
304                                 int start,
305                                 int limit)
306 {
307     CcnetDB *db = mgr->priv->db;
308     char *sql;
309     GList *ret = NULL;
310     int rc;
311 
312     if (start == -1 && limit == -1) {
313         sql = "SELECT * FROM Organization ORDER BY org_id";
314         rc = seaf_db_statement_foreach_row (db, sql, get_all_orgs_cb, &ret, 0);
315     } else {
316         sql = "SELECT * FROM Organization ORDER BY org_id LIMIT ? OFFSET ?";
317         rc = seaf_db_statement_foreach_row (db, sql, get_all_orgs_cb, &ret,
318                                              2, "int", limit, "int", start);
319     }
320 
321     if (rc < 0)
322         return NULL;
323 
324     return g_list_reverse (ret);
325 }
326 
327 int
ccnet_org_manager_count_orgs(CcnetOrgManager * mgr)328 ccnet_org_manager_count_orgs (CcnetOrgManager *mgr)
329 {
330     CcnetDB *db = mgr->priv->db;
331     char *sql;
332     gint64 ret;
333 
334     sql = "SELECT count(*) FROM Organization";
335 
336     ret = seaf_db_get_int64 (db, sql);
337     if (ret < 0)
338         return -1;
339     return ret;
340 }
341 
342 static gboolean
get_org_cb(CcnetDBRow * row,void * data)343 get_org_cb (CcnetDBRow *row, void *data)
344 {
345     CcnetOrganization **p_org = data;
346     int org_id;
347     const char *org_name;
348     const char *url_prefix;
349     const char *creator;
350     gint64 ctime;
351 
352     org_id = seaf_db_row_get_column_int (row, 0);
353     org_name = seaf_db_row_get_column_text (row, 1);
354     url_prefix = seaf_db_row_get_column_text (row, 2);
355     creator = seaf_db_row_get_column_text (row, 3);
356     ctime = seaf_db_row_get_column_int64 (row, 4);
357 
358     *p_org = g_object_new (CCNET_TYPE_ORGANIZATION,
359                            "org_id", org_id,
360                            "org_name", org_name,
361                            "url_prefix", url_prefix,
362                            "creator", creator,
363                            "ctime", ctime,
364                            NULL);
365     return FALSE;
366 }
367 
368 CcnetOrganization *
ccnet_org_manager_get_org_by_url_prefix(CcnetOrgManager * mgr,const char * url_prefix,GError ** error)369 ccnet_org_manager_get_org_by_url_prefix (CcnetOrgManager *mgr,
370                                          const char *url_prefix,
371                                          GError **error)
372 {
373     CcnetDB *db = mgr->priv->db;
374     char *sql;
375     CcnetOrganization *org = NULL;
376 
377     sql = "SELECT org_id, org_name, url_prefix, creator,"
378         " ctime FROM Organization WHERE url_prefix = ?";
379 
380     if (seaf_db_statement_foreach_row (db, sql, get_org_cb, &org,
381                                         1, "string", url_prefix) < 0) {
382         return NULL;
383     }
384 
385     return org;
386 }
387 
388 CcnetOrganization *
ccnet_org_manager_get_org_by_id(CcnetOrgManager * mgr,int org_id,GError ** error)389 ccnet_org_manager_get_org_by_id (CcnetOrgManager *mgr,
390                                  int org_id,
391                                  GError **error)
392 {
393     CcnetDB *db = mgr->priv->db;
394     char *sql;
395     CcnetOrganization *org = NULL;
396 
397     sql = "SELECT org_id, org_name, url_prefix, creator,"
398         " ctime FROM Organization WHERE org_id = ?";
399 
400     if (seaf_db_statement_foreach_row (db, sql, get_org_cb, &org,
401                                         1, "int", org_id) < 0) {
402         return NULL;
403     }
404 
405     return org;
406 }
407 
408 int
ccnet_org_manager_add_org_user(CcnetOrgManager * mgr,int org_id,const char * email,int is_staff,GError ** error)409 ccnet_org_manager_add_org_user (CcnetOrgManager *mgr,
410                                 int org_id,
411                                 const char *email,
412                                 int is_staff,
413                                 GError **error)
414 {
415     CcnetDB *db = mgr->priv->db;
416 
417     return seaf_db_statement_query (db, "INSERT INTO OrgUser (org_id, email, is_staff) values (?, ?, ?)",
418                                      3, "int", org_id, "string", email,
419                                      "int", is_staff);
420 }
421 
422 int
ccnet_org_manager_remove_org_user(CcnetOrgManager * mgr,int org_id,const char * email,GError ** error)423 ccnet_org_manager_remove_org_user (CcnetOrgManager *mgr,
424                                    int org_id,
425                                    const char *email,
426                                    GError **error)
427 {
428     CcnetDB *db = mgr->priv->db;
429 
430     return seaf_db_statement_query (db, "DELETE FROM OrgUser WHERE org_id=? AND "
431                                      "email=?", 2, "int", org_id, "string", email);
432 }
433 
434 static gboolean
get_orgs_by_user_cb(CcnetDBRow * row,void * data)435 get_orgs_by_user_cb (CcnetDBRow *row, void *data)
436 {
437     GList **p_list = (GList **)data;
438     CcnetOrganization *org = NULL;
439     int org_id;
440     const char *email;
441     int is_staff;
442     const char *org_name;
443     const char *url_prefix;
444     const char *creator;
445     gint64 ctime;
446 
447     org_id = seaf_db_row_get_column_int (row, 0);
448     email = (char *) seaf_db_row_get_column_text (row, 1);
449     is_staff = seaf_db_row_get_column_int (row, 2);
450     org_name = (char *) seaf_db_row_get_column_text (row, 3);
451     url_prefix = (char *) seaf_db_row_get_column_text (row, 4);
452     creator = (char *) seaf_db_row_get_column_text (row, 5);
453     ctime = seaf_db_row_get_column_int64 (row, 6);
454 
455     org = g_object_new (CCNET_TYPE_ORGANIZATION,
456                         "org_id", org_id,
457                         "email", email,
458                         "is_staff", is_staff,
459                         "org_name", org_name,
460                         "url_prefix", url_prefix,
461                         "creator", creator,
462                         "ctime", ctime,
463                         NULL);
464     *p_list = g_list_prepend (*p_list, org);
465 
466     return TRUE;
467 }
468 
469 GList *
ccnet_org_manager_get_orgs_by_user(CcnetOrgManager * mgr,const char * email,GError ** error)470 ccnet_org_manager_get_orgs_by_user (CcnetOrgManager *mgr,
471                                    const char *email,
472                                    GError **error)
473 {
474     CcnetDB *db = mgr->priv->db;
475     char *sql;
476     GList *ret = NULL;
477 
478     sql = "SELECT t1.org_id, email, is_staff, org_name,"
479         " url_prefix, creator, ctime FROM OrgUser t1, Organization t2"
480         " WHERE t1.org_id = t2.org_id AND email = ?";
481 
482     if (seaf_db_statement_foreach_row (db, sql, get_orgs_by_user_cb, &ret,
483                                         1, "string", email) < 0) {
484         g_list_free (ret);
485         return NULL;
486     }
487 
488     return g_list_reverse (ret);
489 }
490 
491 static gboolean
get_org_emailusers(CcnetDBRow * row,void * data)492 get_org_emailusers (CcnetDBRow *row, void *data)
493 {
494     GList **list = (GList **)data;
495     const char *email = (char *) seaf_db_row_get_column_text (row, 0);
496 
497     *list = g_list_prepend (*list, g_strdup (email));
498     return TRUE;
499 }
500 
501 GList *
ccnet_org_manager_get_org_emailusers(CcnetOrgManager * mgr,const char * url_prefix,int start,int limit)502 ccnet_org_manager_get_org_emailusers (CcnetOrgManager *mgr,
503                                       const char *url_prefix,
504                                       int start, int limit)
505 {
506     CcnetDB *db = mgr->priv->db;
507     char *sql;
508     GList *ret = NULL;
509     int rc;
510 
511     if (start == -1 && limit == -1) {
512         sql = "SELECT email FROM OrgUser WHERE org_id ="
513             " (SELECT org_id FROM Organization WHERE url_prefix = ?)"
514             " ORDER BY email";
515         rc = seaf_db_statement_foreach_row (db, sql, get_org_emailusers, &ret,
516                                              1, "string", url_prefix);
517     } else {
518         sql = "SELECT email FROM OrgUser WHERE org_id ="
519             " (SELECT org_id FROM Organization WHERE url_prefix = ?)"
520             " ORDER BY email LIMIT ? OFFSET ?";
521         rc = seaf_db_statement_foreach_row (db, sql, get_org_emailusers, &ret,
522                                              3, "string", url_prefix,
523                                              "int", limit, "int", start);
524     }
525 
526     if (rc < 0)
527         return NULL;
528 
529     return g_list_reverse (ret);
530 }
531 
532 int
ccnet_org_manager_add_org_group(CcnetOrgManager * mgr,int org_id,int group_id,GError ** error)533 ccnet_org_manager_add_org_group (CcnetOrgManager *mgr,
534                                  int org_id,
535                                  int group_id,
536                                  GError **error)
537 {
538     CcnetDB *db = mgr->priv->db;
539 
540     return seaf_db_statement_query (db, "INSERT INTO OrgGroup (org_id, group_id) VALUES (?, ?)",
541                                      2, "int", org_id, "int", group_id);
542 }
543 
544 int
ccnet_org_manager_remove_org_group(CcnetOrgManager * mgr,int org_id,int group_id,GError ** error)545 ccnet_org_manager_remove_org_group (CcnetOrgManager *mgr,
546                                     int org_id,
547                                     int group_id,
548                                     GError **error)
549 {
550     CcnetDB *db = mgr->priv->db;
551 
552     return seaf_db_statement_query (db, "DELETE FROM OrgGroup WHERE org_id=?"
553                                      " AND group_id=?",
554                                      2, "int", org_id, "string", group_id);
555 }
556 
557 int
ccnet_org_manager_is_org_group(CcnetOrgManager * mgr,int group_id,GError ** error)558 ccnet_org_manager_is_org_group (CcnetOrgManager *mgr,
559                                 int group_id,
560                                 GError **error)
561 {
562     gboolean exists, err;
563 
564     CcnetDB *db = mgr->priv->db;
565 
566     exists = seaf_db_statement_exists (db, "SELECT group_id FROM OrgGroup "
567                                         "WHERE group_id = ?", &err, 1, "int", group_id);
568     if (err) {
569         ccnet_warning ("DB error when check group exist in OrgGroup.\n");
570         return 0;
571     }
572     return exists;
573 }
574 
575 int
ccnet_org_manager_get_org_id_by_group(CcnetOrgManager * mgr,int group_id,GError ** error)576 ccnet_org_manager_get_org_id_by_group (CcnetOrgManager *mgr,
577                                        int group_id,
578                                        GError **error)
579 {
580     CcnetDB *db = mgr->priv->db;
581     char *sql;
582 
583     sql = "SELECT org_id FROM OrgGroup WHERE group_id = ?";
584     return seaf_db_statement_get_int (db, sql, 1, "int", group_id);
585 }
586 
587 static gboolean
get_org_group_ids(CcnetDBRow * row,void * data)588 get_org_group_ids (CcnetDBRow *row, void *data)
589 {
590     GList **plist = data;
591 
592     int group_id = seaf_db_row_get_column_int (row, 0);
593 
594     *plist = g_list_prepend (*plist, (gpointer)(long)group_id);
595 
596     return TRUE;
597 }
598 
599 GList *
ccnet_org_manager_get_org_group_ids(CcnetOrgManager * mgr,int org_id,int start,int limit)600 ccnet_org_manager_get_org_group_ids (CcnetOrgManager *mgr,
601                                      int org_id,
602                                      int start,
603                                      int limit)
604 {
605     CcnetDB *db = mgr->priv->db;
606     GList *ret = NULL;
607     int rc;
608 
609     if (limit == -1) {
610         rc = seaf_db_statement_foreach_row (db,
611                                              "SELECT group_id FROM OrgGroup WHERE "
612                                              "org_id = ?",
613                                              get_org_group_ids, &ret,
614                                              1, "int", org_id);
615     } else {
616         rc = seaf_db_statement_foreach_row (db,
617                                              "SELECT group_id FROM OrgGroup WHERE "
618                                              "org_id = ? LIMIT ? OFFSET ?",
619                                              get_org_group_ids, &ret,
620                                              3, "int", org_id, "int", limit,
621                                              "int", start);
622     }
623 
624     if (rc < 0) {
625         g_list_free (ret);
626         return NULL;
627     }
628 
629     return g_list_reverse (ret);
630 }
631 
632 static gboolean
get_org_groups(CcnetDBRow * row,void * data)633 get_org_groups (CcnetDBRow *row, void *data)
634 {
635     GList **plist = data;
636     CcnetGroup *group;
637 
638     int group_id = seaf_db_row_get_column_int (row, 0);
639     const char *group_name = seaf_db_row_get_column_text (row, 1);
640     const char *creator_name = seaf_db_row_get_column_text (row, 2);
641     gint64 ts = seaf_db_row_get_column_int64 (row, 3);
642     int parent_group_id = seaf_db_row_get_column_int (row, 4);
643 
644     group = g_object_new (CCNET_TYPE_GROUP,
645                           "id", group_id,
646                           "group_name", group_name,
647                           "creator_name", creator_name,
648                           "timestamp", ts,
649                           "source", "DB",
650                           "parent_group_id", parent_group_id,
651                           NULL);
652 
653     *plist = g_list_prepend (*plist, group);
654 
655     return TRUE;
656 }
657 
658 GList *
ccnet_org_manager_get_org_top_groups(CcnetOrgManager * mgr,int org_id,GError ** error)659 ccnet_org_manager_get_org_top_groups (CcnetOrgManager *mgr, int org_id, GError **error)
660 {
661     CcnetDB *db = mgr->priv->db;
662     GList *ret = NULL;
663     char *sql;
664     int rc;
665 
666     sql = "SELECT g.group_id, group_name, creator_name, timestamp, parent_group_id FROM "
667           "`OrgGroup` o, `Group` g WHERE o.group_id = g.group_id AND "
668           "org_id=? AND parent_group_id=-1 ORDER BY timestamp DESC";
669 
670     rc = seaf_db_statement_foreach_row (db, sql,
671                                          get_org_groups, &ret,
672                                          1, "int", org_id);
673     if (rc < 0)
674         return NULL;
675 
676     return g_list_reverse (ret);
677 }
678 
679 GList *
ccnet_org_manager_get_org_groups(CcnetOrgManager * mgr,int org_id,int start,int limit)680 ccnet_org_manager_get_org_groups (CcnetOrgManager *mgr,
681                                   int org_id,
682                                   int start,
683                                   int limit)
684 {
685     CcnetDB *db = mgr->priv->db;
686     char *sql;
687     GList *ret = NULL;
688     int rc;
689 
690     if (limit == -1) {
691         sql = "SELECT g.group_id, group_name, creator_name, timestamp, parent_group_id FROM "
692             "OrgGroup o, `Group` g WHERE o.group_id = g.group_id AND org_id = ?";
693         rc = seaf_db_statement_foreach_row (db,
694                                              sql,
695                                              get_org_groups, &ret,
696                                              1, "int", org_id);
697     } else {
698         sql = "SELECT g.group_id, group_name, creator_name, timestamp, parent_group_id FROM "
699             "OrgGroup o, `Group` g WHERE o.group_id = g.group_id AND org_id = ? "
700             "LIMIT ? OFFSET ?";
701         rc = seaf_db_statement_foreach_row (db,
702                                              sql,
703                                              get_org_groups, &ret,
704                                              3, "int", org_id, "int", limit,
705                                              "int", start);
706     }
707 
708     if (rc < 0) {
709         return NULL;
710     }
711 
712     return g_list_reverse (ret);
713 }
714 
715 GList *
ccnet_org_manager_get_org_groups_by_user(CcnetOrgManager * mgr,const char * user,int org_id)716 ccnet_org_manager_get_org_groups_by_user (CcnetOrgManager *mgr,
717                                           const char *user,
718                                           int org_id)
719 {
720     CcnetDB *db = mgr->priv->db;
721     char *sql;
722     GList *ret = NULL;
723     int rc;
724 
725     sql = "SELECT g.group_id, group_name, creator_name, timestamp FROM "
726           "OrgGroup o, `Group` g, GroupUser u "
727           "WHERE o.group_id = g.group_id AND org_id = ? AND "
728           "g.group_id = u.group_id AND user_name = ?";
729     rc = seaf_db_statement_foreach_row (db,
730                                          sql,
731                                          get_org_groups, &ret,
732                                          2, "int", org_id, "string", user);
733     if (rc < 0)
734         return NULL;
735 
736     return g_list_reverse (ret);
737 }
738 
739 int
ccnet_org_manager_org_user_exists(CcnetOrgManager * mgr,int org_id,const char * email,GError ** error)740 ccnet_org_manager_org_user_exists (CcnetOrgManager *mgr,
741                                    int org_id,
742                                    const char *email,
743                                    GError **error)
744 {
745     gboolean exists, err;
746 
747     CcnetDB *db = mgr->priv->db;
748 
749     exists = seaf_db_statement_exists (db, "SELECT org_id FROM OrgUser WHERE "
750                                         "org_id = ? AND email = ?", &err,
751                                         2, "int", org_id, "string", email);
752     if (err) {
753         ccnet_warning ("DB error when check user exist in OrgUser.\n");
754         return 0;
755     }
756     return exists;
757 }
758 
759 char *
ccnet_org_manager_get_url_prefix_by_org_id(CcnetOrgManager * mgr,int org_id,GError ** error)760 ccnet_org_manager_get_url_prefix_by_org_id (CcnetOrgManager *mgr,
761                                             int org_id,
762                                             GError **error)
763 {
764     CcnetDB *db = mgr->priv->db;
765     char *sql;
766 
767     sql = "SELECT url_prefix FROM Organization WHERE org_id = ?";
768 
769     return seaf_db_statement_get_string (db, sql, 1, "int", org_id);
770 }
771 
772 int
ccnet_org_manager_is_org_staff(CcnetOrgManager * mgr,int org_id,const char * email,GError ** error)773 ccnet_org_manager_is_org_staff (CcnetOrgManager *mgr,
774                                 int org_id,
775                                 const char *email,
776                                 GError **error)
777 {
778     CcnetDB *db = mgr->priv->db;
779     char *sql;
780 
781     sql = "SELECT is_staff FROM OrgUser WHERE org_id=? AND email=?";
782 
783     return seaf_db_statement_get_int (db, sql, 2, "int", org_id, "string", email);
784 }
785 
786 int
ccnet_org_manager_set_org_staff(CcnetOrgManager * mgr,int org_id,const char * email,GError ** error)787 ccnet_org_manager_set_org_staff (CcnetOrgManager *mgr,
788                                  int org_id,
789                                  const char *email,
790                                  GError **error)
791 {
792     CcnetDB *db = mgr->priv->db;
793 
794     return seaf_db_statement_query (db, "UPDATE OrgUser SET is_staff = 1 "
795                                      "WHERE org_id=? AND email=?", 2,
796                                      "int", org_id, "string", email);
797 }
798 
799 int
ccnet_org_manager_unset_org_staff(CcnetOrgManager * mgr,int org_id,const char * email,GError ** error)800 ccnet_org_manager_unset_org_staff (CcnetOrgManager *mgr,
801                                    int org_id,
802                                    const char *email,
803                                    GError **error)
804 {
805     CcnetDB *db = mgr->priv->db;
806 
807     return seaf_db_statement_query (db, "UPDATE OrgUser SET is_staff = 0 "
808                                      "WHERE org_id=? AND email=?", 2,
809                                      "int", org_id, "string", email);
810 }
811 
812 int
ccnet_org_manager_set_org_name(CcnetOrgManager * mgr,int org_id,const char * org_name,GError ** error)813 ccnet_org_manager_set_org_name(CcnetOrgManager *mgr,
814                                int org_id,
815                                const char *org_name,
816                                GError **error)
817 {
818     CcnetDB *db = mgr->priv->db;
819 
820     return seaf_db_statement_query (db,
821                                      "UPDATE `Organization` set org_name = ? "
822                                      "WHERE org_id = ?",
823                                      2, "string", org_name, "int", org_id);
824     return 0;
825 }
826 
827