arql 0.2.5 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 032762276fe5d2c764f71eae665d16e2e4786368c7f154e7bd19be5188a49027
4
- data.tar.gz: 73b8ceedbcd0abdc5c87c186374c8cfe0db50e0c22d1e645d2c10396ec8c4aa3
3
+ metadata.gz: 2146ddb3d395a10ebd850db5f4d6a3d01b96dd4d62c1a90771ce286f54d3fb1c
4
+ data.tar.gz: 757595855e4889c2a6e0025954acf8887d728bbbc21d66cf0b09640b2ab848af
5
5
  SHA512:
6
- metadata.gz: cc70e4f11ff7bcfc4f0654d8a3e59ac2ae666e55237dff7d62e408c3c6bba200b22f3e064ea17dc513a94bbd4eacefa8f369d4d79c24d9a9ada857efa00c58af
7
- data.tar.gz: 34491bfc5588a4bae89f26f889c5863e700f79b926902bb769c3e122082342706252fc41bcf461244bfc82e8f5a5e7dbf1eb4bd3c43d726f1d9fb9f5164170b0
6
+ metadata.gz: 9a92b845a7fdafdda21c4e83eeff589d01319d432b58470e92fe28486cc83bb4cc998e8d8e7132b1674c7e61200c39f4f56d24a3ff19604c31e0b15612edbd4d
7
+ data.tar.gz: 19f2b4e03428e99182e5526ac2dbb0ae0f5205115f5f54d635894f4d8c4ce69dff8aadb26358c14ef480c7638203d751949c7f5b9734db68dc3ecf6f2254e521
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- arql (0.2.5)
4
+ arql (0.2.10)
5
5
  activerecord (~> 6.0.3)
6
6
  activesupport (~> 6.0.3)
7
7
  caxlsx (~> 3.0.2)
8
+ composite_primary_keys (~> 12.0.3)
8
9
  mysql2 (~> 0.5.3)
9
10
  net-ssh-gateway (~> 2.0.0)
10
11
  pry (~> 0.13.1)
@@ -19,12 +20,12 @@ PATH
19
20
  GEM
20
21
  remote: https://rubygems.org/
21
22
  specs:
22
- activemodel (6.0.3.3)
23
- activesupport (= 6.0.3.3)
24
- activerecord (6.0.3.3)
25
- activemodel (= 6.0.3.3)
26
- activesupport (= 6.0.3.3)
27
- activesupport (6.0.3.3)
23
+ activemodel (6.0.3.4)
24
+ activesupport (= 6.0.3.4)
25
+ activerecord (6.0.3.4)
26
+ activemodel (= 6.0.3.4)
27
+ activesupport (= 6.0.3.4)
28
+ activesupport (6.0.3.4)
28
29
  concurrent-ruby (~> 1.0, >= 1.0.2)
29
30
  i18n (>= 0.7, < 2)
30
31
  minitest (~> 5.1)
@@ -37,6 +38,8 @@ GEM
37
38
  nokogiri (~> 1.10, >= 1.10.4)
38
39
  rubyzip (>= 1.3.0, < 3)
39
40
  coderay (1.1.3)
41
+ composite_primary_keys (12.0.3)
42
+ activerecord (~> 6.0.0)
40
43
  concurrent-ruby (1.1.7)
41
44
  htmlentities (4.3.4)
42
45
  i18n (1.8.5)
@@ -71,11 +74,11 @@ GEM
71
74
  terminal-table (1.8.0)
72
75
  unicode-display_width (~> 1.1, >= 1.1.1)
73
76
  thread_safe (0.3.6)
74
- tzinfo (1.2.7)
77
+ tzinfo (1.2.8)
75
78
  thread_safe (~> 0.1)
76
79
  unicode-display_width (1.7.0)
77
80
  yard (0.9.25)
78
- zeitwerk (2.4.0)
81
+ zeitwerk (2.4.2)
79
82
 
80
83
  PLATFORMS
81
84
  ruby
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
29
29
  # spec.add_dependency 'activerecord-sqlserver-adapter'
30
30
  # spec.add_dependency 'activerecord-oracle_enhanced-adapter'
31
31
  spec.add_dependency 'activerecord', '~> 6.0.3'
32
+ spec.add_dependency 'composite_primary_keys', '~> 12.0.3'
32
33
  spec.add_dependency 'activesupport', '~> 6.0.3'
