|
| 1 | +/* |
| 2 | + * The MIT License |
| 3 | + * |
| 4 | + * Copyright (c) 2015 GitHub, Inc |
| 5 | + * |
| 6 | + * Permission is hereby granted, free of charge, to any person obtaining a copy |
| 7 | + * of this software and associated documentation files (the "Software"), to deal |
| 8 | + * in the Software without restriction, including without limitation the rights |
| 9 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 10 | + * copies of the Software, and to permit persons to whom the Software is |
| 11 | + * furnished to do so, subject to the following conditions: |
| 12 | + * |
| 13 | + * The above copyright notice and this permission notice shall be included in |
| 14 | + * all copies or substantial portions of the Software. |
| 15 | + * |
| 16 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 17 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 18 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 19 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 20 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 21 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 22 | + * THE SOFTWARE. |
| 23 | + */ |
| 24 | + |
| 25 | +#include "rugged.h" |
| 26 | + |
| 27 | +extern VALUE rb_mRugged; |
| 28 | +VALUE rb_cRuggedOdb; |
| 29 | + |
| 30 | +/* |
| 31 | + * call-seq: |
| 32 | + * Odb.new() -> odb |
| 33 | + * |
| 34 | + * Create a new object database with no backend. |
| 35 | + * |
| 36 | + * Before the object database can be used, backends |
| 37 | + * needs to be assigned using `Odb#add_backend`. |
| 38 | + */ |
| 39 | +static VALUE rb_git_odb_new(VALUE klass) { |
| 40 | + git_odb *odb; |
| 41 | + rugged_exception_check(git_odb_new(&odb)); |
| 42 | + return Data_Wrap_Struct(klass, NULL, git_odb_free, odb); |
| 43 | +} |
| 44 | + |
| 45 | +/* |
| 46 | + * call-seq: |
| 47 | + * Odb.open(dir) -> odb |
| 48 | + * |
| 49 | + * Create a new object database with the default filesystem |
| 50 | + * backends. |
| 51 | + * |
| 52 | + * `dir` needs to boint to the objects folder to be used |
| 53 | + * by the filesystem backends. |
| 54 | + */ |
| 55 | + static VALUE rb_git_odb_open(VALUE klass, VALUE rb_path) { |
| 56 | + git_odb *odb; |
| 57 | + |
| 58 | + rugged_exception_check(git_odb_open(&odb, StringValueCStr(rb_path))); |
| 59 | + |
| 60 | + return Data_Wrap_Struct(klass, NULL, git_odb_free, odb); |
| 61 | + } |
| 62 | + |
| 63 | +/* |
| 64 | + * call-seq: |
| 65 | + * odb.add_backend(backend) -> odb |
| 66 | + * |
| 67 | + * Set the backend to be used by the reference db. |
| 68 | + * |
| 69 | + * A backend can only be assigned once, and becomes unusable from that |
| 70 | + * point on. Trying to assign a backend a second time will raise an |
| 71 | + * exception. |
| 72 | + */ |
| 73 | +static VALUE rb_git_odb_add_backend(VALUE self, VALUE rb_backend, VALUE rb_priority) |
| 74 | +{ |
| 75 | + git_odb *odb; |
| 76 | + git_odb_backend *backend; |
| 77 | + |
| 78 | + Data_Get_Struct(self, git_odb, odb); |
| 79 | + Data_Get_Struct(rb_backend, git_odb_backend, backend); |
| 80 | + |
| 81 | + if (!backend) |
| 82 | + rb_exc_raise(rb_exc_new_cstr(rb_eRuntimeError, "Can not reuse odb backend instances")); |
| 83 | + |
| 84 | + rugged_exception_check(git_odb_add_backend(odb, backend, NUM2INT(rb_priority))); |
| 85 | + |
| 86 | + // libgit2 has taken ownership of the backend, so we should make sure |
| 87 | + // we don't try to free it. |
| 88 | + ((struct RData *)rb_backend)->data = NULL; |
| 89 | + |
| 90 | + return self; |
| 91 | +} |
| 92 | + |
| 93 | +static int cb_odb__each(const git_oid *id, void *data) |
| 94 | +{ |
| 95 | + char out[40]; |
| 96 | + struct rugged_cb_payload *payload = data; |
| 97 | + |
| 98 | + git_oid_fmt(out, id); |
| 99 | + rb_protect(rb_yield, rb_str_new(out, 40), &payload->exception); |
| 100 | + |
| 101 | + return payload->exception ? GIT_ERROR : GIT_OK; |
| 102 | +} |
| 103 | + |
| 104 | +static VALUE rb_git_odb_each(VALUE self) |
| 105 | +{ |
| 106 | + git_odb *odb; |
| 107 | + int error; |
| 108 | + struct rugged_cb_payload payload = { self, 0 }; |
| 109 | + |
| 110 | + Data_Get_Struct(self, git_odb, odb); |
| 111 | + |
| 112 | + error = git_odb_foreach(odb, &cb_odb__each, &payload); |
| 113 | + |
| 114 | + if (payload.exception) |
| 115 | + rb_jump_tag(payload.exception); |
| 116 | + rugged_exception_check(error); |
| 117 | + |
| 118 | + return Qnil; |
| 119 | +} |
| 120 | + |
| 121 | +void Init_rugged_odb(void) |
| 122 | +{ |
| 123 | + rb_cRuggedOdb = rb_define_class_under(rb_mRugged, "Odb", rb_cObject); |
| 124 | + |
| 125 | + rb_define_singleton_method(rb_cRuggedOdb, "new", rb_git_odb_new, 0); |
| 126 | + rb_define_singleton_method(rb_cRuggedOdb, "open", rb_git_odb_open, 1); |
| 127 | + |
| 128 | + rb_define_method(rb_cRuggedOdb, "add_backend", rb_git_odb_add_backend, 2); |
| 129 | + rb_define_method(rb_cRuggedOdb, "each", rb_git_odb_each, 0); |
| 130 | +} |
0 commit comments