Skip to content

Commit

Permalink
Add association generation function to metamodel
Browse files Browse the repository at this point in the history
preliminary add association support #29
  • Loading branch information
Draveness committed Sep 14, 2016
1 parent 855a066 commit a455e07
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 47 deletions.
6 changes: 4 additions & 2 deletions lib/metamodel/command/build.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def run
UI.section "Building MetaModel.framework in project" do
clone_project
models, associations = resolve_template
@models = compact_associtions_into_models models, associations
@models, @associations = compact_associtions_into_models models, associations
validate_models
render_model_files
update_initialize_method
Expand Down Expand Up @@ -61,7 +61,9 @@ def validate_models

def render_model_files
UI.section "Generating model files" do
Renderer.render(@models)
Renderer.new(@models, @associations).tap do |renderer|
renderer.render!
end
end
end

Expand Down
104 changes: 72 additions & 32 deletions lib/metamodel/command/build/renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,87 @@ module MetaModel
class Command
class Build
class Renderer
class << self

def templates
results = []
# file_paths = %w{file_header attributes json recordable initialize static_methods instance_methods model_query model_relation}
file_paths = %w{file_header table_initialize model_initialize model_update model_query model_delete static_methods helper}
file_paths.each do |file_path|
template = File.read File.expand_path(File.join(File.dirname(__FILE__), "../../template/#{file_path}.swift"))
results << template
end
results

attr_reader :project
attr_reader :target

attr_reader :models
attr_reader :associations

def initialize(models, associations)
@models = models
@associations = associations

@project = Xcodeproj::Project.open(Config.instance.metamodel_xcode_project)
@target = project.targets.first
end

def templates
results = []
# file_paths = %w{file_header attributes json recordable initialize static_methods instance_methods model_query model_relation}
file_paths = %w{file_header table_initialize model_initialize model_update model_query model_delete static_methods helper}
file_paths.each do |file_path|
template = File.read File.expand_path(File.join(File.dirname(__FILE__), "../../template/#{file_path}.swift"))
results << template
end
results
end

def render!
render_model_files
render_association_files
@project.save
end

def render(models)
project = Xcodeproj::Project.open(Config.instance.metamodel_xcode_project)
target = project.targets.first
models.each do |model|
target.source_build_phase.files_references.each do |file_ref|
target.source_build_phase.remove_file_reference(file_ref) if file_ref && "#{model.name}.swift" == file_ref.name
end
def render_model_files
@models.each do |model|
@target.source_build_phase.files_references.each do |file_ref|
@target.source_build_phase.remove_file_reference(file_ref) if file_ref && "#{model.name}.swift" == file_ref.name
end
models_group = project.main_group.find_subpath('MetaModel/Models', true)
models_group.clear
models_group.set_source_tree('SOURCE_ROOT')
end
models_group = @project.main_group.find_subpath('MetaModel/Models', true)
models_group.clear
models_group.set_source_tree('SOURCE_ROOT')

file_refs = []
@models.each do |model|
result = templates.map { |template|
ErbalTemplate::render_from_hash(template, { :model => model })
}.join("\n")
model_path = Pathname.new("./metamodel/MetaModel/#{model.name}.swift")
File.write model_path, result

file_refs = []
models.each do |model|
result = templates.map { |template|
ErbalTemplate::render_from_hash(template, { :model => model })
}.join("\n")
model_path = Pathname.new("./metamodel/MetaModel/#{model.name}.swift")
File.write model_path, result
file_refs << models_group.new_reference(Pathname.new("MetaModel/#{model.name}.swift"))

file_refs << models_group.new_reference(Pathname.new("MetaModel/#{model.name}.swift"))
UI.message '-> '.green + "Using #{model.name}.swift file"
end
@target.add_file_references file_refs
end

UI.message '-> '.green + "Using #{model.name}.swift file"
def render_association_files
@associations.each do |association|
@target.source_build_phase.files_references.each do |file_ref|
@target.source_build_phase.remove_file_reference(file_ref) if file_ref && "#{association.class_name}.swift" == file_ref.name
end
target.add_file_references file_refs
end

models_group = @project.main_group.find_subpath('MetaModel/Associations', true)
models_group.clear
models_group.set_source_tree('SOURCE_ROOT')

file_refs = []
@associations.each do |association|
next unless association.relation.to_s.start_with? "has"
template = File.read File.expand_path(File.join(File.dirname(__FILE__), "../../template/association.swift"))
result = ErbalTemplate::render_from_hash(template, { :association => association })
file_name = "#{association.class_name}.swift"
File.write Pathname.new("./metamodel/MetaModel/#{file_name}"), result