33
34
  spec.add_dependency 'net-ssh-gateway', '~> 2.0.0'
34
35
  spec.add_dependency 'pry', '~> 0.13.1'
@@ -22,6 +22,7 @@ module Arql
22
22
  def initialize(options)
23
23
  require 'active_support/all'
24
24
  require 'active_record'
25
+ require 'composite_primary_keys'
25
26
  require "arql/connection"
26
27
  require "arql/definition"
27
28
  @options = options
@@ -5,25 +5,29 @@ module Arql::Commands
5
5
  class << self
6
6
  def models
7
7
  t = []
8
- t << ['Table Name', 'Model Class', 'Abbr']
8
+ t << ['Table Name', 'Model Class', 'Abbr', 'Comment']
9
9
  t << nil
10
10
  Arql::Definition.models.each do |definition|
11
- t << [definition[:table], definition[:model].name, definition[:abbr] || '']
11
+ t << [definition[:table], definition[:model].name, definition[:abbr] || '', definition[:comment] || '']
12
12
  end
13
13
  t
14
14
  end
15
15
 
16
- def models_table
16
+ def models_table(regexp)
17
17
  Terminal::Table.new do |t|
18
- models.each { |row| t << (row || :separator) }
18
+ models.each_with_index { |row, idx| t << (row || :separator) if row.nil? ||
19
+ regexp.nil? ||
20
+ idx.zero? ||
21
+ row.any? { |e| e =~ regexp }
22
+ }
19
23
  end
20
24
  end
21
25
  end
22
26
  end
23
27
 
24
- Pry.commands.block_command 'm' do
28
+ Pry.commands.block_command 'm' do |regexp|
25
29
  puts
26
- puts Models::models_table
30
+ puts Models::models_table(regexp.try { |e| e.start_with?('/') ? eval(e) : Regexp.new(e) })
27
31
  end
28
32
 
29
33
  Pry.commands.alias_command 'l', 'm'
@@ -25,7 +25,7 @@ module Arql::Commands
25
25
  t << nil
26
26
  connection = ::ActiveRecord::Base.connection
27
27
  connection.columns(table_name).each do |column|
28
- pk = if column.name == connection.primary_key(table_name)
28
+ pk = if [connection.primary_key(table_name)].flatten.include?(column.name)
29
29
  'Y'
30
30
  else
31
31
  ''
@@ -83,13 +83,18 @@ module Arql
83
83
  @@models = []
84
84
  ActiveRecord::Base.connection.tap do |conn|
85
85
  conn.tables.each do |table_name|
86
+ table_comment = conn.table_comment(table_name)
86
87
  conn.primary_key(table_name).tap do |pkey|
87
88
  table_name.camelize.tap do |const_name|
88
89
  const_name = 'Modul' if const_name == 'Module'
89
90
  const_name = 'Clazz' if const_name == 'Class'
90
91
  Class.new(::ArqlModel) do
91
92
  include Arql::Extension
92
- self.primary_key = pkey
93
+ if pkey.is_a?(Array)
94
+ self.primary_keys = pkey
95
+ else
96
+ self.primary_key = pkey
97
+ end
93
98
  self.table_name = table_name
94
99
  self.inheritance_column = nil
95
100
  self.default_timezone = :local
@@ -106,16 +111,22 @@ module Arql
106
111
  end
107
112
  end.tap do |clazz|
108
113
  Object.const_set(const_name, clazz).tap do |const|
109
- const_name.gsub(/[a-z]*/, '').tap do |abbr|
110
- unless Object.const_defined?(abbr)
111
- Object.const_set abbr, const
112
- abbr_const = abbr
114
+ const_name.gsub(/[a-z]*/, '').tap do |bare_abbr|
115
+ abbr_const = nil
116
+ 9.times do |idx|
117
+ abbr = idx.zero? ? bare_abbr : "#{bare_abbr}#{idx+1}"
118
+ unless Object.const_defined?(abbr)
119
+ Object.const_set abbr, const
120
+ abbr_const = abbr
121
+ break
122
+ end
113
123
  end
114
124
 
115
125
  @@models << {
116
126
  model: const,
117
127
  abbr: abbr_const,
118
- table: table_name
128
+ table: table_name,
129
+ comment: table_comment
119
130
  }
120
131
  end
121
132
  end
@@ -133,15 +144,258 @@ module Arql
133
144
  @@options = options
