metamodel 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -1
  3. data/lib/metamodel/command/install.rb +30 -1
  4. data/lib/metamodel/installer.rb +8 -0
  5. data/lib/metamodel/installer/renderer.rb +27 -23
  6. data/lib/metamodel/installer/validator.rb +41 -46
  7. data/lib/metamodel/record/association.rb +4 -0
  8. data/lib/metamodel/record/model.rb +6 -10
  9. data/lib/metamodel/record/property.rb +3 -3
  10. data/lib/metamodel/template/{belongs_to_association.swift → association/belongs_to_association.swift} +3 -3
  11. data/lib/metamodel/template/association/has_many_association.swift +120 -0
  12. data/lib/metamodel/template/metamodel.swift +1 -7
  13. data/lib/metamodel/template/{file_header.swift → model/file_header.swift} +0 -0
  14. data/lib/metamodel/template/{foreign_key.swift → model/foreign_key.swift} +0 -0
  15. data/lib/metamodel/template/model/helper.swift +37 -0
  16. data/lib/metamodel/template/{model_delete.swift → model/model_delete.swift} +4 -6
  17. data/lib/metamodel/template/{model_initialize.swift → model/model_initialize.swift} +4 -4
  18. data/lib/metamodel/template/{model_query.swift → model/model_query.swift} +21 -21
  19. data/lib/metamodel/template/{model_update.swift → model/model_update.swift} +13 -14
  20. data/lib/metamodel/template/{static_methods.swift → model/static_methods.swift} +0 -0
  21. data/lib/metamodel/template/{table_initialize.swift → model/table_initialize.swift} +0 -0
  22. data/lib/metamodel/template/packing.swift +52 -0
  23. data/lib/metamodel/template/triggers.swift +0 -0
  24. data/lib/metamodel/version.rb +1 -1
  25. metadata +16 -14
  26. data/lib/metamodel/template/has_many_association.swift +0 -99
  27. data/lib/metamodel/template/helper.swift +0 -53
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a027c62103e0c1e22308807cbb65e60921e2cfc3
4
- data.tar.gz: ef725ae4f7bdfbbfd06b306523f127346ac1b44f
3
+ metadata.gz: 7adfa65f45006eee379d8f03964b8298dee77b52
4
+ data.tar.gz: a108ca5428b350e56a5557f035a9cd4eb62aa255
5
5
  SHA512:
6
- metadata.gz: 0d68afdc7a74ed5c62a66f5ba85a071c1ffdee8a45e30b2d23fe581e4c2b4212c5db55a3de07e2f799ab8a08d18b036f490379da9926faaf6abb74c3d17cfa61
7
- data.tar.gz: 83c413f52a8c1fe141424395862d9640311fc0cbc114b943f02f5463a134da0ddef7661217bc0a087201a62d240ba020cb3e635961039f418f71d4a5f3f7db57
6
+ metadata.gz: 2ab0f7cc26c1801f0f257c50abd3654260b41772a6a5380db0641b9600bd8e7bff3a7bfea338d2c0f8a5a008bfec627563a3ab8ddd6037e09c4bd9633d96e82b
7
+ data.tar.gz: 29e4a52b085c51529068f1a4dfa050563b816da3315c924b2bd303370eefa14ac154aa9ee52aa7a935c56d29a016814fbb3bef4ce3fb760daa5c037812a789bc
data/README.md CHANGED
@@ -4,8 +4,9 @@
4
4
 
