mini_record 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  MiniRecord is a micro extension for our `ActiveRecord` gem.
2
- With it you can add the ability to create columns outside the default schema, directly
3
- in your **model** in a similar way that you just know in others projects
4
- like DataMapper or MongoMapper.
2
+ With MiniRecord you can add the ability to create columns outside the default `schema.rb`, directly
3
+ in your **model** in a similar way that should know in others projects
4
+ like DataMapper, MongoMapper or MongoID.
5
5
 
6
6
  My inspiration come from this handy [project](https://github.com/pjhyett/auto_migrations).
7
7
 
@@ -14,8 +14,8 @@ My inspiration come from this handy [project](https://github.com/pjhyett/auto_mi
14
14
 
15
15
  ## Instructions
16
16
 
17
- What you need is to move/remove `db/migrations` and `db/schema.rb`.
18
- It's no more necessary and it avoid conflicts.
17
+ What you need is to move/remove your `db/schema.rb`.
18
+ This avoid conflicts.
19
19
 
20
20
  Add to your `Gemfile`:
21
21
 
@@ -36,38 +36,50 @@ class Person < ActiveRecord::Base
36
36
  s.string :name
37
37
  s.integer :address_id
38
38
  end
39
+ add_index :address_id
40
+
39
41
  belongs_to :address
40
42
  end
41
43
  Person.auto_upgrade!
42
44
 
43
- # you can use also this way
44
- class Address < ActiveRecord::Base
45
- key.string :city
46
- key.string :state
47
- key.integer :number
48
- has_many :people
45
+ # you can use also this SEXY way
46
+ class Post < ActiveRecord::Base
47
+ key :title
48
+ key :permalink, :index => true, :limit => 50
49
+ key :comments_count, :as => :integer
50
+ key :category, :as => :references, :index => true
49
51
  end
52
+ Post.auto_upgrade!
53
+ ```
50
54
 
51
- # or this
52
- class Address < ActiveRecord::Base
53
- col.string :city
54
- col.string :state
55
- col.integer :number
56
- has_many :people
57
- end
55
+ If you don't like `key` there are also few aliases: `col, field, property`
58
56
 
59
- # or this
60
- class Address < ActiveRecord::Base
61
- property.string :city
62
- property.string :state
63
- property.integer :number
64
- has_many :people
65
- end
57
+ Instead of `:as => :my_type` you can use `:type => :my_type`
58
+
59
+ Option `:as` or `:type` if not provided are `:string`, you can use all ActiveRecord types:
60
+
61
+ ``` rb
62
+ :primary_key, :string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean
63
+ :references, :belongs_to, :primary_key, :timestamp
64
+ ```
66
65
 
67
- Address.auto_upgrade!
66
+ You can provide others ActiveRecord options like:
67
+
68
+ ``` rb
69
+ :limit, :default, :null, :precision, :scale
70
+
71
+ # example
72
+ class Foo < ActiveRecord::Base
73
+ key :title, :default => "MyTitle" # :as => :string is by default
74
+ key :price, :as => :decimal, :scale => 8, :precision => 2
75
+ end
68
76
  ```
69
77
 
70
- Once you bootstrap your **app**, missing columns and tables will be created on the fly.
78
+ See [ActiveRecord::TableDefinition](http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html)
79
+ for more details.
80
+
81
+ Finally, when you execute `MyModel.auto_upgrade!`, missing columns, indexes and tables will be created on the fly.
82
+ Indexes and columns present in the db but **not** in your model schema will be **deleted*** also in your db.
71
83
 
72
84
  ### Adding a new column
73
85
 
@@ -82,17 +94,20 @@ class Person < ActiveRecord::Base
82
94
  end
83
95
  belongs_to :address
84
96
  end
97
+ Person.auto_upgrade!
85
98
 
86
- # or if you use others ways
87
- class Person < ActiveRecord::Base
88
- col.string :name
89
- col.string :surname # <<- this
90
- col.integer :address_id
91
- belongs_to :address
99
+ # or you can use a more interesting way
100
+ class Post < ActiveRecord::Base
101
+ key :title
102
+ key :body, :as => :text # <<- this
103
+ key :permalink, :index => true
104
+ key :comments_count, :as => :integer
105
+ key :category, :as => :references, :index => true
92
106
  end
107
+ Post.auto_upgrade!
93
108
  ```
94
109
 
95
- So now when you start your **webserver** you can see an `ALTER TABLE` statement, this mean that your existing
110
+ So now when you invoke `MyModel.auto_upgrade!` you should see a SQL query like `ALTER TABLE` that mean that your existing
96
111
  records are happy and safe.
97
112
 
98
113
  ### Removing a column
@@ -104,12 +119,44 @@ It's exactly the same, but the column will be _really_ deleted without affect ot
104
119
  It's not possible for us know when/what column you have renamed, but we can know if you changed the `type` so
105
120
  if you change `t.string :name` to `t.text :name` we are be able to perform an `ALTER TABLE`
106
121
 
122
+ ### Add/Remove indexes
123
+
124
+ In the same ways we manage columns MiniRecord will detect new indexes and indexes that needs to be removed.
125
+ So when you perform `MyModel.auto_upgrade!` a SQL command like:
126
+
127
+ ``` SQL
128
+ PRAGMA index_info('index_people_on_name')
129
+ CREATE INDEX "index_people_on_surname" ON "people" ("surname")
130
+ ```
131
+
132
+ Note that writing it in DSL way you have same options as `add_index` so you are be able to write:
133
+
134
+ ``` rb
135
+ class Fox < ActiveRecord::Base
136
+ key :foo, :index => true
137
+ key :foo, :index => :custom_name
138
+ key :foo, :index => [:foo, :bar]
139
+ key :foo, :index => { :column => [:branch_id, :party_id], :unique => true, :name => 'by_branch_party' }
140
+ end
141
+ ```
142
+
143
+ That is the same of:
144
+
145
+ ``` rb
146
+ class Fox < ActiveRecord::Base
147
+ key :foo
148
+ add_index :foo
149
+ add_index :custom_name
150
+ add_index [:foo, :bar]
151
+ add_index [:branch_id, :party_id], :unique => true, :name => 'by_branch_party'
152
+ end
153
+ ```
154
+
107
155
  ## Warnings
108
156
 
109
157
  This software is not yet tested in a production project, now is only heavy development and if you can
110
158
  pleas fork it, find bug add a spec and then come back with a pull request. Thanks!
111
159
 
112
-
113
160
  ## Author
114
161
 
115
162
  DAddYE, you can follow me on twitter [@daddye](http://twitter.com/daddye) or take a look at my site [daddye.it](http://www.daddye.it)
@@ -11,9 +11,23 @@ module MiniRecord
11
11
  tb.primary_key(primary_key)
12
12
  end
13
13
  end
14
- alias :col :table_definition
15
- alias :key :table_definition
16
- alias :property :table_definition
14
+
15
+ def col(column_name, options={})
16
+ type = options.delete(:as) || options.delete(:type) || :string
17
+ table_definition.send(type, column_name, options)
18
+ column_name = table_definition.columns[-1].name
19
+ case index_name = options.delete(:index)
20
+ when Hash
21
+ add_index(options.delete(:column) || column_name, index_name)
22
+ when TrueClass
23
+ add_index(column_name)
24
+ when String, Symbol, Array
25
+ add_index(index_name)
26
+ end
27
+ end
28
+ alias :key :col
29
+ alias :property :col
30
+ alias :field :col
17
31
 
18
32
  def reset_table_definition!
19
33
  @_table_definition = nil
@@ -26,6 +40,17 @@ module MiniRecord
26
40
  alias :keys :schema
27
41
  alias :properties :schema
28
42
 
43
+ def add_index(column_name, options={})
44
+ index_name = connection.index_name(table_name, :column => column_name)
45
+ indexes[index_name] = options.merge(:column => column_name)
46
+ index_name
47
+ end
48
+ alias :index :add_index
49
+
50
+ def indexes
51
+ @_indexes ||= {}
52
+ end
53
+
29
54
  def auto_upgrade!
30
55
  # Table doesn't exist, create it
31
56
  unless connection.tables.include?(table_name)
@@ -95,6 +120,20 @@ module MiniRecord
95
120
  end
96
121
  end
97
122
 
123
+ # Remove old index
124
+ indexes_in_db = connection.indexes(table_name).map(&:name)
125
+ (indexes_in_db - indexes.keys).each do |name|
126
+ connection.remove_index(table_name, :name => name)
127
+ end
128
+
129
+ # Add indexes
130
+ indexes.each do |name, options|
131
+ options = options.dup
132
+ unless connection.indexes(table_name).detect { |i| i.name == name }
133
+ connection.add_index(table_name, options.delete(:column), options)
134
+ end
135
+ end
136
+
98
137
  # Reload column information
99
138
  reset_column_information
100
139
  end
@@ -1,3 +1,3 @@
1
1
  module MiniRecord
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -59,8 +59,8 @@ describe MiniRecord do
59
59
  ActiveRecord::Base.connection.table_exists?(Post.table_name).must_equal false
60
60
  ActiveRecord::Base.connection.table_exists?(Category.table_name).must_equal false
61
61
  Post.auto_upgrade!; Category.auto_upgrade!
62
- Post.column_names.must_equal Post.db_columns
63
- Category.column_names.must_equal Category.schema_columns
62
+ Post.column_names.sort.must_equal Post.db_columns
63
+ Category.column_names.sort.must_equal Category.schema_columns
64
64
 
65
65
  # Check default properties
66
66
  category = Category.create(:title => 'category')
@@ -70,15 +70,40 @@ describe MiniRecord do
70
70
  post.body.must_equal 'bar'
71
71
  post.category.must_equal category
72
72
 
73
+
73
74
  # Remove a column
74
75
  Post.reset_table_definition!
75
76
  Post.class_eval do
76
- key.string :name
77
- key.references :category
77
+ key :name
78
+ key :category, :as => :references
78
79
  end
79
80
  Post.auto_upgrade!
80
81
  post = Post.first
81
82
  post.name.must_be_nil
82
83
  post.category.must_equal category
84
+ post.wont_respond_to :title
85
+ end
86
+
87
+ it 'has indexes inside model' do
88
+ # Check indexes
89
+ Animal.auto_upgrade!
90
+ Animal.db_indexes.size.must_be :>, 0
91
+ Animal.db_indexes.must_equal Animal.indexes.keys.sort
92
+
93
+ indexes_was = Animal.db_indexes
94
+
95
+ # Remove an index
96
+ Animal.indexes.delete(indexes_was.pop)
97
+ Animal.auto_upgrade!
98
+ Animal.indexes.keys.sort.must_equal indexes_was
99
+ Animal.db_indexes.must_equal indexes_was
100
+
101
+ # Add a new index
102
+ Animal.class_eval do
103
+ key :category, :as => :references, :index => true
104
+ end
105
+ Animal.auto_upgrade!
106
+ Animal.db_columns.must_include "category_id"
107
+ Animal.db_indexes.must_equal((indexes_was << "index_animals_on_category_id").sort)
83
108
  end
84
109
  end
data/spec/models.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  require 'logger'
2
2
 
3
3
  ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
4
- # ActiveRecord::Base.connection.tables.each { |t| ActiveRecord::Base.connection.drop_table(t) }
5
- # ActiveRecord::Base.logger = Logger.new($stdout)
4
+ # ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new($stdout)
6
5
 
7
6
  module SpecHelper
8
7
  def self.included(base)
@@ -11,11 +10,15 @@ module SpecHelper
11
10
 
12
11
  module ClassMethods
13
12
  def db_columns
14
- connection.columns(table_name).map(&:name)
13
+ connection.columns(table_name).map(&:name).sort
14
+ end
15
+
16
+ def db_indexes
17
+ connection.indexes(table_name).map(&:name).sort
15
18
  end
16
19
 
17
20
  def schema_columns
18
- table_definition.columns.map { |c| c.name.to_s }
21
+ table_definition.columns.map { |c| c.name.to_s }.sort
19
22
  end
20
23
  end
21
24
  end
@@ -30,15 +33,22 @@ end
30
33
  class Post < ActiveRecord::Base
31
34
  include SpecHelper
32
35
 
33
- key.string :title
34
- key.string :body
35
- key.references :category
36
+ key :title
37
+ key :body
38
+ key :category, :as => :references
36
39
  belongs_to :category
37
40
  end
38
41
 
39
42
  class Category < ActiveRecord::Base
40
43
  include SpecHelper
41
44
 
42
- key.string :title
45
+ key :title
43
46
  has_many :posts
44
47
  end
48
+
49
+ class Animal < ActiveRecord::Base
50
+ include SpecHelper
51
+
52
+ key :name, :index => true
53
+ index :id
54
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_record
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Davide D'Agostino
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-09-06 00:00:00 +02:00
18
+ date: 2011-09-10 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -55,7 +55,6 @@ files:
55
55
  - lib/mini_record/auto_schema.rb
56
56
  - lib/mini_record/version.rb
57
57
  - mini_record.gemspec
58
- - rakefile.compiled.rbc
59
58
  - spec/mini_record_spec.rb
60
59
  - spec/models.rb
61
60
  - spec/spec_helper.rb
@@ -1,309 +0,0 @@
1
- !RBIX
2
- 16846133056282117387
3
- x
4
- M
5
- 1
6
- n
7
- n
8
- x
9
- 10
10
- __script__
11
- i
12
- 86
13
- 5
14
- 7
15
- 0
16
- 64
17
- 47
18
- 49
19
- 1
20
- 1
21
- 15
22
- 5
23
- 7
24
- 2
25
- 64
26
- 47
27
- 49
28
- 1
29
- 1
30
- 15
31
- 5
32
- 7
33
- 3
34
- 64
35
- 47
36
- 49
37
- 1
38
- 1
39
- 15
40
- 45
41
- 4
42
- 5
43
- 43
44
- 6
45
- 7
46
- 7
47
- 56
48
- 8
49
- 50
50
- 9
51
- 1
52
- 15
53
- 5
54
- 44
55
- 43
56
- 10
57
- 79
58
- 49
59
- 11
60
- 1
61
- 13
62
- 7
63
- 12
64
- 7
65
- 7
66
- 49
67
- 13
68
- 2
69
- 15
70
- 47
71
- 49
72
- 14
73
- 1
74
- 15
75
- 5
76
- 44
77
- 43
78
- 10
79
- 79
80
- 49
81
- 11
82
- 1
83
- 13
84
- 7
85
- 15
86
- 7
87
- 7
88
- 49
89
- 13
90
- 2
91
- 15
92
- 47
93
- 49
94
- 14
95
- 1
96
- 15
97
- 2
98
- 11
99
- I
100
- 5
101
- I
102
- 0
103
- I
104
- 0
105
- I
106
- 0
107
- n
108
- p
109
- 16
110
- s
111
- 17
112
- bundler/gem_tasks
113
- x
114
- 7
115
- require
116
- s
117
- 4
118
- rake
119
- s
120
- 13
121
- rake/testtask
122
- x
123
- 4
124
- Rake
125
- n
126
- x
127
- 8
128
- TestTask
129
- x
130
- 4
131
- test
132
- M
133
- 1
134
- p
135
- 2
136
- x
137
- 9
138
- for_block
139
- t
140
- n
141
- x
142
- 9
143
- __block__
144
- i
145
- 46
146
- 57
147
- 19
148
- 0
149
- 15
150
- 20
151
- 0
152
- 49
153
- 0
154
- 0
155
- 7
156
- 1
157
- 64
158
- 49
159
- 2
160
- 1
161
- 15
162
- 20
163
- 0
164
- 45
165
- 3
166
- 4
167
- 7
168
- 5
169
- 64
170
- 49
171
- 6
172
- 1
173
- 13
174
- 18
175
- 2
176
- 49
177
- 7
178
- 1
179
- 15
180
- 15
181
- 20
182
- 0
183
- 2
184
- 13
185
- 18
186
- 2
187
- 49
188
- 8
189
- 1
190
- 15
191
- 11
192
- I
193
- 5
194
- I
195
- 1
196
- I
197
- 1
198
- I
199
- 1
200
- n
201
- p
202
- 9
203
- x
204
- 4
205
- libs
206
- s
207
- 4
208
- spec
209
- x
210
- 2
211
- <<
212
- x
213
- 3
214
- Dir
215
- n
216
- s
217
- 17
218
- spec/**/*_spec.rb
219
- x
220
- 2
221
- []
222
- x
223
- 11
224
- test_files=
225
- x
226
- 8
227
- verbose=
228
- p
229
- 9
230
- I
231
- 0
232
- I
233
- 5
234
- I
235
- 4
236
- I
237
- 6
238
- I
239
- 10
240
- I
241
- 7
242
- I
243
- 23
244
- I
245
- 8
246
- I
247
- 2e
248
- x
249
- 42
250
- /Developer/src/Extras/mini_record/rakefile
251
- p
252
- 1
253
- x
254
- 4
255
- test
256
- x
257
- 3
258
- new
259
- x
260
- 4
261
- Hash
262
- x
263
- 16
264
- new_from_literal
265
- x
266
- 7
267
- default
268
- x
269
- 3
270
- []=
271
- x
272
- 4
273
- task
274
- x
275
- 4
276
- spec
277
- p
278
- 13
279
- I
280
- 0
281
- I
282
- 1
283
- I
284
- 9
285
- I
286
- 2
287
- I
288
- 12
289
- I
290
- 3
291
- I
292
- 1b
293
- I
294
- 5
295
- I
296
- 28
297
- I
298
- b
299
- I
300
- 3e
301
- I
302
- c
303
- I
304
- 56
305
- x
306
- 42
307
- /Developer/src/Extras/mini_record/rakefile
308
- p
309
- 0