meta-record 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|