meta-record 1.0.1
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.
- checksums.yaml +7 -0
- data/bin/metarecord-make +53 -0
- data/lib/guard/metarecord.rb +22 -0
- data/lib/metarecord/generator_base.rb +197 -0
- data/lib/metarecord/generators/aurelia_generator.rb +150 -0
- data/lib/metarecord/generators/comet/archive_generator.rb +108 -0
- data/lib/metarecord/generators/comet/data_generator.rb +77 -0
- data/lib/metarecord/generators/comet/edit_generator.rb +153 -0
- data/lib/metarecord/generators/crails/data_generator.rb +289 -0
- data/lib/metarecord/generators/crails/destroy_generator.rb +178 -0
- data/lib/metarecord/generators/crails/edit_generator.rb +364 -0
- data/lib/metarecord/generators/crails/helpers/validations.rb +77 -0
- data/lib/metarecord/generators/crails/query_generator.rb +88 -0
- data/lib/metarecord/generators/crails/view_generator.rb +80 -0
- data/lib/metarecord/generators/rails/data_generator.rb +143 -0
- data/lib/metarecord/generators/rails/migration_generator.rb +89 -0
- data/lib/metarecord/generators/rails/migrations/table_helpers.rb +67 -0
- data/lib/metarecord/generators/rails/migrations/type_helpers.rb +45 -0
- data/lib/metarecord/manifest_generator.rb +42 -0
- data/lib/metarecord/model.rb +66 -0
- data/lib/metarecord/runner.rb +56 -0
- metadata +68 -0
@@ -0,0 +1,364 @@
|
|
1
|
+
require 'metarecord/model'
|
2
|
+
require 'metarecord/generator_base'
|
3
|
+
require 'metarecord/generators/crails/helpers/validations'
|
4
|
+
|
5
|
+
class CrailsEditGenerator < GeneratorBase
|
6
|
+
def reset
|
7
|
+
super
|
8
|
+
@required_params = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate_for object
|
12
|
+
@modelname = object[:name].underscore
|
13
|
+
@klassname = get_classname(object)
|
14
|
+
reset
|
15
|
+
generate_edit_method object
|
16
|
+
generate_json_methods object
|
17
|
+
generate_parameter_validator object
|
18
|
+
generate_relations object
|
19
|
+
@src
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate_relations object
|
23
|
+
@rendering_has_many = true
|
24
|
+
self.instance_eval &object[:block]
|
25
|
+
@rendering_has_many = false
|
26
|
+
end
|
27
|
+
|
28
|
+
def generate_edit_method object
|
29
|
+
_append "void #{@klassname}::edit(Data data)"
|
30
|
+
_append "{"
|
31
|
+
@indent += 1
|
32
|
+
self.instance_eval &object[:block]
|
33
|
+
@indent -= 1
|
34
|
+
_append "}\n"
|
35
|
+
end
|
36
|
+
|
37
|
+
def generate_json_methods object
|
38
|
+
@rendering_to_json = true
|
39
|
+
_append "std::string #{@klassname}::to_json() const"
|
40
|
+
_append "{"
|
41
|
+
@indent += 1
|
42
|
+
_append "DataTree data;\n"
|
43
|
+
self.instance_eval &object[:block]
|
44
|
+
_append "return data.to_json();"
|
45
|
+
@indent -= 1
|
46
|
+
_append "}\n"
|
47
|
+
@rendering_to_json = false
|
48
|
+
end
|
49
|
+
|
50
|
+
def generate_parameter_validator object
|
51
|
+
_append "std::vector<std::string> #{@klassname}::find_missing_parameters(Data data) const"
|
52
|
+
_append "{"
|
53
|
+
@indent += 1
|
54
|
+
if @required_params.size > 0
|
55
|
+
_append "return data.find_missing_keys({#{@required_params.join ','}});"
|
56
|
+
else
|
57
|
+
_append "return {};"
|
58
|
+
end
|
59
|
+
@indent -= 1
|
60
|
+
_append "}"
|
61
|
+
|
62
|
+
_append "bool #{@klassname}::is_valid()"
|
63
|
+
_append "{"
|
64
|
+
@indent += 1
|
65
|
+
_append "errors.clear();"
|
66
|
+
@rendering_validations = true
|
67
|
+
self.instance_eval &object[:block]
|
68
|
+
@rendering_validations = false
|
69
|
+
_append "return errors.as_data().get_keys().size() == 0;"
|
70
|
+
@indent -= 1
|
71
|
+
_append "}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def resource_name name
|
75
|
+
if @rendering_has_many
|
76
|
+
_append "const std::string #{@klassname}::scope = #{name.to_s.inspect};"
|
77
|
+
_append "const std::string #{@klassname}::plural_scope = #{(get_pluralized_name name.to_s).inspect};"
|
78
|
+
_append "const std::string #{@klassname}::view = \"${view-placeholder}/data/#{@modelname}\";"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def rendering_edit?
|
83
|
+
not ([@rendering_has_many, @rendering_validations, @rendering_to_json].include? true)
|
84
|
+
end
|
85
|
+
|
86
|
+
def property type, name, options = {}
|
87
|
+
if @rendering_validations && !options[:validate].nil?
|
88
|
+
validation type, name, options[:validate]
|
89
|
+
elsif @rendering_to_json
|
90
|
+
case type
|
91
|
+
when "DataTree" then _append "data[\"#{name}\"].merge(#{name});"
|
92
|
+
when "LocaleString" then _append "data[\"#{name}\"] = #{name}.to_string();"
|
93
|
+
else _append "data[\"#{name}\"] = #{name};"
|
94
|
+
end
|
95
|
+
elsif options[:read_only] != true && rendering_edit?
|
96
|
+
setter = "set_#{name}(data[\"#{name}\"]);"
|
97
|
+
setter = "set_#{name}(data[\"#{name}\"].as<int>());" if not (type =~ /^(unsigned)?\s*char$/).nil?
|
98
|
+
if options[:required] == true
|
99
|
+
@required_params.push "\"#{name}\""
|
100
|
+
_append setter
|
101
|
+
else
|
102
|
+
_append "if (data[\"#{name}\"].exists())"
|
103
|
+
@indent += 1
|
104
|
+
_append setter
|
105
|
+
@indent -= 1
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def validation type, name, data
|
111
|
+
if !data[:min].nil?
|
112
|
+
_append validate_number_min name, data[:min]
|
113
|
+
end
|
114
|
+
if !data[:max].nil?
|
115
|
+
_append validate_number_max name, data[:max]
|
116
|
+
end
|
117
|
+
if data[:required] == true
|
118
|
+
_append validate_required type, name
|
119
|
+
end
|
120
|
+
if data[:self_reference] == true
|
121
|
+
_append validate_self_reference type, name
|
122
|
+
end
|
123
|
+
if data[:uniqueness] == true
|
124
|
+
puts "/!\\ WARNING: uniqueness validations not available for crails generators"
|
125
|
+
#_append validate_uniqueness type, name
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def has_one_getter type, name, options
|
130
|
+
type = get_type type
|
131
|
+
tptr = ptr_type type
|
132
|
+
_append "#{tptr} #{@klassname}::get_#{name}() const"
|
133
|
+
_append "{"
|
134
|
+
_append " auto& database = *#{GeneratorBase.odb_connection[:object]}::instance;"
|
135
|
+
_append " #{tptr} result;\n"
|
136
|
+
_append " database.find_one(result, #{name}_id);"
|
137
|
+
_append " return result;"
|
138
|
+
_append "}\n"
|
139
|
+
end
|
140
|
+
|
141
|
+
def has_one_setter type, name, options
|
142
|
+
type = get_type type
|
143
|
+
tptr = ptr_type type
|
144
|
+
_append "void #{@klassname}::set_#{name}(#{tptr} v)"
|
145
|
+
_append "{"
|
146
|
+
_append " #{name}_id = v != nullptr ? v->get_id() : #{null_id};"
|
147
|
+
_append "}\n"
|
148
|
+
end
|
149
|
+
|
150
|
+
def joined_has_one_edit type, name, options
|
151
|
+
tptr = ptr_type type
|
152
|
+
data_id = "data[\"#{name}_id\"]"
|
153
|
+
_append "{"
|
154
|
+
_append " if (#{data_id} == #{null_id})"
|
155
|
+
_append " set_#{name}(nullptr);"
|
156
|
+
_append " else if (!get_#{name}() || #{data_id} != get_#{name}()->get_id())"
|
157
|
+
_append " {"
|
158
|
+
_append " auto& database = *#{GeneratorBase.odb_connection[:object]}::instance;"
|
159
|
+
_append " #{tptr} linked_resource;"
|
160
|
+
_append " database.find_one(linked_resource, data[\"#{name}_id\"].as<#{id_type}>());"
|
161
|
+
_append " set_#{name}(linked_resource);"
|
162
|
+
_append " }"
|
163
|
+
_append "}"
|
164
|
+
end
|
165
|
+
|
166
|
+
def has_one type, name, options = {}
|
167
|
+
type = get_type type
|
168
|
+
tptr = ptr_type type
|
169
|
+
if @rendering_has_many
|
170
|
+
if options[:joined] == false
|
171
|
+
has_one_getter type, name, options
|
172
|
+
has_one_setter type, name, options
|
173
|
+
else
|
174
|
+
_append "#{id_type} #{@klassname}::get_#{name}_id() const"
|
175
|
+
_append "{"
|
176
|
+
_append " return #{name} ? #{name}->get_id() : #{null_id};"
|
177
|
+
_append "}\n"
|
178
|
+
end
|
179
|
+
elsif @rendering_validations
|
180
|
+
if not options[:validate].nil?
|
181
|
+
if options[:joined] == false
|
182
|
+
validation "#{id_type}", "#{name}_id", options[:validate]
|
183
|
+
else
|
184
|
+
validation tptr, name, options[:validate]
|
185
|
+
end
|
186
|
+
end
|
187
|
+
elsif @rendering_to_json
|
188
|
+
if options[:joined] == false
|
189
|
+
_append "data[\"#{name}_id\"] = get_#{name}_id();"
|
190
|
+
else
|
191
|
+
_append "if (#{name} != nullptr)"
|
192
|
+
_append " data[\"#{name}_id\"] = get_#{name}_id();"
|
193
|
+
end
|
194
|
+
elsif options[:read_only] != true
|
195
|
+
data_id = "data[\"#{name}_id\"]"
|
196
|
+
_append "if (#{data_id}.exists())"
|
197
|
+
if options[:joined] != false
|
198
|
+
joined_has_one_edit type, name, options
|
199
|
+
else
|
200
|
+
_append "set_#{name}_id(data[\"#{name}_id\"]);"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def has_many type, name, options = {}
|
206
|
+
type = get_type type
|
207
|
+
if @rendering_has_many
|
208
|
+
if options[:joined] != false
|
209
|
+
_join_based_has_many type, name, options
|
210
|
+
else
|
211
|
+
_id_based_has_many type, name, options
|
212
|
+
end
|
213
|
+
_append "void #{@klassname}::collect_#{name}(std::map<#{id_type}, #{ptr_type type}>& results)"
|
214
|
+
_append "{"
|
215
|
+
@indent += 1
|
216
|
+
_append "for (auto model : get_#{name}())"
|
217
|
+
_append "{"
|
218
|
+
@indent += 1
|
219
|
+
_append "if (results.find(model->get_id()) == results.end())"
|
220
|
+
_append " results[model->get_id()] = model;"
|
221
|
+
@indent -= 1
|
222
|
+
_append "}"
|
223
|
+
@indent -= 1
|
224
|
+
_append "}"
|
225
|
+
elsif @rendering_validations
|
226
|
+
elsif @rendering_to_json
|
227
|
+
_append "data[\"#{get_singular_name name}_ids\"].from_vector<#{id_type}>(get_#{get_singular_name name}_ids());"
|
228
|
+
elsif options[:read_only] != true
|
229
|
+
data = "data[\"#{get_singular_name name}_ids\"]"
|
230
|
+
_append "if (#{data}.exists())"
|
231
|
+
_append " update_#{name}(#{data});"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def _join_based_has_many type, name, options
|
236
|
+
tptr = ptr_type type
|
237
|
+
list_type = "std::list<#{tptr} >"
|
238
|
+
singular_name = get_singular_name name
|
239
|
+
_append "std::vector<#{id_type}> #{@klassname}::get_#{singular_name}_ids() const"
|
240
|
+
_append "{"
|
241
|
+
@indent += 1
|
242
|
+
_append "return collect_ids_from(get_#{name}());"
|
243
|
+
@indent -= 1
|
244
|
+
_append "}\n"
|
245
|
+
|
246
|
+
_append "bool #{@klassname}::update_#{name}(Data ids)"
|
247
|
+
_append "{"
|
248
|
+
@indent += 1
|
249
|
+
_append "return update_id_list<#{type}>(#{name}, ids);"
|
250
|
+
@indent -= 1
|
251
|
+
_append "}\n"
|
252
|
+
|
253
|
+
_append "void #{@klassname}::add_#{singular_name}(#{tptr} resource)"
|
254
|
+
_append "{"
|
255
|
+
@indent += 1
|
256
|
+
_append "remove_#{singular_name}(*resource);"
|
257
|
+
_append "#{name}.push_back(resource);"
|
258
|
+
@indent -= 1
|
259
|
+
_append "}\n"
|
260
|
+
|
261
|
+
_append "void #{@klassname}::remove_#{singular_name}(const #{type}& resource)"
|
262
|
+
_append "{"
|
263
|
+
@indent += 1
|
264
|
+
_append "#{name}.remove_if([&resource](#{tptr} comp)"
|
265
|
+
_append "{"
|
266
|
+
@indent += 1
|
267
|
+
_append "return comp->get_id() == resource.get_id();"
|
268
|
+
@indent -= 1
|
269
|
+
_append "});"
|
270
|
+
@indent -= 1
|
271
|
+
_append "}\n"
|
272
|
+
end
|
273
|
+
|
274
|
+
def _id_based_has_many type, name, options
|
275
|
+
tptr = ptr_type type
|
276
|
+
singular_name = get_singular_name name
|
277
|
+
|
278
|
+
_append "bool #{@klassname}::update_#{name}(Data ids)"
|
279
|
+
_append "{"
|
280
|
+
@indent += 1
|
281
|
+
_append "return update_id_list<#{type}>(this->#{singular_name}_ids, ids);"
|
282
|
+
@indent -= 1
|
283
|
+
_append "}\n"
|
284
|
+
|
285
|
+
_append "void #{@klassname}::add_#{singular_name}(#{tptr} v)"
|
286
|
+
_append "{"
|
287
|
+
@indent += 1
|
288
|
+
_append "remove_#{singular_name}(*v);"
|
289
|
+
_append "#{singular_name}_ids.push_back(v->get_id());"
|
290
|
+
@indent -= 1
|
291
|
+
_append "}\n"
|
292
|
+
|
293
|
+
_append "void #{@klassname}::remove_#{singular_name}(const #{type}& v)"
|
294
|
+
_append "{"
|
295
|
+
@indent += 1
|
296
|
+
_append "auto it = remove_if(#{singular_name}_ids.begin(), #{singular_name}_ids.end(), [v](#{id_type} id)"
|
297
|
+
_append "{"
|
298
|
+
@indent += 1
|
299
|
+
_append "return id == v.get_id();"
|
300
|
+
@indent -= 1
|
301
|
+
_append "});"
|
302
|
+
_append "if (it != #{singular_name}_ids.end())"
|
303
|
+
@indent += 1
|
304
|
+
_append "#{singular_name}_ids.erase(it);"
|
305
|
+
@indent -= 2
|
306
|
+
_append "}\n"
|
307
|
+
|
308
|
+
_append "const std::list<#{tptr} >& #{@klassname}::get_#{name}()"
|
309
|
+
_append "{"
|
310
|
+
@indent += 1
|
311
|
+
_append "if (!#{name}_fetched)"
|
312
|
+
@indent += 1
|
313
|
+
_append "fetch_#{name}();"
|
314
|
+
@indent -= 1
|
315
|
+
_append "return #{name};"
|
316
|
+
@indent -= 1
|
317
|
+
_append "}\n"
|
318
|
+
|
319
|
+
has_many_fetch type, name, options
|
320
|
+
end
|
321
|
+
|
322
|
+
def has_many_fetch type, name, options
|
323
|
+
singular_name = get_singular_name name
|
324
|
+
|
325
|
+
_append "void #{@klassname}::fetch_#{name}()"
|
326
|
+
_append "{"
|
327
|
+
@indent += 1
|
328
|
+
_append "typedef odb::pgsql::query<#{type}> query;"
|
329
|
+
_append "auto& database = *#{GeneratorBase.odb_connection[:object]}::instance;"
|
330
|
+
_append "odb::result<#{type}> results;"
|
331
|
+
_append "#{name}.clear();"
|
332
|
+
_append "database.find<#{type}>(results,"
|
333
|
+
_append " query::id + \"=\" + ODB::any(#{singular_name}_ids, \"int\")"
|
334
|
+
_append ");"
|
335
|
+
_append "for (auto model : results)"
|
336
|
+
_append " #{name}.push_back(std::make_shared<#{type}>(model));"
|
337
|
+
_append "#{name}_fetched = true;"
|
338
|
+
@indent -= 1
|
339
|
+
_append "}\n"
|
340
|
+
end
|
341
|
+
|
342
|
+
class << self
|
343
|
+
def extension ; ".cpp" ; end
|
344
|
+
|
345
|
+
def generate_includes
|
346
|
+
source = "#include <crails/odb/helpers.hpp>\n"
|
347
|
+
source += "#include <crails/odb/any.hpp>\n"
|
348
|
+
source += "#include <#{GeneratorBase.odb_connection[:include]}>\n"
|
349
|
+
source += "#include \"lib/odb/application-odb.hxx\"\n"
|
350
|
+
end
|
351
|
+
|
352
|
+
def make_file filename, data
|
353
|
+
base = "lib/" + filename[0...-3]
|
354
|
+
include = base + ".hpp"
|
355
|
+
data[:bodies].each do |body|
|
356
|
+
body.gsub! "${view-placeholder}", base.split("/")[0...-2].join("/")
|
357
|
+
end
|
358
|
+
source = "#include \"#{include}\"\n"
|
359
|
+
source += generate_includes
|
360
|
+
source += (collect_includes_for filename).join "\n"
|
361
|
+
source += "\n\n" + (data[:bodies].join "\n")
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
def validate_number_min name, min
|
2
|
+
code = <<CPP
|
3
|
+
if (#{name} < #{min})
|
4
|
+
{
|
5
|
+
errors["#{name}"]["t"] = "validate.min";
|
6
|
+
errors["#{name}"]["params"]["min"] = #{min};
|
7
|
+
errors["#{name}"]["params"]["val"] = #{name};
|
8
|
+
}
|
9
|
+
CPP
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate_number_max name, max
|
13
|
+
code = <<CPP
|
14
|
+
if (#{name} < #{max})
|
15
|
+
{
|
16
|
+
errors["#{name}"]["t"] = "validate.max";
|
17
|
+
errors["#{name}"]["params"]["max"] = #{min};
|
18
|
+
errors["#{name}"]["params"]["val"] = #{name};
|
19
|
+
}
|
20
|
+
CPP
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate_uniqueness source_type, name
|
24
|
+
if source_type.start_with?("std::shared_ptr")
|
25
|
+
type = source_type[16..-2]
|
26
|
+
<<CPP
|
27
|
+
{
|
28
|
+
auto& database = *#{GeneratorBase.odb_connection[:object]}::instance;
|
29
|
+
odb::result<#{source_type}> results;
|
30
|
+
|
31
|
+
database.find(results, odb::query<#{source_type}::#{name}->id == get_#{name}_id());
|
32
|
+
if (results.size() > 0)
|
33
|
+
errors["#{name}"]["t"] = "validate.uniqueness";
|
34
|
+
}
|
35
|
+
CPP
|
36
|
+
else
|
37
|
+
<<CPP
|
38
|
+
{
|
39
|
+
auto& database = *#{GeneratorBase.odb_connection[:object]}::instance;
|
40
|
+
odb::result<#{source_type}> results;
|
41
|
+
|
42
|
+
database.find(results, odb::query<#{source_type}::#{name} == #{name});
|
43
|
+
if (results.size() > 0)
|
44
|
+
errors["#{name}"]["t"] = "validate.uniqueness";
|
45
|
+
}
|
46
|
+
CPP
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def validate_required type, name
|
51
|
+
if type == "std::string"
|
52
|
+
<<CPP
|
53
|
+
if (#{name} == "")
|
54
|
+
errors["#{name}"]["t"] = "validate.required";
|
55
|
+
CPP
|
56
|
+
elsif type.start_with?("std::shared_ptr")
|
57
|
+
<<CPP
|
58
|
+
if (#{name} == nullptr)
|
59
|
+
errors["#{name}_id"]["t"] = "validate.required";
|
60
|
+
CPP
|
61
|
+
elsif type == "ODB::id_type"
|
62
|
+
<<CPP
|
63
|
+
if (#{name} == 0)
|
64
|
+
errors["#{name}"]["t"] = "validate.required";
|
65
|
+
CPP
|
66
|
+
else
|
67
|
+
""
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def validate_self_reference type, name
|
72
|
+
raw_ptr_type = type.gsub /std::shared_ptr<(.*)>/, '\1*'
|
73
|
+
<<CPP
|
74
|
+
if (#{name} != nullptr && #{name}->get_id() == static_cast<#{raw_ptr_type}>(this)->get_id())
|
75
|
+
errors["#{name}"]["t"] = "validate.self-reference";
|
76
|
+
CPP
|
77
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'metarecord/model'
|
2
|
+
require 'metarecord/generator_base'
|
3
|
+
require 'metarecord/generators/crails/helpers/validations'
|
4
|
+
|
5
|
+
class CrailsQueryGenerator < GeneratorBase
|
6
|
+
def reset
|
7
|
+
super
|
8
|
+
@required_params = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate_for object
|
12
|
+
@headerfile = object[:header]
|
13
|
+
unless @headerfile.nil?
|
14
|
+
@modelname = object[:name].underscore
|
15
|
+
@klassname = get_classname(object)
|
16
|
+
@finalklass = object[:classname]
|
17
|
+
reset
|
18
|
+
self.instance_eval &object[:block]
|
19
|
+
"# include \"#{@headerfile}\"\n" + @src
|
20
|
+
else
|
21
|
+
@src
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def resource_name name
|
26
|
+
end
|
27
|
+
|
28
|
+
def property type, name, options = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
def validation type, name, data
|
32
|
+
end
|
33
|
+
|
34
|
+
def has_one type, name, options = {}
|
35
|
+
end
|
36
|
+
|
37
|
+
def has_many type, name, options = {}
|
38
|
+
type = get_type type
|
39
|
+
if options[:joined] != false
|
40
|
+
_join_based_has_many type, name, options
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def _join_based_has_many type, name, options
|
45
|
+
tptr = ptr_type type
|
46
|
+
list_type = "std::list<#{tptr} >"
|
47
|
+
singular_name = get_singular_name name
|
48
|
+
|
49
|
+
outer_name = (name.split(/-|_|\s/).each do |i| i.capitalize! end).join
|
50
|
+
query_object = "#{@finalklass.split("::").join}By#{outer_name}"
|
51
|
+
|
52
|
+
_append <<CPP
|
53
|
+
#pragma db view pointer(std::shared_ptr) object(#{type}) object(#{@finalklass} inner)
|
54
|
+
struct #{query_object}
|
55
|
+
{
|
56
|
+
std::string get_database_name() const { return #{type}().get_database_name(); }
|
57
|
+
#{id_type} get_id() const { return self ? self->get_id() : #{null_id}; }
|
58
|
+
std::shared_ptr<#{@finalklass}> self;
|
59
|
+
operator #{@finalklass}() const { return *self; }
|
60
|
+
|
61
|
+
#pragma db view pointer(std::shared_ptr) object(#{type}) object(#{@finalklass} inner)
|
62
|
+
struct Count
|
63
|
+
{
|
64
|
+
#pragma db column("count(" + #{@finalklass}::id + ")")
|
65
|
+
size_t value;
|
66
|
+
};
|
67
|
+
};
|
68
|
+
CPP
|
69
|
+
end
|
70
|
+
|
71
|
+
class << self
|
72
|
+
def extension ; ".queries.hpp" ; end
|
73
|
+
|
74
|
+
def make_file filename, data
|
75
|
+
base = "lib/" + filename[0...-3]
|
76
|
+
include = base + ".hpp"
|
77
|
+
file_define = "_#{filename[0...-3].upcase.gsub "/", "_"}_QUERIES_HPP"
|
78
|
+
source = <<CPP
|
79
|
+
#ifndef #{file_define}
|
80
|
+
# define #{file_define}
|
81
|
+
#{(collect_includes_for filename).join "\n"}
|
82
|
+
#{data[:bodies].join "\n"}
|
83
|
+
#endif
|
84
|
+
CPP
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'metarecord/model'
|
2
|
+
require 'metarecord/generator_base'
|
3
|
+
|
4
|
+
class CrailsViewGenerator < GeneratorBase
|
5
|
+
def self.is_file_based? ; false ; end
|
6
|
+
|
7
|
+
def reset
|
8
|
+
@src = ""
|
9
|
+
@declarations = []
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def should_generate_for object
|
14
|
+
(not object[:header].nil?) && (not object[:classname].nil?)
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate_for object
|
18
|
+
reset
|
19
|
+
@declarations << "#include \"#{object[:header]}\"\n"
|
20
|
+
@declarations << "#{object[:classname]}& @model;"
|
21
|
+
property id_type, "id"
|
22
|
+
self.instance_eval &object[:block]
|
23
|
+
@src
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_headers
|
27
|
+
@declarations.join "\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
def property type, name, options = {}
|
31
|
+
return if (not options[:client].nil?) && options[:client][:ignore] == true
|
32
|
+
if type == "DataTree" || type == "LocaleString"
|
33
|
+
_append "json(#{name.inspect}, model.get_#{name}().as_data());"
|
34
|
+
else
|
35
|
+
_append "json(#{name.inspect}, model.get_#{name}());"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_one type, name, options = {}
|
40
|
+
return if (not options[:client].nil?) && options[:client][:ignore] == true
|
41
|
+
if options[:joined] == false
|
42
|
+
_append "if (model.get_#{name}_id() != 0)"
|
43
|
+
_append " json(\"#{name}_id\", model.get_#{name}_id());"
|
44
|
+
else
|
45
|
+
_append "if (model.get_#{name}())"
|
46
|
+
_append " json(\"#{name}_id\", model.get_#{name}()->get_id());"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def has_many type, name, options = {}
|
51
|
+
return if (not options[:client].nil?) && options[:client][:ignore] == true
|
52
|
+
_append "{"
|
53
|
+
@indent += 1
|
54
|
+
id_attr = (get_singular_name name) + "_ids"
|
55
|
+
id_collector = if options[:joined] == false
|
56
|
+
"model.get_#{id_attr}()"
|
57
|
+
else
|
58
|
+
"collect_ids_from(model.get_#{name}())"
|
59
|
+
end
|
60
|
+
_append "const auto relation_ids = #{id_collector};"
|
61
|
+
_append "json_array(#{id_attr.inspect}, relation_ids.begin(), relation_ids.end());"
|
62
|
+
@indent -= 1
|
63
|
+
_append "}"
|
64
|
+
end
|
65
|
+
|
66
|
+
class << self
|
67
|
+
def extension ; ".cjson" ; end
|
68
|
+
|
69
|
+
def make_file filename, data
|
70
|
+
source = ""
|
71
|
+
source += "#include <crails/odb/helpers.hpp>\n"
|
72
|
+
#source += ((Includes.list[filename] || []).collect {|a| "#include \"#{a}\""}).join "\n"
|
73
|
+
source += (collect_includes_for filename).join("\n")
|
74
|
+
source += "\n" + (data[:headers].join "\n")
|
75
|
+
source += "\n// END LINKING\n"
|
76
|
+
source += "\n" + (data[:bodies].join "\n")
|
77
|
+
source
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|