mongory 0.7.1 → 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/README.md +34 -0
  4. data/Rakefile +28 -9
  5. data/ext/mongory_ext/mongory_ext.c +77 -29
  6. data/lib/mongory/matchers/in_matcher.rb +2 -2
  7. data/lib/mongory/matchers/nin_matcher.rb +2 -2
  8. data/lib/mongory/version.rb +1 -1
  9. data/lib/mongory.rb +4 -2
  10. metadata +7 -62
  11. data/ext/mongory_ext/mongory-core/LICENSE +0 -3
  12. data/ext/mongory_ext/mongory-core/include/mongory-core/foundations/array.h +0 -105
  13. data/ext/mongory_ext/mongory-core/include/mongory-core/foundations/config.h +0 -206
  14. data/ext/mongory_ext/mongory-core/include/mongory-core/foundations/error.h +0 -82
  15. data/ext/mongory_ext/mongory-core/include/mongory-core/foundations/memory_pool.h +0 -95
  16. data/ext/mongory_ext/mongory-core/include/mongory-core/foundations/table.h +0 -108
  17. data/ext/mongory_ext/mongory-core/include/mongory-core/foundations/value.h +0 -175
  18. data/ext/mongory_ext/mongory-core/include/mongory-core/matchers/matcher.h +0 -76
  19. data/ext/mongory_ext/mongory-core/include/mongory-core.h +0 -12
  20. data/ext/mongory_ext/mongory-core/src/foundations/array.c +0 -246
  21. data/ext/mongory_ext/mongory-core/src/foundations/array_private.h +0 -18
  22. data/ext/mongory_ext/mongory-core/src/foundations/config.c +0 -406
  23. data/ext/mongory_ext/mongory-core/src/foundations/config_private.h +0 -30
  24. data/ext/mongory_ext/mongory-core/src/foundations/error.c +0 -30
  25. data/ext/mongory_ext/mongory-core/src/foundations/memory_pool.c +0 -298
  26. data/ext/mongory_ext/mongory-core/src/foundations/string_buffer.c +0 -65
  27. data/ext/mongory_ext/mongory-core/src/foundations/string_buffer.h +0 -49
  28. data/ext/mongory_ext/mongory-core/src/foundations/table.c +0 -458
  29. data/ext/mongory_ext/mongory-core/src/foundations/value.c +0 -459
  30. data/ext/mongory_ext/mongory-core/src/matchers/array_record_matcher.c +0 -309
  31. data/ext/mongory_ext/mongory-core/src/matchers/array_record_matcher.h +0 -47
  32. data/ext/mongory_ext/mongory-core/src/matchers/base_matcher.c +0 -161
  33. data/ext/mongory_ext/mongory-core/src/matchers/base_matcher.h +0 -115
  34. data/ext/mongory_ext/mongory-core/src/matchers/compare_matcher.c +0 -210
  35. data/ext/mongory_ext/mongory-core/src/matchers/compare_matcher.h +0 -83
  36. data/ext/mongory_ext/mongory-core/src/matchers/composite_matcher.c +0 -539
  37. data/ext/mongory_ext/mongory-core/src/matchers/composite_matcher.h +0 -125
  38. data/ext/mongory_ext/mongory-core/src/matchers/existance_matcher.c +0 -144
  39. data/ext/mongory_ext/mongory-core/src/matchers/existance_matcher.h +0 -48
  40. data/ext/mongory_ext/mongory-core/src/matchers/external_matcher.c +0 -121
  41. data/ext/mongory_ext/mongory-core/src/matchers/external_matcher.h +0 -46
  42. data/ext/mongory_ext/mongory-core/src/matchers/inclusion_matcher.c +0 -199
  43. data/ext/mongory_ext/mongory-core/src/matchers/inclusion_matcher.h +0 -46
  44. data/ext/mongory_ext/mongory-core/src/matchers/literal_matcher.c +0 -334
  45. data/ext/mongory_ext/mongory-core/src/matchers/literal_matcher.h +0 -97
  46. data/ext/mongory_ext/mongory-core/src/matchers/matcher.c +0 -198
  47. data/ext/mongory_ext/mongory-core/src/matchers/matcher_explainable.c +0 -107
  48. data/ext/mongory_ext/mongory-core/src/matchers/matcher_explainable.h +0 -50
  49. data/ext/mongory_ext/mongory-core/src/matchers/matcher_traversable.c +0 -55
  50. data/ext/mongory_ext/mongory-core/src/matchers/matcher_traversable.h +0 -23
  51. data/mongory.gemspec +0 -46
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a7ec315565b227d1051af4673da4a5e9eab1c91bb3a578b0bef378d7b829a38
4
- data.tar.gz: 8d85c987c23b6f4066f8ed3fd752b5ba829e830e75eb3859eb7765bcf999278b
3
+ metadata.gz: a9e4755140f8dbd9fe0b675d979760c0bdbc005a391702a60f55615616670ac0
4
+ data.tar.gz: 31584c0ec35cb2ee3e064a7ee0ff20299909ea4ae213bbd7b2bac3bb07cd0a03
5
5
  SHA512:
