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 #ifndef INCLUDE_sys_git_refdb_backend_h__
8 #define INCLUDE_sys_git_refdb_backend_h__
9 
10 #include "git2/common.h"
11 #include "git2/types.h"
12 #include "git2/oid.h"
13 
14 /**
15  * @file git2/refdb_backend.h
16  * @brief Git custom refs backend functions
17  * @defgroup git_refdb_backend Git custom refs backend API
18  * @ingroup Git
19  * @{
20  */
21 GIT_BEGIN_DECL
22 
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 	git_refdb *db;
37 
38 	/**
39 	 * Return the current reference and advance the iterator.
40 	 */
41 	int (*next)(
42 		git_reference **ref,
43 		git_reference_iterator *iter);
44 
45 	/**
46 	 * Return the name of the current reference and advance the iterator
47 	 */
48 	int (*next_name)(
49 		const char **ref_name,
50 		git_reference_iterator *iter);
51 
52 	/**
53 	 * Free the iterator
54 	 */
55 	void (*free)(
56 		git_reference_iterator *iter);
57 };
58 
59 /** An instance for a custom backend */
60 struct git_refdb_backend {
61 	unsigned int version;
62 
63 	/**
64 	 * Queries the refdb backend to determine if the given ref_name
65 	 * exists.  A refdb implementation must provide this function.
66 	 */
67 	int (*exists)(
68 		int *exists,
69 		git_refdb_backend *backend,
70 		const char *ref_name);
71 
72 	/**
73 	 * Queries the refdb backend for a given reference.  A refdb
74 	 * implementation must provide this function.
75 	 */
76 	int (*lookup)(
77 		git_reference **out,
78 		git_refdb_backend *backend,
79 		const char *ref_name);
80 
81 	/**
82 	 * Allocate an iterator object for the backend.
83 	 *
84 	 * A refdb implementation must provide this function.
85 	 */
86 	int (*iterator)(
87 		git_reference_iterator **iter,
88 		struct git_refdb_backend *backend,
89 		const char *glob);
90 
91 	/*
92 	 * Writes the given reference to the refdb.  A refdb implementation
93 	 * must provide this function.
94 	 */
95 	int (*write)(git_refdb_backend *backend,
96 		     const git_reference *ref, int force,
97 		     const git_signature *who, const char *message,
98 		     const git_oid *old, const char *old_target);
99 
100 	int (*rename)(
101 		git_reference **out, git_refdb_backend *backend,
102 		const char *old_name, const char *new_name, int force,
103 		const git_signature *who, const char *message);
104 
105 	/**
106 	 * Deletes the given reference (and if necessary its reflog)
107 	 * from the refdb.  A refdb implementation must provide this
108 	 * function.
109 	 */
110 	int (*del)(git_refdb_backend *backend, const char *ref_name, const git_oid *old_id, const char *old_target);
111 
112 	/**
113 	 * Suggests that the given refdb compress or optimize its references.
114 	 * This mechanism is implementation specific.  (For on-disk reference
115 	 * databases, this may pack all loose references.)    A refdb
116 	 * implementation may provide this function; if it is not provided,
117 	 * nothing will be done.
118 	 */
119 	int (*compress)(git_refdb_backend *backend);
120 
121 	/**
122 	 * Query whether a particular reference has a log (may be empty)
123 	 */
124 	int (*has_log)(git_refdb_backend *backend, const char *refname);
125 
126 	/**
127 	 * Make sure a particular reference will have a reflog which
128 	 * will be appended to on writes.
129 	 */
130 	int (*ensure_log)(git_refdb_backend *backend, const char *refname);
131 
132 	/**
133 	 * Frees any resources held by the refdb (including the `git_refdb_backend`
134 	 * itself). A refdb backend implementation must provide this function.
135 	 */
136 	void (*free)(git_refdb_backend *backend);
137 
138 	/**
139 	 * Read the reflog for the given reference name.
140 	 */
141 	int (*reflog_read)(git_reflog **out, git_refdb_backend *backend, const char *name);
142 
143 	/**
144 	 * Write a reflog to disk.
145 	 */
146 	int (*reflog_write)(git_refdb_backend *backend, git_reflog *reflog);
147 
148 	/**
149 	 * Rename a reflog
150 	 */
151 	int (*reflog_rename)(git_refdb_backend *_backend, const char *old_name, const char *new_name);
152 
153 	/**
154 	 * Remove a reflog.
155 	 */
156 	int (*reflog_delete)(git_refdb_backend *backend, const char *name);
157 
158 	/**
159 	 * Lock a reference. The opaque parameter will be passed to the unlock function
160 	 */
161 	int (*lock)(void **payload_out, git_refdb_backend *backend, const char *refname);
162 
163 	/**
164 	 * Unlock a reference. Only one of target or symbolic_target
165 	 * will be set. success indicates whether to update the
166 	 * reference or discard the lock (if it's false)
167 	 */
168 	int (*unlock)(git_refdb_backend *backend, void *payload, int success, int update_reflog,
169 		      const git_reference *ref, const git_signature *sig, const char *message);
170 };
171 
172 #define GIT_REFDB_BACKEND_VERSION 1
173 #define GIT_REFDB_BACKEND_INIT {GIT_REFDB_BACKEND_VERSION}
174 
175 /**
176  * Initializes a `git_refdb_backend` with default values. Equivalent to
177  * creating an instance with GIT_REFDB_BACKEND_INIT.
178  *
179  * @param backend the `git_refdb_backend` struct to initialize
180  * @param version Version of struct; pass `GIT_REFDB_BACKEND_VERSION`
181  * @return Zero on success; -1 on failure.
182  */
183 GIT_EXTERN(int) git_refdb_init_backend(
184 	git_refdb_backend *backend,
185 	unsigned int version);
186 
187 /**
188  * Constructors for default filesystem-based refdb backend
189  *
190  * Under normal usage, this is called for you when the repository is
191  * opened / created, but you can use this to explicitly construct a
192  * filesystem refdb backend for a repository.
193  *
194  * @param backend_out Output pointer to the git_refdb_backend object
195  * @param repo Git repository to access
196  * @return 0 on success, <0 error code on failure
197  */
198 GIT_EXTERN(int) git_refdb_backend_fs(
199 	git_refdb_backend **backend_out,
200 	git_repository *repo);
201 
202 /**
203  * Sets the custom backend to an existing reference DB
204  *
205  * The `git_refdb` will take ownership of the `git_refdb_backend` so you
206  * should NOT free it after calling this function.
207  *
208  * @param refdb database to add the backend to
209  * @param backend pointer to a git_refdb_backend instance
210  * @return 0 on success; error code otherwise
211  */
212 GIT_EXTERN(int) git_refdb_set_backend(
213 	git_refdb *refdb,
214 	git_refdb_backend *backend);
215 
216 GIT_END_DECL
217 
218 #endif
219