motion_migrate 0.1.0
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.
- data/.gitignore +17 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +152 -0
- data/Rakefile +3 -0
- data/lib/motion_migrate/generate.rb +51 -0
- data/lib/motion_migrate/model.rb +10 -0
- data/lib/motion_migrate/motion_generate/entity.rb +15 -0
- data/lib/motion_migrate/motion_generate/io.rb +79 -0
- data/lib/motion_migrate/motion_generate/parser.rb +27 -0
- data/lib/motion_migrate/motion_generate/property.rb +171 -0
- data/lib/motion_migrate/motion_generate/relationship.rb +153 -0
- data/lib/motion_migrate/motion_model/property.rb +14 -0
- data/lib/motion_migrate/motion_model/relationship.rb +20 -0
- data/lib/motion_migrate.rb +20 -0
- data/lib/tasks/migrate.rake +53 -0
- data/lib/version.rb +3 -0
- data/motion_migrate.gemspec +21 -0
- data/spec/property_spec.rb +113 -0
- data/spec/relationship_spec.rb +54 -0
- data/spec_project/.gitignore +18 -0
- data/spec_project/Gemfile +6 -0
- data/spec_project/Rakefile +14 -0
- data/spec_project/app/app_delegate.rb +7 -0
- data/spec_project/app/models/pilot.rb +7 -0
- data/spec_project/app/models/plane.rb +11 -0
- data/spec_project/db/schema.xcdatamodeld/.xccurrentversion +8 -0
- data/spec_project/db/schema.xcdatamodeld/schema.1.xcdatamodel/contents +6 -0
- data/spec_project/db/schema.xcdatamodeld/schema.10.xcdatamodel/contents +18 -0
- data/spec_project/db/schema.xcdatamodeld/schema.2.xcdatamodel/contents +7 -0
- data/spec_project/db/schema.xcdatamodeld/schema.3.xcdatamodel/contents +7 -0
- data/spec_project/db/schema.xcdatamodeld/schema.4.xcdatamodel/contents +8 -0
- data/spec_project/db/schema.xcdatamodeld/schema.5.xcdatamodel/contents +9 -0
- data/spec_project/db/schema.xcdatamodeld/schema.6.xcdatamodel/contents +13 -0
- data/spec_project/db/schema.xcdatamodeld/schema.7.xcdatamodel/contents +14 -0
- data/spec_project/db/schema.xcdatamodeld/schema.8.xcdatamodel/contents +16 -0
- data/spec_project/db/schema.xcdatamodeld/schema.9.xcdatamodel/contents +16 -0
- data/spec_project/spec/helper.rb +8 -0
- data/spec_project/spec/property_spec.rb +57 -0
- data/spec_project/spec/relationship_spec.rb +105 -0
- data/spec_project/vendor/Podfile.lock +11 -0
- metadata +113 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rvm use 1.9.3
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 Jelle Vandebeeck
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Motion Migrate
|
|
2
|
+
|
|
3
|
+
Generate the Core Data model from your RubyMotion code. Never open XCode again!
|
|
4
|
+
|
|
5
|
+
## Why
|
|
6
|
+
|
|
7
|
+
I love the [Nitron](https://github.com/mattgreen/nitron) gem created by [@mattgreen](https://github.com/mattgreen/). But I missed some features, and I really hate to open Xcode to create the Core Data model. So I created some rake tasks that helped me generate the Core Data model. Thanks to [@mattgreen](https://github.com/mattgreen/) for starting this in the 0.3 branch of the [Nitron](https://github.com/mattgreen/nitron) project.
|
|
8
|
+
|
|
9
|
+
Another reason why I wanted to create this gem is because I love using [Magical Record](https://github.com/magicalpanda/MagicalRecord). This is really a great way to handle Core Data, it's like a small layer on top of it.
|
|
10
|
+
|
|
11
|
+
Most gems that want to --railsify-- Core Data don't make correct use of the different contexts as used by Core Data. So I wanted to be able to use Core Data as it should, by just generating the model.
|
|
12
|
+
|
|
13
|
+
Maybe adding some simplicity in creating the relationships between models will be added later. But for now, generating the Core Data model is the main goal!
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
The installation is simple. Just add this line to you Gemfile:
|
|
18
|
+
|
|
19
|
+
gem 'motion_migrate'
|
|
20
|
+
|
|
21
|
+
Execute:
|
|
22
|
+
|
|
23
|
+
$ bundle install
|
|
24
|
+
|
|
25
|
+
And BOOM, you're on your way!
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
With this gem you can set every option you can while using the Xcode modelling tool. I'm not going to describe every option because I assume RubyMotion developers know how Core Data works. Here is a short list of the available options for a property:
|
|
30
|
+
|
|
31
|
+
- min
|
|
32
|
+
- max
|
|
33
|
+
- default
|
|
34
|
+
- regex
|
|
35
|
+
- external_storage
|
|
36
|
+
- required
|
|
37
|
+
- transient
|
|
38
|
+
- indexed
|
|
39
|
+
- spotlight
|
|
40
|
+
- truth_file
|
|
41
|
+
|
|
42
|
+
And of course here are the available options for the relationships (belongs to and has many):
|
|
43
|
+
|
|
44
|
+
- required
|
|
45
|
+
- deletion_rule
|
|
46
|
+
- class_name
|
|
47
|
+
- spotlight
|
|
48
|
+
- truth_file
|
|
49
|
+
- transient
|
|
50
|
+
- min
|
|
51
|
+
- max
|
|
52
|
+
- inverse_of
|
|
53
|
+
- ordered
|
|
54
|
+
|
|
55
|
+
The 'spec_project' is an example project with two models containing properties and relationships.
|
|
56
|
+
|
|
57
|
+
But the main question is how to generate this Core Data model. Well start by extending your models from MotionMigrate::Model. This class is extended from NSManagedObject so you're ready to continue with Core Data once the
|
|
58
|
+
model is generated.
|
|
59
|
+
|
|
60
|
+
class Plane < MotionMigrate::Model
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
Next define the properties:
|
|
64
|
+
This will generate two properties, a name property and a multi property. To add some relationships to it, you can add a belongs\_to -- rails-like-shizzle-- to the model.
|
|
65
|
+
|
|
66
|
+
class Plane < MotionMigrate::Model
|
|
67
|
+
property :name, :string
|
|
68
|
+
property :multi, :boolean, :default => false
|
|
69
|
+
|
|
70
|
+
belongs_to :pilot, :class_name => "Pilot", :inverse_of => :planes
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
Don't forget to add a has\_many or belongs\_to as a reverse relationship.
|
|
74
|
+
|
|
75
|
+
class Pilot < MotionMigrate::Model
|
|
76
|
+
has_many :planes, :class_name => "Plane", :inverse_of => :pilot
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
The relationships as defined above contain the minimal parameters you'll have to pass to the has\_many or belongs\_to.
|
|
80
|
+
|
|
81
|
+
Now the most important part, migrating the model. Just run this command to generate the Core Data model from the current models.
|
|
82
|
+
|
|
83
|
+
$ rake db:migrate
|
|
84
|
+
|
|
85
|
+
You can also revert to a previous version of the Core Data model by running:
|
|
86
|
+
|
|
87
|
+
$ rake db:rollback
|
|
88
|
+
|
|
89
|
+
You can check out the other rake tasks by running:
|
|
90
|
+
|
|
91
|
+
$ rake -T
|
|
92
|
+
|
|
93
|
+
## Example
|
|
94
|
+
|
|
95
|
+
But for me, the most obvious part is an small example application that shows you how this gem is used. Check out the spec_project en run it so you can see it in action.
|
|
96
|
+
|
|
97
|
+
## Todo
|
|
98
|
+
|
|
99
|
+
This is certainly not the end, still got a lot to do.
|
|
100
|
+
|
|
101
|
+
- [ ] Better version generation. (shouldn't always generate a new version unless told to do so)
|
|
102
|
+
- [ ] Clean up the utility methods.
|
|
103
|
+
- [ ] Implement [mogenerator](https://github.com/rentzsch/mogenerator) functionality.
|
|
104
|
+
- [ ] Add << functionatlity to the relationships in orde to add objects.
|
|
105
|
+
- [ ] Try to handle relationships in a more Ruby on Railzy way.
|
|
106
|
+
|
|
107
|
+
## Tests
|
|
108
|
+
|
|
109
|
+
When contributing to this project make sure you run the tests to make sure everything keeps working like it should.
|
|
110
|
+
|
|
111
|
+
Run the migration tests by executing this command from the project root:
|
|
112
|
+
|
|
113
|
+
$ rspec
|
|
114
|
+
|
|
115
|
+
When you want to test the functional integration with [Magical Record](https://github.com/magicalpanda/MagicalRecord) by moving to the spec_project folder and running the specs.
|
|
116
|
+
|
|
117
|
+
$ rake spec
|
|
118
|
+
|
|
119
|
+
## Contributing
|
|
120
|
+
|
|
121
|
+
It would be awesome if you contribute!
|
|
122
|
+
|
|
123
|
+
1. Fork it
|
|
124
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
125
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
126
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
127
|
+
5. Create new Pull Request
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
Copyright (c) 2013 Jelle Vandebeeck
|
|
132
|
+
|
|
133
|
+
MIT License
|
|
134
|
+
|
|
135
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
136
|
+
a copy of this software and associated documentation files (the
|
|
137
|
+
"Software"), to deal in the Software without restriction, including
|
|
138
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
139
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
140
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
141
|
+
the following conditions:
|
|
142
|
+
|
|
143
|
+
The above copyright notice and this permission notice shall be
|
|
144
|
+
included in all copies or substantial portions of the Software.
|
|
145
|
+
|
|
146
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
147
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
148
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
149
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
150
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
151
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
152
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module MotionMigrate
|
|
2
|
+
class Model
|
|
3
|
+
include MotionMigrate::MotionGenerate::Entity
|
|
4
|
+
include MotionMigrate::MotionGenerate::Parser
|
|
5
|
+
include MotionMigrate::MotionGenerate::Property
|
|
6
|
+
include MotionMigrate::MotionGenerate::Relationship
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class Generate
|
|
10
|
+
class << self
|
|
11
|
+
def build
|
|
12
|
+
models = Dir.glob("app/models/*.rb")
|
|
13
|
+
raise "! No models defined in 'app/models', add models to this folder if you want to generate the database model." if models.count == 0
|
|
14
|
+
|
|
15
|
+
models.each do |filename|
|
|
16
|
+
File.open(filename) { |file| eval(file.read) }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
builder = Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |xml|
|
|
20
|
+
xml.model(database_model_attributes) do
|
|
21
|
+
ObjectSpace.each_object(Class).select { |klass| klass < MotionMigrate::Model }.each do |entity|
|
|
22
|
+
xml.entity(:name => entity.entity_name, :representedClassName => entity.entity_name, :syncable => "YES") do
|
|
23
|
+
entity.properties[entity.entity_name].each do |name, property|
|
|
24
|
+
xml.attribute(property)
|
|
25
|
+
end unless entity.properties[entity.entity_name].nil?
|
|
26
|
+
entity.relationships[entity.entity_name].each do |name, relationship|
|
|
27
|
+
xml.relationship(relationship)
|
|
28
|
+
end unless entity.relationships[entity.entity_name].nil?
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
builder.to_xml
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def database_model_attributes
|
|
37
|
+
{
|
|
38
|
+
:name => "",
|
|
39
|
+
:userDefinedModelVersionIdentifier => "",
|
|
40
|
+
:type => "com.apple.IDECoreDataModeler.DataModel",
|
|
41
|
+
:documentVersion => "1.0",
|
|
42
|
+
:lastSavedToolsVersion => "1811",
|
|
43
|
+
:systemVersion => "11D50",
|
|
44
|
+
:minimumToolsVersion => "Automatic",
|
|
45
|
+
:macOSVersion => "Automatic",
|
|
46
|
+
:iOSVersion => "Automatic"
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module MotionMigrate
|
|
2
|
+
class IO
|
|
3
|
+
class << self
|
|
4
|
+
def write(xml="")
|
|
5
|
+
create_db
|
|
6
|
+
|
|
7
|
+
current_schema = nil
|
|
8
|
+
if version = current_schema_version()
|
|
9
|
+
File.open(File.join(current_schema(), "contents")) do |f|
|
|
10
|
+
current_schema = f.read
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
if current_schema != xml
|
|
15
|
+
version = (version || 0) + 1
|
|
16
|
+
|
|
17
|
+
latest_schema_path = xcdatamodeld_path("schema.#{version}.xcdatamodel")
|
|
18
|
+
Dir.mkdir(latest_schema_path) unless Dir.exists?(latest_schema_path)
|
|
19
|
+
|
|
20
|
+
File.open(File.join(latest_schema_path, "contents"), "w") do |file|
|
|
21
|
+
file.write(xml)
|
|
22
|
+
end
|
|
23
|
+
write_current_schema(version)
|
|
24
|
+
|
|
25
|
+
unless File.symlink?("resources/schema.xcdatamodeld")
|
|
26
|
+
File.symlink("../db/schema.xcdatamodeld", "resources/schema.xcdatamodeld")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
puts "# Data model migrated to version #{version}."
|
|
30
|
+
else
|
|
31
|
+
length = 38 + version.to_s.length
|
|
32
|
+
puts "# Data model already at version #{version}."
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def current_schema_version
|
|
37
|
+
return nil unless path = current_schema
|
|
38
|
+
|
|
39
|
+
version = nil
|
|
40
|
+
path.match(/\.([0-9]+)\.xcdatamodel$/) do |match|
|
|
41
|
+
version = match[1].to_i
|
|
42
|
+
end
|
|
43
|
+
version
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def current_schema
|
|
47
|
+
plist = xcdatamodeld_path(".xccurrentversion")
|
|
48
|
+
return nil unless File.exists?(plist)
|
|
49
|
+
|
|
50
|
+
xcdatamodeld_path(Nokogiri::XML(File.open(plist)).at_xpath("/plist/dict/string").text)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def write_current_schema(version)
|
|
54
|
+
File.open(xcdatamodeld_path(".xccurrentversion"), "w") do |file|
|
|
55
|
+
file.write(<<-PLIST)
|
|
56
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
57
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
58
|
+
<plist version="1.0">
|
|
59
|
+
<dict>
|
|
60
|
+
<key>_XCCurrentVersionName</key>
|
|
61
|
+
<string>schema.#{version}.xcdatamodel</string>
|
|
62
|
+
</dict>
|
|
63
|
+
</plist>
|
|
64
|
+
PLIST
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
protected
|
|
69
|
+
|
|
70
|
+
def create_db
|
|
71
|
+
FileUtils.mkdir_p(File.join("db", "schema.xcdatamodeld"))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def xcdatamodeld_path(*args)
|
|
75
|
+
File.join(["db", "schema.xcdatamodeld"] + args)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module MotionMigrate
|
|
2
|
+
module MotionGenerate
|
|
3
|
+
module Parser
|
|
4
|
+
def self.included(base)
|
|
5
|
+
base.extend(ClassMethods)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module ClassMethods
|
|
9
|
+
def core_data_string(string)
|
|
10
|
+
string.to_s.split("_").each{|word| word.capitalize! }.join(" ")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def core_data_variable(value)
|
|
14
|
+
value.to_s.split("_").each{ |word| word.capitalize! }.join("")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def core_data_boolean(value)
|
|
18
|
+
value == true ? "YES" : "NO"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def core_data_date(value)
|
|
22
|
+
(value.to_time.to_i - Date.new(2001, 1, 1).to_time.to_i).to_s
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
module MotionMigrate
|
|
2
|
+
module MotionGenerate
|
|
3
|
+
module Property
|
|
4
|
+
def self.included(base)
|
|
5
|
+
base.extend(ClassMethods)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module ClassMethods
|
|
9
|
+
def property(name, type, options={})
|
|
10
|
+
type = type.to_sym
|
|
11
|
+
|
|
12
|
+
raise_if_property_type_not_allowed(type)
|
|
13
|
+
options.each { |key, value| raise_if_property_option_not_allowed(type, key) }
|
|
14
|
+
|
|
15
|
+
attribute_type = type == :binary_data ? "Binary" : core_data_string(type)
|
|
16
|
+
attributes = {
|
|
17
|
+
name: name,
|
|
18
|
+
attributeType: attribute_type,
|
|
19
|
+
optional: core_data_boolean(true),
|
|
20
|
+
syncable: core_data_boolean(true)
|
|
21
|
+
}
|
|
22
|
+
attributes.merge!(core_data_property_attributes(type, options))
|
|
23
|
+
properties[self.entity_name] = {} if properties[self.entity_name].nil?
|
|
24
|
+
properties[self.entity_name][name] = attributes
|
|
25
|
+
attributes
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def properties
|
|
29
|
+
@@properties ||= {}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def raise_if_property_type_not_allowed(type)
|
|
33
|
+
unless property_type_allowed?(type)
|
|
34
|
+
raise <<-ERROR
|
|
35
|
+
! The type must be one of the following:
|
|
36
|
+
! :string
|
|
37
|
+
! :integer_16
|
|
38
|
+
! :integer_32
|
|
39
|
+
! :integer_64
|
|
40
|
+
! :decimal
|
|
41
|
+
! :double
|
|
42
|
+
! :float
|
|
43
|
+
! :boolean
|
|
44
|
+
! :date
|
|
45
|
+
! :binary_data
|
|
46
|
+
ERROR
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def property_type_allowed?(type)
|
|
51
|
+
[
|
|
52
|
+
:string,
|
|
53
|
+
:integer_16,
|
|
54
|
+
:integer_32,
|
|
55
|
+
:integer_64,
|
|
56
|
+
:decimal,
|
|
57
|
+
:double,
|
|
58
|
+
:float,
|
|
59
|
+
:boolean,
|
|
60
|
+
:date,
|
|
61
|
+
:binary_data
|
|
62
|
+
].include?(type)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def raise_if_property_option_not_allowed(type, option)
|
|
66
|
+
unless property_option_allowed?(type, option)
|
|
67
|
+
raise <<-ERROR
|
|
68
|
+
! The option must be one of the following:
|
|
69
|
+
!
|
|
70
|
+
! For type :string:
|
|
71
|
+
! :min
|
|
72
|
+
! :max
|
|
73
|
+
! :default
|
|
74
|
+
! :regex
|
|
75
|
+
!
|
|
76
|
+
! For type :boolean:
|
|
77
|
+
! :default
|
|
78
|
+
!
|
|
79
|
+
! For type :date, :integer_16, :integer_32, :integer_64, :decimal, :double or :float:
|
|
80
|
+
! :min
|
|
81
|
+
! :max
|
|
82
|
+
! :default
|
|
83
|
+
!
|
|
84
|
+
! For type :binary_data:
|
|
85
|
+
! :external_storage
|
|
86
|
+
!
|
|
87
|
+
! Options allowed for all types:
|
|
88
|
+
! :required
|
|
89
|
+
! :transient
|
|
90
|
+
! :indexed
|
|
91
|
+
! :spotlight
|
|
92
|
+
! :truth_file
|
|
93
|
+
ERROR
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def property_option_allowed?(type, option)
|
|
98
|
+
type = :number if [
|
|
99
|
+
:integer_16,
|
|
100
|
+
:integer_32,
|
|
101
|
+
:integer_64,
|
|
102
|
+
:decimal,
|
|
103
|
+
:double,
|
|
104
|
+
:float,
|
|
105
|
+
:date
|
|
106
|
+
].include?(type)
|
|
107
|
+
|
|
108
|
+
allowed_options = {
|
|
109
|
+
number: [:min, :max, :default],
|
|
110
|
+
string: [:min, :max, :default, :regex],
|
|
111
|
+
boolean: [:default],
|
|
112
|
+
binary_data: [:external_storage]
|
|
113
|
+
}[type]
|
|
114
|
+
|
|
115
|
+
allowed_options += [
|
|
116
|
+
:required,
|
|
117
|
+
:transient,
|
|
118
|
+
:indexed,
|
|
119
|
+
:spotlight,
|
|
120
|
+
:truth_file
|
|
121
|
+
]
|
|
122
|
+
allowed_options.include?(option)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def core_data_property_attributes(type, options)
|
|
126
|
+
attributes = {}
|
|
127
|
+
|
|
128
|
+
options.each do |key, value|
|
|
129
|
+
case key
|
|
130
|
+
when :required
|
|
131
|
+
attributes[:optional] = core_data_boolean(value != true)
|
|
132
|
+
when :transient
|
|
133
|
+
attributes[:transient] = core_data_boolean(value)
|
|
134
|
+
when :indexed
|
|
135
|
+
attributes[:indexed] = core_data_boolean(value)
|
|
136
|
+
when :spotlight
|
|
137
|
+
attributes[:spotlightIndexingEnabled] = core_data_boolean(value)
|
|
138
|
+
when :truth_file
|
|
139
|
+
attributes[:storedInTruthFile] = core_data_boolean(value)
|
|
140
|
+
when :min
|
|
141
|
+
if type == :date
|
|
142
|
+
attributes[:minDateTimeInterval] = core_data_date(value)
|
|
143
|
+
else
|
|
144
|
+
attributes[:minValueString] = value
|
|
145
|
+
end
|
|
146
|
+
when :max
|
|
147
|
+
if type == :date
|
|
148
|
+
attributes[:maxDateTimeInterval] = core_data_date(value)
|
|
149
|
+
else
|
|
150
|
+
attributes[:maxValueString] = value
|
|
151
|
+
end
|
|
152
|
+
when :default
|
|
153
|
+
if type == :date
|
|
154
|
+
attributes[:defaultDateTimeInterval] = core_data_date(value)
|
|
155
|
+
elsif type == :boolean
|
|
156
|
+
attributes[:defaultValueString] = core_data_boolean(value)
|
|
157
|
+
else
|
|
158
|
+
attributes[:defaultValueString] = value
|
|
159
|
+
end
|
|
160
|
+
when :regex
|
|
161
|
+
attributes[:regularExpressionString] = value
|
|
162
|
+
when :external_storage
|
|
163
|
+
attributes[:allowsExternalBinaryDataStorage] = core_data_boolean(value)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
attributes
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|