134
145
  @@models = []
135
146
  ActiveRecord::Base.connection.tap do |conn|
136
- Object.const_set('ArqlModel', Class.new(ActiveRecord::Base) { self.abstract_class = true })
147
+ Object.const_set('ArqlModel', Class.new(ActiveRecord::Base) do
148
+ self.abstract_class = true
149
+
150
+ define_singleton_method(:indexes) do
151
+ conn.indexes(table_name).map do |idx|
152
+ {
153
+ Table: idx.table,
154
+ Name: idx.name,
155
+ Columns: idx.columns.join(', '),
156
+ Unique: idx.unique,
157
+ Comment: idx.comment
158
+ }
159
+ end.t
160
+ end
161
+ # Add a new +type+ column named +column_name+ to +table_name+.
162
+ #
163
+ # The +type+ parameter is normally one of the migrations native types,
164
+ # which is one of the following:
165
+ # <tt>:primary_key</tt>, <tt>:string</tt>, <tt>:text</tt>,
166
+ # <tt>:integer</tt>, <tt>:bigint</tt>, <tt>:float</tt>, <tt>:decimal</tt>, <tt>:numeric</tt>,
167
+ # <tt>:datetime</tt>, <tt>:time</tt>, <tt>:date</tt>,
168
+ # <tt>:binary</tt>, <tt>:boolean</tt>.
169
+ #
170
+ # You may use a type not in this list as long as it is supported by your
171
+ # database (for example, "polygon" in MySQL), but this will not be database
172
+ # agnostic and should usually be avoided.
173
+ #
174
+ # Available options are (none of these exists by default):
175
+ # * <tt>:limit</tt> -
176
+ # Requests a maximum column length. This is the number of characters for a <tt>:string</tt> column
177
+ # and number of bytes for <tt>:text</tt>, <tt>:binary</tt>, and <tt>:integer</tt> columns.
178
+ # This option is ignored by some backends.
179
+ # * <tt>:default</tt> -
180
+ # The column's default value. Use +nil+ for +NULL+.
181
+ # * <tt>:null</tt> -
182
+ # Allows or disallows +NULL+ values in the column.
183
+ # * <tt>:precision</tt> -
184
+ # Specifies the precision for the <tt>:decimal</tt>, <tt>:numeric</tt>,
185
+ # <tt>:datetime</tt>, and <tt>:time</tt> columns.
186
+ # * <tt>:scale</tt> -
187
+ # Specifies the scale for the <tt>:decimal</tt> and <tt>:numeric</tt> columns.
188
+ # * <tt>:collation</tt> -
189
+ # Specifies the collation for a <tt>:string</tt> or <tt>:text</tt> column. If not specified, the
190
+ # column will have the same collation as the table.
191
+ # * <tt>:comment</tt> -
192
+ # Specifies the comment for the column. This option is ignored by some backends.
193
+ #
194
+ # Note: The precision is the total number of significant digits,
195
+ # and the scale is the number of digits that can be stored following
196
+ # the decimal point. For example, the number 123.45 has a precision of 5
197
+ # and a scale of 2. A decimal with a precision of 5 and a scale of 2 can
198
+ # range from -999.99 to 999.99.
199
+ #
200
+ # Please be aware of different RDBMS implementations behavior with
201
+ # <tt>:decimal</tt> columns:
202
+ # * The SQL standard says the default scale should be 0, <tt>:scale</tt> <=
203
+ # <tt>:precision</tt>, and makes no comments about the requirements of
204
+ # <tt>:precision</tt>.
205
+ # * MySQL: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..30].
206
+ # Default is (10,0).
207
+ # * PostgreSQL: <tt>:precision</tt> [1..infinity],
208
+ # <tt>:scale</tt> [0..infinity]. No default.
209
+ # * SQLite3: No restrictions on <tt>:precision</tt> and <tt>:scale</tt>,
210
+ # but the maximum supported <tt>:precision</tt> is 16. No default.
211
+ # * Oracle: <tt>:precision</tt> [1..38], <tt>:scale</tt> [-84..127].
212
+ # Default is (38,0).
213
+ # * DB2: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..62].
214
+ # Default unknown.
215
+ # * SqlServer: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
216
+ # Default (38,0).
217
+ #
218
+ # == Examples
219
+ #
220
+ # User.add_column(:picture, :binary, limit: 2.megabytes)
221
+ # # ALTER TABLE "users" ADD "picture" blob(2097152)
222
+ #
223
+ # Article.add_column(:status, :string, limit: 20, default: 'draft', null: false)
224
+ # # ALTER TABLE "articles" ADD "status" varchar(20) DEFAULT 'draft' NOT NULL
225
+ #
226
+ # Answer.add_column(:bill_gates_money, :decimal, precision: 15, scale: 2)
227
+ # # ALTER TABLE "answers" ADD "bill_gates_money" decimal(15,2)
228
+ #
229
+ # Measurement.add_column(:sensor_reading, :decimal, precision: 30, scale: 20)
230
+ # # ALTER TABLE "measurements" ADD "sensor_reading" decimal(30,20)
231
+ #
232
+ # # While :scale defaults to zero on most databases, it
233
+ # # probably wouldn't hurt to include it.
234
+ # Measurement.add_column(:huge_integer, :decimal, precision: 30)
235
+ # # ALTER TABLE "measurements" ADD "huge_integer" decimal(30)
236
+ #
237
+ # # Defines a column that stores an array of a type.
238
+ # User.add_column(:skills, :text, array: true)
239
+ # # ALTER TABLE "users" ADD "skills" text[]
240
+ #
241
+ # # Defines a column with a database-specific type.
242
+ # Shape.add_column(:triangle, 'polygon')
243
+ # # ALTER TABLE "shapes" ADD "triangle" polygon
244
+ define_singleton_method(:add_column) do |column_name, type, **options|
245
+ conn.add_column(table_name, column_name, type, **options)
246
+ end
247
+
248
+ # Changes the column's definition according to the new options.
249
+ # See TableDefinition#column for details of the options you can use.
250
+ #
251
+ # Supplier.change_column(:name, :string, limit: 80)
252
+ # Post.change_column(:description, :text)
253
+ #
254
+ define_singleton_method(:change_column) do |column_name, type, options = {}|
255
+ conn.change_column(table_name, column_name, type, options)
256
+ end
257
+
258
+ # Removes the column from the table definition.
259
+ #
260
+ # Supplier.remove_column(:qualification)
261
+ #
262
+ # The +type+ and +options+ parameters will be ignored if present. It can be helpful
263
+ # to provide these in a migration's +change+ method so it can be reverted.
264
+ # In that case, +type+ and +options+ will be used by #add_column.
265
+ # Indexes on the column are automatically removed.
266
+ define_singleton_method(:remove_column) do |column_name, type = nil, **options|
267
+ conn.remove_column(table_name, column_name, type, **options)
268
+ end
269
+
270
+ # Adds a new index to the table. +column_name+ can be a single Symbol, or
271
+ # an Array of Symbols.
272
+ #
273
+ # The index will be named after the table and the column name(s), unless
274
+ # you pass <tt>:name</tt> as an option.
275
+ #
276
+ # ====== Creating a simple index
277
+ #
278
+ # Supplier.add_index(:name)
279
+ #
280
+ # generates:
281
+ #
282
+ # CREATE INDEX suppliers_name_index ON suppliers(name)
283
+ #
284
+ # ====== Creating a unique index
285
+ #
286
+ # Account.add_index([:branch_id, :party_id], unique: true)
287
+ #
288
+ # generates:
289
+ #
290
+ # CREATE UNIQUE INDEX accounts_branch_id_party_id_index ON accounts(branch_id, party_id)
291
+ #
292
+ # ====== Creating a named index
293
+ #
294
+ # Account.add_index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
295
+ #
296
+ # generates:
297
+ #
298
+ # CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)
299
+ #
300
+ # ====== Creating an index with specific key length
301
+ #
302
+ # Account.add_index(:name, name: 'by_name', length: 10)
303
+ #
304
+ # generates:
305
+ #
306
+ # CREATE INDEX by_name ON accounts(name(10))
307
+ #
308
+ # ====== Creating an index with specific key lengths for multiple keys
309
+ #
310
+ # Account.add_index([:name, :surname], name: 'by_name_surname', length: {name: 10, surname: 15})
311
+ #
312
+ # generates:
313
+ #
314
+ # CREATE INDEX by_name_surname ON accounts(name(10), surname(15))
315
+ #
316
+ # Note: SQLite doesn't support index length.
317
+ #
318
+ # ====== Creating an index with a sort order (desc or asc, asc is the default)
319
+ #
320
+ # Account.add_index([:branch_id, :party_id, :surname], order: {branch_id: :desc, party_id: :asc})
321
+ #
322
+ # generates:
323
+ #
324
+ # CREATE INDEX by_branch_desc_party ON accounts(branch_id DESC, party_id ASC, surname)
325
+ #
326
+ # Note: MySQL only supports index order from 8.0.1 onwards (earlier versions accepted the syntax but ignored it).
327
+ #
328
+ # ====== Creating a partial index
329
+ #
330
+ # Account.add_index([:branch_id, :party_id], unique: true, where: "active")
331
+ #
332
+ # generates:
333
+ #
334
+ # CREATE UNIQUE INDEX index_accounts_on_branch_id_and_party_id ON accounts(branch_id, party_id) WHERE active
335
+ #
336
+ # Note: Partial indexes are only supported for PostgreSQL and SQLite 3.8.0+.
337
+ #
338
+ # ====== Creating an index with a specific method
339
+ #
340
+ # Developer.add_index(:name, using: 'btree')
341
+ #
342
+ # generates:
343
+ #
344
+ # CREATE INDEX index_developers_on_name ON developers USING btree (name) -- PostgreSQL
345
+ # CREATE INDEX index_developers_on_name USING btree ON developers (name) -- MySQL
346
+ #
347
+ # Note: only supported by PostgreSQL and MySQL
348
+ #
349
+ # ====== Creating an index with a specific operator class
350
+ #
351
+ # Developer.add_index(:name, using: 'gist', opclass: :gist_trgm_ops)
352
+ # # CREATE INDEX developers_on_name ON developers USING gist (name gist_trgm_ops) -- PostgreSQL
353
+ #
354
+ # Developer.add_index([:name, :city], using: 'gist', opclass: { city: :gist_trgm_ops })
355
+ # # CREATE INDEX developers_on_name_and_city ON developers USING gist (name, city gist_trgm_ops) -- PostgreSQL
356
+ #
357
+ # Developer.add_index([:name, :city], using: 'gist', opclass: :gist_trgm_ops)
358
+ # # CREATE INDEX developers_on_name_and_city ON developers USING gist (name gist_trgm_ops, city gist_trgm_ops) -- PostgreSQL
359
+ #
360
+ # Note: only supported by PostgreSQL
361
+ #
362
+ # ====== Creating an index with a specific type
363
+ #
364
+ # Developer.add_index(:name, type: :fulltext)
365
+ #
366
+ # generates:
367
+ #
368
+ # CREATE FULLTEXT INDEX index_developers_on_name ON developers (name) -- MySQL
369
+ #
370
+ # Note: only supported by MySQL.
371
+ #
372
+ # ====== Creating an index with a specific algorithm
373
+ #
374
+ # Developer.add_index(:name, algorithm: :concurrently)
375
+ # # CREATE INDEX CONCURRENTLY developers_on_name on developers (name)
376
+ #
377
+ # Note: only supported by PostgreSQL.
378
+ #
379
+ # Concurrently adding an index is not supported in a transaction.
380
+ #
381
+ # For more information see the {"Transactional Migrations" section}[rdoc-ref:Migration].
382
+ define_singleton_method(:add_index) do |column_name, options = {}|
383
+ conn.add_index(table_name, column_name, options)
384
+ end
385
+ end)
137
386
  conn.tables.each do |table_name|
