Class: Yerba::Collection

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/yerba/collection.rb,
ext/yerba/yerba.c

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(glob) ⇒ Collection

Returns a new instance of Collection.



7
8
9
# File 'lib/yerba/collection.rb', line 7

def initialize(glob)
  @glob = glob
end

Class Method Details

.find(*args) ⇒ Object

Collection.find(glob, path, condition: nil, select: nil)



969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
# File 'ext/yerba/yerba.c', line 969

static VALUE collection_s_find(int argc, VALUE *argv, VALUE self) {
  (void)self;
  VALUE pattern, path, opts;
  rb_scan_args(argc, argv, "2:", &pattern, &path, &opts);

  const char *condition = NULL;
  const char *select = NULL;

  if (!NIL_P(opts)) {
    VALUE v_condition = rb_hash_aref(opts, ID2SYM(rb_intern("condition")));
    VALUE v_select = rb_hash_aref(opts, ID2SYM(rb_intern("select")));

    if (!NIL_P(v_condition)) condition = StringValueCStr(v_condition);
    if (!NIL_P(v_select)) select = StringValueCStr(v_select);
  }

  YerbaTypedList result = yerba_glob_find(StringValueCStr(pattern), StringValueCStr(path), condition, select);

  if (!result.json) return rb_ary_new();

  VALUE json_string = make_utf8_string(result.json);
  yerba_string_free(result.json);

  return rb_funcall(rb_path2class("JSON"), rb_intern("parse"), 1, json_string);
}

.get(pattern, path) ⇒ Object

Collection.get(glob, selector) → [Yerba::Scalar|Map|Sequence, …]



915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
# File 'ext/yerba/yerba.c', line 915

static VALUE collection_s_get(VALUE self, VALUE pattern, VALUE path) {
  (void) self;

  YerbaTypedList result = yerba_glob_get(StringValueCStr(pattern), StringValueCStr(path));

  if (!result.json) return rb_ary_new();

  VALUE json_string = make_utf8_string(result.json);
  yerba_string_free(result.json);

  VALUE items = rb_funcall(rb_path2class("JSON"), rb_intern("parse"), 1, json_string);
  long length = RARRAY_LEN(items);
  VALUE array = rb_ary_new_capa(length);


  for (long i = 0; i < length; i++) {
    VALUE item = rb_ary_entry(items, i);
    VALUE node_type = rb_hash_aref(item, rb_str_new_cstr("node_type"));
    VALUE file_path = rb_hash_aref(item, rb_str_new_cstr("file_path"));
    VALUE selector = rb_hash_aref(item, rb_str_new_cstr("selector"));
    const char *type_str = NIL_P(node_type) ? "" : StringValueCStr(node_type);

    if (NIL_P(selector)) continue;

    VALUE line = rb_hash_aref(item, rb_str_new_cstr("line"));
    VALUE kwargs = rb_hash_new();

    rb_hash_aset(kwargs, ID2SYM(rb_intern("selector")), selector);
    if (!NIL_P(file_path)) rb_hash_aset(kwargs, ID2SYM(rb_intern("file_path")), file_path);
    if (!NIL_P(line)) rb_hash_aset(kwargs, ID2SYM(rb_intern("line")), line);

    if (strcmp(type_str, "scalar") == 0) {
      VALUE text = rb_hash_aref(item, rb_str_new_cstr("text"));
      if (NIL_P(text)) continue;

      int type_value = NUM2INT(rb_hash_aref(item, rb_str_new_cstr("type")));
      YerbaTypedValue typed_value;
      typed_value.text = (char *)StringValueCStr(text);
      typed_value.value_type = (YerbaValueType)type_value;

      rb_hash_aset(kwargs, ID2SYM(rb_intern("value")), typed_value_to_ruby(typed_value));
      VALUE scalar_args[1] = { kwargs };
      rb_ary_push(array, rb_funcallv_kw(rb_path2class("Yerba::Scalar"), rb_intern("from"), 1, scalar_args, RB_PASS_KEYWORDS));
    } else {
      const char *klass_name = strcmp(type_str, "sequence") == 0 ? "Yerba::Sequence" : "Yerba::Map";
      VALUE node_args[1] = { kwargs };
      rb_ary_push(array, rb_funcallv_kw(rb_path2class(klass_name), rb_intern("from"), 1, node_args, RB_PASS_KEYWORDS));
    }
  }

  return array;
}

Instance Method Details

#apply!Object



58
59
60
61
62
63
64
# File 'lib/yerba/collection.rb', line 58

def apply!
  each do |document|
    yield document

    document.save!
  end
end

#eachObject



11
12
13
# File 'lib/yerba/collection.rb', line 11

def each
  Dir.glob(@glob).each { |path| yield Document.new(path) }
end

#find(path, condition: nil, select: nil) ⇒ Object



19
20
21
# File 'lib/yerba/collection.rb', line 19

def find(path, condition: nil, select: nil)
  self.class.find(@glob, path, condition: condition, select: select)
end

#find_byObject



23
24
25
26
27
28
29
30
31
32
# File 'lib/yerba/collection.rb', line 23

def find_by(...)
  each do |document|
    next unless document.sequence?

    result = document.root.find_by(...)
    return result if result
  end

  nil
end

#get(path) ⇒ Object



15
16
17
# File 'lib/yerba/collection.rb', line 15

def get(path)
  self.class.get(@glob, path)
end

#pluckObject



46
47
48
49
50
51
52
53
54
55
56
# File 'lib/yerba/collection.rb', line 46

def pluck(...)
  results = []

  each do |document|
    next unless document.sequence?

    results.concat(document.root.pluck(...))
  end

  results
end

#whereObject



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/yerba/collection.rb', line 34

def where(...)
  results = []

  each do |document|
    next unless document.sequence?

    results.concat(document.root.where(...).to_a)
  end

  results
end