1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 #ifndef SEAF_COMMIT_MGR_H
4 #define SEAF_COMMIT_MGR_H
5 
6 struct _SeafCommitManager;
7 typedef struct _SeafCommit SeafCommit;
8 
9 #include <glib/gstdio.h>
10 #include "db.h"
11 
12 #include "obj-store.h"
13 
14 struct _SeafCommit {
15     struct _SeafCommitManager *manager;
16 
17     int         ref;
18 
19     char        commit_id[41];
20     char        repo_id[37];
21     char        root_id[41];    /* the fs root */
22     char       *desc;
23     char       *creator_name;
24     char        creator_id[41];
25     guint64     ctime;          /* creation time */
26     char       *parent_id;
27     char       *second_parent_id;
28     char       *repo_name;
29     char       *repo_desc;
30     char       *repo_category;
31     char       *device_name;
32     char       *client_version;
33 
34     gboolean    encrypted;
35     int         enc_version;
36     char       *magic;
37     char       *random_key;
38     char       *salt;
39     gboolean    no_local_history;
40 
41     int         version;
42     gboolean    new_merge;
43     gboolean    conflict;
44     gboolean    repaired;
45 };
46 
47 
48 /**
49  * @commit_id: if this is NULL, will create a new id.
50  * @ctime: if this is 0, will use current time.
51  *
52  * Any new commit should be added to commit manager before used.
53  */
54 SeafCommit *
55 seaf_commit_new (const char *commit_id,
56                  const char *repo_id,
57                  const char *root_id,
58                  const char *author_name,
59                  const char *creator_id,
60                  const char *desc,
61                  guint64 ctime);
62 
63 char *
64 seaf_commit_to_data (SeafCommit *commit, gsize *len);
65 
66 SeafCommit *
67 seaf_commit_from_data (const char *id, char *data, gsize len);
68 
69 void
70 seaf_commit_ref (SeafCommit *commit);
71 
72 void
73 seaf_commit_unref (SeafCommit *commit);
74 
75 /* Set stop to TRUE if you want to stop traversing a branch in the history graph.
76    Note, if currently there are multi branches, this function will be called again.
77    So, set stop to TRUE not always stop traversing the history graph.
78 */
79 typedef gboolean (*CommitTraverseFunc) (SeafCommit *commit, void *data, gboolean *stop);
80 
81 struct _SeafileSession;
82 
83 typedef struct _SeafCommitManager SeafCommitManager;
84 typedef struct _SeafCommitManagerPriv SeafCommitManagerPriv;
85 
86 struct _SeafCommitManager {
87     struct _SeafileSession *seaf;
88 
89     sqlite3    *db;
90     struct SeafObjStore *obj_store;
91 
92     SeafCommitManagerPriv *priv;
93 };
94 
95 SeafCommitManager *
96 seaf_commit_manager_new (struct _SeafileSession *seaf);
97 
98 int
99 seaf_commit_manager_init (SeafCommitManager *mgr);
100 
101 /**
102  * Add a commit to commit manager and persist it to disk.
103  * Any new commit should be added to commit manager before used.
104  * This function increments ref count of the commit object.
105  * Not MT safe.
106  */
107 int
108 seaf_commit_manager_add_commit (SeafCommitManager *mgr, SeafCommit *commit);
109 
110 /**
111  * Delete a commit from commit manager and permanently remove it from disk.
112  * A commit object to be deleted should have ref cournt <= 1.
113  * Not MT safe.
114  */
115 void
116 seaf_commit_manager_del_commit (SeafCommitManager *mgr,
117                                 const char *repo_id,
118                                 int version,
119                                 const char *id);
120 
121 /**
122  * Find a commit object.
123  * This function increments ref count of returned object.
124  * Not MT safe.
125  */
126 SeafCommit*
127 seaf_commit_manager_get_commit (SeafCommitManager *mgr,
128                                 const char *repo_id,
129                                 int version,
130                                 const char *id);
131 
132 /**
133  * Get a commit object, with compatibility between version 0 and version 1.
134  * It will first try to get commit with version 1 layout; if fails, will
135  * try version 0 layout for compatibility.
136  * This is useful for loading a repo. In that case, we don't know the version
137  * of the repo before loading its head commit.
138  */
139 SeafCommit *
140 seaf_commit_manager_get_commit_compatible (SeafCommitManager *mgr,
141                                            const char *repo_id,
142                                            const char *id);
143 
144 /**
145  * Traverse the commits DAG start from head in topological order.
146  * The ordering is based on commit time.
147  * return FALSE if some commits is missing, TRUE otherwise.
148  */
149 gboolean
150 seaf_commit_manager_traverse_commit_tree (SeafCommitManager *mgr,
151                                           const char *repo_id,
152                                           int version,
153                                           const char *head,
154                                           CommitTraverseFunc func,
155                                           void *data,
156                                           gboolean skip_errors);
157 
158 /*
159  * The same as the above function, but stops traverse down if parent commit
160  * doesn't exists, instead of returning error.
161  */
162 gboolean
163 seaf_commit_manager_traverse_commit_tree_truncated (SeafCommitManager *mgr,
164                                                     const char *repo_id,
165                                                     int version,
166                                                     const char *head,
167                                                     CommitTraverseFunc func,
168                                                     void *data,
169                                                     gboolean skip_errors);
170 
171 /**
172  * Works the same as seaf_commit_manager_traverse_commit_tree, but stops
173  * traversing when a total number of _limit_ commits is reached. If
174  * limit <= 0, there is no limit
175  */
176 gboolean
177 seaf_commit_manager_traverse_commit_tree_with_limit (SeafCommitManager *mgr,
178                                                      const char *repo_id,
179                                                      int version,
180                                                      const char *head,
181                                                      CommitTraverseFunc func,
182                                                      int limit,
183                                                      void *data,
184                                                      char **next_start_commit,
185                                                      gboolean skip_errors);
186 
187 gboolean
188 seaf_commit_manager_commit_exists (SeafCommitManager *mgr,
189                                    const char *repo_id,
190                                    int version,
191                                    const char *id);
192 
193 int
194 seaf_commit_manager_remove_store (SeafCommitManager *mgr,
195                                   const char *store_id);
196 
197 #endif
198