1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 module libgit2_d.sys.refdb_backend;
8 
9 
10 private static import libgit2_d.oid;
11 private static import libgit2_d.types;
12 
13 /**
14  * @file git2/refdb_backend.h
15  * @brief Git custom refs backend functions
16  * @defgroup git_refdb_backend Git custom refs backend API
17  * @ingroup Git
18  * @{
19  */
20 extern (C):
21 nothrow @nogc:
22 package(libgit2_d):
23 
24 /**
25  * Every backend's iterator must have a pointer to itself as the first
26  * element, so the API can talk to it. You'd define your iterator as
27  *
28  *     struct my_iterator {
29  *             git_reference_iterator parent;
30  *             ...
31  *     }
32  *
33  * and assign `iter->parent.backend` to your `git_refdb_backend`.
34  */
35 struct git_reference_iterator
36 {
37 	libgit2_d.types.git_refdb* db;
38 
39 	/**
40 	 * Return the current reference and advance the iterator.
41 	 */
42 	int function(libgit2_d.types.git_reference** ref_, .git_reference_iterator* iter) next;
43 
44 	/**
45 	 * Return the name of the current reference and advance the iterator
46 	 */
47 	int function(const (char)** ref_name, .git_reference_iterator* iter) next_name;
48 
49 	/**
50 	 * Free the iterator
51 	 */
52 	void function(.git_reference_iterator* iter) free;
53 }
54 
55 /**
56  * An instance for a custom backend
57  */
58 struct git_refdb_backend
59 {
60 	/**
61 	 * The backend API version
62 	 */
63 	uint version_;
64 
65 	/**
66 	 * Queries the refdb backend for the existence of a reference.
67 	 *
68 	 * A refdb implementation must provide this function.
69 	 *
70 	 * Params:
71 	 *      exists = The implementation shall set this to `0` if a ref does not exist, otherwise to `1`.
72 	 *      ref_name = The reference's name that should be checked for existence.
73 	 *
74 	 * Returns: `0` on success, a negative error value code.
75 	 */
76 	int function(int* exists, .git_refdb_backend* backend, const (char)* ref_name) exists;
77 
78 	/**
79 	 * Queries the refdb backend for a given reference.
80 	 *
81 	 * A refdb implementation must provide this function.
82 	 *
83 	 * Params:
84 	 *      out_ = The implementation shall set this to the allocated reference, if it could be found, otherwise to `NULL`.
85 	 *      ref_name = The reference's name that should be checked for existence.
86 	 *
87 	 * Returns: `0` on success, `GIT_ENOTFOUND` if the reference does exist, otherwise a negative error code.
88 	 */
89 	int function(libgit2_d.types.git_reference** out_, .git_refdb_backend* backend, const (char)* ref_name) lookup;
90 
91 	/**
92 	 * Allocate an iterator object for the backend.
93 	 *
94 	 * A refdb implementation must provide this function.
95 	 *
96 	 * Params:
97 	 *      out = The implementation shall set this to the allocated reference iterator. A custom structure may be used with an embedded `git_reference_iterator` structure. Both `next` and `next_name` functions of `git_reference_iterator` need to be populated.
98 	 *      glob = A pattern to filter references by. If given, the iterator shall only return references that match the glob when passed to `wildmatch`.
99 	 *
100 	 * Returns: `0` on success, otherwise a negative error code.
101 	 */
102 	int function(.git_reference_iterator** iter,  .git_refdb_backend* backend, const (char)* glob) iterator;
103 
104 	/**
105 	 * Writes the given reference to the refdb.
106 	 *
107 	 * A refdb implementation must provide this function.
108 	 *
109 	 * Params:
110 	 *      ref_ = The reference to persist. May either be a symbolic or direct reference.
111 	 *      force = Whether to write the reference if a reference with the same name already exists.
112 	 *      who = The person updating the reference. Shall be used to create a reflog entry.
113 	 *      message = The message detailing what kind of reference update is performed. Shall be used to create a reflog entry.
114 	 *      old = If not `NULL` and `force` is not set, then the implementation needs to ensure that the reference is currently at the given OID before writing the new value. If both `old` and `old_target` are `NULL`, then the reference should not exist at the point of writing.
115 	 *      old_target = If not `NULL` and `force` is not set, then the implementation needs to ensure that the symbolic reference is currently at the given target before writing the new value. If both `old` and `old_target` are `NULL`, then the reference should not exist at the point of writing.
116 	 *
117 	 * Returns: `0` on success, otherwise a negative error code.
118 	 */
119 	int function(.git_refdb_backend* backend, const (libgit2_d.types.git_reference)* ref_, int force, const (libgit2_d.types.git_signature)* who, const (char)* message, const (libgit2_d.oid.git_oid)* old, const (char)* old_target) write;
120 
121 	/**
122 	 * Rename a reference in the refdb.
123 	 *
124 	 * A refdb implementation must provide this function.
125 	 *
126 	 * Params:
127 	 *      out_ = The implementation shall set this to the newly created reference or `NULL` on error.
128 	 *      old_name = The current name of the reference that is to be renamed.
129 	 *      new_name = The new name that the old reference shall be renamed to.
130 	 *      force = Whether to write the reference if a reference with the target name already exists.
131 	 *      who = The person updating the reference. Shall be used to create a reflog entry.
132 	 *      message = The message detailing what kind of reference update is performed. Shall be used to create a reflog entry.
133 	 *
134 	 * Returns: `0` on success, otherwise a negative error code.
135 	 */
136 	int function(libgit2_d.types.git_reference** out_, .git_refdb_backend* backend, const (char)* old_name, const (char)* new_name, int force, const (libgit2_d.types.git_signature)* who, const (char)* message) rename;
137 
138 	/**
139 	 * Deletes the given reference from the refdb.
140 	 *
141 	 * If it exists, its reflog should be deleted as well.
142 	 *
143 	 * A refdb implementation must provide this function.
144 	 *
145 	 * Params:
146 	 *      ref_name = The name of the reference name that shall be deleted.
147 	 *      old_id = If not `NULL` and `force` is not set, then the implementation needs to ensure that the reference is currently at the given OID before writing the new value.
148 	 *      old_target = If not `NULL` and `force` is not set, then the implementation needs to ensure that the symbolic reference is currently at the given target before writing the new value.
149 	 *
150 	 * Returns: `0` on success, otherwise a negative error code.
151 	 */
152 	int function(.git_refdb_backend* backend, const (char)* ref_name, const (libgit2_d.oid.git_oid)* old_id, const (char)* old_target) del;
153 
154 	/**
155 	 * Suggests that the given refdb compress or optimize its references.
156 	 *
157 	 * This mechanism is implementation specific. For on-disk reference
158 	 * databases, this may pack all loose references.
159 	 *
160 	 * A refdb implementation may provide this function; if it is not
161 	 * provided, nothing will be done.
162 	 *
163 	 * Returns: `0` on success a negative error code otherwise
164 	 */
165 	int function(.git_refdb_backend* backend) compress;
166 
167 	/**
168 	 * Query whether a particular reference has a log (may be empty)
169 	 *
170 	 * Shall return 1 if it has a reflog, 0 it it doesn't and negative in
171 	 * case an error occurred.
172 	 *
173 	 * A refdb implementation must provide this function.
174 	 *
175 	 * Returns: `0` on success, `1` if the reflog for the given reference exists, a negative error code otherwise
176 	 */
177 	int function(.git_refdb_backend* backend, const (char)* refname) has_log;
178 
179 	/**
180 	 * Make sure a particular reference will have a reflog which
181 	 * will be appended to on writes.
182 	 *
183 	 * A refdb implementation must provide this function.
184 	 *
185 	 * Returns: `0` on success, a negative error code otherwise
186 	 */
187 	int function(.git_refdb_backend* backend, const (char)* refname) ensure_log;
188 
189 	/**
190 	 * Frees any resources held by the refdb (including the `git_refdb_backend`
191 	 * itself).
192 	 *
193 	 * A refdb backend implementation must provide this function.
194 	 */
195 	void function(.git_refdb_backend* backend) free;
196 
197 	/**
198 	 * Read the reflog for the given reference name.
199 	 *
200 	 * A refdb implementation must provide this function.
201 	 *
202 	 * Returns: `0` on success, a negative error code otherwise
203 	 */
204 	int function(libgit2_d.types.git_reflog** out_, .git_refdb_backend* backend, const (char)* name) reflog_read;
205 
206 	/**
207 	 * Write a reflog to disk.
208 	 *
209 	 * A refdb implementation must provide this function.
210 	 *
211 	 * Params:
212 	 *      reflog = The complete reference log for a given reference. Note that this may contain entries that have already been written to disk.
213 	 *
214 	 * Returns: `0` on success, a negative error code otherwise
215 	 */
216 	int function(.git_refdb_backend* backend, libgit2_d.types.git_reflog* reflog) reflog_write;
217 
218 	/**
219 	 * Rename a reflog.
220 	 *
221 	 * A refdb implementation must provide this function.
222 	 *
223 	 * Params:
224 	 *      old_name = The name of old reference whose reflog shall be renamed from.
225 	 *      new_name = The name of new reference whose reflog shall be renamed to.
226 	 *
227 	 * Returns: `0` on success, a negative error code otherwise
228 	 */
229 	int function(.git_refdb_backend* _backend, const (char)* old_name, const (char)* new_name) reflog_rename;
230 
231 	/**
232 	 * Remove a reflog.
233 	 *
234 	 * A refdb implementation must provide this function.
235 	 *
236 	 * Params:
237 	 *      name = The name of the reference whose reflog shall be deleted.
238 	 *
239 	 * Returns: `0` on success, a negative error code otherwise
240 	 */
241 	int function(.git_refdb_backend* backend, const (char)* name) reflog_delete;
242 
243 	/**
244 	 * Lock a reference.
245 	 *
246 	 * A refdb implementation may provide this function; if it is not
247 	 * provided, the transaction API will fail to work.
248 	 *
249 	 * Params:
250 	 *      payload_out = Opaque parameter that will be passed verbosely to `unlock`.
251 	 *      refname = Reference that shall be locked.
252 	 *
253 	 * Returns: `0` on success, a negative error code otherwise
254 	 */
255 	int function(void** payload_out, .git_refdb_backend* backend, const (char)* refname) lock;
256 
257 	/**
258 	 * Unlock a reference.
259 	 *
260 	 * Only one of target or symbolic_target will be set.
261 	 * `success` will be true if the reference should be update, false if
262 	 * the lock must be discarded.
263 	 *
264 	 * A refdb implementation must provide this function if a `lock`
265 	 * implementation is provided.
266 	 *
267 	 * Params:
268 	 *      payload = The payload returned by `lock`.
269 	 *      success = `1` if a reference should be updated, `2` if a reference should be deleted, `0` if the lock must be discarded.
270 	 *      update_reflog = `1` in case the reflog should be updated, `0` otherwise.
271 	 *      ref_ = The reference which should be unlocked.
272 	 *      who = The person updating the reference. Shall be used to create a reflog entry in case `update_reflog` is set.
273 	 *      message = The message detailing what kind of reference update is performed. Shall be used to create a reflog entry in case `update_reflog` is set.
274 	 *
275 	 * Returns: `0` on success, a negative error code otherwise
276 	 */
277 	int function(.git_refdb_backend* backend, void* payload, int success, int update_reflog, const (libgit2_d.types.git_reference)* ref_, const (libgit2_d.types.git_signature)* sig, const (char)* message) unlock;
278 }
279 
280 enum GIT_REFDB_BACKEND_VERSION = 1;
281 
282 pragma(inline, true)
283 pure nothrow @safe @nogc
284 .git_refdb_backend GIT_REFDB_BACKEND_INIT()
285 
286 	do
287 	{
288 		.git_refdb_backend OUTPUT =
289 		{
290 			version_: .GIT_REFDB_BACKEND_VERSION,
291 		};
292 
293 		return OUTPUT;
294 	}
295 
296 /**
297  * Initializes a `git_refdb_backend` with default values. Equivalent to
298  * creating an instance with GIT_REFDB_BACKEND_INIT.
299  *
300  * Params:
301  *      backend = the `git_refdb_backend` struct to initialize
302  *      version = Version of struct; pass `GIT_REFDB_BACKEND_VERSION`
303  *
304  * Returns: Zero on success; -1 on failure.
305  */
306 //GIT_EXTERN
307 int git_refdb_init_backend(.git_refdb_backend* backend, uint version_);
308 
309 /**
310  * Constructors for default filesystem-based refdb backend
311  *
312  * Under normal usage, this is called for you when the repository is
313  * opened / created, but you can use this to explicitly construct a
314  * filesystem refdb backend for a repository.
315  *
316  * Params:
317  *      backend_out = Output pointer to the git_refdb_backend object
318  *      repo = Git repository to access
319  *
320  * Returns: 0 on success, <0 error code on failure
321  */
322 //GIT_EXTERN
323 int git_refdb_backend_fs(.git_refdb_backend** backend_out, libgit2_d.types.git_repository* repo);
324 
325 /**
326  * Sets the custom backend to an existing reference DB
327  *
328  * The `git_refdb` will take ownership of the `git_refdb_backend` so you
329  * should NOT free it after calling this function.
330  *
331  * Params:
332  *      refdb = database to add the backend to
333  *      backend = pointer to a git_refdb_backend instance
334  *
335  * Returns: 0 on success; error code otherwise
336  */
337 //GIT_EXTERN
338 int git_refdb_set_backend(libgit2_d.types.git_refdb* refdb, .git_refdb_backend* backend);