6
- metadata.gz: 894bf40d954782890b1793b78f2710f370c964b4fec5cd9e3b453dc9d57bcf102081dee5ea1023e3c59dabe5f37ff09ccb2dde2d5585cbd7c0c6e79b6c115904
7
- data.tar.gz: afdc73456ddfec6bce3e326bc1a948293c0e6a844c358cb06130b20678ea9c7c53dc06d2e0e43cfb03cf067a4f3a696938243a5c6af4715efd1a813276300a2e
6
+ metadata.gz: af4d275a953e7dc08a05f2685ea590e5173f114e149699bd9649accbcaba044fa3146597e3aa01accce89f643f6fc030418f86e6c59a21678728b727645349fe
7
+ data.tar.gz: 5d2ac8f618111e083e17393eec30a777da4b74a73a3bbc2643818601880e544738223830f538d3048d7e057bd87118d331a4de30f227a931d245afa102449ad8
data/.rubocop.yml CHANGED
@@ -7,6 +7,8 @@ AllCops:
7
7
  - 'tmp/**/*'
8
8
  - 'examples/**/*'
9
9
  - 'ext/**/*'
10
+ - 'pkg/**/*'
11
+ - 'mongory.gemspec'
10
12
  TargetRubyVersion: 2.6
11
13
 
12
14
  Style/StringLiterals:
data/README.md CHANGED
@@ -51,6 +51,40 @@ Or add to your Gemfile:
51
51
  gem 'mongory'
