dataMetaDom 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,141 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+
3
+ require 'set'
4
+ require 'dataMetaDom/util'
5
+ require 'dataMetaDom/recAttr'
6
+ require 'dataMetaDom/dataType'
7
+ require 'dataMetaDom/field'
8
+ require 'dataMetaDom/docs'
9
+ require 'dataMetaDom/enum'
10
+ require 'dataMetaDom/record'
11
+ require 'dataMetaDom/ref'
12
+ require 'dataMetaDom/sourceFile'
13
+ require 'date'
14
+ require 'dataMetaXtra'
15
+ require 'dataMetaDom/sources'
16
+ require 'dataMetaDom/model'
17
+
18
+ =begin rdoc
19
+
20
+ DataMeta DOM infrastructure root.
21
+
22
+ For command line details either check the new method's source or the README.rdoc file, the usage section.
23
+
24
+ =end
25
+ module DataMetaDom
26
+
27
+ # Current version
28
+ VERSION = '1.0.0'
29
+
30
+ =begin rdoc
31
+ Quick and dirty turning a Windows path into a path of the platform on which this script is running.
32
+ Assumes that backslash is never used as a part of a directory name, pretty safe assumption.
33
+ =end
34
+ def uniPath(source)
35
+ source.gsub(/\\/, File::SEPARATOR)
36
+ end
37
+
38
+ =begin rdoc
39
+ Returns an array of the namespace and the base, first element nil if no namespace
40
+ both elements nil if not a proper namespace.
41
+ @param [String] source source text to split
42
+ @return [Array] array of +String+, the namespace and the base
43
+ =end
44
+ def splitNameSpace(source)
45
+ #noinspection RubyNestedTernaryOperatorsInspection
46
+ source =~ /(\w[\w\.]*)\.(#{TYPE_START}\w*)/ ? [($1.empty? ? nil : $1), $2] :
47
+ (source =~ /(#{TYPE_START}\w*)/ ? [nil, source] : [nil, nil])
48
+ end
49
+
50
+ # adjust the namespace if required
51
+ def nsAdjustment(namespace, options, src)
52
+ src && options[:autoNsVer] ? "#{namespace}.v#{src.ver.full.toVarName}" : namespace
53
+ end
54
+
55
+ =begin rdoc
56
+ Combines the namespace with the base name: if the namespace is empty or +nil+, returns the base name as a symbol,
57
+ otherwise returns namespace.base
58
+ @param [String] namespace the namespace part
59
+ @param [String] base the base name of the entity
60
+ @return [String] base and namespace properly combined into full name specification
61
+ =end
62
+ def combineNsBase(namespace, base)
63
+ namespace && !namespace.empty? ? "#{namespace}.#{base}".to_sym : base.to_sym
64
+ end
65
+
66
+ =begin rdoc
67
+ Given the namespace and the base, returns true if the namespace is a valid one.
68
+ @param [String] namespace the namespace part
69
+ @param [String] base the base name of the entity
70
+ @return [Boolean] true if the given namespace passes simple smell check with the given base
71
+ =end
72
+ def validNs?(namespace, base)
73
+ namespace && !namespace.empty? && namespace.to_sym != base
74
+ end
75
+
76
+ =begin rdoc
77
+ if name is a standard type, return it.
78
+ if name is a fully qualified namespaced name, return it
79
+ otherwise, combine the namespace provided with the base to return the full name
80
+ =end
81
+ def fullTypeName(namespace, name)
82
+ #noinspection RubyUnusedLocalVariable
83
+ ns, _ = splitNameSpace(name.to_s) # if it is already a full namespaced name or a standard type, return original
84
+ validNs?(ns, name) || STANDARD_TYPES.member?(name) ? name.to_sym : "#{combineNsBase(namespace, name)}".to_sym
85
+ end
86
+
87
+ # Returns qualified name for the given namespace: strips the namespace if the namespace is the same, or keep it
88
+ def qualName(namespace, name)
89
+ ns, b = splitNameSpace(name.to_s)
90
+ !STANDARD_TYPES.member?(name.to_sym) && (!validNs?(ns, b) || ns == namespace) ? b : name
91
+ end
92
+
93
+ =begin rdoc
94
+ Simplest diminfo to be reused wherever no other aspect of a datatype is needed
95
+
96
+ @!attribute [r] len
97
+ @return [Fixnum] the Length part of the dimension info
98
+ @!attribute [r] scale
99
+ @return [Fixnum] the Scale part of the dimension info
100
+
101
+ =end
102
+ class DimInfo
103
+
104
+ attr_reader :len, :scale
105
+
106
+ # Creates an instance with the given parameters
107
+ def initialize(len, scale); @len = len; @scale = scale end
108
+
109
+ # Textual representation of this instance, length.scale
110
+ def to_s; "#{@len}.#{@scale}" end
111
+
112
+ # Convenience constant - NIL dimension to use in the types that are not dimensioned.
113
+ NIL=DimInfo.new(nil, nil)
114
+ end
115
+
116
+ =begin rdoc
117
+ # Parses parenthesized dimension info such as (18, 2) or just (18)
118
+
119
+ Returns DimInfo::NIL if the dimSpec is +nil+ or the DimInfo instance as specified
120
+ =end
121
+ def getParenDimInfo(dimSpec)
122
+ return DimInfo::NIL unless dimSpec
123
+ result = dimSpec =~ /^\s*\(\s*(\d+)\s*(?:,\s*(\d+))?\s*\)\s*$/
124
+ raise "Invalid dimension specification: '#{dimSpec}'" unless result
125
+ DimInfo.new($1.to_i, $2.to_i)
126
+ end
127
+
128
+ =begin rdoc
129
+ Adds options to help and version from the first argument
130
+ And shortcuts to showing the help screen if the ARGV is empty.
131
+ The options for help are either <tt>--help</tt> or </tt>-h</tt>.
132
+ The option for show version and exit is either <tt>--version</tt> or <tt>-v</tt>.
133
+ =end
134
+ def helpAndVerFirstArg
135
+ raise Trollop::HelpNeeded if ARGV.empty? || ARGV[0] == '--help' || ARGV[0] == '-h' # show help screen
136
+ raise Trollop::VersionNeeded if ARGV[0] == '--version' || ARGV[0].downcase == '-v' # show version screen
137
+ end
138
+
139
+ module_function :combineNsBase, :splitNameSpace, :uniPath, :validNs?, :getParenDimInfo,
140
+ :helpAndVerFirstArg, :fullTypeName, :nsAdjustment
141
+ end
@@ -0,0 +1,130 @@
1
+ # keep this underscore naming in the test subdir, it's easier to append files names to test
2
+ require './test/test_helper.rb'
3
+
4
+ # Unit test cases for the DataMetaDom
5
+ # See for instance:
6
+ # - test_full
7
+ class TestNewGem < Test::Unit::TestCase
8
+
9
+ # an empty stub for now
10
+ def setup
11
+ DataMetaDom::L.level = Logger::DEBUG
12
+ end
13
+
14
+ =begin rdoc
15
+ Tests splitting full name without namespace, the base class name only.
16
+ =end
17
+ def test_splitNameSpaceClassOnly
18
+ orig = 'ZeeKlass'
19
+ ns, base = DataMetaDom.splitNameSpace('ZeeKlass')
20
+ assert_nil(ns, "for the original #{orig}, namespace must be nil")
21
+ assert_equal(orig, base)
22
+ end
23
+
24
+ =begin rdoc
25
+ Helper method to test the given combination of the NS and the Base,
26
+ to vary the parameters and make sure they all work
27
+ =end
28
+ def splitNameSpaceFullLevelN(origNs, origBase)
29
+ origFull = DataMetaDom.combineNsBase(origNs, origBase)
30
+ ns, base = DataMetaDom.splitNameSpace(origFull)
31
+ assert_equal(origBase, base)
32
+ assert_equal(origNs, ns)
33
+ DataMetaDom::L.info "original: #{origNs}.#{origBase}, orig ver=#{origFull}, ns=#{ns}, base=#{base}"
34
+ end
35
+
36
+ =begin rdoc
37
+ Uses splitNameSpaceFullLevelN to test 3 levels of namespace nesting.
38
+ =end
39
+ def test_splitNameSpaceFull
40
+ %w(Klass ZeeKlass).each { |c|
41
+ splitNameSpaceFullLevelN('one', c)
42
+ splitNameSpaceFullLevelN('one.two', c)
43
+ splitNameSpaceFullLevelN('one.two.three', c)
44
+ }
45
+ end
46
+
47
+ # Semantic Version Parsing scenarios
48
+ def test_semVerParsing
49
+ assert_raise(ArgumentError) { DataMetaDom::SemVer.new('.2.3') }
50
+ assert_raise(ArgumentError) { DataMetaDom::SemVer.new('1.2.') }
51
+ assert_raise(ArgumentError) { DataMetaDom::SemVer.new('1a.2.3') }
52
+ assert_raise(ArgumentError) { DataMetaDom::SemVer.new('1.2a.3') }
53
+ assert_raise(ArgumentError) { DataMetaDom::SemVer.new('1.2.a3') }
54
+ assert_raise(ArgumentError) { DataMetaDom::SemVer.new('') }
55
+ assert_raise(ArgumentError) { DataMetaDom::SemVer.new(nil) }
56
+ assert_raise(ArgumentError) { DataMetaDom::SemVer.new('-1.2.3') }
57
+ assert_raise(ArgumentError) { DataMetaDom::SemVer.new('1.-2.3') }
58
+ assert_raise(ArgumentError) { DataMetaDom::SemVer.new('1.2.-3') }
59
+
60
+ assert_true(DataMetaDom::SemVer.new('12.234.456').toVarName == '12_234_456')
61
+ assert_true(DataMetaDom::SemVer.new('12.234.456.7890').toVarName == '12_234_456_7890')
62
+ assert_true(DataMetaDom::SemVer.new('12.234.456.7890.blah.yada.meh').toVarName == '12_234_456_7890')
63
+
64
+ v = DataMetaDom::SemVer.new('12.345.6.7')
65
+ DataMetaDom::L.debug("Parsed: #{fullSemVerInfo(v)}")
66
+ assertSemVer(v, 12, 345, 6, 7)
67
+
68
+ v = DataMetaDom::SemVer.new('12.345.6.7.blah-blah-yada.yada')
69
+ DataMetaDom::L.debug("Parsed: #{fullSemVerInfo(v)}")
70
+ assertSemVer(v, 12, 345, 6, 7)
71
+
72
+ v = DataMetaDom::SemVer.new('12.345.6')
73
+ DataMetaDom::L.debug("Parsed: #{fullSemVerInfo(v)}")
74
+ assertSemVer(v, 12, 345, 6, nil)
75
+
76
+ v = DataMetaDom::SemVer.new('12.345.6.blah-blah-yada.yada')
77
+ DataMetaDom::L.debug("Parsed: #{fullSemVerInfo(v)}")
78
+ assertSemVer(v, 12, 345, 6, nil)
79
+
80
+ end
81
+
82
+ # Semantic Version Comparison
83
+ def test_semVerCmp
84
+ v1, v2 = DataMetaDom::SemVer.new('5.6.7'), DataMetaDom::SemVer.new('12.15.16')
85
+ assert_true( (v1.source <=> v2.source) > 0) # stringwise, v1 > v2
86
+ assert_true( (v1 <=> v2) < 0) # versionwise, v1 < v2
87
+
88
+ v1, v2 = DataMetaDom::SemVer.new('5.6.7.8'), DataMetaDom::SemVer.new('5.6.7')
89
+ assert_true( (v1.source <=> v2.source) > 0)
90
+ DataMetaDom::L.debug("v1.items=#{v1.items.inspect}, v2.items=#{v2.items.inspect}")
91
+ assert_true( (v1 <=> v2) > 0)
92
+
93
+ v1, v2 = DataMetaDom::SemVer.new('5.6.7'), DataMetaDom::SemVer.new('5.6.7.8')
94
+ assert_true( (v1.source <=> v2.source) < 0)
95
+ assert_true( (v1 <=> v2) < 0)
96
+
97
+ v1, v2 = DataMetaDom::SemVer.new('5.6.7.3'), DataMetaDom::SemVer.new('5.6.7.12')
98
+ assert_true( (v1.source <=> v2.source) > 0)
99
+ assert_true( (v1 <=> v2) < 0)
100
+
101
+ v1, v2 = DataMetaDom::SemVer.new('5.6.7.8'), DataMetaDom::SemVer.new('5.6.7.8')
102
+ assert_true( (v1.source <=> v2.source) == 0)
103
+ assert_true( (v1 <=> v2) == 0)
104
+ end
105
+
106
+ def test_diffLevel
107
+ assert_equal(DataMetaDom::SemVer.new('1.2.3').diffLevel(DataMetaDom::SemVer.new('1.2.3.blah')), DataMetaDom::SemVer::DiffLevel::NONE)
108
+ assert_equal(DataMetaDom::SemVer.new('1.2.3.4').diffLevel(DataMetaDom::SemVer.new('1.2.3.4.blah')), DataMetaDom::SemVer::DiffLevel::NONE)
109
+ assert_equal(DataMetaDom::SemVer.new('1.2.3').diffLevel(DataMetaDom::SemVer.new('2.2.3.blah')), DataMetaDom::SemVer::DiffLevel::MAJOR)
110
+ assert_equal(DataMetaDom::SemVer.new('1.2.3').diffLevel(DataMetaDom::SemVer.new('1.4.3.blah')), DataMetaDom::SemVer::DiffLevel::MINOR)
111
+ assert_equal(DataMetaDom::SemVer.new('1.2.3').diffLevel(DataMetaDom::SemVer.new('1.2.4.blah')), DataMetaDom::SemVer::DiffLevel::UPDATE)
112
+ assert_equal(DataMetaDom::SemVer.new('1.2.3.4').diffLevel(DataMetaDom::SemVer.new('1.2.3.blah')), DataMetaDom::SemVer::DiffLevel::BUILD)
113
+ assert_equal(DataMetaDom::SemVer.new('1.2.3').diffLevel(DataMetaDom::SemVer.new('1.2.3.4.blah')), DataMetaDom::SemVer::DiffLevel::BUILD)
114
+ assert_equal(DataMetaDom::SemVer.new('1.2.3.4').diffLevel(DataMetaDom::SemVer.new('1.2.3.5.blah')), DataMetaDom::SemVer::DiffLevel::BUILD)
115
+ end
116
+
117
+ # Helper method
118
+ def fullSemVerInfo(semVer)
119
+ %<#{semVer.to_long_s}: maj=#{semVer.major}, min=#{semVer.minor}, upd=#{semVer.update}, bld=#{semVer.build}>
120
+ end
121
+
122
+ # Helper method
123
+ def assertSemVer(semVer, maj, min, upd, bld)
124
+ assert_equal(semVer.major, maj)
125
+ assert_equal(semVer.minor, min)
126
+ assert_equal(semVer.update, upd)
127
+ assert_equal(semVer.build, bld)
128
+ end
129
+ end
130
+
@@ -0,0 +1,6 @@
1
+ ## keep this underscore naming in the test subdir, it's easier to append files names to test
2
+ %w(stringio test/unit).each { |r| require r }
3
+ # this is expected to run from the project root, normally by the rake file
4
+ require './lib/dataMetaDom'
5
+ require './lib/dataMetaDom/util'
6
+ require './lib/dataMetaDom/ver'
@@ -0,0 +1,172 @@
1
+ <%#
2
+ Template for Java POJO migration scenario, includes full migration support for enums too.
3
+ %>
4
+ package <%=javaPackage%>;
5
+
6
+ /*
7
+ This class is generated by DataMeta DOM. Do not edit manually!
8
+ */
9
+ import java.time.ZonedDateTime;
10
+ import org.ebay.datameta.dom.Migrator;
11
+ import java.util.stream.Collectors;
12
+ import java.util.ArrayList;
13
+ import java.util.LinkedList;
14
+ import java.util.List;
15
+ import java.util.Set;
16
+
17
+ import static java.util.stream.Collectors.toList;
18
+ import static java.util.stream.Collectors.toSet;
19
+
20
+ <%
21
+ srcPackage = javaPackage.gsub(".v#{ver2.toVarName}", ".v#{ver1.toVarName}")
22
+ %>
23
+ public class <%=javaClassName%> implements Migrator<<%=srcPackage%>.<%=baseName%>, <%=baseName%>> {
24
+
25
+ private static final <%=javaClassName%> INSTANCE = new <%=javaClassName%>();
26
+
27
+ public static <%=javaClassName%> getInstance() { return INSTANCE; }
28
+
29
+ public <%=baseName%> migrate(<%=srcPackage%>.<%=baseName%> src, Object... xtras) {
30
+ final <%=baseName%> result = new <%=baseName%>();
31
+ <%
32
+ srcFldKeys = Set.new srcE.fields.keys
33
+ trgFldKeys = Set.new trgE.fields.keys
34
+ added = trgFldKeys - srcFldKeys
35
+ addedReq = added.select{|k| trgE[k].isRequired}
36
+ addedOpt = added.reject{|k| trgE[k].isRequired}
37
+ if addedReq.size > 0
38
+ migrCtx.canAuto = false%>
39
+ !!>/* !!> The following <%=addedReq.size%> required field(s) added to this record:
40
+ !!> <%= addedReq.map{|k| k.to_s}.sort.join(', ') %>
41
+ !!> you must add some value for those here */
42
+ <%end
43
+
44
+ if addedOpt.size > 0%>
45
+ /*
46
+ The following <%=addedOpt.size%> optional field(s) added to this record:
47
+ <%= addedOpt.map{|k| k.to_s}.sort.join(', ') %>
48
+ no action taken on this.
49
+ */
50
+ <% end
51
+
52
+ removed = srcFldKeys - trgFldKeys
53
+ if removed.size > 0%>
54
+ /*
55
+ The following <%=removed.size%> field(s) removed from this record:
56
+ <%= removed.map{|k| k.to_s}.sort.join(', ') %>
57
+ no action taken on this.
58
+ */
59
+ <%end
60
+ # _erbout << "/*\ntrgE.fields.keys: #{trgE.fields.keys.inspect}\n*/\n"
61
+ trgE.fields.keys.sort.each { |trgK|
62
+ vars.trgFld = trgE.fields[trgK]
63
+ vars.trgDType = vars.trgFld.dataType
64
+ vars.trgType = vars.trgDType.type
65
+ if vars.trgFld.trgType
66
+ migrCtx.canAuto = false%>
67
+ !!> // field "<%=vars.trgFld.name%>" is a map. Maps currently are not supported on serialization level!!<%
68
+ end
69
+ vars.srcFld = srcE.fields[trgK]
70
+ # _erbout << "//trgFld=#{vars.trgFld}, srcFld=#{vars.srcFld}\n"
71
+ next unless vars.srcFld
72
+ vars.srcType = flipVer(vars.srcFld.dataType.type, ver2, ver1)
73
+ if model1.records[vars.srcType] # DataMeta DOM record type
74
+ fNs, vars.fBase = DataMetaDom.splitNameSpace(vars.trgFld.dataType.type)
75
+ if vars.trgFld.aggr
76
+ case vars.trgFld.aggr
77
+ when Field::SET
78
+ %> result.<%=setterName(vars.trgFld)%>(src.<%=getterName(vars.trgFld)%>().stream().map(e -> <%=migrClass(vars.fBase, ver1, ver2)%>.getInstance().migrate(e)).collect(toSet()));
79
+ <% when Field::DEQUE
80
+ %> result.<%=setterName(vars.trgFld)%>(new LinkedList<>(src.<%=getterName(vars.trgFld)%>().stream().map(e -> <%=migrClass(vars.fBase, ver1, ver2)%>.getInstance().migrate(e)).collect(toList())));
81
+ <% when Field::LIST
82
+ %> result.<%=setterName(vars.trgFld)%>(new ArrayList<>(src.<%=getterName(vars.trgFld)%>().stream().map(e -> <%=migrClass(vars.fBase, ver1, ver2)%>.getInstance().migrate(e)).collect(toList())));
83
+ <% else
84
+ raise ArgumentError, %<Unsupported aggregation type "#{vars.trgFld.aggr}" on the field "#{trgK}" of the record>
85
+ end
86
+ #result.setEmbeds(new ArrayList<>(src.getEmbeds().stream().map(e -> Migrate_EmbeddedType_v6_to_v7.getInstance().migrate(e)).collect(toList())));
87
+ #result.setIdLessNess(src.getIdLessNess().stream().map(e -> Migrate_IdLess_v6_to_v7.getInstance().migrate(e)).collect(toSet()));
88
+ else
89
+ if vars.srcFld.aggr
90
+ migrCtx.canAuto = false%>
91
+ !!> // field "<%=vars.trgFld.name%>" changed from aggregate to scalar, you need to write up custom code for this.
92
+ <% else%>
93
+ result.<%=setterName(vars.trgFld)%>(<%=migrClass(vars.fBase, ver1, ver2)%>.getInstance().migrate(src.<%=getterName(vars.trgFld)%>()));
94
+ <% end
95
+
96
+ end
97
+
98
+ elsif model1.enums[vars.srcType] # DataMeta enum type
99
+ unless model2.enums[vars.trgType]
100
+ migrCtx.canAuto = false%>
101
+ !!> // field "<%=vars.trgFld.name%>" turned from an enumerable type to a non-enumerable type. Please handle this manually.!!
102
+ <% end
103
+ fNs, vars.fBase = DataMetaDom.splitNameSpace(vars.trgFld.dataType.type)
104
+ e1 = model1.enums[vars.srcType]
105
+ e2 = model2.enums[vars.trgType]
106
+ if e2.kind_of?(DataMetaDom::Mappings)
107
+ migrCtx.canAuto = false%>
108
+ !! Field "<%=vars.trgFld.name%>" is a mapping. Mappings are not supported on serialization level!!
109
+ <% elsif e2.kind_of?(DataMetaDom::BitSet)
110
+ migrCtx.canAuto = false%>
111
+ !! Field "<%=vars.trgFld.name%>" is a Bit Set. Bit Sets are not supported on serialization level!!
112
+ <% else
113
+ if e2.isEqOrXtOf(e1) == :ne
114
+ migrCtx.canAuto = false%>
115
+ !!> // Irreconcilable changes in the enum field "<%=vars.trgFld.name%>": list of [<%= e1.rawVals * ', ' %>] to [<%=e2.rawVals * ', '%>]. Please handle this manually.!!
116
+ <% else%>
117
+ result.<%=setterName(vars.trgFld)%>(<%=vars.fBase%>.forOrd(src.<%=getterName(vars.trgFld)%>().ordinal()));
118
+ <% end
119
+ end
120
+
121
+ else # DataMeta DOM standard type
122
+ vars.srcDType = vars.srcFld.dataType # can go easy on namespaces and such, they don't apply to std types
123
+ vars.srcType = vars.srcDType.type
124
+ case vars.trgType
125
+ when DATETIME
126
+ if vars.srcType == DATETIME%>
127
+ result.<%=setterName(vars.trgFld)%>(src.<%=getterName(vars.trgFld)%>());
128
+ <% else
129
+ migrCtx.canAuto = false%>
130
+ !!> // Field "<%=vars.trgFld.name%>" changed from <%=vars.srcType%> to <%=vars.trgType%> -- please handle this manually!
131
+ <% end
132
+ when URL%>
133
+ result.<%=setterName(vars.trgFld)%>(src.<%=getterName(vars.trgFld)%>());
134
+ <%
135
+ when BOOL%>
136
+ result.<%=setterName(vars.trgFld)%>(src.<%=getterName(vars.trgFld)%>());
137
+ <% when INT
138
+ if vars.trgFld.aggr%>
139
+ //noinspection Convert2MethodRef
140
+ result.<%=setterName(vars.trgFld)%>(<%=setAggrPrims(vars.trgFld)%>);
141
+ <% else
142
+ if vars.trgDType.length == vars.srcDType.length%>
143
+ result.<%=setterName(vars.trgFld)%>(src.<%=getterName(vars.trgFld)%>());
144
+ <% else%>
145
+ result.<%=setterName(vars.trgFld)%>(src.<%=getterName(vars.trgFld)%>().<%=primValMethod(vars.trgDType)%>());
146
+ <% end
147
+ end
148
+ when FLOAT
149
+ if vars.trgFld.aggr%>
150
+ //noinspection Convert2MethodRef
151
+ result.<%=setterName(vars.trgFld)%>(<%=setAggrPrims(vars.trgFld)%>);
152
+ <% else
153
+ if vars.trgDType.length == vars.srcDType.length%>
154
+ result.<%=setterName(vars.trgFld)%>(src.<%=getterName(vars.trgFld)%>());
155
+ <% else%>
156
+ result.<%=setterName(vars.trgFld)%>(src.<%=getterName(vars.trgFld)%>().<%=primValMethod(vars.trgDType)%>());
157
+ <% end
158
+ end
159
+ when NUMERIC%>
160
+ result.<%=setterName(vars.trgFld)%>(src.<%=getterName(vars.trgFld)%>());
161
+ <% when STRING, CHAR%>
162
+ result.<%=setterName(vars.trgFld)%>(src.<%=getterName(vars.trgFld)%>());
163
+ <% else
164
+ migrCtx.canAuto = false%>
165
+ !!> // Unsupported data type "<%=vars.trgType%>" on the field "<%=vars.trgFld.name%>". !!
166
+ <% end
167
+ end
168
+ }
169
+ %>
170
+ return result;
171
+ }
172
+ }
@@ -0,0 +1,50 @@
1
+ # package <%=@pyPackage%>
2
+
3
+
4
+ # ****************** <%=pyClassName%> ***************
5
+ class <%=pyClassName%>(Verifiable):
6
+ VERSION = SemVer("<%=srcE.ver.full%>")
7
+ <%=rxRoster.to_patterns%>
8
+
9
+ def __init__(self):
10
+ <% srcE.fields.keys.each { |fieldName|%>
11
+ self.__<%=fieldName%> = None
12
+ <%}
13
+ %>
14
+ def getVersion(self):
15
+ return self.__class__.VERSION
16
+
17
+ <% srcE.fields.keys.each { |fieldName|
18
+ field = srcE.fields[fieldName]%>
19
+ def <%=getterName(field)%>(self):
20
+ return self.__<%=fieldName%>
21
+
22
+ def <%=setterName(field)%>(self, val):<% if field.isRequired%>
23
+ if val is None: raise AttributeError("The \"None\" argument passed to the setter of the required field \"<%=fieldName%>\" on the class <%=srcE.name%>.")<% end%>
24
+ self.__<%=fieldName%> = val
25
+ <%}
26
+ %>
27
+
28
+ def __eq__(self, other):
29
+ if not isinstance(other, type(self)): raise AttributeError("Attempt to compare an instance of %s to an instance of %s" % (self.__class__, other.__class__))
30
+ return (<%=eqHashFields.map{|f| "self.__#{f}"}.join(', ')%>) == (<%=eqHashFields.map{|f| "other._#{pyClassName}__#{f}"}.join(', ')%>)
31
+ <%# the reference to the self.__x vars as instance._ClassName__x has been tested with classes in packages, it works %>
32
+
33
+ def __ne__(self, other):
34
+ return not self.__eq__(other)
35
+
36
+ def __hash__(self):
37
+ return (<%=eqHashFields.map{|f| "hash(self.__#{f})"}.join(' ^ ')%> ^ hash((<%=eqHashFields.map{|f| "self.__#{f}"}.join(', ')%>)))
38
+
39
+ def verify(self):<%unless verCalls.empty?%>
40
+ missingFields = []
41
+ <%=verCalls%>
42
+ if(len(missingFields) != 0): raise AttributeError("<%=baseName%>: required fields not set: %s" % ", ".join(missingFields))
43
+ <%end%>
44
+ <%=rxRoster.to_verifications(baseName)%>
45
+ <%=fieldVerifications%>
46
+
47
+ return
48
+
49
+ # -------------- END of <%=pyClassName%> --------------
50
+
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dataMetaDom
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Bergens
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dataMetaXtra
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: typesafe_enum
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.1'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.1.7
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.1'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.1.7
53
+ description: DataMeta DOM classes and runnables
54
+ email: michael.bergens@gmail.com
55
+ executables:
56
+ - dataMetaPojo.rb
57
+ - dataMetaMySqlDdl.rb
58
+ - dataMetaSameFullJ.rb
59
+ - dataMetaSameIdJ.rb
60
+ - dataMetaGvExport.rb
61
+ - dataMetaOracleDdl.rb
62
+ - dataMetaReVersion.rb
63
+ extensions: []
64
+ extra_rdoc_files: []
65
+ files:
66
+ - ".yardopts"
67
+ - History.md
68
+ - PostInstall.txt
69
+ - README.md
70
+ - Rakefile
71
+ - bin/dataMetaGvExport.rb
72
+ - bin/dataMetaMySqlDdl.rb
73
+ - bin/dataMetaOracleDdl.rb
74
+ - bin/dataMetaPojo.rb
75
+ - bin/dataMetaReVersion.rb
76
+ - bin/dataMetaSameFullJ.rb
77
+ - bin/dataMetaSameIdJ.rb
78
+ - lib/dataMetaDom.rb
79
+ - lib/dataMetaDom/converter.rb
80
+ - lib/dataMetaDom/dataType.rb
81
+ - lib/dataMetaDom/docs.rb
82
+ - lib/dataMetaDom/enum.rb
83
+ - lib/dataMetaDom/field.rb
84
+ - lib/dataMetaDom/help.rb
85
+ - lib/dataMetaDom/model.rb
86
+ - lib/dataMetaDom/mySql.rb
87
+ - lib/dataMetaDom/ora.rb
88
+ - lib/dataMetaDom/pojo.rb
89
+ - lib/dataMetaDom/python.rb
90
+ - lib/dataMetaDom/recAttr.rb
91
+ - lib/dataMetaDom/record.rb
92
+ - lib/dataMetaDom/ref.rb
93
+ - lib/dataMetaDom/sourceFile.rb
94
+ - lib/dataMetaDom/sources.rb
95
+ - lib/dataMetaDom/util.rb
96
+ - lib/dataMetaDom/ver.rb
97
+ - test/test_dataMetaDom.rb
98
+ - test/test_helper.rb
99
+ - tmpl/java/migrationEntityEnums.erb
100
+ - tmpl/python/entity.erb
101
+ homepage: https://github.com/eBayDataMeta
102
+ licenses:
103
+ - Apache-2.0
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: 2.1.1
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.5.1
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: DataMeta DOM
125
+ test_files:
126
+ - test/test_dataMetaDom.rb