meta-record 1.0.8 → 1.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/metarecord-make +7 -0
- data/lib/metarecord/generator_base.rb +22 -16
- data/lib/metarecord/generators/comet/archive_generator.rb +5 -1
- data/lib/metarecord/generators/crails/destroy_generator.rb +3 -3
- data/lib/metarecord/generators/crails/view_generator.rb +1 -1
- data/lib/metarecord/generators/qt/base.rb +63 -0
- data/lib/metarecord/generators/qt/header_generator.rb +205 -0
- data/lib/metarecord/generators/qt/source_generator.rb +133 -0
- data/lib/metarecord/properties.rb +83 -0
- data/lib/metarecord/string.rb +29 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58fbb9177aa570904c4a8c5083ac7e8bbcc07e4b0e18f7844bc716a806b15621
|
4
|
+
data.tar.gz: d0ae2bc3f374b37852bda9e98bf6eaaa310aa2a619b680db27df61a32ea94f45
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2585a7e423d1cec1d1cc80c27e012f6569bce7d50695d620ce631aa01fa452441b9d7de9249672b5e3d5dec850f7b55d405732219a4d0222e6e5d3068daa0f9f
|
7
|
+
data.tar.gz: 5d1b3032e8a9510bf383620b3c34eb6626daa749378e35c9809b1d2390e2c98ccdc14f05fe9ddc981984d7e373e31a422f4f77406148283c154601d3a73ca14a
|
data/bin/metarecord-make
CHANGED
@@ -8,11 +8,18 @@ Dir["config/metarecord.rb"].each do |file|
|
|
8
8
|
require "#{Dir.pwd}/#{file}"
|
9
9
|
end
|
10
10
|
|
11
|
+
config_filepath = "config/metarecord.rb"
|
12
|
+
|
11
13
|
@base_path = ""
|
12
14
|
@output = ""
|
13
15
|
@input = []
|
14
16
|
@generators = []
|
15
17
|
@tmpdir = ".tmp"
|
18
|
+
$: << Dir.pwd
|
19
|
+
|
20
|
+
if File.exists? config_filepath
|
21
|
+
require_relative config_filepath
|
22
|
+
end
|
16
23
|
|
17
24
|
OptionParser.new do |opts|
|
18
25
|
opts.on "-v", "--verbose" do @verbose == true end
|
@@ -1,20 +1,7 @@
|
|
1
|
-
class String
|
2
|
-
def underscore
|
3
|
-
self.gsub(/::/, '/').
|
4
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
5
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
6
|
-
tr("-", "_").
|
7
|
-
downcase
|
8
|
-
end
|
9
|
-
|
10
|
-
def camelcase
|
11
|
-
return self if self !~ /_/ && self =~ /[A-Z]+.*/
|
12
|
-
split(/_|\//).map{|e| e.capitalize}.join
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
1
|
require 'pathname'
|
17
2
|
require 'json'
|
3
|
+
require_relative './string'
|
4
|
+
require_relative './properties'
|
18
5
|
|
19
6
|
class GeneratorBase
|
20
7
|
def self.is_file_based? ; true ; end
|
@@ -118,7 +105,7 @@ class GeneratorBase
|
|
118
105
|
|
119
106
|
def make_block delimiters = '{}', &block
|
120
107
|
_append delimiters[0] if delimiters.size > 0
|
121
|
-
indent block
|
108
|
+
indent &block
|
122
109
|
_append delimiters[1] if delimiters.size > 1
|
123
110
|
end
|
124
111
|
|
@@ -199,3 +186,22 @@ class GeneratorBase
|
|
199
186
|
(not options[:client].nil?) && options[:client][:ignore] == true
|
200
187
|
end
|
201
188
|
end
|
189
|
+
|
190
|
+
class GeneratorCppBase < GeneratorBase
|
191
|
+
def nativeTypeNameFor type
|
192
|
+
if type.class == Class
|
193
|
+
case type.name
|
194
|
+
when 'String' then 'std::string'
|
195
|
+
when 'ByteArray' then 'std::string'
|
196
|
+
when 'Hash' then 'DataTree'
|
197
|
+
when 'DateTime' then 'std::time_t'
|
198
|
+
when 'Integer' then 'int'
|
199
|
+
when 'Float' then 'float'
|
200
|
+
when 'Boolean' then 'bool'
|
201
|
+
else type
|
202
|
+
end
|
203
|
+
else
|
204
|
+
type
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -18,6 +18,7 @@ class CometArchiveGenerator < GeneratorBase
|
|
18
18
|
reset
|
19
19
|
_append "#ifndef #{self.class.client_define}"
|
20
20
|
_append "# include <crails/renderer.hpp>"
|
21
|
+
_append "# include <crails/utils/backtrace.hpp>"
|
21
22
|
_append "#endif"
|
22
23
|
_append "#include <crails/archive.hpp>"
|
23
24
|
_append "#include \"#{object[:header]}\"\n"
|
@@ -49,7 +50,10 @@ class CometArchiveGenerator < GeneratorBase
|
|
49
50
|
@indent += 1
|
50
51
|
_append "auto* model = Crails::cast<#{ptr_type}>(vars, \"model\");"
|
51
52
|
_append "OArchive archive;\n"
|
52
|
-
_append "model
|
53
|
+
_append "if (model)"
|
54
|
+
_append " model->serialize(archive);"
|
55
|
+
_append "else"
|
56
|
+
_append " throw boost_ext::runtime_error(\"Called #{funcname} with null model\");"
|
53
57
|
_append "target.set_body(archive.as_string());"
|
54
58
|
@indent -= 1
|
55
59
|
_append "}\n"
|
@@ -101,7 +101,7 @@ class CrailsDestroyGenerator < GeneratorBase
|
|
101
101
|
_append "query = Query::#{relation[:field]}_id == self_id;"
|
102
102
|
end
|
103
103
|
_append "database.find<::#{relation[:class]}>(models, query);"
|
104
|
-
_append "for (auto model :
|
104
|
+
_append "for (auto model : Crails::Odb::to_vector<::#{relation[:class]}>(models))"
|
105
105
|
if relation[:options][:dependent] == :destroy
|
106
106
|
_append " database.destroy(model);"
|
107
107
|
elsif relation[:options][:dependent] == :unlink
|
@@ -127,7 +127,7 @@ class CrailsDestroyGenerator < GeneratorBase
|
|
127
127
|
_append "Query query;\n"
|
128
128
|
_append "query = Query::#{klassname}::id == self_id;"
|
129
129
|
_append "database.find<#{view_klass}>(models, query);"
|
130
|
-
_append "for (auto model :
|
130
|
+
_append "for (auto model : Crails::Odb::to_vector<#{relation[:class]}, #{view_klass}>(models))"
|
131
131
|
_append "{"
|
132
132
|
@indent += 1
|
133
133
|
if relation[:options][:dependent] == :destroy
|
@@ -152,7 +152,7 @@ class CrailsDestroyGenerator < GeneratorBase
|
|
152
152
|
id_field = "#{get_singular_name relation[:field]}_ids"
|
153
153
|
_append "query = Query::#{id_field} + \"@>\" + Crails::Odb::array_to_string(ids, \"int\");"
|
154
154
|
_append "database.find<#{relation[:class]}>(models, query);"
|
155
|
-
_append "for (auto model :
|
155
|
+
_append "for (auto model : Crails::Odb::to_vector<#{relation[:class]}>(models))"
|
156
156
|
_append "{"
|
157
157
|
@indent += 1
|
158
158
|
if relation[:options][:dependent] == :destroy
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'metarecord/model'
|
2
|
+
require 'metarecord/generator_base'
|
3
|
+
|
4
|
+
class GeneratorQtBase < GeneratorBase
|
5
|
+
class << self
|
6
|
+
def super_class
|
7
|
+
if defined? METARECORD_MODEL_SUPER_CLASS
|
8
|
+
METARECORD_MODEL_SUPER_CLASS
|
9
|
+
else
|
10
|
+
"MetaRecordNotifiable"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def super_class_include
|
15
|
+
if defined? METARECORD_MODEL_SUPER_CLASS_PATH
|
16
|
+
METARECORD_MODEL_SUPER_CLASS_PATH
|
17
|
+
else
|
18
|
+
"metarecord-qt/metarecordnotifiable.h"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def id_type
|
24
|
+
"QByteArray"
|
25
|
+
end
|
26
|
+
|
27
|
+
def null_id
|
28
|
+
case id_type
|
29
|
+
when 'QByteArray' then 'QByteArray()'
|
30
|
+
else 0
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_type type
|
35
|
+
if type.kind_of? Class
|
36
|
+
return type.new self if type <= PropertyType
|
37
|
+
end
|
38
|
+
PropertyType.new(nativeTypeNameFor type)
|
39
|
+
end
|
40
|
+
|
41
|
+
def nativeTypeNameFor type
|
42
|
+
if type.class == Class
|
43
|
+
case type.name
|
44
|
+
when 'String' then 'QString'
|
45
|
+
when 'ByteArray' then 'QByteArray'
|
46
|
+
when 'Hash' then 'QVariantMap'
|
47
|
+
when 'DateTime' then 'QDateTime'
|
48
|
+
when 'Integer' then 'qint64'
|
49
|
+
when 'Float' then 'qfloat16'
|
50
|
+
when 'Boolean' then 'bool'
|
51
|
+
else type
|
52
|
+
end
|
53
|
+
else
|
54
|
+
case type
|
55
|
+
when 'std::string' then 'QString'
|
56
|
+
when 'std::time_t' then 'QDateTime'
|
57
|
+
when 'DataTree' then 'QJsonObject'
|
58
|
+
when 'Crails::Odb::id_type' then id_type
|
59
|
+
else type
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'metarecord/generators/qt/base'
|
2
|
+
|
3
|
+
class QtHeaderGenerator < GeneratorQtBase
|
4
|
+
def reset
|
5
|
+
super
|
6
|
+
@state = nil
|
7
|
+
@relations = {}
|
8
|
+
@fields = []
|
9
|
+
@transients = []
|
10
|
+
@signals = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate_for object
|
14
|
+
reset
|
15
|
+
@class_name = object[:name]
|
16
|
+
@inherits = object[:inherits]
|
17
|
+
_append "class #{@class_name} : public #{super_class}"
|
18
|
+
make_block ['{', '};'] do
|
19
|
+
generate_qobject object
|
20
|
+
generate_transient_members unless @transients.empty?
|
21
|
+
unindent do _append "public:" end
|
22
|
+
generate_constructor object
|
23
|
+
generate_methods object
|
24
|
+
generate_signals object
|
25
|
+
generate_members object
|
26
|
+
end
|
27
|
+
@src
|
28
|
+
end
|
29
|
+
|
30
|
+
def super_class
|
31
|
+
if @inherits.nil?
|
32
|
+
self.class.super_class
|
33
|
+
else
|
34
|
+
@inherits
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def generate_qobject object
|
39
|
+
@state = :qproperty
|
40
|
+
_append "Q_OBJECT"
|
41
|
+
_append "Q_PROPERTY(#{id_type} uid READ getUid WRITE setUid NOTIFY uidChanged)"
|
42
|
+
self.instance_eval &object[:block]
|
43
|
+
end
|
44
|
+
|
45
|
+
def generate_constructor object
|
46
|
+
@state = :constructor
|
47
|
+
_append "#{@class_name}(QObject* parent = nullptr);"
|
48
|
+
end
|
49
|
+
|
50
|
+
def generate_methods object
|
51
|
+
@state = :methods
|
52
|
+
self.instance_eval &object[:block]
|
53
|
+
end
|
54
|
+
|
55
|
+
def generate_transient_members
|
56
|
+
list = []
|
57
|
+
macro = "METARECORD_VIRTUAL_PROPERTIES"
|
58
|
+
_append "static const QStringList virtualPropertyNames;"
|
59
|
+
_append "#{macro}(#{super_class}, virtualPropertyNames)"
|
60
|
+
end
|
61
|
+
|
62
|
+
def generate_members object
|
63
|
+
@state = :members
|
64
|
+
self.instance_eval &object[:block]
|
65
|
+
end
|
66
|
+
|
67
|
+
def generate_signals object
|
68
|
+
unindent do _append "Q_SIGNALS:" end
|
69
|
+
@signals.each do |signal|
|
70
|
+
_append "void #{signal}();"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def property type, name, options = {}
|
75
|
+
property_type = type.to_property_type(self)
|
76
|
+
type = property_type.name
|
77
|
+
member = "m_#{name.lower_camelcase}"
|
78
|
+
member = options[:qt][:member] if options[:qt] && options[:qt][:member]
|
79
|
+
getter = name.lower_camelcase
|
80
|
+
setter = "set#{name.camelcase}"
|
81
|
+
signal = "#{name.lower_camelcase}Changed"
|
82
|
+
case @state
|
83
|
+
when :qproperty
|
84
|
+
_append "Q_PROPERTY(#{type} #{name} READ #{getter} WRITE #{setter} NOTIFY #{signal})"
|
85
|
+
@transients << name if options[:db] && options[:db][:transient]
|
86
|
+
@signals << signal
|
87
|
+
when :members
|
88
|
+
if options[:qt].nil? || options[:qt][:member].nil?
|
89
|
+
if options[:default].nil?
|
90
|
+
_append "#{type} #{member};"
|
91
|
+
else
|
92
|
+
_append "#{type} #{member} = #{get_value options[:default]};"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
when :methods
|
96
|
+
getter_options = if options[:qt] && options[:qt][:getter] then options[:qt][:getter] else {} end
|
97
|
+
setter_options = if options[:qt] && options[:qt][:setter] then options[:qt][:setter] else {} end
|
98
|
+
getter_type = property_type.parameter_type getter_options
|
99
|
+
setter_type = property_type.parameter_type setter_options
|
100
|
+
getter_override = if getter_options[:override] then " override" else "" end
|
101
|
+
setter_override = if setter_options[:override] then " override" else "" end
|
102
|
+
_append "virtual #{getter_type} #{getter}() const#{getter_override};"
|
103
|
+
_append "virtual void #{setter}(#{setter_type} _value)#{setter_override};"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def has_one type, name, options = {}
|
108
|
+
id_name = "#{name.lower_camelcase}Id"
|
109
|
+
getter = name.lower_camelcase
|
110
|
+
setter = "set#{name.camelcase}"
|
111
|
+
signal = "#{name}Changed"
|
112
|
+
member_name = "m_#{name.lower_camelcase}"
|
113
|
+
case @state
|
114
|
+
when :qproperty
|
115
|
+
_append "Q_PROPERTY(#{id_type} #{id_name} MEMBER m_#{id_name} NOTIFY #{signal})"
|
116
|
+
_append "Q_PROPERTY(#{type.gsub! /^::/, ''}* #{name} READ #{getter} WRITE #{setter} NOTIFY #{signal})"
|
117
|
+
@transients << name
|
118
|
+
@signals << signal
|
119
|
+
when :constructor
|
120
|
+
_append "connect(this, #{@class_name}::#{signal}, this, #{@class_name}::attributeChanged);"
|
121
|
+
when :methods
|
122
|
+
_append "#{type}* #{getter}() const { return #{member_name}; }"
|
123
|
+
_append "METARECORD_MODEL_SETTER_BY_COPY_WITH_SIGNAL(#{type}, #{member_name}, #{setter}, #{signal})"
|
124
|
+
when :members
|
125
|
+
_append "#{id_type} m_#{id_name} = #{null_id};"
|
126
|
+
_append "#{type}* #{member_name} = nullptr;"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def has_many type, name, options = {}
|
131
|
+
qml_getter = "getQml#{name.camelcase}"
|
132
|
+
getter = name.lower_camelcase
|
133
|
+
setter = "set#{name.camelcase}"
|
134
|
+
member_name = "m_#{name.lower_camelcase}"
|
135
|
+
signal = "#{name}Changed"
|
136
|
+
case @state
|
137
|
+
when :qproperty
|
138
|
+
@src += "# ifdef METARECORD_WITH_QML\n"
|
139
|
+
_append "Q_PROPERTY(QQmlListProperty<#{type}> #{name} READ #{qml_getter} NOTIFY #{signal})"
|
140
|
+
@src += "# endif\n"
|
141
|
+
@signals << signal
|
142
|
+
when :constructor
|
143
|
+
_append "registerRelationship(\"#{name}\", #{name});"
|
144
|
+
when :methods
|
145
|
+
_append "const QList<#{type}*>& #{getter}() const { return #{member_name}; }"
|
146
|
+
_append "void #{setter}(const QList<#{type}*>&);"
|
147
|
+
@src += "# ifdef METARECORD_WITH_QML\n"
|
148
|
+
_append "Q_INVOKABLE QQmlListProperty<#{type}> #{qml_getter}() { return QQmlListProperty<#{type}>(this, &#{member_name}); }"
|
149
|
+
@src += "# endif\n"
|
150
|
+
when :members
|
151
|
+
_append "QList<#{type}*> #{member_name};"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def visibility name
|
156
|
+
case @state
|
157
|
+
when :members
|
158
|
+
@src += name.to_s + ":\n"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def resource_name name
|
163
|
+
case @state
|
164
|
+
when :methods
|
165
|
+
_append "static QByteArray resourceName() { return #{name.to_s.inspect}; }"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def order_by name, flow = nil
|
170
|
+
flow_value = if flow == :desc then -1 else 1 end
|
171
|
+
case @state
|
172
|
+
when :methods
|
173
|
+
_append "static QPair<QByteArray, int> orderedBy() { return {#{name.to_s.inspect}, #{flow_value}}; }"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
class << self
|
178
|
+
def extension ; ".h" ; end
|
179
|
+
|
180
|
+
def is_file_based? ; true ; end
|
181
|
+
|
182
|
+
def generate_includes
|
183
|
+
<<CPP
|
184
|
+
# include <#{super_class_include}>
|
185
|
+
# include <metarecord-qt/hasOne.h>
|
186
|
+
# ifdef METARECORD_WITH_QML
|
187
|
+
# include <QQmlListProperty>
|
188
|
+
# endif
|
189
|
+
CPP
|
190
|
+
end
|
191
|
+
|
192
|
+
def make_file filename, data
|
193
|
+
file_define = "_#{filename[0...-3].upcase.gsub "/", "_"}_H"
|
194
|
+
source = <<CPP
|
195
|
+
#ifndef #{file_define}
|
196
|
+
# define #{file_define}
|
197
|
+
#{generate_includes}
|
198
|
+
#{collect_includes_for(filename, true).join "\n"}
|
199
|
+
|
200
|
+
#{data[:bodies].join "\n"}
|
201
|
+
#endif
|
202
|
+
CPP
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'metarecord/generators/qt/base'
|
2
|
+
|
3
|
+
class QtSourceGenerator < GeneratorQtBase
|
4
|
+
def reset
|
5
|
+
super
|
6
|
+
@state = nil
|
7
|
+
@relations = {}
|
8
|
+
@fields = []
|
9
|
+
@transients = []
|
10
|
+
@signals = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate_for object
|
14
|
+
reset
|
15
|
+
@class_name = object[:name]
|
16
|
+
@inherits = object[:inherits]
|
17
|
+
generate_constructor object
|
18
|
+
generate_transient_members unless @transients.empty?
|
19
|
+
generate_methods object
|
20
|
+
@src
|
21
|
+
end
|
22
|
+
|
23
|
+
def super_class
|
24
|
+
if @inherits.nil?
|
25
|
+
self.class.super_class
|
26
|
+
else
|
27
|
+
@inherits
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate_constructor object
|
32
|
+
@state = :constructor
|
33
|
+
_append "#{@class_name}::#{@class_name}(QObject* parent) : #{super_class}(parent)"
|
34
|
+
make_block do
|
35
|
+
self.instance_eval &object[:block]
|
36
|
+
end
|
37
|
+
_append ""
|
38
|
+
end
|
39
|
+
|
40
|
+
def generate_transient_members
|
41
|
+
@transients.each do |member|
|
42
|
+
list << "{#{member.inspect}}"
|
43
|
+
end
|
44
|
+
_append "const QStringList #{@class_name}::virtualPropertyNames = {#{list.join ','}};"
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate_methods object
|
48
|
+
@state = :methods
|
49
|
+
self.instance_eval &object[:block]
|
50
|
+
end
|
51
|
+
|
52
|
+
def property type, name, options = {}
|
53
|
+
property_type = type.to_property_type(self)
|
54
|
+
type = property_type.name
|
55
|
+
member = "m_#{name.lower_camelcase}"
|
56
|
+
member = options[:qt][:member] if options[:qt] && options[:qt][:member]
|
57
|
+
getter = name.lower_camelcase
|
58
|
+
setter = "set#{name.camelcase}"
|
59
|
+
signal = "#{name.lower_camelcase}Changed"
|
60
|
+
case @state
|
61
|
+
when :constructor
|
62
|
+
_append "connect(this, &#{@class_name}::#{signal}, this, &#{@class_name}::attributeChanged);"
|
63
|
+
unless options[:qt].nil? || options[:qt][:member].nil?
|
64
|
+
_append "#{member} = #{get_value options[:default]};" unless options[:default].nil?
|
65
|
+
end
|
66
|
+
@transients << name if options[:db] && options[:db][:transient]
|
67
|
+
when :methods
|
68
|
+
getter_options = if options[:qt] && options[:qt][:getter] then options[:qt][:getter] else {} end
|
69
|
+
setter_options = if options[:qt] && options[:qt][:setter] then options[:qt][:setter] else {} end
|
70
|
+
getter_type = property_type.parameter_type getter_options
|
71
|
+
setter_type = property_type.parameter_type setter_options
|
72
|
+
_append "\n#{getter_type} #{@class_name}::#{getter}() const"
|
73
|
+
make_block do
|
74
|
+
_append "return #{member};"
|
75
|
+
end
|
76
|
+
_append "\nvoid #{@class_name}::#{setter}(#{setter_type} _value)"
|
77
|
+
make_block do
|
78
|
+
_append "if (_value != #{member})"
|
79
|
+
make_block do
|
80
|
+
_append "#{member} = _value;"
|
81
|
+
_append "Q_EMIT #{signal}();"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def has_one type, name, options = {}
|
88
|
+
case @state
|
89
|
+
when :constructor
|
90
|
+
@transients << name
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def has_many type, name, options = {}
|
95
|
+
setter = "set#{name.camelcase}"
|
96
|
+
member_name = "m_#{name.lower_camelcase}"
|
97
|
+
signal = "#{name}Changed"
|
98
|
+
case @state
|
99
|
+
when :constructor
|
100
|
+
_append "registerRelationship(\"#{name}\", #{member_name});"
|
101
|
+
when :methods
|
102
|
+
_append "void #{@class_name}::#{setter}(const QList<#{type}*>& value)"
|
103
|
+
make_block do
|
104
|
+
_append "#{member_name} = value;"
|
105
|
+
_append "Q_EMIT #{signal}();"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def visibility name
|
111
|
+
end
|
112
|
+
|
113
|
+
def resource_name name
|
114
|
+
end
|
115
|
+
|
116
|
+
def order_by name, flow = nil
|
117
|
+
end
|
118
|
+
|
119
|
+
class << self
|
120
|
+
def extension ; ".cpp" ; end
|
121
|
+
|
122
|
+
def is_file_based? ; true ; end
|
123
|
+
|
124
|
+
def make_file filename, data
|
125
|
+
source = <<CPP
|
126
|
+
#include "#{filename.split('/').last[0...-3]}.h"
|
127
|
+
#{collect_includes_for(filename).join "\n"}
|
128
|
+
|
129
|
+
#{data[:bodies].join "\n"}
|
130
|
+
CPP
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
class PropertyType
|
2
|
+
def initialize name
|
3
|
+
@name = name
|
4
|
+
end
|
5
|
+
|
6
|
+
def name
|
7
|
+
@name
|
8
|
+
end
|
9
|
+
|
10
|
+
def parameter_type options = {}
|
11
|
+
if (pass_by_const_reference? && options[:ref].nil?) || options[:ref]
|
12
|
+
"const #{@name}&"
|
13
|
+
else
|
14
|
+
@name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def pass_by_const_reference?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class PropertyTypeFromRubyType < PropertyType
|
24
|
+
def initialize name, sourceType
|
25
|
+
super name
|
26
|
+
@sourceType = sourceType
|
27
|
+
end
|
28
|
+
|
29
|
+
def pass_by_const_reference?
|
30
|
+
if [Float, Integer, Fixnum, Bignum, Complex, Rational].include? @sourceType
|
31
|
+
false
|
32
|
+
else
|
33
|
+
true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Boolean < PropertyType
|
39
|
+
def initialize parent
|
40
|
+
super(if parent.methods.include?(:nativeTypeNameFor)
|
41
|
+
name = parent.nativeTypeNameFor ByteArray
|
42
|
+
if name == ByteArray then default_name else name end
|
43
|
+
else
|
44
|
+
default_name
|
45
|
+
end)
|
46
|
+
end
|
47
|
+
|
48
|
+
def default_name
|
49
|
+
"bool"
|
50
|
+
end
|
51
|
+
|
52
|
+
def pass_by_const_reference?
|
53
|
+
false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class ByteArray < PropertyType
|
58
|
+
def initialize parent
|
59
|
+
super(if parent.methods.include?(:nativeTypeNameFor)
|
60
|
+
name = parent.nativeTypeNameFor ByteArray
|
61
|
+
if name == ByteArray then default_name else name end
|
62
|
+
else
|
63
|
+
default_name
|
64
|
+
end)
|
65
|
+
end
|
66
|
+
|
67
|
+
def default_name
|
68
|
+
"std::string"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class Class
|
73
|
+
def to_property_type parent
|
74
|
+
if self <= PropertyType
|
75
|
+
self.new parent
|
76
|
+
elsif parent.methods.include? :nativeTypeNameFor
|
77
|
+
PropertyTypeFromRubyType.new parent.nativeTypeNameFor(self), self
|
78
|
+
else
|
79
|
+
throw "Cannot use Class as a property type parameter with a generator that doesn't implement nativeTypeNameFor"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative './properties'
|
2
|
+
|
3
|
+
class String
|
4
|
+
def underscore
|
5
|
+
self.gsub(/::/, '/').
|
6
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
7
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
8
|
+
tr("-", "_").
|
9
|
+
downcase
|
10
|
+
end
|
11
|
+
|
12
|
+
def camelcase
|
13
|
+
return self if self !~ /_/ && self =~ /[A-Z]+.*/
|
14
|
+
split(/_|\//).map{|e| e.capitalize}.join
|
15
|
+
end
|
16
|
+
|
17
|
+
def lower_camelcase
|
18
|
+
upperCamelcase = camelcase
|
19
|
+
upperCamelcase[0].downcase + upperCamelcase[1..-1]
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_property_type parent
|
23
|
+
if parent.methods.include? :nativeTypeNameFor
|
24
|
+
PropertyType.new(parent.nativeTypeNameFor self)
|
25
|
+
else
|
26
|
+
PropertyType.new self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
metadata
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meta-record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Martin Moro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
14
|
MetaRecord is a code generator that allows you to define your application
|
15
15
|
models using a Ruby-powered DSL, and generates various implementation for
|
16
16
|
them, for your web server, client, or mobile application.
|
17
|
-
It can
|
17
|
+
It can generate code for the following targests: Crails, Qt, ActiveRecord,
|
18
18
|
Comet.cpp, and Aurelia.js.
|
19
19
|
email: michael@unetresgrossebite.com
|
20
20
|
executables:
|
@@ -36,13 +36,18 @@ files:
|
|
36
36
|
- lib/metarecord/generators/crails/helpers/validations.rb
|
37
37
|
- lib/metarecord/generators/crails/query_generator.rb
|
38
38
|
- lib/metarecord/generators/crails/view_generator.rb
|
39
|
+
- lib/metarecord/generators/qt/base.rb
|
40
|
+
- lib/metarecord/generators/qt/header_generator.rb
|
41
|
+
- lib/metarecord/generators/qt/source_generator.rb
|
39
42
|
- lib/metarecord/generators/rails/data_generator.rb
|
40
43
|
- lib/metarecord/generators/rails/migration_generator.rb
|
41
44
|
- lib/metarecord/generators/rails/migrations/table_helpers.rb
|
42
45
|
- lib/metarecord/generators/rails/migrations/type_helpers.rb
|
43
46
|
- lib/metarecord/manifest_generator.rb
|
44
47
|
- lib/metarecord/model.rb
|
48
|
+
- lib/metarecord/properties.rb
|
45
49
|
- lib/metarecord/runner.rb
|
50
|
+
- lib/metarecord/string.rb
|
46
51
|
homepage: https://github.com/crails-framework/meta-record
|
47
52
|
licenses:
|
48
53
|
- 0BSD
|