52
52
  ```
53
53
 
54
+ #### Before installing: install build tools
55
+
56
+ Mongory ships with an optional native extension. Before installing the gem, make sure your system has a C build toolchain (gcc/clang and make). Install the toolchain with the following commands for your platform:
57
+
58
+ - Debian/Ubuntu (including ruby:*-slim base images)
59
+ ```bash
60
+ apt-get update && apt-get install -y build-essential
61
+ ```
62
+
63
+ - Alpine
64
+ ```bash
65
+ apk add --no-cache build-base
66
+ ```
67
+
68
+ - CentOS/RHEL
69
+ ```bash
70
+ yum groupinstall -y "Development Tools"
71
+ ```
72
+
73
+ - Fedora
74
+ ```bash
75
+ dnf groupinstall -y "Development Tools"
76
+ ```
77
+
78
+ - Amazon Linux
79
+ ```bash
80
+ yum groupinstall -y "Development Tools"
81
+ ```
82
+
83
+ - macOS
84
+ ```bash
85
+ xcode-select --install
86
+ ```
87
+
54
88
  #### Rails Generator
55
89
 
56
90
  You can install a starter configuration with:
data/Rakefile CHANGED
@@ -1,22 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rake/extensiontask'
3
4
  require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- require 'rubocop/rake_task'
5
+ begin
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:spec)
9
8
 
10
- RuboCop::RakeTask.new
9
+ require 'rubocop/rake_task'
10
+ RuboCop::RakeTask.new
11
+ rescue LoadError
12
+ # When rspec or rubocop is not installed in the CI cross-build environment, the definition of the test task is skipped
13
+ end
11
14
 
12
15
  # Add support for rake-compiler if available
13
16
  begin
14
- require 'rake/extensiontask'
17
+ ENV['RUBY_CC_VERSION'] ||= '2.6.0:2.7.0:3.0.0:3.1.0:3.2.0:3.3.0'
18
+
19
+ spec = Gem::Specification.load('mongory.gemspec')
15
20
 
16
- Rake::ExtensionTask.new('mongory_ext') do |ext|
17
- ext.lib_dir = 'ext/mongory_ext'
21
+ Rake::ExtensionTask.new('mongory_ext', spec) do |ext|
22
+ abi = RUBY_VERSION.split('.').first(2).join('.')
23
+ ext.lib_dir = "lib/core/#{abi}"
18
24
  ext.ext_dir = 'ext/mongory_ext'
19
25
  ext.source_pattern = '*.c'
26
+ ext.gem_spec = spec
27
+ ext.cross_compile = true
28
+ ext.cross_platform = [
29
+ 'x86_64-linux',
30
+ 'aarch64-linux',
31
+ 'x86_64-darwin',
32
+ 'arm64-darwin',
33
+ # 'arm64-mingw-ucrt', # TODO: add this when we have a mingw-ucrt rake-compiler-dock image
34
+ 'x64-mingw32',
35
+ 'x64-mingw-ucrt',
36
+ 'x86_64-linux-musl',
37
+ 'aarch64-linux-musl'
38
+ ]
20
39
  end
21
40
 
22
41
  # Add tasks for building with submodule
@@ -71,6 +71,7 @@ static VALUE cache_fetch_string(ruby_mongory_matcher_t *owner, const char *key);
71
71
  static VALUE cache_fetch_symbol(ruby_mongory_matcher_t *owner, const char *key);
72
72
  static ruby_mongory_memory_pool_t *ruby_mongory_memory_pool_new();
73
73
  static void rb_mongory_matcher_parse_argv(ruby_mongory_matcher_t *wrapper, int argc, VALUE *argv);
74
+ static bool mongory_error_handling(mongory_memory_pool *pool, char *error_message);
74
75
 
75
76
  static const rb_data_type_t ruby_mongory_matcher_type = {
76
77
  .wrap_struct_name = "mongory_matcher",
@@ -102,8 +103,7 @@ static VALUE ruby_mongory_matcher_new(int argc, VALUE *argv, VALUE class) {
102
103
  rb_mongory_matcher_parse_argv(wrapper, argc, argv);
103
104
 
104
105
  mongory_matcher *matcher = mongory_matcher_new(wrapper->pool, wrapper->condition, wrapper->ctx);
105
- if (wrapper->pool->error) {
106
- rb_raise(eMongoryTypeError, "Failed to create matcher: %s", wrapper->pool->error->message);
106
+ if (mongory_error_handling(wrapper->pool, "Failed to create matcher")) {
107
107
  return Qnil;
108
108
  }
109
109
 
@@ -137,14 +137,13 @@ static VALUE ruby_mongory_matcher_match(VALUE self, VALUE data) {
137
137
  ruby_mongory_matcher_t *wrapper;
138
138
  TypedData_Get_Struct(self, ruby_mongory_matcher_t, &ruby_mongory_matcher_type, wrapper);
139
139
  mongory_value *data_value;
140
- if (wrapper->trace_enabled) {
141
- data_value = ruby_to_mongory_value_deep(wrapper->scratch_pool, data);
142
- } else {
143
- data_value = ruby_to_mongory_value_shallow(wrapper->scratch_pool, data);
140
+ data_value = ruby_to_mongory_value_shallow(wrapper->scratch_pool, data);
141
+ if (mongory_error_handling(wrapper->scratch_pool, "Match failed")) {
142
+ return Qnil;
144
143
  }
145
144
  bool result = mongory_matcher_match(wrapper->matcher, data_value);
146
145
  if (!wrapper->trace_enabled) {
147
- wrapper->scratch_pool->reset(wrapper->scratch_pool->ctx);
146
+ wrapper->scratch_pool->reset(wrapper->scratch_pool);
148
147
  }
149
148
  return result ? Qtrue : Qfalse;
150
149
  }
@@ -154,7 +153,10 @@ static VALUE ruby_mongory_matcher_explain(VALUE self) {
154
153
  ruby_mongory_matcher_t *wrapper;
155
154
  TypedData_Get_Struct(self, ruby_mongory_matcher_t, &ruby_mongory_matcher_type, wrapper);
156
155
  mongory_matcher_explain(wrapper->matcher, wrapper->scratch_pool);
157
- wrapper->scratch_pool->reset(wrapper->scratch_pool->ctx);
156
+ if (mongory_error_handling(wrapper->scratch_pool, "Explain failed")) {
157
+ return Qnil;
158
+ }
159
+ wrapper->scratch_pool->reset(wrapper->scratch_pool);
158
160
  return Qnil;
159
161
  }
160
162
 
@@ -162,9 +164,12 @@ static VALUE ruby_mongory_matcher_explain(VALUE self) {
162
164
  static VALUE ruby_mongory_matcher_trace(VALUE self, VALUE data) {
163
165
  ruby_mongory_matcher_t *wrapper;
164
166
  TypedData_Get_Struct(self, ruby_mongory_matcher_t, &ruby_mongory_matcher_type, wrapper);
165
- mongory_value *data_value = ruby_to_mongory_value_deep(wrapper->scratch_pool, data);
167
+ mongory_value *data_value = ruby_to_mongory_value_shallow(wrapper->scratch_pool, data);
168
+ if (mongory_error_handling(wrapper->scratch_pool, "Trace failed")) {
169
+ return Qnil;
170
+ }
166
171
  bool matched = mongory_matcher_trace(wrapper->matcher, data_value);
167
- wrapper->scratch_pool->reset(wrapper->scratch_pool->ctx);
172
+ wrapper->scratch_pool->reset(wrapper->scratch_pool);
168
173
  return matched ? Qtrue : Qfalse;
169
174
  }
170
175
 
@@ -173,6 +178,9 @@ static VALUE ruby_mongory_matcher_enable_trace(VALUE self) {
173
178
  ruby_mongory_matcher_t *wrapper;
174
179
  TypedData_Get_Struct(self, ruby_mongory_matcher_t, &ruby_mongory_matcher_type, wrapper);
175
180
  mongory_matcher_enable_trace(wrapper->matcher, wrapper->scratch_pool);
181
+ if (mongory_error_handling(wrapper->scratch_pool, "Enable trace failed")) {
182
+ return Qnil;
183
+ }
176
184
  wrapper->trace_enabled = true;
177
185
  return Qnil;
178
186
  }
@@ -182,7 +190,10 @@ static VALUE ruby_mongory_matcher_disable_trace(VALUE self) {
182
190
  ruby_mongory_matcher_t *wrapper;
183
191
  TypedData_Get_Struct(self, ruby_mongory_matcher_t, &ruby_mongory_matcher_type, wrapper);
184
192
  mongory_matcher_disable_trace(wrapper->matcher);
185
- wrapper->scratch_pool->reset(wrapper->scratch_pool->ctx);
193
+ if (mongory_error_handling(wrapper->scratch_pool, "Disable trace failed")) {
194
+ return Qnil;
195
+ }
196
+ wrapper->scratch_pool->reset(wrapper->scratch_pool);
186
197
  wrapper->trace_enabled = false;
187
198
  return Qnil;
188
199
  }
@@ -192,6 +203,7 @@ static VALUE ruby_mongory_matcher_print_trace(VALUE self) {
192
203
  ruby_mongory_matcher_t *wrapper;
193
204
  TypedData_Get_Struct(self, ruby_mongory_matcher_t, &ruby_mongory_matcher_type, wrapper);
194
205
  mongory_matcher_print_trace(wrapper->matcher);
206
+ mongory_error_handling(wrapper->scratch_pool, "Print trace failed");
195
207
  return Qnil;
196
208
  }
197
209
 
@@ -206,7 +218,14 @@ static VALUE ruby_mongory_matcher_condition(VALUE self) {
206
218
  static VALUE ruby_mongory_matcher_context(VALUE self) {
207
219
  ruby_mongory_matcher_t *wrapper;
208
220
  TypedData_Get_Struct(self, ruby_mongory_matcher_t, &ruby_mongory_matcher_type, wrapper);
209
- return wrapper->ctx == NULL ? Qnil : wrapper->ctx;
221
+ return wrapper->ctx ? wrapper->ctx : Qnil;
222
+ }
223
+
224
+ // Mongory::CMatcher.trace_result_colorful=(colorful)
225
+ static VALUE ruby_mongory_matcher_trace_result_colorful(VALUE self, VALUE colorful) {
226
+ (void)self;
227
+ mongory_matcher_trace_result_colorful_set(RTEST(colorful));
228
+ return Qnil;
210
229
  }
211
230
 
212
231
  /**
@@ -255,6 +274,15 @@ static void ruby_mongory_matcher_mark(void *ptr) {
255
274
  * Helper functions for Ruby/C conversion
256
275
  */
257
276
 
277
+ // Helper function to convert Ruby value to C string
278
+ static char *ruby_mongory_value_to_cstr(mongory_value *value, mongory_memory_pool *pool) {
279
+ (void)pool;
280
+ VALUE rb_value = (VALUE)value->origin;
281
+ VALUE rb_str = rb_funcall(rb_value, rb_intern("inspect"), 0);
282
+ return StringValueCStr(rb_str);
283
+ }
284
+
285
+ // Helper function for primitive conversion of Ruby value to mongory_value
258
286
  static mongory_value *ruby_to_mongory_value_primitive(mongory_memory_pool *pool, VALUE rb_value) {
259
287
  mongory_value *mg_value = NULL;
260
288
  switch (TYPE(rb_value)) {
@@ -333,6 +361,7 @@ mongory_value *ruby_to_mongory_value_shallow(mongory_memory_pool *pool, VALUE rb
333
361
  return ruby_to_mongory_value_shallow_rec(pool, rb_value, false);
334
362
  }
335
363
 
364
+ // Helper function for deep conversion of hash values
336
365
  static int hash_foreach_deep_convert_cb(VALUE key, VALUE val, VALUE ptr) {
337
366
  hash_conv_ctx *ctx = (hash_conv_ctx *)ptr;
338
367
  ruby_mongory_memory_pool_t *rb_pool = (ruby_mongory_memory_pool_t *)ctx->pool;
@@ -354,6 +383,7 @@ static int hash_foreach_deep_convert_cb(VALUE key, VALUE val, VALUE ptr) {
354
383
  return ST_CONTINUE;
355
384
  }
356
385
 
386
+ // Deep conversion: Convert Ruby value to mongory_value (fully materialize arrays/tables)
357
387
  static mongory_value *ruby_to_mongory_value_deep_rec(mongory_memory_pool *pool, VALUE rb_value, bool converted) {
358
388
  mongory_value *mg_value = ruby_to_mongory_value_primitive(pool, rb_value);
359
389
  if (mg_value) {
@@ -395,10 +425,12 @@ static mongory_value *ruby_to_mongory_value_deep_rec(mongory_memory_pool *pool,
395
425
  return mg_value;
396
426
  }
397
427
 
428
+ // Deep conversion: Convert Ruby value to mongory_value (fully materialize arrays/tables)
398
429
  mongory_value *ruby_to_mongory_value_deep(mongory_memory_pool *pool, VALUE rb_value) {
399
430
  return ruby_to_mongory_value_deep_rec(pool, rb_value, false);
400
431
  }
401
432
 
433
+ // Get value from Ruby hash via mongory_table
402
434
  mongory_value *ruby_mongory_table_get(mongory_table *self, char *key) {
403
435
  ruby_mongory_table_t *table = (ruby_mongory_table_t *)self;
404
436
  VALUE rb_hash = table->rb_hash;
@@ -420,6 +452,7 @@ mongory_value *ruby_mongory_table_get(mongory_table *self, char *key) {
420
452
  return ruby_to_mongory_value_shallow(table->base.pool, rb_value);
421
453
  }
422
454
 
455
+ // Shallow conversion: Wrap Ruby hash as mongory_table
423
456
  mongory_value *ruby_mongory_table_wrap(mongory_memory_pool *pool, VALUE rb_hash) {
424
457
  ruby_mongory_table_t *table = MG_ALLOC_PTR(pool, ruby_mongory_table_t);
425
458
  ruby_mongory_memory_pool_t *rb_pool = (ruby_mongory_memory_pool_t *)pool;
@@ -428,9 +461,13 @@ mongory_value *ruby_mongory_table_wrap(mongory_memory_pool *pool, VALUE rb_hash)
428
461
  table->rb_hash = rb_hash;
429
462
  table->base.count = RHASH_SIZE(rb_hash);
430
463
  table->owner = rb_pool->owner;
431
- return mongory_value_wrap_t(pool, &table->base);
464
+ mongory_value *mg_value = mongory_value_wrap_t(pool, &table->base);
465
+ mg_value->origin = (void *)rb_hash;
466
+ mg_value->to_str = ruby_mongory_value_to_cstr;
467
+ return mg_value;
432
468
  }
433
469
 
470
+ // Get value from Ruby array via mongory_array
434
471
  static mongory_value *ruby_mongory_array_get(mongory_array *self, size_t index) {
435
472
  ruby_mongory_array_t *array = (ruby_mongory_array_t *)self;
436
473
  VALUE rb_array = array->rb_array;
@@ -441,32 +478,22 @@ static mongory_value *ruby_mongory_array_get(mongory_array *self, size_t index)
441
478
  return ruby_to_mongory_value_shallow(self->pool, rb_value);
442
479
  }
443
480
 
444
- static bool ruby_mongory_array_each(mongory_array *self, void *acc, mongory_array_callback_func func) {
445
- ruby_mongory_array_t *array = (ruby_mongory_array_t *)self;
446
- VALUE rb_array = array->rb_array;
447
- for (long i = 0; i < RARRAY_LEN(rb_array); i++) {
448
- VALUE rb_value = rb_ary_entry(rb_array, i);
449
- mongory_value *cval = ruby_to_mongory_value_shallow(self->pool, rb_value);
450
- if (!func(cval, acc)) {
451
- return false;
452
- }
453
- }
454
- return true;
455
- }
456
-
481
+ // Shallow conversion: Wrap Ruby array as mongory_array
457
482
  mongory_value *ruby_mongory_array_wrap(mongory_memory_pool *pool, VALUE rb_array) {
458
483
  ruby_mongory_array_t *array = MG_ALLOC_PTR(pool, ruby_mongory_array_t);
459
484
  ruby_mongory_memory_pool_t *rb_pool = (ruby_mongory_memory_pool_t *)pool;
460
485
  array->base.pool = pool;
461
486
  array->base.get = ruby_mongory_array_get;
462
- array->base.each = ruby_mongory_array_each;
463
487
  array->rb_array = rb_array;
464
488
  array->base.count = RARRAY_LEN(rb_array);
465
489
  array->owner = rb_pool->owner;
466
- return mongory_value_wrap_a(pool, &array->base);
490
+ mongory_value *mg_value = mongory_value_wrap_a(pool, &array->base);
491
+ mg_value->origin = (void *)rb_array;
492
+ mg_value->to_str = ruby_mongory_value_to_cstr;
493
+ return mg_value;
467
494
  }
468
495
 
469
- // Convert mongory_value to Ruby value
496
+ // Convert mongory_value to Ruby value (returns the original Ruby value where binding in below conversion is needed)
470
497
  void *mongory_value_to_ruby(mongory_memory_pool *pool, mongory_value *value) {
471
498
  (void)pool;
472
499
  if (!value)
@@ -487,12 +514,14 @@ static VALUE cache_fetch_string(ruby_mongory_matcher_t *owner, const char *key)
487
514
  return s;
488
515
  }
489
516
 
517
+ // Helper function to convert char* key to Ruby symbol
490
518
  static inline VALUE char_key_to_symbol(const char *key, rb_encoding *enc) {
491
519
  ID id = rb_check_id_cstr(key, (long)strlen(key), enc);
492
520
  if (!id) id = rb_intern3(key, (long)strlen(key), enc);
493
521
  return ID2SYM(id);
494
522
  }
495
523
 
524
+ // Cache helper for Ruby symbol keys
496
525
  static VALUE cache_fetch_symbol(ruby_mongory_matcher_t *owner, const char *key) {
497
526
  rb_encoding *enc = rb_utf8_encoding();
498
527
  if (!owner || !owner->symbol_map) {
@@ -535,6 +564,7 @@ static bool ruby_regex_match_adapter(mongory_memory_pool *pool, mongory_value *p
535
564
  return RTEST(matched);
536
565
  }
537
566
 
567
+ // Regex adapter bridging to Ruby's Regexp
538
568
  static char *ruby_regex_stringify_adapter(mongory_memory_pool *pool, mongory_value *pattern) {
539
569
  (void)pool;
540
570
  if (pattern->type != MONGORY_TYPE_REGEX) {
@@ -545,6 +575,7 @@ static char *ruby_regex_stringify_adapter(mongory_memory_pool *pool, mongory_val
545
575
  return StringValueCStr(rb_str);
546
576
  }
547
577
 
578
+ // Custom matcher adapter bridging to Ruby's custom matcher
548
579
  static mongory_matcher_custom_context *ruby_custom_matcher_build(char *key, mongory_value *condition, void *ctx) {
549
580
  mongory_memory_pool *pool = condition->pool;
550
581
  ruby_mongory_memory_pool_t *rb_pool = (ruby_mongory_memory_pool_t *)pool;
@@ -579,17 +610,30 @@ static mongory_matcher_custom_context *ruby_custom_matcher_build(char *key, mong
579
610
  return return_ctx;
580
611
  }
581
612
 
613
+ // Custom matcher adapter bridging to Ruby's custom matcher
582
614
  static bool ruby_custom_matcher_match(void *ruby_matcher, mongory_value *value) {
583
615
  VALUE matcher = (VALUE)ruby_matcher;
584
616
  VALUE match_result = rb_funcall(matcher, rb_intern("match?"), 1, value->origin);
585
617
  return RTEST(match_result);
586
618
  }
587
619
 
620
+ // Custom matcher adapter bridging to Ruby's custom matcher
588
621
  static bool ruby_custom_matcher_lookup(char *key) {
589
622
  VALUE matcher_class = rb_funcall(mMongoryMatchers, rb_intern("lookup"), 1, rb_str_new_cstr(key));
590
623
  return RTEST(matcher_class);
591
624
  }
592
625
 
626
+ // Error handling for mongory_memory_pool
627
+ static bool mongory_error_handling(mongory_memory_pool *pool, char *error_message) {
628
+ if (pool->error) {
629
+ rb_raise(eMongoryTypeError, "%s: %s", error_message, pool->error->message);
630
+ pool->error = NULL;
631
+ pool->reset(pool);
632
+ return true;
633
+ }
634
+ return false;
635
+ }
636
+
593
637
  /**
594
638
  * Extension initialization
595
639
  */
@@ -613,6 +657,7 @@ void Init_mongory_ext(void) {
613
657
 
614
658
  // Define Matcher methods
615
659
  rb_define_singleton_method(cMongoryMatcher, "new", ruby_mongory_matcher_new, -1);
660
+ rb_define_singleton_method(cMongoryMatcher, "trace_result_colorful=", ruby_mongory_matcher_trace_result_colorful, 1);
616
661
  rb_define_method(cMongoryMatcher, "match?", ruby_mongory_matcher_match, 1);
617
662
  rb_define_method(cMongoryMatcher, "explain", ruby_mongory_matcher_explain, 0);
618
663
  rb_define_method(cMongoryMatcher, "condition", ruby_mongory_matcher_condition, 0);
@@ -621,13 +666,16 @@ void Init_mongory_ext(void) {
621
666
  rb_define_method(cMongoryMatcher, "enable_trace", ruby_mongory_matcher_enable_trace, 0);
622
667
  rb_define_method(cMongoryMatcher, "disable_trace", ruby_mongory_matcher_disable_trace, 0);
623
668
  rb_define_method(cMongoryMatcher, "print_trace", ruby_mongory_matcher_print_trace, 0);
669
+
624
670
  // Set regex adapter to use Ruby's Regexp
625
671
  mongory_regex_func_set(ruby_regex_match_adapter);
626
672
  mongory_regex_stringify_func_set(ruby_regex_stringify_adapter);
673
+
627
674
  // Set value converter functions
628
675
  mongory_value_converter_deep_convert_set(ruby_to_mongory_value_deep);
629
676
  mongory_value_converter_shallow_convert_set(ruby_to_mongory_value_shallow);
630
677
  mongory_value_converter_recover_set(mongory_value_to_ruby);
678
+
631
679
  // Set custom matcher adapter
632
680
  mongory_custom_matcher_match_func_set(ruby_custom_matcher_match);
633
681
  mongory_custom_matcher_build_func_set(ruby_custom_matcher_build);
@@ -24,12 +24,12 @@ module Mongory
24
24
  #
25
25
  # @see AbstractMatcher
26
26
  class InMatcher < AbstractMatcher
27
- def self.build(condition, *args)
27
+ def self.build(condition, context: Context.new)
28
28
  return super unless condition.is_a?(Range)
29
29
 
30
30
  end_op = condition.exclude_end? ? '$lt' : '$lte'
31
31
  head, tail = [condition.first, condition.last].sort
32
- AndMatcher.build([{ '$gte' => head }, { end_op => tail }], *args)
32
+ AndMatcher.build([{ '$gte' => head }, { end_op => tail }], context: context)
33
33
  end
34
34
 
35
35
  # Creates a raw Proc that performs the in-matching operation.
@@ -24,12 +24,12 @@ module Mongory
24
24
  #
25
25
  # @see AbstractMatcher
26
26
  class NinMatcher < AbstractMatcher
27
- def self.build(condition, *args)
27
+ def self.build(condition, context: Context.new)
28
28
  return super unless condition.is_a?(Range)
29
29
 
30
30
  end_op = condition.exclude_end? ? '$gte' : '$gt'
31
31
  head, tail = [condition.first, condition.last].sort
32
- OrMatcher.build([{ '$lt' => head }, { end_op => tail }], *args)
32
+ OrMatcher.build([{ '$lt' => head }, { end_op => tail }], context: context)
33
33
  end
34
34
 
35
35
  # Creates a raw Proc that performs the not-in matching operation.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mongory
4
- VERSION = '0.7.1'
4
+ VERSION = '0.7.5'
5
5
  end
data/lib/mongory.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'time'
4
4
  require 'date'
5
+ require 'set'
5
6
  require 'singleton'
6
7
  require_relative 'mongory/version'
7
8
  require_relative 'mongory/utils'
@@ -116,8 +117,9 @@ module Mongory
116
117
  end
117
118
 
118
119
  begin
119
- require_relative '../ext/mongory_ext/mongory_ext'
120
+ abi = RUBY_VERSION.split('.').first(2).join('.')
121
+ require "core/#{abi}/mongory_ext"
120
122
  require_relative 'mongory/c_query_builder'
121
123
  rescue LoadError
122
- Mongory.debugger.warn('Mongory::CQueryBuilder is disabled because mongory_ext is not loaded')
124
+ warn('Mongory::CQueryBuilder is disabled because mongory_ext is not loaded')
123
125
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - koten0224
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-08-17 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: rake-compiler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.0'
11
+ date: 2025-08-26 00:00:00.000000000 Z
12
+ dependencies: []
27
13
  description: A Mongo-like in-memory query DSL for Ruby
28
14
  email:
29
15
  - koten0224@gmail.com
@@ -50,46 +36,6 @@ files:
50
36
  - examples/benchmark-rails.rb
51
37
  - examples/benchmark.rb
52
38
  - ext/mongory_ext/extconf.rb
53
- - ext/mongory_ext/mongory-core/LICENSE
54
- - ext/mongory_ext/mongory-core/include/mongory-core.h
55
- - ext/mongory_ext/mongory-core/include/mongory-core/foundations/array.h
56
- - ext/mongory_ext/mongory-core/include/mongory-core/foundations/config.h
57
- - ext/mongory_ext/mongory-core/include/mongory-core/foundations/error.h
58
- - ext/mongory_ext/mongory-core/include/mongory-core/foundations/memory_pool.h
59
- - ext/mongory_ext/mongory-core/include/mongory-core/foundations/table.h
60
- - ext/mongory_ext/mongory-core/include/mongory-core/foundations/value.h
61
- - ext/mongory_ext/mongory-core/include/mongory-core/matchers/matcher.h
62
- - ext/mongory_ext/mongory-core/src/foundations/array.c
63
- - ext/mongory_ext/mongory-core/src/foundations/array_private.h
64
- - ext/mongory_ext/mongory-core/src/foundations/config.c
65
- - ext/mongory_ext/mongory-core/src/foundations/config_private.h
66
- - ext/mongory_ext/mongory-core/src/foundations/error.c
67
- - ext/mongory_ext/mongory-core/src/foundations/memory_pool.c
68
- - ext/mongory_ext/mongory-core/src/foundations/string_buffer.c
69
- - ext/mongory_ext/mongory-core/src/foundations/string_buffer.h
70
- - ext/mongory_ext/mongory-core/src/foundations/table.c
71
- - ext/mongory_ext/mongory-core/src/foundations/value.c
72
- - ext/mongory_ext/mongory-core/src/matchers/array_record_matcher.c
73
- - ext/mongory_ext/mongory-core/src/matchers/array_record_matcher.h
74
- - ext/mongory_ext/mongory-core/src/matchers/base_matcher.c
75
- - ext/mongory_ext/mongory-core/src/matchers/base_matcher.h
76
- - ext/mongory_ext/mongory-core/src/matchers/compare_matcher.c
77
- - ext/mongory_ext/mongory-core/src/matchers/compare_matcher.h
78
- - ext/mongory_ext/mongory-core/src/matchers/composite_matcher.c
79
- - ext/mongory_ext/mongory-core/src/matchers/composite_matcher.h
80
- - ext/mongory_ext/mongory-core/src/matchers/existance_matcher.c
81
- - ext/mongory_ext/mongory-core/src/matchers/existance_matcher.h
82
- - ext/mongory_ext/mongory-core/src/matchers/external_matcher.c
83
- - ext/mongory_ext/mongory-core/src/matchers/external_matcher.h
84
- - ext/mongory_ext/mongory-core/src/matchers/inclusion_matcher.c
85
- - ext/mongory_ext/mongory-core/src/matchers/inclusion_matcher.h
86
- - ext/mongory_ext/mongory-core/src/matchers/literal_matcher.c
87
- - ext/mongory_ext/mongory-core/src/matchers/literal_matcher.h
88
- - ext/mongory_ext/mongory-core/src/matchers/matcher.c
89
- - ext/mongory_ext/mongory-core/src/matchers/matcher_explainable.c
90
- - ext/mongory_ext/mongory-core/src/matchers/matcher_explainable.h
91
- - ext/mongory_ext/mongory-core/src/matchers/matcher_traversable.c
92
- - ext/mongory_ext/mongory-core/src/matchers/matcher_traversable.h
93
39
  - ext/mongory_ext/mongory_ext.c
94
40
  - lib/generators/mongory/install/install_generator.rb
95
41
  - lib/generators/mongory/install/templates/initializer.rb.erb
@@ -140,7 +86,6 @@ files:
140
86
  - lib/mongory/utils/rails_patch.rb
141
87
  - lib/mongory/utils/singleton_builder.rb
142
88
  - lib/mongory/version.rb
143
- - mongory.gemspec
144
89
  - scripts/build_with_core.sh
145
90
  - sig/mongory.rbs
146
91
  homepage: https://mongoryhq.github.io/mongory-rb/
@@ -152,7 +97,7 @@ metadata:
152
97
  homepage_uri: https://mongoryhq.github.io/mongory-rb/
153
98
  source_code_uri: https://github.com/mongoryhq/mongory-rb
154
99
  changelog_uri: https://github.com/mongoryhq/mongory-rb/blob/main/CHANGELOG.md
155
- post_install_message:
100
+ post_install_message:
156
101
  rdoc_options: []
157
102
  require_paths:
158
103
  - lib
@@ -167,8 +112,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
112
  - !ruby/object:Gem::Version
168
113
  version: '0'
169
114
  requirements: []
170
- rubygems_version: 3.1.6
171
- signing_key:
115
+ rubygems_version: 3.4.19
116
+ signing_key:
172
117
  specification_version: 4
173
118
  summary: MongoDB-like in-memory query DSL for Ruby
174
119
  test_files: []
@@ -1,3 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c)