2 * Copyright © 2008 Jelmer Vernooij <jelmer@samba.org>
3 * -*- coding: utf-8 -*-
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <apr_general.h>
23 #include <svn_repos.h>
27 PyAPI_DATA(PyTypeObject) Repository_Type;
28 PyAPI_DATA(PyTypeObject) FileSystem_Type;
36 static PyObject *repos_create(PyObject *self, PyObject *args)
39 PyObject *config=Py_None, *fs_config=Py_None;
42 apr_hash_t *hash_config, *hash_fs_config;
43 RepositoryObject *ret;
45 if (!PyArg_ParseTuple(args, "s|OO", &path, &config, &fs_config))
51 hash_config = config_hash_from_object(config, pool);
52 if (hash_config == NULL)
54 hash_fs_config = apr_hash_make(pool); /* FIXME */
55 if (hash_fs_config == NULL) {
56 PyErr_SetString(PyExc_RuntimeError, "Unable to create fs config hash");
59 RUN_SVN_WITH_POOL(pool, svn_repos_create(&repos, path, NULL, NULL,
60 hash_config, hash_fs_config, pool));
62 ret = PyObject_New(RepositoryObject, &Repository_Type);
69 return (PyObject *)ret;
72 static void repos_dealloc(PyObject *self)
74 RepositoryObject *repos = (RepositoryObject *)self;
76 apr_pool_destroy(repos->pool);
79 static PyObject *repos_init(PyTypeObject *type, PyObject *args, PyObject *kwargs)
82 char *kwnames[] = { "path", NULL };
83 RepositoryObject *ret;
85 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwnames, &path))
88 ret = PyObject_New(RepositoryObject, &Repository_Type);
92 ret->pool = Pool(NULL);
93 if (ret->pool == NULL)
95 Py_BEGIN_ALLOW_THREADS
96 if (!check_error(svn_repos_open(&ret->repos, path, ret->pool))) {
97 apr_pool_destroy(ret->pool);
98 PyEval_RestoreThread(_save);
104 return (PyObject *)ret;
109 RepositoryObject *repos;
114 static PyObject *repos_fs(PyObject *self)
116 RepositoryObject *reposobj = (RepositoryObject *)self;
117 FileSystemObject *ret;
120 fs = svn_repos_fs(reposobj->repos);
123 PyErr_SetString(PyExc_RuntimeError, "Unable to obtain fs handle");
127 ret = PyObject_New(FileSystemObject, &FileSystem_Type);
132 ret->repos = reposobj;
133 ret->pool = reposobj->pool;
136 return (PyObject *)ret;
139 static PyObject *fs_get_uuid(PyObject *self)
141 FileSystemObject *fsobj = (FileSystemObject *)self;
144 apr_pool_t *temp_pool;
146 temp_pool = Pool(NULL);
147 if (temp_pool == NULL)
149 RUN_SVN_WITH_POOL(temp_pool, svn_fs_get_uuid(fsobj->fs, &uuid, temp_pool));
150 ret = PyString_FromString(uuid);
151 apr_pool_destroy(temp_pool);
156 static PyMethodDef fs_methods[] = {
157 { "get_uuid", (PyCFunction)fs_get_uuid, METH_NOARGS, NULL },
161 static void fs_dealloc(PyObject *self)
163 FileSystemObject *fsobj = (FileSystemObject *)self;
165 Py_DECREF(fsobj->repos);
166 apr_pool_destroy(fsobj->pool);
169 PyTypeObject FileSystem_Type = {
170 PyObject_HEAD_INIT(NULL) 0,
171 "repos.FileSystem", /* const char *tp_name; For printing, in format "<module>.<name>" */
172 sizeof(FileSystemObject),
173 0,/* Py_ssize_t tp_basicsize, tp_itemsize; For allocation */
175 /* Methods to implement standard operations */
177 fs_dealloc, /* destructor tp_dealloc; */
178 NULL, /* printfunc tp_print; */
179 NULL, /* getattrfunc tp_getattr; */
180 NULL, /* setattrfunc tp_setattr; */
181 NULL, /* cmpfunc tp_compare; */
182 NULL, /* reprfunc tp_repr; */
184 /* Method suites for standard classes */
186 NULL, /* PyNumberMethods *tp_as_number; */
187 NULL, /* PySequenceMethods *tp_as_sequence; */
188 NULL, /* PyMappingMethods *tp_as_mapping; */
190 /* More standard operations (here for binary compatibility) */
192 NULL, /* hashfunc tp_hash; */
193 NULL, /* ternaryfunc tp_call; */
194 NULL, /* reprfunc tp_str; */
195 NULL, /* getattrofunc tp_getattro; */
196 NULL, /* setattrofunc tp_setattro; */
198 /* Functions to access object as input/output buffer */
199 NULL, /* PyBufferProcs *tp_as_buffer; */
201 /* Flags to define presence of optional/expanded features */
202 0, /* long tp_flags; */
204 NULL, /* const char *tp_doc; Documentation string */
206 /* Assigned meaning in release 2.0 */
207 /* call function for all accessible objects */
208 NULL, /* traverseproc tp_traverse; */
210 /* delete references to contained objects */
211 NULL, /* inquiry tp_clear; */
213 /* Assigned meaning in release 2.1 */
214 /* rich comparisons */
215 NULL, /* richcmpfunc tp_richcompare; */
217 /* weak reference enabler */
218 0, /* Py_ssize_t tp_weaklistoffset; */
220 /* Added in release 2.2 */
222 NULL, /* getiterfunc tp_iter; */
223 NULL, /* iternextfunc tp_iternext; */
225 /* Attribute descriptor and subclassing stuff */
226 fs_methods, /* struct PyMethodDef *tp_methods; */
230 static PyObject *repos_load_fs(PyObject *self, PyObject *args, PyObject *kwargs)
232 const char *parent_dir = "";
233 PyObject *dumpstream, *feedback_stream, *cancel_func = Py_None;
234 bool use_pre_commit_hook = false, use_post_commit_hook = false;
235 char *kwnames[] = { "dumpstream", "feedback_stream", "uuid_action",
236 "parent_dir", "use_pre_commit_hook",
237 "use_post_commit_hook", "cancel_func", NULL };
239 apr_pool_t *temp_pool;
240 RepositoryObject *reposobj = (RepositoryObject *)self;
242 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|sbbO", kwnames,
243 &dumpstream, &feedback_stream, &uuid_action,
244 &parent_dir, &use_pre_commit_hook,
245 &use_post_commit_hook,
249 temp_pool = Pool(NULL);
250 if (temp_pool == NULL)
252 RUN_SVN_WITH_POOL(temp_pool, svn_repos_load_fs2(reposobj->repos,
253 new_py_stream(temp_pool, dumpstream),
254 new_py_stream(temp_pool, feedback_stream),
255 uuid_action, parent_dir, use_pre_commit_hook,
256 use_post_commit_hook, py_cancel_func, (void *)cancel_func,
258 apr_pool_destroy(temp_pool);
262 static PyMethodDef repos_module_methods[] = {
263 { "create", repos_create, METH_VARARGS, NULL },
267 static PyMethodDef repos_methods[] = {
268 { "load_fs", (PyCFunction)repos_load_fs, METH_VARARGS|METH_KEYWORDS, NULL },
269 { "fs", (PyCFunction)repos_fs, METH_NOARGS, NULL },
273 PyTypeObject Repository_Type = {
274 PyObject_HEAD_INIT(NULL) 0,
275 "repos.Repository", /* const char *tp_name; For printing, in format "<module>.<name>" */
276 sizeof(RepositoryObject),
277 0,/* Py_ssize_t tp_basicsize, tp_itemsize; For allocation */
279 /* Methods to implement standard operations */
281 repos_dealloc, /* destructor tp_dealloc; */
282 NULL, /* printfunc tp_print; */
283 NULL, /* getattrfunc tp_getattr; */
284 NULL, /* setattrfunc tp_setattr; */
285 NULL, /* cmpfunc tp_compare; */
286 NULL, /* reprfunc tp_repr; */
288 /* Method suites for standard classes */
290 NULL, /* PyNumberMethods *tp_as_number; */
291 NULL, /* PySequenceMethods *tp_as_sequence; */
292 NULL, /* PyMappingMethods *tp_as_mapping; */
294 /* More standard operations (here for binary compatibility) */
296 NULL, /* hashfunc tp_hash; */
297 NULL, /* ternaryfunc tp_call; */
298 NULL, /* reprfunc tp_str; */
299 NULL, /* getattrofunc tp_getattro; */
300 NULL, /* setattrofunc tp_setattro; */
302 /* Functions to access object as input/output buffer */
303 NULL, /* PyBufferProcs *tp_as_buffer; */
305 /* Flags to define presence of optional/expanded features */
306 0, /* long tp_flags; */
308 NULL, /* const char *tp_doc; Documentation string */
310 /* Assigned meaning in release 2.0 */
311 /* call function for all accessible objects */
312 NULL, /* traverseproc tp_traverse; */
314 /* delete references to contained objects */
315 NULL, /* inquiry tp_clear; */
317 /* Assigned meaning in release 2.1 */
318 /* rich comparisons */
319 NULL, /* richcmpfunc tp_richcompare; */
321 /* weak reference enabler */
322 0, /* Py_ssize_t tp_weaklistoffset; */
324 /* Added in release 2.2 */
326 NULL, /* getiterfunc tp_iter; */
327 NULL, /* iternextfunc tp_iternext; */
329 /* Attribute descriptor and subclassing stuff */
330 repos_methods, /* struct PyMethodDef *tp_methods; */
331 NULL, /* struct PyMemberDef *tp_members; */
332 NULL, /* struct PyGetSetDef *tp_getset; */
333 NULL, /* struct _typeobject *tp_base; */
334 NULL, /* PyObject *tp_dict; */
335 NULL, /* descrgetfunc tp_descr_get; */
336 NULL, /* descrsetfunc tp_descr_set; */
337 0, /* Py_ssize_t tp_dictoffset; */
338 NULL, /* initproc tp_init; */
339 NULL, /* allocfunc tp_alloc; */
340 repos_init, /* newfunc tp_new; */
346 static apr_pool_t *pool;
349 if (PyType_Ready(&Repository_Type) < 0)
352 if (PyType_Ready(&FileSystem_Type) < 0)
360 svn_fs_initialize(pool);
362 mod = Py_InitModule3("repos", repos_module_methods, "Local repository management");
366 PyModule_AddObject(mod, "LOAD_UUID_DEFAULT", PyLong_FromLong(0));
367 PyModule_AddObject(mod, "LOAD_UUID_IGNORE", PyLong_FromLong(1));
368 PyModule_AddObject(mod, "LOAD_UUID_FORCE", PyLong_FromLong(2));
370 PyModule_AddObject(mod, "Repository", (PyObject *)&Repository_Type);
371 Py_INCREF(&Repository_Type);