metamodel 0.2.0 → 0.3.1

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.
@@ -7,16 +7,12 @@ module MetaModel
7
7
  attr_reader :dependent
8
8
  attr_accessor :major_model
9
9
  attr_accessor :secondary_model
10
- attr_accessor :through
11
10
 
12
11
  def initialize(name, major_model, secondary_model, relation, args)
13
- # through = args[:through]
14
- through = nil
15
12
  dependent = args[:dependent] || :nullify
16
13
 
17
14
  @name = name.to_s.camelize :lower
18
15
  @relation = relation
19
- @through = through.to_s.camelize.singularize unless through.nil?
20
16
  @dependent = dependent
21
17
  @major_model = major_model
22
18
  @secondary_model = secondary_model
@@ -24,44 +20,52 @@ module MetaModel
24
20
  validate_association
25
21
  end
26
22
 
23
+ def class_name
24
+ "#{major_model.name}#{secondary_model.name}Association".camelize
25
+ end
26
+
27
+ def reverse_class_name
28
+ "#{secondary_model.name}#{major_model.name}Association".camelize
29
+ end
30
+
31
+ def major_model_id
32
+ major_model.foreign_id
33
+ end
34
+
35
+ def secondary_model_id
36
+ secondary_model.foreign_id
37
+ end
38
+
39
+ def hash_value
40
+ self.hash.to_s(16)
41
+ end
42
+
27
43
  def expect_constraint?(constraint)
28
44
  result = true
29
45
  result &= self.major_model == constraint.secondary_model
30
46
  result &= self.secondary_model == constraint.major_model
31
- result &= self.through == constraint.through
32
47
 
33
48
  result &= case [self.relation, constraint.relation]
34
49
  when [:has_one, :belongs_to], [:belongs_to, :has_one] then true
35
50
  when [:belongs_to, :has_many] then
36
51
  return false if self.dependent == :destroy
37
- return true unless constraint.through
38
- return false
52
+ return true
39
53
  when [:has_many, :belongs_to] then
40
54
  return false if constraint.dependent == :destroy
41
- return true unless self.through
42
- return false
55
+ return true
43
56
  when [:has_many, :has_many] then
44
- self.through == constraint.through
57
+ return true
45
58
  else false
46
59
  end
47
60
  result
48
61
  end
49
62
 
50
- def secondary_model_instance
51
- case relation
52
- when :has_many, :has_one then "#{secondary_model.name}.find(privateId)"
53
- when :belongs_to then "#{secondary_model.name}.find(#{secondary_model.foreign_id})"
54
- else ""
55
- end
56
- end
57
-
58
63
  #-------------------------------------------------------------------------#
59
64
 
60
65
  # @!group Validation
61
66
 
62
67
  def validate_association
63
68
  validate_dependent(@dependent)
64
- validate_through(@through)
65
69
  end
66
70
 
67
71
  def validate_dependent(dependent)
@@ -71,12 +75,6 @@ module MetaModel
71
75
  unless supported_dependent_options.include? dependent
72
76
  end
73
77
 
74
- def validate_through(through)
75
- raise Informative, "belongs_to can't coexist with through." \
76
- if !!through && @relation == :belongs_to
77
- end
78
-
79
-
80
78
  #-------------------------------------------------------------------------#
81
79
 
82
80
  # @!group Relation
@@ -100,11 +98,7 @@ module MetaModel
100
98
  end
101
99
 
102
100
  def debug_description
103
- if through
104
- "#{major_model.name}.#{relation}.#{secondary_model.name}.through.#{through.name}.#{dependent}"
105
- else
106
- "#{major_model.name}.#{relation}.#{secondary_model.name}.#{dependent}"
107
- end
101
+ "#{major_model.name}.#{relation}.#{secondary_model.name}.#{dependent}"
108
102
  end
109
103
  end
110
104
  end
@@ -15,10 +15,6 @@ module MetaModel
15
15
  @properties.select { |prop| prop.name == property }.size > 0
16
16
  end
17
17
 