file_refs << models_group.new_reference(Pathname.new("MetaModel/#{file_name}"))

project.save
UI.message '-> '.green + "Using #{file_name} file"
end
@target.add_file_references file_refs
end

private
Expand Down
1 change: 1 addition & 0 deletions lib/metamodel/command/build/translator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def translate
@models.each do |model|
model.properties.uniq! { |prop| [prop.name] }
end
return @models, @associations
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ typealias <%= association.reverse_class_name %> = <%= association.class_name %>

struct <%= association.class_name %> {
private var privateId: Int = 0
private var <%= association.major_model.foreignId %>: Int = 0
private var <%= association.secondary_model.foreignId %>: Int = 0
private var <%= association.major_model.foreign_id %>: Int = 0
private var <%= association.secondary_model.foreign_id %>: Int = 0

static func findBy<%= association.major_model.foreignId.camelize %>(<%= association.major_model.foreignId %>: Int) -> [<%= association.class_name %>] {
let query = "SELECT * FROM \(tableName) WHERE <%= association.major_model.foreignId %> = \(<%= association.major_model.foreignId %>)"
static func findBy<%= association.major_model.foreign_id.camelize %>(<%= association.major_model.foreign_id %>: Int) -> [<%= association.class_name %>] {
let query = "SELECT * FROM \(tableName) WHERE <%= association.major_model.foreign_id %> = \(<%= association.major_model.foreign_id %>)"
var models: [<%= association.class_name %>] = []
guard let stmt = executeSQL(query) else { return models }
Expand All @@ -27,8 +27,8 @@ struct <%= association.class_name %> {
return models
}
static func findBy<%= association.secondary_model.foreignId.camelize %>(<%= association.secondary_model.foreignId %>: Int) -> [<%= association.class_name %>] {
let query = "SELECT * FROM \(tableName) WHERE <%= association.secondary_model.foreignId %> = \(<%= association.secondary_model.foreignId %>)"
static func findBy<%= association.secondary_model.foreign_id.camelize %>(<%= association.secondary_model.foreign_id %>: Int) -> [<%= association.class_name %>] {
let query = "SELECT * FROM \(tableName) WHERE <%= association.secondary_model.foreign_id %> = \(<%= association.secondary_model.foreign_id %>)"
var models: [<%= association.class_name %>] = []
guard let stmt = executeSQL(query) else { return models }
Expand All @@ -43,10 +43,10 @@ struct <%= association.class_name %> {
extension <%= association.class_name %> {
init(values: Array<Optional<Binding>>) {
let privateId: Int64 = values[0] as! Int64
let <%= association.major_model.foreignId %>: Int64 = values[1] as! Int64
let <%= association.secondary_model.foreignId %>: Int64 = values[2] as! Int64
let <%= association.major_model.foreign_id %>: Int64 = values[1] as! Int64
let <%= association.secondary_model.foreign_id %>: Int64 = values[2] as! Int64
self.init(privateId: Int(privateId), <%= association.major_model.foreignId %>: Int(<%= association.major_model.foreignId %>), <%= association.secondary_model.foreignId %>: Int(<%= association.secondary_model.foreignId %>))
self.init(privateId: Int(privateId), <%= association.major_model.foreign_id %>: Int(<%= association.major_model.foreign_id %>), <%= association.secondary_model.foreign_id %>: Int(<%= association.secondary_model.foreign_id %>))
}
}
Expand All @@ -56,10 +56,10 @@ extension <%= association.class_name %> {
static func initialize() {
let initializeTableSQL = "CREATE TABLE \(tableName)(" +
"private_id INTEGER PRIMARY KEY, " +
"<%= association.major_model.foreignId %> INTEGER NOT NULL, " +
"<%= association.secondary_model.foreignId %> INTEGER NOT NULL, " +
"FOREIGN KEY(<%= association.major_model.foreignId %>) REFERENCES <%= association.major_model.table_name %>(private_id)," +
"FOREIGN KEY(<%= association.secondary_model.foreignId %>) REFERENCES <%= association.secondary_model.table_name %>(private_id));"
"<%= association.major_model.foreign_id %> INTEGER NOT NULL, " +
"<%= association.secondary_model.foreign_id %> INTEGER NOT NULL, " +
"FOREIGN KEY(<%= association.major_model.foreign_id %>) REFERENCES <%= association.major_model.table_name %>(private_id)," +
"FOREIGN KEY(<%= association.secondary_model.foreign_id %>) REFERENCES <%= association.secondary_model.table_name %>(private_id));"

executeSQL(initializeTableSQL)
}
Expand Down

0 comments on commit a455e07

Please sign in to comment.