mongory 0.7.3-aarch64-linux-musl

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.

Potentially problematic release.


This version of mongory might be problematic. Click here for more details.

Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +88 -0
  4. data/.yardopts +7 -0
  5. data/CHANGELOG.md +364 -0
  6. data/CODE_OF_CONDUCT.md +84 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +488 -0
  9. data/Rakefile +107 -0
  10. data/SUBMODULE_INTEGRATION.md +325 -0
  11. data/docs/advanced_usage.md +40 -0
  12. data/docs/clang_bridge.md +69 -0
  13. data/docs/field_names.md +30 -0
  14. data/docs/migration.md +30 -0
  15. data/docs/performance.md +61 -0
  16. data/examples/README.md +41 -0
  17. data/examples/benchmark-rails.rb +52 -0
  18. data/examples/benchmark.rb +184 -0
  19. data/ext/mongory_ext/extconf.rb +91 -0
  20. data/ext/mongory_ext/mongory-core/include/mongory-core/foundations/array.h +122 -0
  21. data/ext/mongory_ext/mongory-core/include/mongory-core/foundations/config.h +161 -0
  22. data/ext/mongory_ext/mongory-core/include/mongory-core/foundations/error.h +79 -0
  23. data/ext/mongory_ext/mongory-core/include/mongory-core/foundations/memory_pool.h +95 -0
  24. data/ext/mongory_ext/mongory-core/include/mongory-core/foundations/table.h +127 -0
  25. data/ext/mongory_ext/mongory-core/include/mongory-core/foundations/value.h +175 -0
  26. data/ext/mongory_ext/mongory-core/include/mongory-core/matchers/matcher.h +76 -0
  27. data/ext/mongory_ext/mongory-core/include/mongory-core.h +12 -0
  28. data/ext/mongory_ext/mongory-core/src/foundations/array.c +287 -0
  29. data/ext/mongory_ext/mongory-core/src/foundations/array_private.h +19 -0
  30. data/ext/mongory_ext/mongory-core/src/foundations/config.c +270 -0
  31. data/ext/mongory_ext/mongory-core/src/foundations/config_private.h +48 -0
  32. data/ext/mongory_ext/mongory-core/src/foundations/error.c +38 -0
  33. data/ext/mongory_ext/mongory-core/src/foundations/memory_pool.c +298 -0
  34. data/ext/mongory_ext/mongory-core/src/foundations/string_buffer.c +65 -0
  35. data/ext/mongory_ext/mongory-core/src/foundations/string_buffer.h +49 -0
  36. data/ext/mongory_ext/mongory-core/src/foundations/table.c +498 -0
  37. data/ext/mongory_ext/mongory-core/src/foundations/utils.c +210 -0
  38. data/ext/mongory_ext/mongory-core/src/foundations/utils.h +70 -0
  39. data/ext/mongory_ext/mongory-core/src/foundations/value.c +500 -0
  40. data/ext/mongory_ext/mongory-core/src/matchers/array_record_matcher.c +164 -0
  41. data/ext/mongory_ext/mongory-core/src/matchers/array_record_matcher.h +47 -0
  42. data/ext/mongory_ext/mongory-core/src/matchers/base_matcher.c +122 -0
  43. data/ext/mongory_ext/mongory-core/src/matchers/base_matcher.h +100 -0
  44. data/ext/mongory_ext/mongory-core/src/matchers/compare_matcher.c +217 -0
  45. data/ext/mongory_ext/mongory-core/src/matchers/compare_matcher.h +83 -0
  46. data/ext/mongory_ext/mongory-core/src/matchers/composite_matcher.c +573 -0
  47. data/ext/mongory_ext/mongory-core/src/matchers/composite_matcher.h +125 -0
  48. data/ext/mongory_ext/mongory-core/src/matchers/existance_matcher.c +147 -0
  49. data/ext/mongory_ext/mongory-core/src/matchers/existance_matcher.h +48 -0
  50. data/ext/mongory_ext/mongory-core/src/matchers/external_matcher.c +124 -0
  51. data/ext/mongory_ext/mongory-core/src/matchers/external_matcher.h +46 -0
  52. data/ext/mongory_ext/mongory-core/src/matchers/inclusion_matcher.c +126 -0
  53. data/ext/mongory_ext/mongory-core/src/matchers/inclusion_matcher.h +46 -0
  54. data/ext/mongory_ext/mongory-core/src/matchers/literal_matcher.c +314 -0
  55. data/ext/mongory_ext/mongory-core/src/matchers/literal_matcher.h +97 -0
  56. data/ext/mongory_ext/mongory-core/src/matchers/matcher.c +252 -0
  57. data/ext/mongory_ext/mongory-core/src/matchers/matcher_explainable.c +79 -0
  58. data/ext/mongory_ext/mongory-core/src/matchers/matcher_explainable.h +23 -0
  59. data/ext/mongory_ext/mongory-core/src/matchers/matcher_traversable.c +60 -0
  60. data/ext/mongory_ext/mongory-core/src/matchers/matcher_traversable.h +23 -0
  61. data/ext/mongory_ext/mongory_ext.c +683 -0
  62. data/lib/generators/mongory/install/install_generator.rb +42 -0
  63. data/lib/generators/mongory/install/templates/initializer.rb.erb +83 -0
  64. data/lib/generators/mongory/matcher/matcher_generator.rb +56 -0
  65. data/lib/generators/mongory/matcher/templates/matcher.rb.erb +92 -0
  66. data/lib/generators/mongory/matcher/templates/matcher_spec.rb.erb +17 -0
  67. data/lib/mongory/c_query_builder.rb +44 -0
  68. data/lib/mongory/converters/abstract_converter.rb +111 -0
  69. data/lib/mongory/converters/condition_converter.rb +64 -0
  70. data/lib/mongory/converters/converted.rb +81 -0
  71. data/lib/mongory/converters/data_converter.rb +37 -0
  72. data/lib/mongory/converters/key_converter.rb +87 -0
  73. data/lib/mongory/converters/value_converter.rb +52 -0
  74. data/lib/mongory/converters.rb +8 -0
  75. data/lib/mongory/matchers/abstract_matcher.rb +219 -0
  76. data/lib/mongory/matchers/abstract_multi_matcher.rb +124 -0
  77. data/lib/mongory/matchers/and_matcher.rb +72 -0
  78. data/lib/mongory/matchers/array_record_matcher.rb +93 -0
  79. data/lib/mongory/matchers/elem_match_matcher.rb +55 -0
  80. data/lib/mongory/matchers/eq_matcher.rb +46 -0
  81. data/lib/mongory/matchers/every_matcher.rb +56 -0
  82. data/lib/mongory/matchers/exists_matcher.rb +53 -0
  83. data/lib/mongory/matchers/field_matcher.rb +147 -0
  84. data/lib/mongory/matchers/gt_matcher.rb +41 -0
  85. data/lib/mongory/matchers/gte_matcher.rb +41 -0
  86. data/lib/mongory/matchers/hash_condition_matcher.rb +62 -0
  87. data/lib/mongory/matchers/in_matcher.rb +68 -0
  88. data/lib/mongory/matchers/literal_matcher.rb +121 -0
  89. data/lib/mongory/matchers/lt_matcher.rb +41 -0
  90. data/lib/mongory/matchers/lte_matcher.rb +41 -0
  91. data/lib/mongory/matchers/ne_matcher.rb +38 -0
  92. data/lib/mongory/matchers/nin_matcher.rb +68 -0
  93. data/lib/mongory/matchers/not_matcher.rb +40 -0
  94. data/lib/mongory/matchers/or_matcher.rb +68 -0
  95. data/lib/mongory/matchers/present_matcher.rb +55 -0
  96. data/lib/mongory/matchers/regex_matcher.rb +80 -0
  97. data/lib/mongory/matchers/size_matcher.rb +54 -0
  98. data/lib/mongory/matchers.rb +176 -0
  99. data/lib/mongory/mongoid.rb +19 -0
  100. data/lib/mongory/query_builder.rb +257 -0
  101. data/lib/mongory/query_matcher.rb +93 -0
  102. data/lib/mongory/query_operator.rb +28 -0
  103. data/lib/mongory/rails.rb +15 -0
  104. data/lib/mongory/utils/context.rb +48 -0
  105. data/lib/mongory/utils/debugger.rb +125 -0
  106. data/lib/mongory/utils/rails_patch.rb +22 -0
  107. data/lib/mongory/utils/singleton_builder.rb +31 -0
  108. data/lib/mongory/utils.rb +76 -0
  109. data/lib/mongory/version.rb +5 -0
  110. data/lib/mongory.rb +123 -0
  111. data/lib/mongory_ext.so +0 -0
  112. data/mongory.gemspec +62 -0
  113. data/scripts/build_with_core.sh +292 -0
  114. data/sig/mongory.rbs +4 -0
  115. metadata +159 -0
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/mongory'
4
+ require 'benchmark'
5
+
6
+ # Register Array class
7
+ Mongory.register(Array)
8
+ Mongory.enable_symbol_snippets!
9
+
10
+ def gc_handler
11
+ GC.disable
12
+ before = GC.stat
13
+ yield
14
+ GC.start
15
+ after = GC.stat
16
+ GC.enable
17
+ created = after[:total_allocated_objects] - before[:total_allocated_objects]
18
+ freed = after[:total_freed_objects] - before[:total_freed_objects]
19
+ alive = after[:heap_live_slots] - before[:heap_live_slots]
20
+
21
+ puts "Created: #{created}" # 分配了幾個 object
22
+ puts "Freed: #{freed}" # 中途 GC 掃掉幾個(若 GC 有觸發)
23
+ puts "Net alive: #{alive}" # 最後還活著的物件數
24
+ end
25
+ # Test with different data sizes
26
+ [20, 1000, 10_000, 100_000].each do |size|
27
+ puts "\nTesting with #{size} records:"
28
+
29
+ # Generate test data
30
+ records = (1..size).map do |_|
31
+ {
32
+ 'age' => [nil, rand(1..100)].sample,
33
+ 'status' => ['active', 'inactive'].sample
34
+ }
35
+ end
36
+
37
+ count_of_simple_query = records.count { |r| r['age'].is_a?(Numeric) && r['age'] >= 18 }
38
+ # Simple query (Plain Ruby) test
39
+ puts "\nSimple query (Plain Ruby) (#{size} records):"
40
+ gc_handler do
41
+ 5.times do
42
+ result = Benchmark.measure do
43
+ records.select { |r| r['age'].is_a?(Numeric) && r['age'] >= 18 }
44
+ end
45
+ puts result
46
+ end
47
+ end
48
+
49
+ # Simple query (Mongory) test
50
+ puts "\nSimple query (Mongory) (#{size} records):"
51
+ gc_handler do
52
+ builder = records.mongory.where(:age.gte => 18)
53
+ 5.times do
54
+ result = Benchmark.measure do
55
+ builder.to_a
56
+ end
57
+ puts result
58
+ end
59
+ raise "count mismatch" if builder.to_a.count != count_of_simple_query
60
+ end
61
+
62
+ # Simple query (Mongory::CMatcher) test
63
+ puts "\nSimple query (Mongory::CMatcher) (#{size} records):"
64
+ gc_handler do
65
+ matcher = Mongory::CMatcher.new(:age.gte => 18)
66
+ 5.times do
67
+ result = Benchmark.measure do
68
+ records.select { |r| matcher.match?(r) }
69
+ end
70
+ puts result
71
+ end
72
+ raise "count mismatch" if records.count { |r| matcher.match?(r) } != count_of_simple_query
73
+ end
74
+
75
+ # Simple query (Mongory::CQueryBuilder) test
76
+ puts "\nSimple query (Mongory::CQueryBuilder) (#{size} records):"
77
+ gc_handler do
78
+ builder = Mongory::CQueryBuilder.new(records).where(:age.gte => 18)
79
+ 5.times do
80
+ result = Benchmark.measure do
81
+ builder.to_a
82
+ end
83
+ puts result
84
+ end
85
+ raise "count mismatch" if builder.count != count_of_simple_query
86
+ end
87
+
88
+ # Complex query (Plain Ruby) test
89
+ puts "\nComplex query (Plain Ruby) (#{size} records):"
90
+ gc_handler do
91
+ 5.times do
92
+ result = Benchmark.measure do
93
+ records.select do |r|
94
+ next false unless r.key?('age') && r.key?('status')
95
+
96
+ r['age'].is_a?(Numeric) && r['age'] >= 18 || r['status'] == 'active'
97
+ end
98
+ end
99
+ puts result
100
+ end
101
+ end
102
+
103
+ count_of_complex_query = records.count do |r|
104
+ r.key?('age') && r.key?('status') && (r['age'].is_a?(Numeric) && r['age'] >= 18 || r['status'] == 'active')
105
+ end
106
+
107
+ # Complex query (Mongory) test
108
+ puts "\nComplex query (Mongory) (#{size} records):"
109
+ gc_handler do
110
+ builder = records.mongory.or(
111
+ { :age.gte => 18 },
112
+ { status: 'active' }
113
+ )
114
+ 5.times do
115
+ result = Benchmark.measure do
116
+ builder.to_a
117
+ end
118
+ puts result
119
+ end
120
+ raise "count mismatch" if builder.count != count_of_complex_query
121
+ end
122
+
123
+ # Complex query (Mongory) test
124
+ puts "\nComplex query (Mongory) fast mode (#{size} records):"
125
+ gc_handler do
126
+ builder = records.mongory.or(
127
+ { :age.gte => 18 },
128
+ { status: 'active' }
129
+ ).fast
130
+ 5.times do
131
+ result = Benchmark.measure do
132
+ builder.to_a
133
+ end
134
+ puts result
135
+ end
136
+ raise "count mismatch" if builder.count != count_of_complex_query
137
+ end
138
+
139
+ puts "\nComplex query (Mongory) use CMatcher (#{size} records):"
140
+ gc_handler do
141
+ matcher = Mongory::CMatcher.new(
142
+ '$or' => [
143
+ { :age.gte => 18 },
144
+ { status: 'active' }
145
+ ]
146
+ )
147
+ 5.times do
148
+ result = Benchmark.measure do
149
+ records.select { |r| matcher.match?(r) }
150
+ end
151
+ puts result
152
+ end
153
+ raise "count mismatch" if records.count { |r| matcher.match?(r) } != count_of_complex_query
154
+ end
155
+
156
+ puts "\nComplex query (Mongory) use CQueryBuilder (#{size} records):"
157
+ gc_handler do
158
+ builder = records.mongory.c.or(
159
+ { :age.gte => 18 },
160
+ { status: 'active' }
161
+ )
162
+ 5.times do
163
+ result = Benchmark.measure do
164
+ builder.to_a
165
+ end
166
+ puts result
167
+ end
168
+ raise "count mismatch" if builder.count != count_of_complex_query
169
+ end
170
+
171
+ puts "\nTest Mongory::CMatcher#trace"
172
+ matcher = Mongory::CMatcher.new(
173
+ '$or' => [
174
+ { :age.gte => 18 },
175
+ { status: 'active' }
176
+ ]
177
+ )
178
+ # matcher.enable_trace
179
+ records.sample(30).each do |r|
180
+ matcher.trace(r)
181
+ end
182
+ # matcher.print_trace
183
+ # matcher.disable_trace
184
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Style/GlobalVars
4
+
5
+ require 'mkmf'
6
+ require 'rbconfig'
7
+
8
+ # Set the path to mongory-core
9
+ core_dir = File.expand_path('mongory-core', __dir__)
10
+ core_src_dir = File.join(core_dir, 'src')
11
+ core_include_dir = File.join(core_dir, 'include')
12
+
13
+ # Check if mongory-core submodule exists
14
+ unless Dir.exist?(core_dir)
15
+ puts "Error: mongory-core submodule not found at #{core_dir}"
16
+ puts 'Please run: git submodule update --init --recursive'
17
+ exit 1
18
+ end
19
+
20
+ # mongory-rb does not require cJSON; only mongory-core's tests use it, so we don't check cJSON here
21
+
22
+ # Normalize compiler flags across GCC/Clang on CI (Ruby 2.6 on Ubuntu may inject clang-only warn flags)
23
+ def scrub_flags_from_config!(keys, patterns)
24
+ [RbConfig::CONFIG, RbConfig::MAKEFILE_CONFIG].uniq.each do |cfg|
25
+ keys.each do |k|
26
+ next unless cfg[k]
27
+
28
+ patterns.each do |pat|
29
+ cfg[k] = cfg[k].gsub(/\b#{Regexp.escape(pat)}\b/, '')
30
+ end
31
+ cfg[k] = cfg[k].squeeze(' ').strip
32
+ end
33
+ end
34
+ end
35
+
36
+ gcc_like = RbConfig::CONFIG['GCC'] == 'yes' || RbConfig::CONFIG['CC'].to_s =~ /(gcc|cc)/
37
+ if gcc_like
38
+ scrub_flags_from_config!(%w(warnflags cflags optflags debugflags), [
39
+ '-Wno-self-assign',
40
+ '-Wno-parentheses-equality',
41
+ '-Wno-constant-logical-operand'
42
+ ])
43
+ end
44
+
45
+ # Add include paths
46
+ $INCFLAGS << " -I#{core_include_dir}"
47
+
48
+ # Collect source files to compile directly into the extension
49
+ foundations_src = Dir.glob(File.join(core_src_dir, 'foundations', '*.c'))
50
+ matchers_src = Dir.glob(File.join(core_src_dir, 'matchers', '*.c'))
51
+
52
+ $CFLAGS << ' -std=c99 -Wall -Wextra -Wno-incompatible-pointer-types -Wno-int-conversion'
53
+ # Silence C90-style warnings on older GCC when standard flags are not fully applied by toolchains
54
+ $CFLAGS << ' -Wno-declaration-after-statement -Wno-discarded-qualifiers'
55
+ $CFLAGS << ' -O2' unless ENV['DEBUG']
56
+ $CFLAGS << ' -g -O0 -DDEBUG' if ENV['DEBUG']
57
+
58
+ # Let mkmf generate rules by listing all sources and corresponding objects
59
+ $INCFLAGS << ' -I.'
60
+ $INCFLAGS << " -I#{File.join(core_src_dir, 'foundations')}"
61
+ $INCFLAGS << " -I#{File.join(core_src_dir, 'matchers')}"
62
+ all_sources = ['mongory_ext.c'] + foundations_src + matchers_src
63
+ $srcs = all_sources
64
+ $objs = all_sources.map { |src| "#{File.basename(src, '.c')}.o" }
65
+
66
+ # Generate Makefile
67
+ create_makefile('mongory_ext')
68
+
69
+ puts 'extconf.rb completed successfully'
70
+ puts "Found #{foundations_src.length} foundation sources"
71
+ puts "Found #{matchers_src.length} matcher sources"
72
+ puts "Use 'make' to build the extension"
73
+
74
+ # Append Makefile rules: explicit compilation rules for submodule sources to avoid copying/linking files
75
+ mk = File.read('Makefile')
76
+
77
+ # rubocop:disable Layout/HeredocIndentation
78
+ rules = +"\n# --- custom rules for mongory-core submodule sources ---\n"
79
+ (foundations_src + matchers_src).each do |src|
80
+ obj = "#{File.basename(src, '.c')}.o"
81
+ rules << <<~MAKE
82
+ #{obj}: #{src}
83
+ $(ECHO) compiling $<
84
+ $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
85
+
86
+ MAKE
87
+ end
88
+
89
+ File.write('Makefile', mk + rules)
90
+ # rubocop:enable Layout/HeredocIndentation
91
+ # rubocop:enable Style/GlobalVars
@@ -0,0 +1,122 @@
1
+ #ifndef MONGORY_ARRAY
2
+ #define MONGORY_ARRAY
3
+
4
+ /**
5
+ * @file array.h
6
+ * @brief Defines the mongory_array structure and its associated operations.
7
+ *
8
+ * mongory_array is a dynamic array implementation that stores mongory_value
9
+ * pointers. It handles its own memory management for the array storage using a
10
+ * provided mongory_memory_pool. The array can grow automatically as new
11
+ * elements are added.
12
+ */
13
+
14
+ #include "mongory-core/foundations/memory_pool.h"
15
+ #include "mongory-core/foundations/value.h"
16
+ #include <stdbool.h>
17
+
18
+ /**
19
+ * @brief Forward declaration for the mongory_array structure.
20
+ */
21
+ typedef struct mongory_array mongory_array;
22
+
23
+ /**
24
+ * @brief Callback function type used by mongory_array_each_func.
25
+ *
26
+ * This function is called for each item in the array during an iteration.
27
+ *
28
+ * @param item A pointer to the current mongory_value item in the array.
29
+ * @param acc An accumulator or context pointer passed through the iteration.
30
+ * @return bool Return true to continue iteration, false to stop.
31
+ */
32
+ typedef bool (*mongory_array_callback_func)(mongory_value *item, void *acc);
33
+
34
+ /**
35
+ * @brief Function pointer type for iterating over the array.
36
+ * @param self A pointer to the mongory_array instance.
37
+ * @param acc An accumulator or context pointer to be passed to the callback.
38
+ * @param func The callback function to be executed for each item.
39
+ * @return bool Returns true if the iteration completed fully, false if it was
40
+ * stopped by a callback.
41
+ */
42
+ typedef bool (*mongory_array_each_func)(mongory_array *self, void *acc, mongory_array_callback_func func);
43
+
44
+ /**
45
+ * @brief Function pointer type for adding an element to the end of the array.
46
+ * @param self A pointer to the mongory_array instance.
47
+ * @param value A pointer to the mongory_value to add.
48
+ * @return bool Returns true if the value was successfully added, false
49
+ * otherwise (e.g., memory allocation failure).
50
+ */
51
+ typedef bool (*mongory_array_push_func)(mongory_array *self, mongory_value *value);
52
+
53
+ /**
54
+ * @brief Function pointer type for retrieving an element at a specific index.
55
+ * @param self A pointer to the mongory_array instance.
56
+ * @param index The index of the element to retrieve.
57
+ * @return mongory_value* A pointer to the mongory_value at the given index, or
58
+ * NULL if the index is out of bounds.
59
+ */
60
+ typedef mongory_value *(*mongory_array_get_func)(mongory_array *self, size_t index);
61
+
62
+ /**
63
+ * @brief Function pointer type for setting or replacing an element at a
64
+ * specific index.
65
+ *
66
+ * If the index is beyond the current count, the array will be grown, and
67
+ * intermediate elements will be initialized to NULL.
68
+ *
69
+ * @param self A pointer to the mongory_array instance.
70
+ * @param index The index at which to set the value.
71
+ * @param value A pointer to the mongory_value to set.
72
+ * @return bool Returns true if the value was successfully set, false otherwise
73
+ * (e.g., memory allocation failure).
74
+ */
75
+ typedef bool (*mongory_array_set_func)(mongory_array *self, size_t index, mongory_value *value);
76
+
77
+ /**
78
+ * @brief Creates a new mongory_array instance.
79
+ *
80
+ * The array is initialized with a default capacity and will use the provided
81
+ * memory pool for all its internal allocations related to storing elements.
82
+ *
83
+ * @param pool A pointer to the mongory_memory_pool to be used for allocations.
84
+ * @return mongory_array* A pointer to the newly created mongory_array, or NULL
85
+ * if creation fails (e.g., memory allocation failure).
86
+ */
87
+ mongory_array *mongory_array_new(mongory_memory_pool *pool);
88
+
89
+ /**
90
+ * @brief Creates a new mongory_array instance with a nested array.
91
+ *
92
+ * This function is used to create a new mongory_array instance with a nested
93
+ * array. The nested array is created with the given memory pool and the given
94
+ * values. The nested array is returned as a pointer to the mongory_array
95
+ * structure.
96
+ *
97
+ * @param pool A pointer to the mongory_memory_pool to be used for allocations.
98
+ * @param argc The number of values to be set.
99
+ * @param ... The values to be set.
100
+ * @return mongory_array* A pointer to the newly created mongory_array, or NULL
101
+ * if creation fails (e.g., memory allocation failure).
102
+ */
103
+ mongory_array *mongory_array_nested_wrap(mongory_memory_pool *pool, int argc, ...);
104
+ #define MG_ARRAY_WRAP(pool, n, ...) mongory_value_wrap_a(pool, mongory_array_nested_wrap(pool, n, __VA_ARGS__))
105
+
106
+ /**
107
+ * @struct mongory_array
108
+ * @brief Represents a dynamic array of mongory_value pointers.
109
+ *
110
+ * This structure provides function pointers for common array operations,
111
+ * allowing for a somewhat object-oriented interface in C.
112
+ */
113
+ struct mongory_array {
114
+ size_t count; /**< The current number of elements in the array. */
115
+ mongory_memory_pool *pool; /**< The memory pool used for allocations. */
116
+ mongory_array_each_func each; /**< Function to iterate over elements in the array. */
117
+ mongory_array_push_func push; /**< Function to add an element to the end of the array. */
118
+ mongory_array_get_func get; /**< Function to retrieve an element by index. */
119
+ mongory_array_set_func set; /**< Function to set or replace an element at an index. */
120
+ };
121
+
122
+ #endif /* MONGORY_ARRAY */
@@ -0,0 +1,161 @@
1
+ #ifndef MONGORY_FOUNDATIONS_CONFIG_H
2
+ #define MONGORY_FOUNDATIONS_CONFIG_H
3
+
4
+ /**
5
+ * @file config.h
6
+ * @brief Defines global configuration functions and types for the Mongory
7
+ * library.
8
+ *
9
+ * This includes initialization and cleanup routines, as well as functions
10
+ * for setting up custom behaviors like regex matching and value conversion.
11
+ * It also provides a string copying utility that uses the library's memory
12
+ * pool.
13
+ */
14
+
15
+ #include "mongory-core/foundations/memory_pool.h"
16
+ #include "mongory-core/foundations/value.h"
17
+ #include <stdbool.h>
18
+
19
+ /**
20
+ * @brief Function pointer type for custom regex matching.
21
+ *
22
+ * This function is called when a regex match is required.
23
+ *
24
+ * @param pool The memory pool to use for any allocations during the match.
25
+ * @param pattern The regex pattern (as a mongory_value, typically a string or
26
+ * regex type).
27
+ * @param value The value to match against (as a mongory_value, typically a
28
+ * string).
29
+ * @return bool True if the value matches the pattern, false otherwise.
30
+ */
31
+ typedef bool (*mongory_regex_func)(mongory_memory_pool *pool, mongory_value *pattern, mongory_value *value);
32
+
33
+ /**
34
+ * @brief Function pointer type for stringifying a regex pattern.
35
+ *
36
+ * This function is called when a regex pattern needs to be stringified.
37
+ *
38
+ * @param pool The memory pool to use for any allocations during the
39
+ * stringification.
40
+ * @param pattern The regex pattern (as a mongory_value, typically a string or
41
+ * regex type).
42
+ * @return char* A stringified representation of the regex pattern, or NULL on failure.
43
+ */
44
+ typedef char* (*mongory_regex_stringify_func)(mongory_memory_pool *pool, mongory_value *pattern);
45
+
46
+ /**
47
+ * @brief Function pointer type for deep conversion of an external value to a
48
+ * mongory_value.
49
+ *
50
+ * "Deep" implies that if the external value is a complex type (e.g., a struct
51
+ * representing a document or array), its contents should also be converted.
52
+ *
53
+ * @param pool The memory pool to use for allocating the new mongory_value and
54
+ * its data.
55
+ * @param value A pointer to the external value to convert.
56
+ * @return mongory_value* A new mongory_value representing the converted data,
57
+ * or NULL on failure.
58
+ */
59
+ typedef mongory_value *(*mongory_deep_convert_func)(mongory_memory_pool *pool, void *value);
60
+
61
+ /**
62
+ * @brief Function pointer type for shallow conversion of an external value to a
63
+ * mongory_value.
64
+ *
65
+ * "Shallow" implies that if the external value is complex, only a wrapper or
66
+ * pointer might be stored in the mongory_value, without deeply converting its
67
+ * contents.
68
+ *
69
+ * @param pool The memory pool to use for allocating the new mongory_value.
70
+ * @param value A pointer to the external value to convert.
71
+ * @return mongory_value* A new mongory_value, or NULL on failure.
72
+ */
73
+ typedef mongory_value *(*mongory_shallow_convert_func)(mongory_memory_pool *pool, void *value);
74
+
75
+ /**
76
+ * @brief Function pointer type for recovering an external value from a
77
+ * mongory_value.
78
+ *
79
+ * This is the reverse of a conversion, intended to get back the original
80
+ * external data representation if it was stored or wrapped.
81
+ *
82
+ * @param pool The memory pool (can be used if recovery involves allocation,
83
+ * though often it might just retrieve a stored pointer).
84
+ * @param value The mongory_value from which to recover the external data.
85
+ * @return void* A pointer to the recovered external value, or NULL if not
86
+ * possible.
87
+ */
88
+ typedef void *(*mongory_recover_func)(mongory_memory_pool *pool, mongory_value *value);
89
+
90
+ /**
91
+ * @brief Initializes the Mongory library.
92
+ *
93
+ * Sets up internal structures, including the global memory pool,
94
+ * regex adapter, matcher mapping, and value converter. This function
95
+ * should be called before any other Mongory library functions are used.
96
+ * It also registers the default set of matchers (e.g., $in, $eq).
97
+ */
98
+ void mongory_init();
99
+
100
+ /**
101
+ * @brief Cleans up resources used by the Mongory library.
102
+ *
103
+ * Frees the internal memory pool and resets global pointers. This should
104
+ * be called when the library is no longer needed to prevent memory leaks.
105
+ */
106
+ void mongory_cleanup();
107
+
108
+ /**
109
+ * @brief Sets the custom regex matching function.
110
+ *
111
+ * If not called, a default function that always returns false is used.
112
+ *
113
+ * @param func The custom regex function to use.
114
+ */
115
+ void mongory_regex_func_set(mongory_regex_func func);
116
+
117
+ /**
118
+ * @brief Sets the custom regex stringify function.
119
+ *
120
+ * If not called, a default function that always returns NULL is used.
121
+ *
122
+ * @param func The custom regex stringify function to use.
123
+ */
124
+ void mongory_regex_stringify_func_set(mongory_regex_stringify_func func);
125
+
126
+ /**
127
+ * @brief Sets the custom deep value conversion function.
128
+ * @param deep_convert The function to use for deep conversions.
129
+ */
130
+ void mongory_value_converter_deep_convert_set(mongory_deep_convert_func deep_convert);
131
+
132
+ /**
133
+ * @brief Sets the custom shallow value conversion function.
134
+ * @param shallow_convert The function to use for shallow conversions.
135
+ */
136
+ void mongory_value_converter_shallow_convert_set(mongory_shallow_convert_func shallow_convert);
137
+
138
+ /**
139
+ * @brief Sets the custom value recovery function.
140
+ * @param recover The function to use for recovering external values.
141
+ */
142
+ void mongory_value_converter_recover_set(mongory_recover_func recover);
143
+
144
+ /**
145
+ * @brief Function pointer type for matching a value against an external matcher.
146
+ * @param external_matcher The external reference to the matcher.
147
+ * @param value The value to match against.
148
+ * @return bool True if the value matches the matcher, false otherwise.
149
+ */
150
+ typedef struct mongory_matcher_custom_context {
151
+ char *name; // Name of the custom matcher.
152
+ void *external_matcher; // External reference to the custom matcher.
153
+ } mongory_matcher_custom_context;
154
+
155
+ void mongory_custom_matcher_match_func_set(bool (*match)(void *external_matcher, mongory_value *value));
156
+ void mongory_custom_matcher_build_func_set(mongory_matcher_custom_context *(*build)(char *key, mongory_value *condition, void *extern_ctx));
157
+ void mongory_custom_matcher_lookup_func_set(bool (*lookup)(char *key));
158
+
159
+ void mongory_matcher_trace_result_colorful_set(bool colorful);
160
+
161
+ #endif /* MONGORY_FOUNDATIONS_CONFIG_H */
@@ -0,0 +1,79 @@
1
+ #ifndef MONGORY_ERROR
2
+ #define MONGORY_ERROR
3
+
4
+ /**
5
+ * @file error.h
6
+ * @brief Defines error types and structures for the Mongory library.
7
+ *
8
+ * This file provides an enumeration of possible error codes and a structure
9
+ * for representing error information, typically consisting of an error type
10
+ * and an associated message.
11
+ */
12
+
13
+ #include <stdbool.h>
14
+
15
+ /**
16
+ * @def MONGORY_ERROR_TYPE_MAGIC
17
+ * @brief A magic number used in generating enum values for error types.
18
+ * Helps in creating somewhat unique integer values for the enums.
19
+ */
20
+ #define MONGORY_ERROR_TYPE_MAGIC 107
21
+
22
+ /**
23
+ * @def MONGORY_ERROR_TYPE_MACRO
24
+ * @brief X-Macro for defining error types.
25
+ * This macro allows defining the error enum, string conversion, etc.,
26
+ * from a single list, promoting consistency.
27
+ * Each entry takes the enum name, a numeric suffix, and a string description.
28
+ */
29
+ #define MONGORY_ERROR_TYPE_MACRO(_) \
30
+ _(MONGORY_ERROR_NONE, 10, "No Error") \
31
+ _(MONGORY_ERROR_MEMORY, 11, "Memory Allocation Error") \
32
+ _(MONGORY_ERROR_INVALID_TYPE, 12, "Invalid Type Error") \
33
+ _(MONGORY_ERROR_OUT_OF_BOUNDS, 13, "Out of Bounds Error") \
34
+ _(MONGORY_ERROR_UNSUPPORTED_OPERATION, 14, "Unsupported Operation Error") \
35
+ _(MONGORY_ERROR_INVALID_ARGUMENT, 15, "Invalid Argument Error") \
36
+ _(MONGORY_ERROR_IO, 16, "I/O Error") \
37
+ _(MONGORY_ERROR_PARSE, 17, "Parse Error") \
38
+ _(MONGORY_ERROR_UNKNOWN, 99, "Unknown Error")
39
+
40
+ /**
41
+ * @enum mongory_error_type
42
+ * @brief Enumerates the types of errors that can occur within the Mongory
43
+ * library. Values are generated using MONGORY_ERROR_TYPE_MACRO and
44
+ * MONGORY_ERROR_TYPE_MAGIC.
45
+ */
46
+ typedef enum mongory_error_type {
47
+ #define DEFINE_ERROR_ENUM(name, num, str) name = num * MONGORY_ERROR_TYPE_MAGIC,
48
+ MONGORY_ERROR_TYPE_MACRO(DEFINE_ERROR_ENUM)
49
+ #undef DEFINE_ERROR_ENUM
50
+ } mongory_error_type;
51
+
52
+ /**
53
+ * @brief Converts a mongory_error_type enum to its string representation.
54
+ *
55
+ * @param type The error type enum value.
56
+ * @return const char* A string describing the error type. Returns "Unknown
57
+ * Error Type" if the type is not recognized.
58
+ */
59
+ const char *mongory_error_type_to_string(enum mongory_error_type type);
60
+
61
+ /**
62
+ * @struct mongory_error
63
+ * @brief Structure to hold error information.
64
+ *
65
+ * Contains the type of error and an optional descriptive message.
66
+ * The message string is expected to be a literal or have a lifetime
67
+ * managed elsewhere (e.g., allocated from a memory pool).
68
+ */
69
+ typedef struct mongory_error {
70
+ mongory_error_type type; /**< The type of the error. */
71
+ const char *message; /**< A descriptive message for the error. This message
72
+ might be a string literal or allocated from a
73
+ memory pool. Its lifetime should be considered
74
+ carefully. */
75
+ } mongory_error;
76
+
77
+ extern mongory_error MONGORY_ALLOC_ERROR;
78
+
79
+ #endif /* MONGORY_ERROR */