18
- def all_foreign_properties
19
- @properties.select { |element| element.is_foreign? }
20
- end
21
-
22
18
  def properties_exclude_id
23
19
  properties_exclude_property "id"
24
20
  end
@@ -70,19 +66,19 @@ module MetaModel
70
66
  def build_table
71
67
  table = "CREATE TABLE #{table_name}"
72
68
  main_sql = @properties.map do |property|
73
- result = "#{property.name} #{property.database_type}"
69
+ result = "#{property.name.underscore} #{property.database_type}"
74
70
  result << " PRIMARY KEY" if property.is_primary?
75
71
  result << " UNIQUE" if property.is_unique?
76
72
  result << " DEFAULT #{property.default_value}" if property.has_default_value?
77
73
  result
78
74
  end
79
- foreign_sql = @properties.map do |property|
80
- next unless property.is_foreign?
81
- reference_table_name = property.type.tableize
82
- "FOREIGN KEY(#{property.name}) REFERENCES #{reference_table_name}(privateId)"
83
- end
75
+ # foreign_sql = @properties.map do |property|
76
+ # next unless property.is_foreign?
77
+ # reference_table_name = property.type.tableize
78
+ # "FOREIGN KEY(#{property.name}) REFERENCES #{reference_table_name}(privateId)"
79
+ # end
84
80
 
85
- table + "(privateId INTEGER PRIMARY KEY, #{(main_sql + foreign_sql).compact.join(", ")});"
81
+ table + "(private_id INTEGER PRIMARY KEY, #{(main_sql).compact.join(", ")});"
86
82
  end
87
83
 
88
84
  private
@@ -73,10 +73,6 @@ module MetaModel
73
73
  @modifiers.include? :primary
74
74
  end
75
75
 
76
- def is_foreign?
77
- @modifiers[:foreign]
78
- end
79
-
80
76
  def is_optional?
81
77
  @type.to_s.end_with? "?"
82
78
  end
