meta-record 1.0.8 → 1.0.9
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 +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: fd905957387d68112f4bb8859fe5ae06db2034f9348ab5fc0905f89dbade4788
|
4
|
+
data.tar.gz: ab7706bc2a7a16473f50608a0a034c686256972060297cc84dcef8a33605034b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50b8d575404dce1818ab374dac6c3109261c9cc28289f2627b150e1c984c7ba01fb142267ee58b28496ff9172b487998e6cd9f7b54d473030b57993f148387ff
|
7
|
+
data.tar.gz: 963ce8511befec8d569fe8308e52781b274b59626e6ceb19a8cd0c298802da48626901a2ce17294282cf6050fd6abd97bb6cee98d3c5db19f784800c46ca245f
|
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.9
|
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
|