5
5
  [![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/draveness/metamodel/blob/master/LICENSE)
6
6
  [![Gem](https://img.shields.io/gem/v/metamodel.svg?style=flat)](http://rubygems.org/gems/metamodel)
7
+ [![Swift](https://img.shields.io/badge/swift-3.0-yellow.svg)](https://img.shields.io/badge/Swift-%203.0%20-yellow.svg)
7
8
 
8
- MetaModel is an iOS framework designed to help developer to deal with data persistent, JSON parsing and a bunch of APIs which provides an approach of handling client side database very easily.
9
+ MetaModel is an iOS framework designed to help developer to deal with data persistent, JSON parsing and offer a bunch of APIs which provides an approach of handling client side database very easily.
9
10
 
10
11
  > MetaModel is under-development, API may constantly change before gets to 1.0.0.
11
12
 
@@ -23,7 +23,10 @@ module MetaModel
23
23
  installer = installer_for_config
24
24
  installer.install!
25
25
  end
26
- UI.notice "Please drag MetaModel.framework into Embedded Binaries phrase.\n"
26
+ UI.section "Copying MetaModel.framework into Embedded Binaries phrase." do
27
+ integrate_to_project
28
+ end
29
+ # UI.notice "Please drag MetaModel.framework into Embedded Binaries phrase.\n"
27
30
  end
28
31
 
29
32
  def prepare
@@ -41,6 +44,32 @@ module MetaModel
41
44
  end
42
45
  end
43
46
 
47
+ def integrate_to_project
48
+ xcodeprojs = Dir.glob("#{config.installation_root}/*.xcodeproj")
49
+ project = Xcodeproj::Project.open(xcodeprojs.first)
50
+ target = project.targets.first
51
+ return if target.build_phases.find { |build_phase| build_phase.to_s == "[MetaModel] Embedded Frameworks"}
52
+
53
+ # Get useful variables
54
+ frameworks_group = project.main_group.find_subpath('MetaModel', true)
55
+ frameworks_group.clear
56
+ frameworks_group.set_source_tree('SOURCE_ROOT')
57
+ frameworks_build_phase = target.build_phases.find { |build_phase| build_phase.to_s == 'FrameworksBuildPhase' }
58
+
59
+ # Add new "Embed Frameworks" build phase to target
60
+ embedded_frameworks_build_phase = project.new(Xcodeproj::Project::Object::PBXCopyFilesBuildPhase)
61
+ embedded_frameworks_build_phase.name = '[MetaModel] Embedded Frameworks'
62
+ embedded_frameworks_build_phase.symbol_dst_subfolder_spec = :frameworks
63
+ target.build_phases << embedded_frameworks_build_phase
64
+
65
+ # Add framework to target as "Embedded Frameworks"
66
+ framework_ref = frameworks_group.new_file("./MetaModel.framework")
67
+ build_file = embedded_frameworks_build_phase.add_file_reference(framework_ref)
68
+ frameworks_build_phase.add_file_reference(framework_ref)
69
+ build_file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy', 'RemoveHeadersOnCopy'] }
70
+ project.save
71
+ end
72
+
44
73
  def validate!
45
74
  # super
46
75
  raise Informative, 'No Metafile in current directory' unless config.metafile_in_dir(Pathname.pwd)
@@ -24,6 +24,7 @@ module MetaModel
24
24
  end
25
25
 
26
26
  update_initialize_method
27
+ update_packing_file
27
28
  build_metamodel_framework unless config.skip_build?
28
29
  end
29
30
 
@@ -34,6 +35,13 @@ module MetaModel
34
35
  File.write model_path, result
35
36
  end
36
37
 
38
+ def update_packing_file
39
+ template = File.read File.expand_path(File.join(File.dirname(__FILE__), "./template/packing.swift"))
40
+ result = ErbalTemplate::render_from_hash(template, { :models => @models, :associations => @associations })
41
+ model_path = Pathname.new("./metamodel/MetaModel/Packing.swift")
42
+ File.write model_path, result
43
+ end
44
+
37
45
  def build_metamodel_framework
38
46
  UI.section "Generating MetaModel.framework" do
39
47
  build_framework_on_iphoneos
@@ -16,26 +16,6 @@ module MetaModel
16
16
  @project = Xcodeproj::Project.open(Config.instance.metamodel_xcode_project)
17
17
  end
18
18
 
19
- SWIFT_TEMPLATES_FILES = %w(
20
- file_header
21
- table_initialize
22
- model_initialize
23
- model_update
24
- model_query
25
- model_delete
26
- static_methods
27
- helper
28
- )
29
-
30
- def model_swift_templates
31
- [].tap do |templates|
32
- SWIFT_TEMPLATES_FILES.each do |file_path|
33
- template = File.read File.expand_path(File.join(File.dirname(__FILE__), "../template/#{file_path}.swift"))
34
- templates << template
35
- end
36
- end
37
- end
38
-
39
19
  def render!
40
20
  remove_previous_files_refereneces
41
21
  UI.section "Generating model files" do
@@ -92,9 +72,6 @@ module MetaModel
92
72
  association_group.clear
93
73
  association_group.set_source_tree('SOURCE_ROOT')
94
74
 
95
- has_many_association_template = File.read File.expand_path(File.join(File.dirname(__FILE__), "../template/has_many_association.swift"))
96
- belongs_to_association_template = File.read File.expand_path(File.join(File.dirname(__FILE__), "../template/belongs_to_association.swift"))
97
-
98
75
  file_refs = []
99
76
  @associations.each do |association|
100
77
  template = association.relation == :has_many ? has_many_association_template : belongs_to_association_template
@@ -111,6 +88,33 @@ module MetaModel
111
88
 
112
89
  private
113
90
 
91
+ SWIFT_TEMPLATES_FILES = %w(
92
+ file_header
93
+ table_initialize
94
+ model_initialize
95
+ model_update
96
+ model_query
97
+ model_delete
98
+ static_methods
99
+ helper
100
+ )
101
+
102
+ def model_swift_templates
103
+ [].tap do |templates|
104
+ SWIFT_TEMPLATES_FILES.each do |file_path|
105
+ template = File.read File.expand_path(File.join(File.dirname(__FILE__), "../template/model/#{file_path}.swift"))
106
+ templates << template
107
+ end
108
+ end
109
+ end
110
+
111
+ def has_many_association_template
112
+ File.read File.expand_path(File.join(File.dirname(__FILE__), "../template/association/has_many_association.swift"))
113
+ end
114
+
115
+ def belongs_to_association_template
116
+ File.read File.expand_path(File.join(File.dirname(__FILE__), "../template/association/belongs_to_association.swift"))
117
+ end
114
118
  end
115
119
  end
116
120
  end
@@ -1,55 +1,50 @@
1
1
  module MetaModel
2
- class Installer
3
- class Validator
4
- require 'metamodel/record/model'
5
- require 'metamodel/record/property'
6
- require 'metamodel/record/association'
7
-
8
- def translate!
9
- satisfy_constraint = @associations.reduce([]) do |remain, association|
10
- expect = remain.select { |assoc| assoc.expect_constraint? association }
11
- if expect.empty?
12
- remain << association
13
- else
14
- remain.delete expect.first
15
- end
16
- remain
2
+ class Command
3
+ class Install
4
+ class Validator
5
+ require 'metamodel/record/model'
6
+ require 'metamodel/record/property'
7
+ require 'metamodel/record/association'
8
+
9
+ attr_reader :models
10
+ attr_reader :associations
11
+
12
+ def initialize(models, associations)
13
+ @models = models
14
+ @associations = associations
17
15
  end
18
- raise Informative, "Unsatisfied constraints in #{satisfy_constraint.map \
19
- { |x| x.debug_description }}" if satisfy_constraint.size > 0
20
-
21
- end
22
16
 
23
- def validate_models
24
- existing_types = @models.map { |m| m.properties.map { |property| property.type } }.flatten.uniq
25
- unsupported_types = existing_types - supported_types
26
- raise Informative, "Unsupported types #{unsupported_types}" unless unsupported_types == []
27
- end
28
-
29
- CURRENT_SUPPORTED_BUILT_IN_TYPES = %w[
30
- Int
31
- Double
32
- Float
33
- String
34
- Bool
35
- NSDate
36
- ]
17
+ def translate
18
+ name_model_hash = Hash[@models.collect { |model| [model.name, model] }]
19
+ @associations.map! do |association|
20
+ major_model = name_model_hash[association.major_model]
21
+ major_model.associations << association
22
+ association.major_model = major_model
23
+ association.secondary_model = name_model_hash[association.secondary_model]
24
+ raise Informative, "Associations not satisfied in `Metafile`" \
25
+ unless [association.major_model, association.secondary_model].compact.size == 2
26
+ association
27
+ end
37
28
 
38
- def built_in_types
39
- CURRENT_SUPPORTED_BUILT_IN_TYPES.map do |t|
40
- [t, "#{t}?"]
41
- end.flatten
42
- end
29
+ satisfy_constraint = @associations.reduce([]) do |remain, association|
30
+ expect = remain.select { |assoc| assoc.expect_constraint? association }
31
+ if expect.empty?
32
+ remain << association
33
+ else
34
+ remain.delete expect.first
35
+ end
36
+ remain
37
+ end
38
+ raise Informative, "Unsatisfied constraints in #{satisfy_constraint.map \
39
+ { |x| x.debug_description }}" \
40
+ if satisfy_constraint.size > 0
43
41
 
44
- def supported_types
45
- @models.reduce(CURRENT_SUPPORTED_BUILT_IN_TYPES) { |types, model|
46
- types << model.name.to_s
47
- }.map { |type|
48
- [type, "#{type}?"]
49
- }.flatten
42
+ @models.each do |model|
43
+ model.properties.uniq! { |prop| [prop.name] }
44
+ end
45
+ return @models, @associations
46
+ end
50
47
  end
51
-
52
-
53
48
  end
54
49
  end
55
50
  end
@@ -91,6 +91,10 @@ module MetaModel
91
91
  @relation == :belongs_to
92
92
  end
93
93
 
94
+ def is_active?
95
+ has_one? || has_many?
96
+ end
97
+
94
98
  def type
95
99
  case @relation
96
100
  when :has_one, :has_many, :belongs_to then secondary_model.name
@@ -51,12 +51,12 @@ module MetaModel
51
51
  key_value_pairs_with_property properties_exclude_id, cast
52
52
  end
53
53
 
54
- def property_key_type_pairs(remove_extra_param = true, use_default_value = false)
55
- key_type_pairs_with_property @properties, remove_extra_param, use_default_value
54
+ def property_key_type_pairs(use_default_value = false)
55
+ key_type_pairs_with_property @properties, use_default_value
56
56
  end
57
57
 
58
- def property_exclude_id_key_type_pairs(remove_extra_param = true, use_default_value = false)
59
- key_type_pairs_with_property properties_exclude_id, remove_extra_param, use_default_value
58
+ def property_exclude_id_key_type_pairs(use_default_value = false)
59
+ key_type_pairs_with_property properties_exclude_id, use_default_value
60
60
  end
61
61
 
62
62
  def property_key_type_pairs_without_property(property)
@@ -93,18 +93,14 @@ module MetaModel
93
93
  end.join(", ")
94
94
  end
95
95
 
96
- def key_type_pairs_with_property(properties, remove_extra_param = true, use_default_value = false)
96
+ def key_type_pairs_with_property(properties, use_default_value = false)
97
97
  properties.enum_for(:each_with_index).map do |property, index|
98
98
  has_default_value = property.has_default_value?
99
99
  default_value = property.type_without_optional == "String" ? "\"#{property.default_value}\"" : property.default_value
100
100
 
101
101
  result = "#{property.name}: #{property.type.to_s}#{if has_default_value then " = " + "#{default_value}" end}"
102
102
  result = "#{property.name}: #{property.type.to_s} = #{property.type_without_optional}DefaultValue" if use_default_value
103
- if index == 0 && remove_extra_param
104
- "#{property.name} #{result}"
105
- else
106
- result
107
- end
103
+ result
108
104
  end.join(", ")
109
105
  end
110
106
 
@@ -35,7 +35,7 @@ module MetaModel
35
35
  case type_without_optional
36
36
  when "String" then "TEXT"
37
37
  when "Int", "Bool" then "INTEGER"
38
- when "Double", "NSDate", "Float" then "REAL"
38
+ when "Double", "Date", "Float" then "REAL"
39
39
  else raise Informative, "Unsupported type #{self.type}"
40
40
  end
41
41
  end
@@ -44,7 +44,7 @@ module MetaModel
44
44
  case type_without_optional
45
45
  when "String" then "String"
46
46
  when "Int", "Bool" then "Int64"
47
- when "Double", "NSDate", "Float" then "Double"
47
+ when "Double", "Date", "Float" then "Double"
48
48
  else raise Informative, "Unsupported type #{self.type}"
49
49
  end
50
50
  end
@@ -55,7 +55,7 @@ module MetaModel
55
55
  when :double then "Double"
56
56
  when :bool then "Bool"
57
57
  when :string then "String"
58
- when :date then "NSDate"
58
+ when :date then "Date"
59
59
  else symbol.to_s.camelize
60
60
  end
61
61
  end
@@ -9,7 +9,7 @@
9
9
  import Foundation
10
10
 
11
11
  extension <%= association.class_name %> {
12
- static func create(<%= association.major_model_id %> <%= association.major_model_id %>: Int, <%= association.secondary_model_id %>: Int) {
12
+ @discardableResult static func create(<%= association.major_model_id %>: Int, <%= association.secondary_model_id %>: Int) {
13
13
  executeSQL("INSERT INTO \(<%= association.class_name %>.tableName) (<%= association.major_model_id.underscore %>, <%= association.secondary_model_id.underscore %>) VALUES (\(<%= association.major_model_id %>), \(<%= association.secondary_model_id %>))")
14
14
  }
15
15
  }
@@ -17,12 +17,12 @@ extension <%= association.class_name %> {
17
17
  public extension <%= association.major_model.name %> {
18
18
  var <%= association.name %>: <%= association.secondary_model.name %>? {
19
19
  get {
20
- guard let id = <%= association.class_name %>.findBy(<%= association.major_model.foreign_id %>: privateId).first?.commentId else { return nil }
20
+ guard let id = <%= association.class_name %>.findBy(<%= association.major_model.foreign_id %>: privateId).first?.<%= association.secondary_model.foreign_id %> else { return nil }
21
21
  return <%= association.secondary_model.name %>.find(id)
22
22
  }
23
23
  set {
24
24
  guard let newValue = newValue else { return }
25
- <%= association.class_name %>.findBy(<%= association.major_model_id %>: privateId).forEach { $0.delete() }
25
+ <%= association.class_name %>.findBy(<%= association.major_model_id %>: privateId).forEach { $0.delete }
26
26
  <%= association.class_name %>.create(<%= association.major_model_id %>: newValue.privateId, <%= association.secondary_model_id %>: privateId)
27
27
  }
28
28
  }
@@ -0,0 +1,120 @@
1
+ //
2
+ // <%= association.class_name %>.swift
3
+ // MetaModel
4
+ //
5
+ // Created by MetaModel.
6
+ // Copyright © 2016 metamodel. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+
11
+ typealias <%= association.reverse_class_name %> = <%= association.class_name %>
12
+
13
+ struct <%= association.class_name %> {
14
+ var privateId: Int = 0
15
+ var <%= association.major_model_id %>: Int = 0
16
+ var <%= association.secondary_model_id %>: Int = 0
17
+
18
+ enum Association: String, CustomStringConvertible {
19
+ case privateId = "private_id"
20
+ case <%= association.major_model_id %> = "<%= association.major_model_id.underscore %>"
21
+ case <%= association.secondary_model_id %> = "<%= association.secondary_model_id.underscore %>"
22
+ var description: String { get { return self.rawValue } }
23
+ }
24
+ <% [association.major_model, association.secondary_model].zip([association.secondary_model, association.major_model]).each do |first, second| %>
25
+ static func fetch<%= first.table_name.camelize %>(<%= second.foreign_id %>: Int, first: Bool = false) -> [<%= first.name %>] {
26
+ var query = "SELECT * FROM <%= first.table_name %> WHERE <%= first.table_name %>.private_id IN (" +
27
+ "SELECT private_id " +
28
+ "FROM \(tableName) " +
29
+ "WHERE \(Association.<%= second.foreign_id %>) = \(<%= second.foreign_id %>)" +
30
+ ")"
31
+ if first { query += "LIMIT 1" }
32
+ return MetaModels.fromQuery(query)
33
+ }
34
+ <% end %><% [association.major_model, association.secondary_model].each do |model| %>
35
+ static func findBy(<%= model.foreign_id %>: Int) -> [<%= association.class_name %>] {
36
+ let query = "SELECT * FROM \(tableName) WHERE <%= model.foreign_id.underscore %> = \(<%= model.foreign_id %>)"
37
+ return MetaModels.fromQuery(query)
38
+ }
39
+ <% end %>
40
+ var delete: Void {
41
+ get {
42
+ executeSQL("DELETE * FROM \(<%= association.class_name %>.tableName) WHERE private_id = \(privateId)")
43
+ }
44
+ }
45
+ }
46
+
47
+ extension <%= association.class_name %> {
48
+ static func create(<%= association.major_model_id %>: Int, <%= association.secondary_model_id %>: Int) {
49
+ executeSQL("INSERT INTO \(<%= association.class_name %>.tableName) (<%= association.major_model_id.underscore %>, <%= association.secondary_model_id.underscore %>) VALUES (\(<%= association.major_model_id %>), \(<%= association.secondary_model_id %>))")
50
+ }
51
+ }
52
+
53
+ extension <%= association.class_name %> {
54
+ static let tableName = "<%= association.class_name.underscore %>"
55
+ static func initialize() {
56
+ let initializeTableSQL = "CREATE TABLE \(tableName)(" +
57
+ "private_id INTEGER PRIMARY KEY, " +
58
+ "<%= association.major_model_id.underscore %> INTEGER NOT NULL, " +
59
+ "<%= association.secondary_model_id.underscore %> INTEGER NOT NULL, " +
60
+ "FOREIGN KEY(<%= association.major_model_id.underscore %>) REFERENCES <%= association.major_model.table_name %>(private_id)," +
61
+ "FOREIGN KEY(<%= association.secondary_model_id.underscore %>) REFERENCES <%= association.secondary_model.table_name %>(private_id)" +
62
+ ");"
63
+
64
+ executeSQL(initializeTableSQL)
65
+ initializeTrigger()
66
+ }
67
+
68
+ static func deinitialize() {
69
+ let dropTableSQL = "DROP TABLE \(tableName)"
70
+ executeSQL(dropTableSQL)
71
+ deinitializeTrigger()
72
+ }
73
+
74
+ static func initializeTrigger() {
75
+ let majorDeleteTrigger = "CREATE TRIGGER <%= association.major_model.name.underscore %>_delete_trigger " +
76
+ "AFTER DELETE ON <%= association.major_model.table_name %> " +
77
+ "FOR EACH ROW BEGIN " +
78
+ "DELETE FROM \(tableName) WHERE private_id = OLD.private_id; " +
79
+ "END;";
80
+
81
+ let secondaryDeleteTrigger = "CREATE TRIGGER <%= association.secondary_model.name.underscore %>_delete_trigger " +
82
+ "AFTER DELETE ON <%= association.secondary_model.table_name %> " +
83
+ "FOR EACH ROW BEGIN " +
84
+ "DELETE FROM \(tableName) WHERE private_id = OLD.private_id; " +
85
+ "END;";
86
+
87
+ executeSQL(majorDeleteTrigger)
88
+ executeSQL(secondaryDeleteTrigger)
89
+ }
90
+
91
+ static func deinitializeTrigger() {
92
+ let dropMajorTrigger = "DROP TRIGGER IF EXISTS <%= association.major_model.name.underscore %>_delete_trigger;"
93
+ executeSQL(dropMajorTrigger)
94
+
95
+ let dropSecondaryTrigger = "DROP TRIGGER IF EXISTS <%= association.secondary_model.name.underscore %>_delete_trigger;"
96
+ executeSQL(dropSecondaryTrigger)
97
+ }
98
+ }
99
+
100
+ public extension <%= association.major_model.name %> {
101
+ var <%= association.name %>: [<%= association.secondary_model.name %>] {
102
+ get {
103
+ return <%= association.class_name %>.fetch<%= association.secondary_model.name.tableize.camelize %>(<%= association.major_model.foreign_id %>: privateId)
104
+ }
105
+ set {
106
+ <%= association.class_name %>.findBy(<%= association.major_model_id %>: privateId).forEach { $0.delete }
107
+ newValue.forEach { <%= association.class_name %>.create(<%= association.major_model_id %>: privateId, <%= association.secondary_model_id %>: $0.privateId) }
108
+ }
109
+ }
110
+
111
+ @discardableResult func create<%= association.secondary_model.name %>(<%= association.secondary_model.property_key_type_pairs %>) -> <%= association.secondary_model.name %>? {
112
+ guard let result = <%= association.secondary_model.name %>.create(<%= association.secondary_model.property_key_value_pairs %>) else { return nil }
113
+ <%= association.class_name %>.create(<%= association.major_model_id %>: privateId, <%= association.secondary_model_id %>: result.privateId)
114
+ return result
115
+ }
116
+
117
+ @discardableResult func append<%= association.secondary_model.name %>(<%= association.secondary_model.property_key_type_pairs %>) -> <%= association.secondary_model.name %>? {
118
+ return create<%= association.secondary_model.name %>(<%= association.secondary_model.property_key_value_pairs %>)
119
+ }
120
+ }
@@ -8,12 +8,6 @@
8
8
 
9
9
  import Foundation
10
10
 
11
- let path = NSSearchPathForDirectoriesInDomains(
12
- .DocumentDirectory, .UserDomainMask, true
13
- ).first! as String
14
-
15
- let db = try! Connection("\(path)/metamodel_db.sqlite3")
16
-
17
11
  public class MetaModel {
18
12
  public static func initialize() {
19
13
  validateMetaModelTables()
@@ -28,7 +22,7 @@ public class MetaModel {
28
22
  }""" %>
29
23
  <% end %>
30
24
 
31
- <% associations.each do |association| %><% if association.relation.to_s.start_with? "has" %><%= """if infos[#{association.class_name}.tableName] != \"#{association.hash_value}\" {
25
+ <% associations.each do |association| %><% if association.is_active? %><%= """if infos[#{association.class_name}.tableName] != \"#{association.hash_value}\" {
32
26
  updateMetaModelTableInfos(#{association.class_name}.tableName, hashValue: \"#{association.hash_value}\")
33
27
  #{association.class_name}.deinitialize()
34
28
  #{association.class_name}.initialize()
@@ -0,0 +1,37 @@
1
+ // MAKR: - Helper
2
+
3
+ open class <%= model.relation_name %>: Relation<<%= model.name %>> {
4
+ override init() {
5
+ super.init()
6
+ self.select = "SELECT \(<%= model.name %>.tableName).* FROM \(<%= model.name %>.tableName)"
7
+ }
8
+
9
+ override var result: [<%= model.name %>] {
10
+ get {
11
+ return MetaModels.fromQuery(query)
12
+ }
13
+ }
14
+
15
+ func expandColumn(_ column: <%= model.name %>.Column) -> String {
16
+ return "\(<%= model.name %>.tableName).\(column)"
17
+ }
18
+ }
19
+
20
+ extension <%= model.name %> {
21
+ var itself: String { get { return "WHERE \(<%= model.name %>.tableName).private_id = \(privateId)" } }
22
+ }
23
+
24
+ extension <%= model.relation_name %> {
25
+ func find(_ privateId: Int) -> Self {
26
+ return filter(privateId)
27
+ }
28
+
29
+ func find(_ privateIds: [Int]) -> Self {
30
+ return filter(conditions: [.privateId: privateIds])
31
+ }
32
+
33
+ func filter(_ privateId: Int) -> Self {
34
+ self.filter.append("private_id = \(privateId)")
35
+ return self
36
+ }
37
+ }
@@ -1,23 +1,21 @@
1
1
  // MARK: - Delete
2
2
 
3
3
  public extension <%= model.name %> {
4
- var delete: Bool {
4
+ var delete: Void {
5
5
  get {
6
6
  let deleteSQL = "DELETE FROM \(<%= model.name %>.tableName) \(itself)"
7
7
  executeSQL(deleteSQL)
8
- return true
9
8
  }
10
9
  }
11
- static var deleteAll: Bool { get { return <%= model.relation_name %>().deleteAll } }
10
+ static var deleteAll: Void { get { return <%= model.relation_name %>().deleteAll } }
12
11
  }
13
12
 
14
13
  public extension <%= model.relation_name %> {
15
- var delete: Bool { get { return deleteAll } }
14
+ var delete: Void { get { return deleteAll } }
16
15
 
17
- var deleteAll: Bool {
16
+ var deleteAll: Void {
18
17
  get {
19
18
  self.result.forEach { $0.delete }
20
- return true
21
19
  }
22
20
  }
23
21
  }
@@ -12,16 +12,16 @@ public struct <%= model.name %> {
12
12
  public var description: String { get { return self.rawValue } }
13
13
  }
14
14
 
15
- public init(<%= model.property_key_type_pairs false %>) {
15
+ public init(<%= model.property_key_type_pairs %>) {
16
16
  <% model.properties.each do |property| %><%= """self.#{property.name} = #{property.name}" %>
17
17
  <% end %>
18
18
  }
19
19
 
20
- static public func new(<%= model.property_key_type_pairs %>) -> <%= model.name %> {
20
+ @discardableResult static public func new(<%= model.property_key_type_pairs %>) -> <%= model.name %> {
21
21
  return <%= model.name %>(<%= model.property_key_value_pairs %>)
22
22
  }
23
23
 
24
- static public func create(<%= model.property_key_type_pairs %>) -> <%= model.name %>? {
24
+ @discardableResult static public func create(<%= model.property_key_type_pairs %>) -> <%= model.name %>? {
25
25
  //if <%= model.properties.select { |p| p.name.downcase.end_with? "id" }.map { |p| "#{p.name} == 0" }.push("false == true").join(" || ") %> { return nil }
26
26
 
27
27
  var columnsSQL: [<%= model.name %>.Column] = []
@@ -35,7 +35,7 @@ public struct <%= model.name %> {
35
35
  <%= """columnsSQL.append(.#{property.name})
36
36
  valuesSQL.append(#{property.name})
37
37
  """ %><% end %><% end %>
38
- let insertSQL = "INSERT INTO \(tableName) (\(columnsSQL.map { $0.rawValue }.joinWithSeparator(", "))) VALUES (\(valuesSQL.map { $0.unwrapped }.joinWithSeparator(", ")))"
38
+ let insertSQL = "INSERT INTO \(tableName) (\(columnsSQL.map { $0.rawValue }.joined(separator: ", "))) VALUES (\(valuesSQL.map { $0.unwrapped }.joined(separator: ", ")))"
39
39
  guard let _ = executeSQL(insertSQL),
40
40
  let lastInsertRowId = executeScalarSQL("SELECT last_insert_rowid();") as? Int64 else { return nil }
41
41
  var result = <%= model.name %>(<%= model.property_key_value_pairs %>)
@@ -7,37 +7,37 @@ public extension <%= model.name %> {
7
7
 
8
8
  static var first: <%= model.name %>? {
9
9
  get {
10
- return <%= model.relation_name %>().orderBy(.privateId, asc: true).first
10
+ return <%= model.relation_name %>().orderBy(column: .privateId, asc: true).first
11
11
  }
12
12
  }
13
13
 
14
14
  static var last: <%= model.name %>? {
15
15
  get {
16
- return <%= model.relation_name %>().orderBy(.privateId, asc: false).first
16
+ return <%= model.relation_name %>().orderBy(column: .privateId, asc: false).first
17
17
  }
18
18
  }
19
19
 
20
20
  static func first(length: UInt) -> <%= model.relation_name %> {
21
- return <%= model.relation_name %>().orderBy(.privateId, asc: true).limit(length)
21
+ return <%= model.relation_name %>().orderBy(column: .privateId, asc: true).limit(length)
22
22
  }
23
23
 
24
24
  static func last(length: UInt) -> <%= model.relation_name %> {
25
- return <%= model.relation_name %>().orderBy(.privateId, asc: false).limit(length)
25
+ return <%= model.relation_name %>().orderBy(column: .privateId, asc: false).limit(length)
26
26
  }
27
27
 
28
- static func find(id: Int) -> <%= model.name %>? {
29
- return <%= model.relation_name %>().find(id).first
28
+ internal static func find(_ privateId: Int) -> <%= model.name %>? {
29
+ return <%= model.relation_name %>().find(privateId).first
30
30
  }
31
31
 
32
- static func find(ids: [Int]) -> <%= model.relation_name %> {
33
- return <%= model.relation_name %>().find(ids)
32
+ internal static func find(_ privateIds: [Int]) -> <%= model.relation_name %> {
33
+ return <%= model.relation_name %>().find(privateIds)
34
34
  }
35
35
 
36
- static func findBy(<%= model.property_key_type_pairs(true, true) %>) -> <%= model.relation_name %> {
36
+ static func findBy(<%= model.property_key_type_pairs(true) %>) -> <%= model.relation_name %> {
37
37
  return <%= model.relation_name %>().findBy(<%= model.property_key_value_pairs %>)
38
38
  }
39
39
 
40
- static func filter(<%= model.property_key_type_pairs(true, true) %>) -> <%= model.relation_name %> {
40
+ static func filter(<%= model.property_key_type_pairs(true) %>) -> <%= model.relation_name %> {
41
41
  return <%= model.relation_name %>().filter(<%= model.property_key_value_pairs %>)
42
42
  }
43
43
 
@@ -54,30 +54,30 @@ public extension <%= model.name %> {
54
54
  }
55
55
 
56
56
  static func groupBy(columns: <%= model.name %>.Column...) -> <%= model.relation_name %> {
57
- return <%= model.relation_name %>().groupBy(columns)
57
+ return <%= model.relation_name %>().groupBy(columns: columns)
58
58
  }
59
59
 
60
60
  static func groupBy(columns: [<%= model.name %>.Column]) -> <%= model.relation_name %> {
61
- return <%= model.relation_name %>().groupBy(columns)
61
+ return <%= model.relation_name %>().groupBy(columns: columns)
62
62
  }
63
63
 
64
64
  static func orderBy(column: <%= model.name %>.Column) -> <%= model.relation_name %> {
65
- return <%= model.relation_name %>().orderBy(column)
65
+ return <%= model.relation_name %>().orderBy(column: column)
66
66
  }
67
67
 
68
68
  static func orderBy(column: <%= model.name %>.Column, asc: Bool) -> <%= model.relation_name %> {
69
- return <%= model.relation_name %>().orderBy(column, asc: asc)
69
+ return <%= model.relation_name %>().orderBy(column: column, asc: asc)
70
70
  }
71
71
  }
72
72
 
73
73
  public extension <%= model.relation_name %> {
74
- func findBy(<%= model.property_key_type_pairs(true, true) %>) -> Self {
74
+ func findBy(<%= model.property_key_type_pairs(true) %>) -> Self {
75
75
  var attributes: [<%= model.name %>.Column: Any] = [:]
76
76
  <% model.properties.each do |property| %><%= "if (#{property.name} != #{property.type_without_optional}DefaultValue) { attributes[.#{property.name}] = #{property.name} }" %>
77
- <% end %>return self.filter(attributes)
77
+ <% end %>return self.filter(conditions: attributes)
78
78
  }
79
79
 
80
- func filter(<%= model.property_key_type_pairs(true, true) %>) -> Self {
80
+ func filter(<%= model.property_key_type_pairs(true) %>) -> Self {
81
81
  return findBy(<%= model.property_key_value_pairs %>)
82
82
  }
83
83
 
@@ -85,12 +85,12 @@ public extension <%= model.relation_name %> {
85
85
  for (column, value) in conditions {
86
86
  let columnSQL = "\(expandColumn(column))"
87
87
 
88
- func filterByEqual(value: Any) {
88
+ func filterByEqual(_ value: Any) {
89
89
  self.filter.append("\(columnSQL) = \(value)")
90
90
  }
91
91
 
92
- func filterByIn(value: [String]) {
93
- self.filter.append("\(columnSQL) IN (\(value.joinWithSeparator(", ")))")
92
+ func filterByIn(_ value: [String]) {
93
+ self.filter.append("\(columnSQL) IN (\(value.joined(separator: ", ")))")
94
94
  }
95
95
 
96
96
  if let value = value as? String {
@@ -115,7 +115,7 @@ public extension <%= model.relation_name %> {
115
115
  }
116
116
 
117
117
  func groupBy(columns: <%= model.name %>.Column...) -> Self {
118
- return self.groupBy(columns)
118
+ return self.groupBy(columns: columns)
119
119
  }
120
120
 
121
121
  func groupBy(columns: [<%= model.name %>.Column]) -> Self {
@@ -1,14 +1,14 @@
1
1
  // MARK: - Update
2
2
 
3
3
  public extension <%= model.name %> {
4
- mutating func update(<%= model.property_exclude_id_key_type_pairs(true, true) %>) {
4
+ @discardableResult mutating func update(<%= model.property_exclude_id_key_type_pairs true %>) {
5
5
  var attributes: [<%= model.name %>.Column: Any] = [:]
6
6
  <% model.properties_exclude_id.each do |property| %><%= "if (#{property.name} != #{property.type_without_optional}DefaultValue) { attributes[.#{property.name}] = #{property.name} }" %>
7
7
  <% end %>
8
- self.update(attributes)
8
+ self.update(attributes: attributes)
9
9
  }
10
10
 
11
- mutating func update(attributes: [<%= model.name %>.Column: Any]) {
11
+ @discardableResult mutating func update(attributes: [<%= model.name %>.Column: Any]) {
12
12
  var setSQL: [String] = []
13
13
  if let attributes = attributes as? [<%= model.name %>.Column: Unwrapped] {
14
14
  for (key, value) in attributes {
@@ -17,13 +17,12 @@ public extension <%= model.name %> {
17
17
  <% end %>default: break
18
18
  }
19
19
  }
20
- let updateSQL = "UPDATE \(<%= model.name %>.tableName) SET \(setSQL.joinWithSeparator(", ")) \(itself)"
21
- executeSQL(updateSQL) {
22
- for (key, value) in attributes {
23
- switch key {
24
- <% model.properties_exclude_id.each do |property| %><%= """case .#{property.name}: self.#{property.name} = value as#{property.is_optional? ? "?" : "!"} #{property.type_without_optional}""" %>
25
- <% end %>default: break
26
- }
20
+ let updateSQL = "UPDATE \(<%= model.name %>.tableName) SET \(setSQL.joined(separator: ", ")) \(itself)"
21
+ guard let _ = executeSQL(updateSQL) else { return }
22
+ for (key, value) in attributes {
23
+ switch key {
24
+ <% model.properties_exclude_id.each do |property| %><%= """case .#{property.name}: #{property.name} = value as#{property.is_optional? ? "?" : "!"} #{property.type_without_optional}""" %>
25
+ <% end %>default: break
27
26
  }
28
27
  }
29
28
  }
@@ -32,7 +31,7 @@ public extension <%= model.name %> {
32
31
  var save: <%= model.name %> {
33
32
  mutating get {
34
33
  if let _ = <%= model.name %>.find(privateId) {
35
- update([<% column_values = model.properties.map do |property| %><% ".#{property.name}: #{property.name}" %><% end %><%= column_values.join(", ") %>])
34
+ update(attributes: [<% column_values = model.properties.map do |property| %><% ".#{property.name}: #{property.name}" %><% end %><%= column_values.join(", ") %>])
36
35
  } else {
37
36
  <%= model.name %>.create(<%= model.property_key_value_pairs %>)
38
37
  }
@@ -48,17 +47,17 @@ public extension <%= model.name %> {
48
47
  }
49
48
 
50
49
  public extension <%= model.relation_name %> {
51
- public func updateAll(<%= model.property_exclude_id_key_type_pairs(true, true) %>) -> Self {
50
+ @discardableResult public func updateAll(<%= model.property_exclude_id_key_type_pairs true %>) -> Self {
52
51
  return update(<%= model.property_exclude_id_key_value_pairs %>)
53
52
  }
54
53
 
55
- public func update(<%= model.property_exclude_id_key_type_pairs(true, true) %>) -> Self {
54
+ @discardableResult public func update(<%= model.property_exclude_id_key_type_pairs true %>) -> Self {
56
55
  var attributes: [<%= model.name %>.Column: Any] = [:]
57
56
  <% model.properties_exclude_id.each do |property| %><%= "if (#{property.name} != #{property.type_without_optional}DefaultValue) { attributes[.#{property.name}] = #{property.name} }" %>
58
57
  <% end %>
59
58
  result.forEach { (element) in
60
59
  var element = element
61
- element.update(attributes)
60
+ element.update(attributes: attributes)
62
61
  }
63
62
  return self
64
63
  }
@@ -0,0 +1,52 @@
1
+ //
2
+ // Packing.swift
3
+ // MetaModel
4
+ //
5
+ // Created by Draveness on 9/16/16.
6
+ // Copyright © 2016 metamodel. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+
11
+ protocol Packing {
12
+ init(values: Array<Optional<Binding>>);
13
+ }
14
+
15
+ class MetaModels {
16
+ static func fromQuery<T>(_ query: String) -> [T] where T: Packing {
17
+ var models: [T] = []
18
+ guard let stmt = executeSQL(query) else { return models }
19
+ for values in stmt {
20
+ let association = T(values: values)
21
+ models.append(association)
22
+ }
23
+ return models
24
+ }
25
+ }
26
+
27
+ // MARK: - Model Packing
28
+ <% models.each do |model| %>
29
+ extension <%= model.name %>: Packing {
30
+ init(values: Array<Optional<Binding>>) {
31
+ <% model.properties.each_with_index do |property, index| %><%= """let #{property.name}: #{property.real_type} = values[#{index+1}] as! #{property.real_type}""" %>
32
+ <% end %>
33
+ self.init(<%= model.property_key_value_pairs true %>)
34
+
35
+ let privateId: Int64 = values[0] as! Int64
36
+ self.privateId = Int(privateId)
37
+ }
38
+ }
39
+ <% end %>
40
+
41
+ // MARK: - Association Packing
42
+ <% associations.each do |association| if association.is_active? %>
43
+ extension <%= association.class_name %>: Packing {
44
+ init(values: Array<Optional<Binding>>) {
45
+ let privateId: Int64 = values[0] as! Int64
46
+ let <%= association.major_model_id %>: Int64 = values[1] as! Int64
47
+ let <%= association.secondary_model_id %>: Int64 = values[2] as! Int64
48
+
49
+ self.init(privateId: Int(privateId), <%= association.major_model_id %>: Int(<%= association.major_model_id %>), <%= association.secondary_model_id %>: Int(<%= association.secondary_model_id %>))
50
+ }
51
+ }
52
+ <% end %><% end %>
File without changes
@@ -1,5 +1,5 @@
1
1
  module MetaModel
2
2
  # The version of the MetaModel command line tool.
3
3
  #
4
- VERSION = '0.3.1' unless defined? MetaModel::VERSION
4
+ VERSION = '0.4.0' unless defined? MetaModel::VERSION
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metamodel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Draveness Zuo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-15 00:00:00.000000000 Z
11
+ date: 2016-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: claide
@@ -161,19 +161,21 @@ files:
161
161
  - lib/metamodel/record/association.rb
162
162
  - lib/metamodel/record/model.rb
163
163
  - lib/metamodel/record/property.rb
164
- - lib/metamodel/template/belongs_to_association.swift
165
- - lib/metamodel/template/file_header.swift
166
- - lib/metamodel/template/foreign_key.swift
167
- - lib/metamodel/template/has_many_association.swift
168
- - lib/metamodel/template/helper.swift
164
+ - lib/metamodel/template/association/belongs_to_association.swift
165
+ - lib/metamodel/template/association/has_many_association.swift
169
166
  - lib/metamodel/template/json.swift
170
167
  - lib/metamodel/template/metamodel.swift
171
- - lib/metamodel/template/model_delete.swift
172
- - lib/metamodel/template/model_initialize.swift
173
- - lib/metamodel/template/model_query.swift
174
- - lib/metamodel/template/model_update.swift
175
- - lib/metamodel/template/static_methods.swift
176
- - lib/metamodel/template/table_initialize.swift
168
+ - lib/metamodel/template/model/file_header.swift
169
+ - lib/metamodel/template/model/foreign_key.swift
170
+ - lib/metamodel/template/model/helper.swift
171
+ - lib/metamodel/template/model/model_delete.swift
172
+ - lib/metamodel/template/model/model_initialize.swift
173
+ - lib/metamodel/template/model/model_query.swift
174
+ - lib/metamodel/template/model/model_update.swift
175
+ - lib/metamodel/template/model/static_methods.swift
176
+ - lib/metamodel/template/model/table_initialize.swift
177
+ - lib/metamodel/template/packing.swift
178
+ - lib/metamodel/template/triggers.swift
177
179
  - lib/metamodel/user_interface.rb
178
180
  - lib/metamodel/version.rb
179
181
  homepage: https://github.com/MModel/MetaModel
@@ -196,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
198
  version: '0'
197
199
  requirements: []
198
200
  rubyforge_project:
199
- rubygems_version: 2.6.4
201
+ rubygems_version: 2.6.6
200
202
  signing_key:
201
203
  specification_version: 4
202
204
  summary: The Cocoa models generator.
@@ -1,99 +0,0 @@
1
- //
2
- // <%= association.class_name %>.swift
3
- // MetaModel
4
- //
5
- // Created by MetaModel.
6
- // Copyright © 2016 metamodel. All rights reserved.
7
- //
8
-
9
- import Foundation
10
-
11
- typealias <%= association.reverse_class_name %> = <%= association.class_name %>
12
-
13
- struct <%= association.class_name %> {
14
- var privateId: Int = 0
15
- var <%= association.major_model_id %>: Int = 0
16
- var <%= association.secondary_model_id %>: Int = 0
17
-
18
- enum Association: String, CustomStringConvertible {
19
- case privateId = "private_id"
20
- case <%= association.major_model_id %> = "<%= association.major_model_id.underscore %>"
21
- case <%= association.secondary_model_id %> = "<%= association.secondary_model_id.underscore %>"
22
- var description: String { get { return self.rawValue } }
23
- }
24
- <% [association.major_model, association.secondary_model].each do |model| %>
25
- <%= """static func findBy(#{model.foreign_id} #{model.foreign_id}: Int) -> [#{association.class_name}] {
26
- let query = \"SELECT * FROM \\(tableName) WHERE \\(Association.#{model.foreign_id}) = \\(#{model.foreign_id})\"
27
-
28
- var models: [#{association.class_name}] = []
29
- guard let stmt = executeSQL(query) else { return models }
30
- for values in stmt {
31
- let association = #{association.class_name}(values: values)
32
- models.append(association)
33
- }
34
- return models
35
- }""" %>
36
- <% end %>
37
- func delete() {
38
- executeSQL("DELETE * FROM \(<%= association.class_name %>.tableName) WHERE \(Association.privateId) = \(privateId)")
39
- }
40
- }
41
-
42
- extension <%= association.class_name %> {
43
- static func create(<%= association.major_model_id %> <%= association.major_model_id %>: Int, <%= association.secondary_model_id %>: Int) {
44
- executeSQL("INSERT INTO \(<%= association.class_name %>.tableName) (<%= association.major_model_id.underscore %>, <%= association.secondary_model_id.underscore %>) VALUES (\(<%= association.major_model_id %>), \(<%= association.secondary_model_id %>))")
45
- }
46
- }
47
-
48
- extension <%= association.class_name %> {
49
- init(values: Array<Optional<Binding>>) {
50
- let privateId: Int64 = values[0] as! Int64
51
- let <%= association.major_model_id %>: Int64 = values[1] as! Int64
52
- let <%= association.secondary_model_id %>: Int64 = values[2] as! Int64
53
-
54
- self.init(privateId: Int(privateId), <%= association.major_model_id %>: Int(<%= association.major_model_id %>), <%= association.secondary_model_id %>: Int(<%= association.secondary_model_id %>))
55
- }
56
- }
57
-
58
- extension <%= association.class_name %> {
59
-
60
- static let tableName = "<%= association.class_name.underscore %>"
61
- static func initialize() {
62
- let initializeTableSQL = "CREATE TABLE \(tableName)(" +
63
- "private_id INTEGER PRIMARY KEY, " +
64
- "<%= association.major_model_id.underscore %> INTEGER NOT NULL, " +
65
- "<%= association.secondary_model_id.underscore %> INTEGER NOT NULL, " +
66
- "FOREIGN KEY(<%= association.major_model_id.underscore %>) REFERENCES <%= association.major_model.table_name %>(private_id)," +
67
- "FOREIGN KEY(<%= association.secondary_model_id.underscore %>) REFERENCES <%= association.secondary_model.table_name %>(private_id)" +
68
- ");"
69
-
70
- executeSQL(initializeTableSQL)
71
- }
72
- static func deinitialize() {
73
- let dropTableSQL = "DROP TABLE \(tableName)"
74
- executeSQL(dropTableSQL)
75
- }
76
- }
77
-
78
- public extension <%= association.major_model.name %> {
79
- var <%= association.name %>: [<%= association.secondary_model.name %>] {
80
- get {
81
- let ids = <%= association.class_name %>.findBy(<%= association.major_model_id %>: privateId).map { $0.<%= association.secondary_model_id %> }
82
- return <%= association.secondary_model.name %>.find(ids).result
83
- }
84
- set {
85
- <%= association.class_name %>.findBy(<%= association.major_model_id %>: privateId).forEach { $0.delete() }
86
- newValue.forEach { <%= association.class_name %>.create(<%= association.major_model_id %>: privateId, <%= association.secondary_model_id %>: $0.privateId) }
87
- }
88
- }
89
-
90
- func create<%= association.secondary_model.name %>(<%= association.secondary_model.property_key_type_pairs %>) -> <%= association.secondary_model.name %>? {
91
- guard let result = <%= association.secondary_model.name %>.create(<%= association.secondary_model.property_key_value_pairs %>) else { return nil }
92
- <%= association.class_name %>.create(<%= association.major_model_id %>: privateId, <%= association.secondary_model_id %>: result.privateId)
93
- return result
94
- }
95
-
96
- func append<%= association.secondary_model.name %>(<%= association.secondary_model.property_key_type_pairs %>) -> <%= association.secondary_model.name %>? {
97
- return create<%= association.secondary_model.name %>(<%= association.secondary_model.property_key_value_pairs %>)
98
- }
99
- }
@@ -1,53 +0,0 @@
1
- // MAKR: - Helper
2
-
3
- public class <%= model.relation_name %>: Relation<<%= model.name %>> {
4
- override init() {
5
- super.init()
6
- self.select = "SELECT \(<%= model.name %>.tableName).* FROM \(<%= model.name %>.tableName)"
7
- }
8
-
9
- override var result: [<%= model.name %>] {
10
- get {
11
- var models: [<%= model.name %>] = []
12
- guard let stmt = executeSQL(query) else { return models }
13
- for values in stmt {
14
- models.append(<%= model.name %>(values: values))
15
- }
16
- return models
17
- }
18
- }
19
-
20
- func expandColumn(column: <%= model.name %>.Column) -> String {
21
- return "\(<%= model.name %>.tableName).\(column)"
22
- }
23
- }
24
-
25
- extension <%= model.name %> {
26
- init(values: Array<Optional<Binding>>) {
27
- <% model.properties.each_with_index do |property, index| %><%= """let #{property.name}: #{property.real_type} = values[#{index+1}] as! #{property.real_type}""" %>
28
- <% end %>
29
- self.init(<%= model.property_key_value_pairs true %>)
30
-
31
- let privateId: Int64 = values[0] as! Int64
32
- self.privateId = Int(privateId)
33
- }
34
- }
35
-
36
- extension <%= model.name %> {
37
- var itself: String { get { return "WHERE \(<%= model.name %>.tableName).private_id = \(privateId)" } }
38
- }
39
-
40
- extension <%= model.relation_name %> {
41
- func find(privateId: Int) -> Self {
42
- return filter(privateId)
43
- }
44
-
45
- func find(privateIds: [Int]) -> Self {
46
- return filter([.privateId: privateIds])
47
- }
48
-
49
- func filter(privateId: Int) -> Self {
50
- self.filter.append("private_id = \(privateId)")
51
- return self
52
- }
53
- }