@@ -0,0 +1,29 @@
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
+ extension <%= association.class_name %> {
12
+ static func create(<%= association.major_model_id %> <%= association.major_model_id %>: Int, <%= association.secondary_model_id %>: Int) {
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
+ }
15
+ }
16
+
17
+ public extension <%= association.major_model.name %> {
18
+ var <%= association.name %>: <%= association.secondary_model.name %>? {
19
+ get {
20
+ guard let id = <%= association.class_name %>.findBy(<%= association.major_model.foreign_id %>: privateId).first?.commentId else { return nil }
21
+ return <%= association.secondary_model.name %>.find(id)
22
+ }
23
+ set {
24
+ guard let newValue = newValue else { return }
25
+ <%= association.class_name %>.findBy(<%= association.major_model_id %>: privateId).forEach { $0.delete() }
26
+ <%= association.class_name %>.create(<%= association.major_model_id %>: newValue.privateId, <%= association.secondary_model_id %>: privateId)
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,99 @@
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,11 +1,9 @@
1
1
  // MAKR: - Helper
2
2
 
3
3
  public class <%= model.relation_name %>: Relation<<%= model.name %>> {
4
- <% model.all_foreign_properties.each do |foreign_property| %><%= """var #{foreign_property.name} = 0
5
- """%><% end %>
6
4
  override init() {
7
5
  super.init()
8
- self.select = "SELECT \(<%= model.name %>.tableName.unwrapped).* FROM \(<%= model.name %>.tableName.unwrapped)"
6
+ self.select = "SELECT \(<%= model.name %>.tableName).* FROM \(<%= model.name %>.tableName)"
9
7
  }
10
8
 
11
9
  override var result: [<%= model.name %>] {
@@ -20,7 +18,7 @@ public class <%= model.relation_name %>: Relation<<%= model.name %>> {
20
18
  }
21
19
 
22
20
  func expandColumn(column: <%= model.name %>.Column) -> String {
23
- return "\(<%= model.name %>.tableName.unwrapped).\(column.unwrapped)"
21
+ return "\(<%= model.name %>.tableName).\(column)"
24
22
  }
25
23
  }
26
24
 
@@ -36,7 +34,7 @@ extension <%= model.name %> {
36
34
  }
37
35
 
38
36
  extension <%= model.name %> {
39
- var itself: String { get { return "WHERE \(<%= model.name %>.tableName.unwrapped).\("privateId".unwrapped) = \(privateId)" } }
37
+ var itself: String { get { return "WHERE \(<%= model.name %>.tableName).private_id = \(privateId)" } }
40
38
  }
41
39
 
42
40
  extension <%= model.relation_name %> {
@@ -44,8 +42,12 @@ extension <%= model.relation_name %> {
44
42
  return filter(privateId)
45
43
  }
46
44
 
45
+ func find(privateIds: [Int]) -> Self {
46
+ return filter([.privateId: privateIds])
47
+ }
48
+
47
49
  func filter(privateId: Int) -> Self {
48
- self.filter.append("\"privateId\" = \(privateId)")
50
+ self.filter.append("private_id = \(privateId)")
49
51
  return self
50
52
  }
51
53
  }
@@ -27,5 +27,12 @@ public class MetaModel {
27
27
  #{model.name}.initialize()
28
28
  }""" %>
29
29
  <% end %>
30
+
31
+ <% associations.each do |association| %><% if association.relation.to_s.start_with? "has" %><%= """if infos[#{association.class_name}.tableName] != \"#{association.hash_value}\" {
32
+ updateMetaModelTableInfos(#{association.class_name}.tableName, hashValue: \"#{association.hash_value}\")
33
+ #{association.class_name}.deinitialize()
34
+ #{association.class_name}.initialize()
35
+ }""" %>
36
+ <% end %><% end %>
30
37
  }
31
38
  }
@@ -3,11 +3,8 @@
3
3
  public extension <%= model.name %> {
4
4
  var delete: Bool {
5
5
  get {
6
- let deleteSQL = "DELETE FROM \(<%= model.name %>.tableName.unwrapped) \(itself)"
7
- executeSQL(deleteSQL)<% model.associations.each do |association| %>
8
- <%= association.secondary_model_instance + "?.delete" if association.dependent == :destroy %>
9
- <%= association.secondary_model_instance + "?.update(#{model.foreign_id}: 0)" if association.dependent == :nullify && model.contains?(model.foreign_id) %>
10
- <% end %>
6
+ let deleteSQL = "DELETE FROM \(<%= model.name %>.tableName) \(itself)"
7
+ executeSQL(deleteSQL)
11
8
  return true
12
9
  }
13
10
  }
@@ -4,11 +4,12 @@ public struct <%= model.name %> {
4
4
  <% end %>
5
5
  static let tableName = "<%= model.table_name %>"
6
6
 
7
- public enum Column: String, Unwrapped {
8
- <% model.properties.each do |property| %><%= """case #{property.name} = \"#{property.name}\"""" %>
7
+ public enum Column: String, CustomStringConvertible {
8
+ <% model.properties.each do |property| %><%= """case #{property.name} = \"#{property.name.underscore}\"""" %>
9
9
  <% end %>
10
- case privateId = "privateId"
11
- var unwrapped: String { get { return self.rawValue.unwrapped } }
10
+ case privateId = "private_id"
11
+
12
+ public var description: String { get { return self.rawValue } }
12
13
  }
13
14
 
14
15
  public init(<%= model.property_key_type_pairs false %>) {
@@ -34,7 +35,7 @@ public struct <%= model.name %> {
34
35
  <%= """columnsSQL.append(.#{property.name})
35
36
  valuesSQL.append(#{property.name})
36
37
  """ %><% end %><% end %>
37
- let insertSQL = "INSERT INTO \(tableName.unwrapped) (\(columnsSQL.map { $0.rawValue }.joinWithSeparator(", "))) VALUES (\(valuesSQL.map { $0.unwrapped }.joinWithSeparator(", ")))"
38
+ let insertSQL = "INSERT INTO \(tableName) (\(columnsSQL.map { $0.rawValue }.joinWithSeparator(", "))) VALUES (\(valuesSQL.map { $0.unwrapped }.joinWithSeparator(", ")))"
38
39
  guard let _ = executeSQL(insertSQL),
39
40
  let lastInsertRowId = executeScalarSQL("SELECT last_insert_rowid();") as? Int64 else { return nil }
40
41
  var result = <%= model.name %>(<%= model.property_key_value_pairs %>)
@@ -42,16 +43,3 @@ public struct <%= model.name %> {
42
43
  return result
43
44
  }
44
45
  }
45
-
46
- public extension <%= model.relation_name %> {
47
- <% model.all_foreign_properties.each do |property| %>
48
- func create(<%= model.property_key_type_pairs_without_property property.name %>) -> <%= model.name %>? {
49
- return <%= model.name %>.create(<% if model.properties_exclude_property(property).count == 0 %><%= "#{property}: property" %><% else %><%= model.property_key_value_pairs %><% end %>)
50
- }
51
-
52
- func append(element: <%= model.name %>) {
53
- var element = element
54
- element.<%= property.name %> = <%= property.name %>
55
- }
56
- <% end %>
57
- }
@@ -29,6 +29,10 @@ public extension <%= model.name %> {
29
29
  return <%= model.relation_name %>().find(id).first
30
30
  }
31
31
 
32
+ static func find(ids: [Int]) -> <%= model.relation_name %> {
33
+ return <%= model.relation_name %>().find(ids)
34
+ }
35
+
32
36
  static func findBy(<%= model.property_key_type_pairs(true, true) %>) -> <%= model.relation_name %> {
33
37
  return <%= model.relation_name %>().findBy(<%= model.property_key_value_pairs %>)
34
38
  }
@@ -90,13 +94,13 @@ public extension <%= model.relation_name %> {
90
94
  }
91
95
 
92
96
  if let value = value as? String {
93
- filterByEqual(value.unwrapped)
97
+ filterByEqual(value)
94
98
  } else if let value = value as? Int {
95
99
  filterByEqual(value)
96
100
  } else if let value = value as? Double {
97
101
  filterByEqual(value)
98
102
  } else if let value = value as? [String] {
99
- filterByIn(value.map { $0.unwrapped })
103
+ filterByIn(value.map { $0 })
100
104
  } else if let value = value as? [Int] {
101
105
  filterByIn(value.map { $0.description })
102
106
  } else if let value = value as? [Double] {
@@ -128,7 +132,7 @@ public extension <%= model.relation_name %> {
128
132
  }
129
133
 
130
134
  func orderBy(column: <%= model.name %>.Column, asc: Bool) -> Self {
131
- self.order.append("\(expandColumn(column)) \(asc ? "ASC".unwrapped : "DESC".unwrapped)")
135
+ self.order.append("\(expandColumn(column)) \(asc ? "ASC" : "DESC")")
132
136
  return self
133
137
  }
134
138
  }
@@ -13,11 +13,11 @@ public extension <%= model.name %> {
13
13
  if let attributes = attributes as? [<%= model.name %>.Column: Unwrapped] {
14
14
  for (key, value) in attributes {
15
15
  switch key {
16
- <% model.properties_exclude_id.each do |property| %><%= """case .#{property.name}: setSQL.append(\"\\(key.unwrapped) = \\(value.unwrapped)\")""" %>
16
+ <% model.properties_exclude_id.each do |property| %><%= """case .#{property.name}: setSQL.append(\"\\(key) = \\(value.unwrapped)\")""" %>
17
17
  <% end %>default: break
18
18
  }
19
19
  }
20
- let updateSQL = "UPDATE \(<%= model.name %>.tableName.unwrapped) SET \(setSQL.joinWithSeparator(", ")) \(itself)"
20
+ let updateSQL = "UPDATE \(<%= model.name %>.tableName) SET \(setSQL.joinWithSeparator(", ")) \(itself)"
21
21
  executeSQL(updateSQL) {
22
22
  for (key, value) in attributes {
23
23
  switch key {