metamodel 0.0.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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +4 -0
- data/bin/meta +5 -0
- data/lib/metamodel/command/build/parser.rb +49 -0
- data/lib/metamodel/command/build/renderer.rb +51 -0
- data/lib/metamodel/command/build.rb +63 -0
- data/lib/metamodel/command/clean.rb +27 -0
- data/lib/metamodel/command/generate.rb +44 -0
- data/lib/metamodel/command/init.rb +33 -0
- data/lib/metamodel/command.rb +42 -0
- data/lib/metamodel/config.rb +145 -0
- data/lib/metamodel/model/cocoa_model.rb +56 -0
- data/lib/metamodel/model/cocoa_property.rb +47 -0
- data/lib/metamodel/model/property_constructor.rb +31 -0
- data/lib/metamodel/template/model.swift.erb +122 -0
- data/lib/metamodel/user_interface.rb +411 -0
- data/lib/metamodel/version.rb +5 -0
- data/lib/metamodel.rb +28 -0
- metadata +181 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0039698aeb5a6943fbab150f42314e52fb601203
|
4
|
+
data.tar.gz: a811eaa4d44154902463572ed3854c0f956b77e7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3d73ffe24665ff900cabcf2c8ba7a72708fe3acc2061db5e7b898ac21488e1d6e2b2418b8d705c97e2cebda43bb7f399823aeeadf73bd96b4f436df3b4020b7d
|
7
|
+
data.tar.gz: 2c73680883d69b487d845cee94a8c07258006c4a87deb39ad768dcac83096b894ca2643bf4b3dc24b0c095531a9260870f4a8152f9d6651028c73dad9039e735
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Draveness
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
data/bin/meta
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module MetaModel
|
2
|
+
class Command
|
3
|
+
class Build
|
4
|
+
class Parser
|
5
|
+
|
6
|
+
include Config::Mixin
|
7
|
+
|
8
|
+
require 'metamodel/model/cocoa_model'
|
9
|
+
require 'metamodel/model/cocoa_property'
|
10
|
+
require 'metamodel/model/property_constructor'
|
11
|
+
require 'metamodel/command/build/renderer'
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@models = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def parse
|
18
|
+
title_options = { :verbose_prefix => '-> '.green }
|
19
|
+
UI.section "Analyzing scaffold files" do
|
20
|
+
scaffold_path = config.scaffold_path
|
21
|
+
scaffolds = Dir[scaffold_path + "*.rb"]
|
22
|
+
scaffolds.each do |scaffold_file|
|
23
|
+
UI.titled_section "Resolving `#{File.basename(scaffold_file)}`", title_options do
|
24
|
+
scaffold_code = File.read(scaffold_path + scaffold_file)
|
25
|
+
eval scaffold_code
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
@models
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def metamodel_version(version)
|
35
|
+
raise Informative,
|
36
|
+
"Scaffold file #{version} not matched with current metamodel version #{VERSION}" if version != VERSION
|
37
|
+
end
|
38
|
+
|
39
|
+
def define(model_name)
|
40
|
+
model = CocoaModel.new(model_name)
|
41
|
+
|
42
|
+
yield PropertyConstructor.new(model)
|
43
|
+
|
44
|
+
@models << model
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'xcodeproj'
|
4
|
+
|
5
|
+
module MetaModel
|
6
|
+
class Command
|
7
|
+
class Build
|
8
|
+
class Renderer
|
9
|
+
class ErbalT < OpenStruct
|
10
|
+
def self.render_from_hash(t, h)
|
11
|
+
ErbalT.new(h).render(t)
|
12
|
+
end
|
13
|
+
|
14
|
+
def render(template)
|
15
|
+
ERB.new(template).result(binding)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def render(model)
|
21
|
+
template_path = File.expand_path(File.join(File.dirname(__FILE__), "../../template/model.swift.erb"))
|
22
|
+
template = File.read template_path
|
23
|
+
|
24
|
+
result = ErbalT::render_from_hash(template, { :model => model })
|
25
|
+
model_path = Pathname.new("./MetaModel/MetaModel/#{model.name}.swift")
|
26
|
+
File.write model_path, result
|
27
|
+
|
28
|
+
project = Xcodeproj::Project.open(Config.instance.metamodel_xcode_project)
|
29
|
+
target = project.targets.first
|
30
|
+
|
31
|
+
target.source_build_phase.files_references.each do |file_ref|
|
32
|
+
target.source_build_phase.remove_file_reference(file_ref) if file_ref && "#{model.name}.swift" == file_ref.name
|
33
|
+
end
|
34
|
+
|
35
|
+
models_group = project.main_group.find_subpath('MetaModel/Models', true)
|
36
|
+
models_group.clear
|
37
|
+
models_group.set_source_tree('SOURCE_ROOT')
|
38
|
+
file_ref = models_group.new_reference Pathname.new("MetaModel/#{model.name}.swift")
|
39
|
+
target.add_file_references [file_ref]
|
40
|
+
|
41
|
+
project.save
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'git'
|
2
|
+
|
3
|
+
module MetaModel
|
4
|
+
class Command
|
5
|
+
class Build < Command
|
6
|
+
require 'metamodel/command/build/parser'
|
7
|
+
require 'metamodel/command/build/renderer'
|
8
|
+
|
9
|
+
self.summary = ""
|
10
|
+
self.description = <<-DESC
|
11
|
+
|
12
|
+
DESC
|
13
|
+
|
14
|
+
attr_accessor :models
|
15
|
+
|
16
|
+
def initialize(argv)
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
UI.section "Building MetaModel project" do
|
22
|
+
clone_project
|
23
|
+
parse_template
|
24
|
+
render_model_files
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def clone_project
|
29
|
+
if File.exist? config.metamodel_xcode_project
|
30
|
+
UI.message "Existing project `#{config.metamodel_xcode_project}`"
|
31
|
+
else
|
32
|
+
UI.section "Cloning MetaModel project into `./MetaModel` folder" do
|
33
|
+
Git.clone(config.metamodel_template_uri, 'MetaModel')
|
34
|
+
UI.message "Using `./MetaModel/MetaModel.xcodeproj` to build module"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_template
|
40
|
+
parser = Parser.new
|
41
|
+
@models = parser.parse
|
42
|
+
end
|
43
|
+
|
44
|
+
def render_model_files
|
45
|
+
title_options = { :verbose_prefix => '-> '.green }
|
46
|
+
UI.section "Generating model files" do
|
47
|
+
@models.each do |model|
|
48
|
+
UI.titled_section "Using #{model.name}.swift file", title_options do
|
49
|
+
Renderer.render(model)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def validate!
|
56
|
+
super
|
57
|
+
raise Informative, 'No scaffold folder in directory' unless config.scaffold_path_in_dir(Pathname.pwd)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module MetaModel
|
4
|
+
class Command
|
5
|
+
class Clean < Command
|
6
|
+
|
7
|
+
self.summary = "Clean MetaModel project from current folder."
|
8
|
+
self.description = <<-DESC
|
9
|
+
Remove MetaModel folder which contains MetaModel.xcodeproj and model
|
10
|
+
files from current path.
|
11
|
+
DESC
|
12
|
+
|
13
|
+
def initialize(argv)
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
UI.section "Removing MetaModel project" do
|
19
|
+
FileUtils.rm_rf 'MetaModel'
|
20
|
+
UI.message "Already clean up the whole MetaModel project from current folder"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module MetaModel
|
2
|
+
class Command
|
3
|
+
class Generate < Command
|
4
|
+
|
5
|
+
self.summary = "Generate a class skeleton for a model."
|
6
|
+
self.description = <<-DESC
|
7
|
+
Generate a skeleton for a Objective-C/Swift class and create
|
8
|
+
this file as model.rb in MetaModel folder.
|
9
|
+
DESC
|
10
|
+
|
11
|
+
def initialize(argv)
|
12
|
+
@model_name = argv.shift_argument
|
13
|
+
@file_path = config.scaffold_path + "#{@model_name.underscore}.rb"
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
verify_scaffold_exists!
|
19
|
+
UI.section "Generating model scaffold file" do
|
20
|
+
title_options = { :verbose_prefix => '-> '.green }
|
21
|
+
UI.titled_section "Adding `#{File.basename(@file_path)}` to scaffold folder", title_options do
|
22
|
+
@file_path.open('w') { |f| f << model_template(@model_name) }
|
23
|
+
end
|
24
|
+
UI.notice "`#{File.basename(@file_path)}` has already generated, use the command below to edit it.\n"
|
25
|
+
UI.message "vim scaffold/#{File.basename(@file_path)}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def model_template(model)
|
32
|
+
modelfile = ''
|
33
|
+
modelfile << "metamodel_version '#{VERSION}'\n\n"
|
34
|
+
modelfile << <<-TEMPLATE.strip_heredoc
|
35
|
+
define :#{model} do |j|
|
36
|
+
# define #{model} model like this
|
37
|
+
# j.nickname :string
|
38
|
+
end
|
39
|
+
TEMPLATE
|
40
|
+
modelfile
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module MetaModel
|
2
|
+
class Command
|
3
|
+
|
4
|
+
class Init < Command
|
5
|
+
self.summary = "Generate a scaffold folder for the current directory."
|
6
|
+
self.description = <<-DESC
|
7
|
+
Creates a scaffold folder for the current directory if none exits. Call
|
8
|
+
this command before all other metamodel command.
|
9
|
+
DESC
|
10
|
+
|
11
|
+
def initialize(argv)
|
12
|
+
@scaffold_path = Pathname.pwd + 'scaffold'
|
13
|
+
@project_path = argv.shift_argument
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate!
|
18
|
+
super
|
19
|
+
raise Informative, 'Existing scaffold folder in directory' unless config.scaffold_path_in_dir(Pathname.pwd).nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
UI.section "Initiating MetaModel project" do
|
24
|
+
UI.section "Creating `scaffold` folder for MetaModel" do
|
25
|
+
FileUtils.mkdir(@scaffold_path)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'colored'
|
2
|
+
require 'claide'
|
3
|
+
|
4
|
+
module MetaModel
|
5
|
+
class Command < CLAide::Command
|
6
|
+
require 'metamodel/command/init'
|
7
|
+
require 'metamodel/command/generate'
|
8
|
+
require 'metamodel/command/build'
|
9
|
+
require 'metamodel/command/clean'
|
10
|
+
|
11
|
+
include Config::Mixin
|
12
|
+
|
13
|
+
self.abstract_command = true
|
14
|
+
self.command = 'meta'
|
15
|
+
self.version = VERSION
|
16
|
+
self.description = 'MetaModel, the Model generator.'
|
17
|
+
self.plugin_prefixes = %w(claide meta)
|
18
|
+
|
19
|
+
def self.run(argv)
|
20
|
+
super(argv)
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(argv)
|
24
|
+
super
|
25
|
+
# config.verbose = self.verbose?
|
26
|
+
config.verbose = true
|
27
|
+
end
|
28
|
+
|
29
|
+
#-------------------------------------------------------------------------#
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Checks that scaffold folder exists
|
34
|
+
#
|
35
|
+
# @return [void]
|
36
|
+
def verify_scaffold_exists!
|
37
|
+
unless config.scaffold_folder
|
38
|
+
raise Informative, "No `scaffold' folder found in the project directory."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'active_support/multibyte/unicode'
|
2
|
+
|
3
|
+
module MetaModel
|
4
|
+
# Stores the global configuration of MetaModel.
|
5
|
+
#
|
6
|
+
class Config
|
7
|
+
|
8
|
+
DEFAULTS = {
|
9
|
+
:verbose => true,
|
10
|
+
:silent => false,
|
11
|
+
}
|
12
|
+
|
13
|
+
public
|
14
|
+
|
15
|
+
#-------------------------------------------------------------------------#
|
16
|
+
|
17
|
+
# @!group UI
|
18
|
+
|
19
|
+
# @return [Bool] Whether CocoaPods should provide detailed output about the
|
20
|
+
# performed actions.
|
21
|
+
#
|
22
|
+
attr_accessor :verbose
|
23
|
+
alias_method :verbose?, :verbose
|
24
|
+
|
25
|
+
public
|
26
|
+
|
27
|
+
#-------------------------------------------------------------------------#
|
28
|
+
|
29
|
+
# @!group Initialization
|
30
|
+
|
31
|
+
def verbose
|
32
|
+
@verbose && !silent
|
33
|
+
end
|
34
|
+
|
35
|
+
public
|
36
|
+
|
37
|
+
#-------------------------------------------------------------------------#
|
38
|
+
|
39
|
+
# @!group Paths
|
40
|
+
|
41
|
+
# @return [Pathname] the root of the MetaModel installation where the
|
42
|
+
# scaffold folder is located.
|
43
|
+
#
|
44
|
+
def installation_root
|
45
|
+
current_dir = ActiveSupport::Multibyte::Unicode.normalize(Dir.pwd)
|
46
|
+
current_path = Pathname.new(current_dir)
|
47
|
+
unless @installation_root
|
48
|
+
until current_path.root?
|
49
|
+
if scaffold_path_in_dir(current_path)
|
50
|
+
@installation_root = current_path
|
51
|
+
break
|
52
|
+
else
|
53
|
+
current_path = current_path.parent
|
54
|
+
end
|
55
|
+
end
|
56
|
+
@installation_root ||= Pathname.pwd
|
57
|
+
end
|
58
|
+
@installation_root
|
59
|
+
end
|
60
|
+
|
61
|
+
attr_writer :installation_root
|
62
|
+
alias_method :project_root, :installation_root
|
63
|
+
|
64
|
+
# Returns the path of the metamodel template uri.
|
65
|
+
#
|
66
|
+
# @return [String]
|
67
|
+
#
|
68
|
+
def metamodel_template_uri
|
69
|
+
"git@github.com:Draveness/MetaModel-Template.git"
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the path of the MetaModel.xcodeproj.
|
73
|
+
#
|
74
|
+
# @return [String]
|
75
|
+
#
|
76
|
+
def metamodel_xcode_project
|
77
|
+
"./MetaModel/MetaModel.xcodeproj"
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns whether or not scaffold folder is in current project.
|
81
|
+
#
|
82
|
+
# @return [Bool]
|
83
|
+
#
|
84
|
+
def scaffold_folder
|
85
|
+
Pathname.new(scaffold_path).exist?
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns the path of the scaffold.
|
89
|
+
#
|
90
|
+
# @return [Pathname]
|
91
|
+
# @return [Nil]
|
92
|
+
#
|
93
|
+
def scaffold_path
|
94
|
+
@scaffold_path_in_dir ||= installation_root + 'scaffold'
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns the path of the scaffold folder in the given dir if any exists.
|
98
|
+
#
|
99
|
+
# @param [Pathname] dir
|
100
|
+
# The directory where to look for the scaffold.
|
101
|
+
#
|
102
|
+
# @return [Pathname] The path of the scaffold.
|
103
|
+
# @return [Nil] If not scaffold was found in the given dir
|
104
|
+
#
|
105
|
+
def scaffold_path_in_dir(dir)
|
106
|
+
candidate = dir + 'scaffold'
|
107
|
+
if candidate.exist?
|
108
|
+
return candidate
|
109
|
+
end
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
|
113
|
+
public
|
114
|
+
|
115
|
+
#-------------------------------------------------------------------------#
|
116
|
+
|
117
|
+
# @!group Singleton
|
118
|
+
|
119
|
+
# @return [Config] the current config instance creating one if needed.
|
120
|
+
#
|
121
|
+
def self.instance
|
122
|
+
@instance ||= new
|
123
|
+
end
|
124
|
+
|
125
|
+
# Sets the current config instance. If set to nil the config will be
|
126
|
+
# recreated when needed.
|
127
|
+
#
|
128
|
+
# @param [Config, Nil] the instance.
|
129
|
+
#
|
130
|
+
# @return [void]
|
131
|
+
#
|
132
|
+
class << self
|
133
|
+
attr_writer :instance
|
134
|
+
end
|
135
|
+
|
136
|
+
# Provides support for accessing the configuration instance in other
|
137
|
+
# scopes.
|
138
|
+
#
|
139
|
+
module Mixin
|
140
|
+
def config
|
141
|
+
Config.instance
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module MetaModel
|
2
|
+
|
3
|
+
class CocoaModel
|
4
|
+
attr_reader :name
|
5
|
+
attr_reader :properties
|
6
|
+
|
7
|
+
def initialize(name)
|
8
|
+
@name = name
|
9
|
+
@properties = []
|
10
|
+
|
11
|
+
validate
|
12
|
+
end
|
13
|
+
|
14
|
+
def properties_exclude_id
|
15
|
+
@properties.select { |property| property.key != :id }
|
16
|
+
end
|
17
|
+
|
18
|
+
def table_name
|
19
|
+
name.to_s.pluralize.underscore
|
20
|
+
end
|
21
|
+
|
22
|
+
def relation_name
|
23
|
+
"#{name}Relation"
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate
|
27
|
+
property_keys = @properties.map { |property| property.key }
|
28
|
+
|
29
|
+
unless property_keys.include? :id
|
30
|
+
property_id = CocoaProperty.new(:id, :int, :primary)
|
31
|
+
@properties << property_id
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def build_table
|
36
|
+
table = ""
|
37
|
+
@properties.each do |property|
|
38
|
+
property_key = property.key
|
39
|
+
if property.has_default_value?
|
40
|
+
default_value = property.default_value
|
41
|
+
if default_value.is_a? String
|
42
|
+
table << "t.column(#{property_key}, defaultValue: \"#{default_value}\")\n\t\t\t"
|
43
|
+
else
|
44
|
+
table << "t.column(#{property_key}, defaultValue: #{default_value})\n\t\t\t"
|
45
|
+
end
|
46
|
+
else
|
47
|
+
table << "t.column(#{property_key})\n\t\t\t"
|
48
|
+
end
|
49
|
+
table << "t.primaryKey(#{property_key})\n\t\t\t" if property.is_primary?
|
50
|
+
table << "t.unique(#{property_key})\n\t\t\t" if property.is_unique?
|
51
|
+
end
|
52
|
+
table
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module MetaModel
|
2
|
+
|
3
|
+
class CocoaProperty
|
4
|
+
attr_reader :json_key
|
5
|
+
attr_reader :key
|
6
|
+
attr_reader :type
|
7
|
+
attr_reader :modifiers
|
8
|
+
|
9
|
+
def initialize(json_key, type = :string, *modifiers)
|
10
|
+
@json_key = json_key
|
11
|
+
@key = json_key.to_s.camelize(:lower).to_sym
|
12
|
+
@type = convert_symbol_to_type type
|
13
|
+
|
14
|
+
@modifiers = {}
|
15
|
+
@modifiers.default = false
|
16
|
+
|
17
|
+
modifiers.flatten.map do |modifier|
|
18
|
+
@modifiers[modifier] = true if modifier.is_a? Symbol
|
19
|
+
@modifiers[:default] = modifier[:default] if modifier.is_a? Hash and modifier[:default]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def is_unique?
|
24
|
+
@modifiers.include? :unique
|
25
|
+
end
|
26
|
+
|
27
|
+
def is_primary?
|
28
|
+
@modifiers.include? :primary
|
29
|
+
end
|
30
|
+
|
31
|
+
def has_default_value?
|
32
|
+
@modifiers[:default].nil?
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_value
|
36
|
+
modifiers[:default]
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def convert_symbol_to_type(symbol)
|
42
|
+
symbol.to_s.capitalize
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module MetaModel
|
2
|
+
|
3
|
+
class PropertyConstructor
|
4
|
+
|
5
|
+
attr_reader :model
|
6
|
+
|
7
|
+
def initialize(model)
|
8
|
+
@model = model
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(meth, *arguments, &block)
|
12
|
+
(class << self; self; end).class_eval do
|
13
|
+
define_method meth do |type, *arguments|
|
14
|
+
save_property CocoaProperty.new(meth, type, arguments)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
self.send meth, *arguments
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# Save property to current Cocoa Model
|
23
|
+
#
|
24
|
+
# @param [CocoaProperty] the instance for cocoa property
|
25
|
+
# @return [Void]
|
26
|
+
def save_property(property)
|
27
|
+
@model.properties << property
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|