387
+ table_comment = conn.table_comment(table_name)
138
388
  conn.primary_key(table_name).tap do |pkey|
139
389
  table_name.camelize.tap do |const_name|
140
390
  const_name = 'Modul' if const_name == 'Module'
141
391
  const_name = 'Clazz' if const_name == 'Class'
142
392
  Class.new(::ArqlModel) do
143
393
  include Arql::Extension
144
- self.primary_key = pkey
394
+ if pkey.is_a?(Array)
395
+ self.primary_keys = pkey
396
+ else
397
+ self.primary_key = pkey
398
+ end
145
399
  self.table_name = table_name
146
400
  self.inheritance_column = nil
147
401
  self.default_timezone = :local
@@ -158,16 +412,22 @@ module Arql
158
412
  end
159
413
  end.tap do |clazz|
160
414
  Object.const_set(const_name, clazz).tap do |const|
161
- const_name.gsub(/[a-z]*/, '').tap do |abbr|
162
- unless Object.const_defined?(abbr)
163
- Object.const_set abbr, const
164
- abbr_const = abbr
415
+ const_name.gsub(/[a-z]*/, '').tap do |bare_abbr|
416
+ abbr_const = nil
417
+ 9.times do |idx|
418
+ abbr = idx.zero? ? bare_abbr : "#{bare_abbr}#{idx+1}"
419
+ unless Object.const_defined?(abbr)
420
+ Object.const_set abbr, const
421
+ abbr_const = abbr
422
+ break
423
+ end
165
424
  end
166
425
 
167
426
  @@models << {
168
427
  model: const,
169
428
  abbr: abbr_const,
170
- table: table_name
429
+ table: table_name,
430
+ comment: table_comment
171
431
  }
172
432
  end
173
433
  end
@@ -25,7 +25,7 @@ module Kernel
25
25
  Terminal::Table.new { |t|
26
26
  t.headings = ['PK', 'Name', 'SQL Type', 'Limit', 'Precision', 'Scale', 'Default', 'Nullable', 'Comment']
27
27
  t.rows = table[:columns].map { |column|
28
- pk = if column.name == ::ActiveRecord::Base.connection.primary_key(table_name)
28
+ pk = if [::ActiveRecord::Base.connection.primary_key(table_name)].flatten.include?(column_name)
29
29
  'Y'
30
30
  else
31
31
  ''
@@ -44,7 +44,7 @@ module Kernel
44
44
  Terminal::Table.new { |t|
45
45
  t.headings = ['PK', 'Name', 'SQL Type', 'Limit', 'Precision', 'Scale', 'Default', 'Nullable', 'Comment']
46
46
  t.rows = table[:columns].map { |column|
47
- pk = if column.name == ::ActiveRecord::Base.connection.primary_key(table_name)
47
+ pk = if [::ActiveRecord::Base.connection.primary_key(table_name)].flatten.include?(column_name)
48
48
  'Y'
49
49
  else
50
50
  ''
@@ -105,4 +105,160 @@ module Kernel
105
105
  end
106
106
  end
107
107
  end
108
+
109
+ # Example:
110
+ #
111
+ # create_table :post, id: false, primary_key: :id do |t|
112
+ # t.column :id, :bigint, precison: 19, comment: 'ID'
113
+ # t.column :name, :string, comment: '名称'
114
+ # t.column :gmt_created, :datetime, comment: '创建时间'
115
+ # t.column :gmt_modified, :datetime, comment: '最后修改时间'
116
+ # end
117
+ #
118
+ # Creates a new table with the name +table_name+. +table_name+ may either
119
+ # be a String or a Symbol.
120
+ #
121
+ # There are two ways to work with #create_table. You can use the block
122
+ # form or the regular form, like this:
123
+ #
124
+ # === Block form
125
+ #
126
+ # # create_table() passes a TableDefinition object to the block.
127
+ # # This form will not only create the table, but also columns for the
128
+ # # table.
129
+ #
130
+ # create_table(:suppliers) do |t|
131
+ # t.column :name, :string, limit: 60
132
+ # # Other fields here
133
+ # end
134
+ #
135
+ # === Block form, with shorthand
136
+ #
137
+ # # You can also use the column types as method calls, rather than calling the column method.
138
+ # create_table(:suppliers) do |t|
139
+ # t.string :name, limit: 60
140
+ # # Other fields here
141
+ # end
142
+ #
143
+ # === Regular form
144
+ #
145
+ # # Creates a table called 'suppliers' with no columns.
146
+ # create_table(:suppliers)
147
+ # # Add a column to 'suppliers'.
148
+ # add_column(:suppliers, :name, :string, {limit: 60})
149
+ #
150
+ # The +options+ hash can include the following keys:
151
+ # [<tt>:id</tt>]
152
+ # Whether to automatically add a primary key column. Defaults to true.
153
+ # Join tables for {ActiveRecord::Base.has_and_belongs_to_many}[rdoc-ref:Associations::ClassMethods#has_and_belongs_to_many] should set it to false.
154
+ #
155
+ # A Symbol can be used to specify the type of the generated primary key column.
156
+ # [<tt>:primary_key</tt>]
157
+ # The name of the primary key, if one is to be added automatically.
158
+ # Defaults to +id+. If <tt>:id</tt> is false, then this option is ignored.
159
+ #
160
+ # If an array is passed, a composite primary key will be created.
161
+ #
162
+ # Note that Active Record models will automatically detect their
163
+ # primary key. This can be avoided by using
164
+ # {self.primary_key=}[rdoc-ref:AttributeMethods::PrimaryKey::ClassMethods#primary_key=] on the model
165
+ # to define the key explicitly.
166
+ #
167
+ # [<tt>:options</tt>]
168
+ # Any extra options you want appended to the table definition.
169
+ # [<tt>:temporary</tt>]
170
+ # Make a temporary table.
171
+ # [<tt>:force</tt>]
172
+ # Set to true to drop the table before creating it.
173
+ # Set to +:cascade+ to drop dependent objects as well.
174
+ # Defaults to false.
175
+ # [<tt>:if_not_exists</tt>]
176
+ # Set to true to avoid raising an error when the table already exists.
177
+ # Defaults to false.
178
+ # [<tt>:as</tt>]
179
+ # SQL to use to generate the table. When this option is used, the block is
180
+ # ignored, as are the <tt>:id</tt> and <tt>:primary_key</tt> options.
181
+ #
182
+ # ====== Add a backend specific option to the generated SQL (MySQL)
183
+ #
184
+ # create_table(:suppliers, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4')
185
+ #
186
+ # generates:
187
+ #
188
+ # CREATE TABLE suppliers (
189
+ # id bigint auto_increment PRIMARY KEY
190
+ # ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
191
+ #
192
+ # ====== Rename the primary key column
193
+ #
194
+ # create_table(:objects, primary_key: 'guid') do |t|
195
+ # t.column :name, :string, limit: 80
196
+ # end
197
+ #
198
+ # generates:
199
+ #
200
+ # CREATE TABLE objects (
201
+ # guid bigint auto_increment PRIMARY KEY,
202
+ # name varchar(80)
203
+ # )
204
+ #
205
+ # ====== Change the primary key column type
206
+ #
207
+ # create_table(:tags, id: :string) do |t|
208
+ # t.column :label, :string
209
+ # end
210
+ #
211
+ # generates:
212
+ #
213
+ # CREATE TABLE tags (
214
+ # id varchar PRIMARY KEY,
215
+ # label varchar
216
+ # )
217
+ #
218
+ # ====== Create a composite primary key
219
+ #
220
+ # create_table(:orders, primary_key: [:product_id, :client_id]) do |t|
221
+ # t.belongs_to :product
222
+ # t.belongs_to :client
223
+ # end
224
+ #
225
+ # generates:
226
+ #
227
+ # CREATE TABLE order (
228
+ # product_id bigint NOT NULL,
229
+ # client_id bigint NOT NULL
230
+ # );
231
+ #
232
+ # ALTER TABLE ONLY "orders"
233
+ # ADD CONSTRAINT orders_pkey PRIMARY KEY (product_id, client_id);
234
+ #
235
+ # ====== Do not add a primary key column
236
+ #
237
+ # create_table(:categories_suppliers, id: false) do |t|
238
+ # t.column :category_id, :bigint
239
+ # t.column :supplier_id, :bigint
240
+ # end
241
+ #
242
+ # generates:
243
+ #
244
+ # CREATE TABLE categories_suppliers (
245
+ # category_id bigint,
246
+ # supplier_id bigint
247
+ # )
248
+ #
249
+ # ====== Create a temporary table based on a query
250
+ #
251
+ # create_table(:long_query, temporary: true,
252
+ # as: "SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id")
253
+ #
254
+ # generates:
255
+ #
256
+ # CREATE TEMPORARY TABLE long_query AS
257
+ # SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id
258
+ #
259
+ # See also TableDefinition#column for details on how to create columns.
260
+
261
+ def create_table(table_name, **options, &blk)
262
+ ActiveRecord::Base.connection.create_table(table_name, **options, &blk)
263
+ end
108
264
  end
@@ -1,3 +1,3 @@
1
1
  module Arql
2
- VERSION = "0.2.5"
2
+ VERSION = "0.2.10"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Liu Xiang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-01 00:00:00.000000000 Z
11
+ date: 2020-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mysql2
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 6.0.3
55
+ - !ruby/object:Gem::Dependency
56
+ name: composite_primary_keys
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 12.0.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 12.0.3
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: activesupport
57
71
  requirement: !ruby/object:Gem::Requirement