arql 0.2.12 → 0.2.13

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: 59eda4176935ad6c21bff248beac1078df7c44239f17c5febd60cd3af5617b34
4
- data.tar.gz: f6362e715937b0792285ded2d9d10dc00a1e4e9cb224ec7e6ac01ea67d08f268
3
+ metadata.gz: a172e23e1a195c0359c73041431fed88cdb54f288e6e836a7f13febaa57632d7
4
+ data.tar.gz: 30f9ebc606efae03e4be2e1774d85b893d81462e75fc712ffb3d543e43c7bbcd
5
5
  SHA512:
6
- metadata.gz: 50c7e6ac7e3014bc25a7b345ac126b61b79a194907d728140deef9a62ef2adc64947dc84cfad5870894005c3b1a48b7b1c96daee2708fac423ed71a207dbba96
7
- data.tar.gz: 825621c088e16302953709aa518e5d19f5064212852b65cb230f685e10b47972400eeb2e77b921fa57fb16a8eb9af743e684a60d7d7bc7cfb0e8a61551608131
6
+ metadata.gz: ec25c920bdd7a96dcd510abd6db5b1217fdc7e7d9f94558a857f37d17338defe804c25949c90f508d88399907b0785dce3014e2c1e073dd3d3da7a758307bffd
7
+ data.tar.gz: 7daaea1f984be21a0a524ce1647b275c748c69a341a5ade443514246999bd013b071c3f6b4bffc9aceb6371fea3803b199e09d51a98e365c3b001f34c3e17420
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- arql (0.2.12)
4
+ arql (0.2.13)
5
5
  activerecord (~> 6.0.3)
6
6
  activesupport (~> 6.0.3)
7
7
  caxlsx (~> 3.0.2)
@@ -0,0 +1,2 @@
1
+ require 'arql/concerns/global_data_definition'
2
+ require 'arql/concerns/tables_data_definition'
@@ -0,0 +1,244 @@
1
+ require 'active_support/concern'
2
+
3
+ module Arql
4
+ module Concerns
5
+ module GlobalDataDefinition
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ # Example:
11
+ #
12
+ # create_table :post, id: false, primary_key: :id do |t|
13
+ # t.column :id, :bigint, precison: 19, comment: 'ID'
14
+ # t.column :name, :string, comment: '名称'
15
+ # t.column :gmt_created, :datetime, comment: '创建时间'
16
+ # t.column :gmt_modified, :datetime, comment: '最后修改时间'
17
+ # end
18
+ #
19
+ # Creates a new table with the name +table_name+. +table_name+ may either
20
+ # be a String or a Symbol.
21
+ #
22
+ # There are two ways to work with #create_table. You can use the block
23
+ # form or the regular form, like this:
24
+ #
25
+ # === Block form
26
+ #
27
+ # # create_table() passes a TableDefinition object to the block.
28
+ # # This form will not only create the table, but also columns for the
29
+ # # table.
30
+ #
31
+ # create_table(:suppliers) do |t|
32
+ # t.column :name, :string, limit: 60
33
+ # # Other fields here
34
+ # end
35
+ #
36
+ # === Block form, with shorthand
37
+ #
38
+ # # You can also use the column types as method calls, rather than calling the column method.
39
+ # create_table(:suppliers) do |t|
40
+ # t.string :name, limit: 60
41
+ # # Other fields here
42
+ # end
43
+ #
44
+ # === Regular form
45
+ #
46
+ # # Creates a table called 'suppliers' with no columns.
47
+ # create_table(:suppliers)
48
+ # # Add a column to 'suppliers'.
49
+ # add_column(:suppliers, :name, :string, {limit: 60})
50
+ #
51
+ # The +options+ hash can include the following keys:
52
+ # [<tt>:id</tt>]
53
+ # Whether to automatically add a primary key column. Defaults to true.
54
+ # Join tables for {ActiveRecord::Base.has_and_belongs_to_many}[rdoc-ref:Associations::ClassMethods#has_and_belongs_to_many] should set it to false.
55
+ #
56
+ # A Symbol can be used to specify the type of the generated primary key column.
57
+ # [<tt>:primary_key</tt>]
58
+ # The name of the primary key, if one is to be added automatically.
59
+ # Defaults to +id+. If <tt>:id</tt> is false, then this option is ignored.
60
+ #
61
+ # If an array is passed, a composite primary key will be created.
62
+ #
63
+ # Note that Active Record models will automatically detect their
64
+ # primary key. This can be avoided by using
65
+ # {self.primary_key=}[rdoc-ref:AttributeMethods::PrimaryKey::ClassMethods#primary_key=] on the model
66
+ # to define the key explicitly.
67
+ #
68
+ # [<tt>:options</tt>]
69
+ # Any extra options you want appended to the table definition.
70
+ # [<tt>:temporary</tt>]
71
+ # Make a temporary table.
72
+ # [<tt>:force</tt>]
73
+ # Set to true to drop the table before creating it.
74
+ # Set to +:cascade+ to drop dependent objects as well.
75
+ # Defaults to false.
76
+ # [<tt>:if_not_exists</tt>]
77
+ # Set to true to avoid raising an error when the table already exists.
78
+ # Defaults to false.
79
+ # [<tt>:as</tt>]
80
+ # SQL to use to generate the table. When this option is used, the block is
81
+ # ignored, as are the <tt>:id</tt> and <tt>:primary_key</tt> options.
82
+ #
83
+ # ====== Add a backend specific option to the generated SQL (MySQL)
84
+ #
85
+ # create_table(:suppliers, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4')
86
+ #
87
+ # generates:
88
+ #
89
+ # CREATE TABLE suppliers (
90
+ # id bigint auto_increment PRIMARY KEY
91
+ # ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
92
+ #
93
+ # ====== Rename the primary key column
94
+ #
95
+ # create_table(:objects, primary_key: 'guid') do |t|
96
+ # t.column :name, :string, limit: 80
97
+ # end
98
+ #
99
+ # generates:
100
+ #
101
+ # CREATE TABLE objects (
102
+ # guid bigint auto_increment PRIMARY KEY,
103
+ # name varchar(80)
104
+ # )
105
+ #
106
+ # ====== Change the primary key column type
107
+ #
108
+ # create_table(:tags, id: :string) do |t|
109
+ # t.column :label, :string
110
+ # end
111
+ #
112
+ # generates:
113
+ #
114
+ # CREATE TABLE tags (
115
+ # id varchar PRIMARY KEY,
116
+ # label varchar
117
+ # )
118
+ #
119
+ # ====== Create a composite primary key
120
+ #
121
+ # create_table(:orders, primary_key: [:product_id, :client_id]) do |t|
122
+ # t.belongs_to :product
123
+ # t.belongs_to :client
124
+ # end
125
+ #
126
+ # generates:
127
+ #
128
+ # CREATE TABLE order (
129
+ # product_id bigint NOT NULL,
130
+ # client_id bigint NOT NULL
131
+ # );
132
+ #
133
+ # ALTER TABLE ONLY "orders"
134
+ # ADD CONSTRAINT orders_pkey PRIMARY KEY (product_id, client_id);
135
+ #
136
+ # ====== Do not add a primary key column
137
+ #
138
+ # create_table(:categories_suppliers, id: false) do |t|
139
+ # t.column :category_id, :bigint
140
+ # t.column :supplier_id, :bigint
141
+ # end
142
+ #
143
+ # generates:
144
+ #
145
+ # CREATE TABLE categories_suppliers (
146
+ # category_id bigint,
147
+ # supplier_id bigint
148
+ # )
149
+ #
150
+ # ====== Create a temporary table based on a query
151
+ #
152
+ # create_table(:long_query, temporary: true,
153
+ # as: "SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id")
154
+ #
155
+ # generates:
156
+ #
157
+ # CREATE TEMPORARY TABLE long_query AS
158
+ # SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id
159
+ #
160
+ # See also TableDefinition#column for details on how to create columns.
161
+ def create_table(table_name, **options, &blk)
162
+ ActiveRecord::Base.connection.create_table(table_name, **options, &blk)
163
+ end
164
+
165
+ # Creates a new join table with the name created using the lexical order of the first two
166
+ # arguments. These arguments can be a String or a Symbol.
167
+ #
168
+ # # Creates a table called 'assemblies_parts' with no id.
169
+ # create_join_table(:assemblies, :parts)
170
+ #
171
+ # You can pass an +options+ hash which can include the following keys:
172
+ # [<tt>:table_name</tt>]
173
+ # Sets the table name, overriding the default.
174
+ # [<tt>:column_options</tt>]
175
+ # Any extra options you want appended to the columns definition.
176
+ # [<tt>:options</tt>]
177
+ # Any extra options you want appended to the table definition.
178
+ # [<tt>:temporary</tt>]
179
+ # Make a temporary table.
180
+ # [<tt>:force</tt>]
181
+ # Set to true to drop the table before creating it.
182
+ # Defaults to false.
183
+ #
184
+ # Note that #create_join_table does not create any indices by default; you can use
185
+ # its block form to do so yourself:
186
+ #
187
+ # create_join_table :products, :categories do |t|
188
+ # t.index :product_id
189
+ # t.index :category_id
190
+ # end
191
+ #
192
+ # ====== Add a backend specific option to the generated SQL (MySQL)
193
+ #
194
+ # create_join_table(:assemblies, :parts, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8')
195
+ #
196
+ # generates:
197
+ #
198
+ # CREATE TABLE assemblies_parts (
199
+ # assembly_id bigint NOT NULL,
200
+ # part_id bigint NOT NULL,
201
+ # ) ENGINE=InnoDB DEFAULT CHARSET=utf8
202
+ #
203
+ def create_join_table(table_1, table_2, column_options: {}, **options)
204
+ ActiveRecord::Base.connection.create_join_table(table_1, table_2, column_options, **options)
205
+ end
206
+
207
+ # Drops a table from the database.
208
+ #
209
+ # [<tt>:force</tt>]
210
+ # Set to +:cascade+ to drop dependent objects as well.
211
+ # Defaults to false.
212
+ # [<tt>:if_exists</tt>]
213
+ # Set to +true+ to only drop the table if it exists.
214
+ # Defaults to false.
215
+ #
216
+ # Although this command ignores most +options+ and the block if one is given,
217
+ # it can be helpful to provide these in a migration's +change+ method so it can be reverted.
218
+ # In that case, +options+ and the block will be used by #create_table.
219
+ def drop_table(table_name, **options)
220
+ ActiveRecord::Base.connection.drop_table(table_name, **options)
221
+ end
222
+
223
+ # Drops the join table specified by the given arguments.
224
+ # See #create_join_table for details.
225
+ #
226
+ # Although this command ignores the block if one is given, it can be helpful
227
+ # to provide one in a migration's +change+ method so it can be reverted.
228
+ # In that case, the block will be used by #create_join_table.
229
+ def drop_join_table(table_1, table_2, **options)
230
+ ActiveRecord::Base.connection.drop_join_table(table_1, table_2, **options)
231
+ end
232
+
233
+ # Renames a table.
234
+ #
235
+ # rename_table('octopuses', 'octopi')
236
+ #
237
+ def rename_table(table_name, new_name)
238
+ ActiveRecord::Base.connection.rename_table(table_name, new_name)
239
+ end
240
+
241
+ end
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,550 @@
1
+ require 'active_support/concern'
2
+
3
+ module Arql
4
+ module Concerns
5
+ module TableDataDefinition
6
+ extend ActiveSupport::Concern
7
+
8
+ class_methods do
9
+
10
+ # Add a new +type+ column named +column_name+ to +table_name+.
11
+ #
12
+ # The +type+ parameter is normally one of the migrations native types,
13
+ # which is one of the following:
14
+ # <tt>:primary_key</tt>, <tt>:string</tt>, <tt>:text</tt>,
15
+ # <tt>:integer</tt>, <tt>:bigint</tt>, <tt>:float</tt>, <tt>:decimal</tt>, <tt>:numeric</tt>,
16
+ # <tt>:datetime</tt>, <tt>:time</tt>, <tt>:date</tt>,
17
+ # <tt>:binary</tt>, <tt>:boolean</tt>.
18
+ #
19
+ # You may use a type not in this list as long as it is supported by your
20
+ # database (for example, "polygon" in MySQL), but this will not be database
21
+ # agnostic and should usually be avoided.
22
+ #
23
+ # Available options are (none of these exists by default):
24
+ # * <tt>:limit</tt> -
25
+ # Requests a maximum column length. This is the number of characters for a <tt>:string</tt> column
26
+ # and number of bytes for <tt>:text</tt>, <tt>:binary</tt>, and <tt>:integer</tt> columns.
27
+ # This option is ignored by some backends.
28
+ # * <tt>:default</tt> -
29
+ # The column's default value. Use +nil+ for +NULL+.
30
+ # * <tt>:null</tt> -
31
+ # Allows or disallows +NULL+ values in the column.
32
+ # * <tt>:precision</tt> -
33
+ # Specifies the precision for the <tt>:decimal</tt>, <tt>:numeric</tt>,
34
+ # <tt>:datetime</tt>, and <tt>:time</tt> columns.
35
+ # * <tt>:scale</tt> -
36
+ # Specifies the scale for the <tt>:decimal</tt> and <tt>:numeric</tt> columns.
37
+ # * <tt>:collation</tt> -
38
+ # Specifies the collation for a <tt>:string</tt> or <tt>:text</tt> column. If not specified, the
39
+ # column will have the same collation as the table.
40
+ # * <tt>:comment</tt> -
41
+ # Specifies the comment for the column. This option is ignored by some backends.
42
+ #
43
+ # Note: The precision is the total number of significant digits,
44
+ # and the scale is the number of digits that can be stored following
45
+ # the decimal point. For example, the number 123.45 has a precision of 5
46
+ # and a scale of 2. A decimal with a precision of 5 and a scale of 2 can
47
+ # range from -999.99 to 999.99.
48
+ #
49
+ # Please be aware of different RDBMS implementations behavior with
50
+ # <tt>:decimal</tt> columns:
51
+ # * The SQL standard says the default scale should be 0, <tt>:scale</tt> <=
52
+ # <tt>:precision</tt>, and makes no comments about the requirements of
53
+ # <tt>:precision</tt>.
54
+ # * MySQL: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..30].
55
+ # Default is (10,0).
56
+ # * PostgreSQL: <tt>:precision</tt> [1..infinity],
57
+ # <tt>:scale</tt> [0..infinity]. No default.
58
+ # * SQLite3: No restrictions on <tt>:precision</tt> and <tt>:scale</tt>,
59
+ # but the maximum supported <tt>:precision</tt> is 16. No default.
60
+ # * Oracle: <tt>:precision</tt> [1..38], <tt>:scale</tt> [-84..127].
61
+ # Default is (38,0).
62
+ # * DB2: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..62].
63
+ # Default unknown.
64
+ # * SqlServer: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
65
+ # Default (38,0).
66
+ #
67
+ # == Examples
68
+ #
69
+ # User.add_column(:picture, :binary, limit: 2.megabytes)
70
+ # # ALTER TABLE "users" ADD "picture" blob(2097152)
71
+ #
72
+ # Article.add_column(:status, :string, limit: 20, default: 'draft', null: false)
73
+ # # ALTER TABLE "articles" ADD "status" varchar(20) DEFAULT 'draft' NOT NULL
74
+ #
75
+ # Answer.add_column(:bill_gates_money, :decimal, precision: 15, scale: 2)
76
+ # # ALTER TABLE "answers" ADD "bill_gates_money" decimal(15,2)
77
+ #
78
+ # Measurement.add_column(:sensor_reading, :decimal, precision: 30, scale: 20)
79
+ # # ALTER TABLE "measurements" ADD "sensor_reading" decimal(30,20)
80
+ #
81
+ # # While :scale defaults to zero on most databases, it
82
+ # # probably wouldn't hurt to include it.
83
+ # Measurement.add_column(:huge_integer, :decimal, precision: 30)
84
+ # # ALTER TABLE "measurements" ADD "huge_integer" decimal(30)
85
+ #
86
+ # # Defines a column that stores an array of a type.
87
+ # User.add_column(:skills, :text, array: true)
88
+ # # ALTER TABLE "users" ADD "skills" text[]
89
+ #
90
+ # # Defines a column with a database-specific type.
91
+ # Shape.add_column(:triangle, 'polygon')
92
+ # # ALTER TABLE "shapes" ADD "triangle" polygon
93
+ def add_column(column_name, type, **options)
94
+ ActiveRecord::Base.connection.add_column(table_name, column_name, type, **options)
95
+ end
96
+
97
+ # Changes the column's definition according to the new options.
98
+ # See TableDefinition#column for details of the options you can use.
99
+ #
100
+ # Supplier.change_column(:name, :string, limit: 80)
101
+ # Post.change_column(:description, :text)
102
+ #
103
+ def change_column(column_name, type, options = {})
104
+ ActiveRecord::Base.connection.change_column(table_name, column_name, type, options)
105
+ end
106
+
107
+ # Removes the column from the table definition.
108
+ #
109
+ # Supplier.remove_column(:qualification)
110
+ #
111
+ # The +type+ and +options+ parameters will be ignored if present. It can be helpful
112
+ # to provide these in a migration's +change+ method so it can be reverted.
113
+ # In that case, +type+ and +options+ will be used by #add_column.
114
+ # Indexes on the column are automatically removed.
115
+ def remove_column(column_name, type = nil, **options)
116
+ ActiveRecord::Base.connection.remove_column(table_name, column_name, type, **options)
117
+ end
118
+
119
+ # Adds a new index to the table. +column_name+ can be a single Symbol, or
120
+ # an Array of Symbols.
121
+ #
122
+ # The index will be named after the table and the column name(s), unless
123
+ # you pass <tt>:name</tt> as an option.
124
+ #
125
+ # ====== Creating a simple index
126
+ #
127
+ # Supplier.add_index(:name)
128
+ #
129
+ # generates:
130
+ #
131
+ # CREATE INDEX suppliers_name_index ON suppliers(name)
132
+ #
133
+ # ====== Creating a unique index
134
+ #
135
+ # Account.add_index([:branch_id, :party_id], unique: true)
136
+ #
137
+ # generates:
138
+ #
139
+ # CREATE UNIQUE INDEX accounts_branch_id_party_id_index ON accounts(branch_id, party_id)
140
+ #
141
+ # ====== Creating a named index
142
+ #
143
+ # Account.add_index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
144
+ #
145
+ # generates:
146
+ #
147
+ # CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)
148
+ #
149
+ # ====== Creating an index with specific key length
150
+ #
151
+ # Account.add_index(:name, name: 'by_name', length: 10)
152
+ #
153
+ # generates:
154
+ #
155
+ # CREATE INDEX by_name ON accounts(name(10))
156
+ #
157
+ # ====== Creating an index with specific key lengths for multiple keys
158
+ #
159
+ # Account.add_index([:name, :surname], name: 'by_name_surname', length: {name: 10, surname: 15})
160
+ #
161
+ # generates:
162
+ #
163
+ # CREATE INDEX by_name_surname ON accounts(name(10), surname(15))
164
+ #
165
+ # Note: SQLite doesn't support index length.
166
+ #
167
+ # ====== Creating an index with a sort order (desc or asc, asc is the default)
168
+ #
169
+ # Account.add_index([:branch_id, :party_id, :surname], order: {branch_id: :desc, party_id: :asc})
170
+ #
171
+ # generates:
172
+ #
173
+ # CREATE INDEX by_branch_desc_party ON accounts(branch_id DESC, party_id ASC, surname)
174
+ #
175
+ # Note: MySQL only supports index order from 8.0.1 onwards (earlier versions accepted the syntax but ignored it).
176
+ #
177
+ # ====== Creating a partial index
178
+ #
179
+ # Account.add_index([:branch_id, :party_id], unique: true, where: "active")
180
+ #
181
+ # generates:
182
+ #
183
+ # CREATE UNIQUE INDEX index_accounts_on_branch_id_and_party_id ON accounts(branch_id, party_id) WHERE active
184
+ #
185
+ # Note: Partial indexes are only supported for PostgreSQL and SQLite 3.8.0+.
186
+ #
187
+ # ====== Creating an index with a specific method
188
+ #
189
+ # Developer.add_index(:name, using: 'btree')
190
+ #
191
+ # generates:
192
+ #
193
+ # CREATE INDEX index_developers_on_name ON developers USING btree (name) -- PostgreSQL
194
+ # CREATE INDEX index_developers_on_name USING btree ON developers (name) -- MySQL
195
+ #
196
+ # Note: only supported by PostgreSQL and MySQL
197
+ #
198
+ # ====== Creating an index with a specific operator class
199
+ #
200
+ # Developer.add_index(:name, using: 'gist', opclass: :gist_trgm_ops)
201
+ # # CREATE INDEX developers_on_name ON developers USING gist (name gist_trgm_ops) -- PostgreSQL
202
+ #
203
+ # Developer.add_index([:name, :city], using: 'gist', opclass: { city: :gist_trgm_ops })
204
+ # # CREATE INDEX developers_on_name_and_city ON developers USING gist (name, city gist_trgm_ops) -- PostgreSQL
205
+ #
206
+ # Developer.add_index([:name, :city], using: 'gist', opclass: :gist_trgm_ops)
207
+ # # CREATE INDEX developers_on_name_and_city ON developers USING gist (name gist_trgm_ops, city gist_trgm_ops) -- PostgreSQL
208
+ #
209
+ # Note: only supported by PostgreSQL
210
+ #
211
+ # ====== Creating an index with a specific type
212
+ #
213
+ # Developer.add_index(:name, type: :fulltext)
214
+ #
215
+ # generates:
216
+ #
217
+ # CREATE FULLTEXT INDEX index_developers_on_name ON developers (name) -- MySQL
218
+ #
219
+ # Note: only supported by MySQL.
220
+ #
221
+ # ====== Creating an index with a specific algorithm
222
+ #
223
+ # Developer.add_index(:name, algorithm: :concurrently)
224
+ # # CREATE INDEX CONCURRENTLY developers_on_name on developers (name)
225
+ #
226
+ # Note: only supported by PostgreSQL.
227
+ #
228
+ # Concurrently adding an index is not supported in a transaction.
229
+ #
230
+ # For more information see the {"Transactional Migrations" section}[rdoc-ref:Migration].
231
+ def add_index(column_name, options = {})
232
+ ActiveRecord::Base.connection.add_index(table_name, column_name, options)
233
+ end
234
+
235
+ # Adds a new foreign key.
236
+ # +to_table+ contains the referenced primary key.
237
+ #
238
+ # The foreign key will be named after the following pattern: <tt>fk_rails_<identifier></tt>.
239
+ # +identifier+ is a 10 character long string which is deterministically generated from this
240
+ # table and +column+. A custom name can be specified with the <tt>:name</tt> option.
241
+ #
242
+ # ====== Creating a simple foreign key
243
+ #
244
+ # Article.add_foreign_key :authors
245
+ #
246
+ # generates:
247
+ #
248
+ # ALTER TABLE "articles" ADD CONSTRAINT fk_rails_e74ce85cbc FOREIGN KEY ("author_id") REFERENCES "authors" ("id")
249
+ #
250
+ # ====== Creating a foreign key on a specific column
251
+ #
252
+ # Article.add_foreign_key :users, column: :author_id, primary_key: "lng_id"
253
+ #
254
+ # generates:
255
+ #
256
+ # ALTER TABLE "articles" ADD CONSTRAINT fk_rails_58ca3d3a82 FOREIGN KEY ("author_id") REFERENCES "users" ("lng_id")
257
+ #
258
+ # ====== Creating a cascading foreign key
259
+ #
260
+ # Article.add_foreign_key :authors, on_delete: :cascade
261
+ #
262
+ # generates:
263
+ #
264
+ # ALTER TABLE "articles" ADD CONSTRAINT fk_rails_e74ce85cbc FOREIGN KEY ("author_id") REFERENCES "authors" ("id") ON DELETE CASCADE
265
+ #
266
+ # The +options+ hash can include the following keys:
267
+ # [<tt>:column</tt>]
268
+ # The foreign key column name on +from_table+. Defaults to <tt>to_table.singularize + "_id"</tt>
269
+ # [<tt>:primary_key</tt>]
270
+ # The primary key column name on +to_table+. Defaults to +id+.
271
+ # [<tt>:name</tt>]
272
+ # The constraint name. Defaults to <tt>fk_rails_<identifier></tt>.
273
+ # [<tt>:on_delete</tt>]
274
+ # Action that happens <tt>ON DELETE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
275
+ # [<tt>:on_update</tt>]
276
+ # Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
277
+ # [<tt>:validate</tt>]
278
+ # (PostgreSQL only) Specify whether or not the constraint should be validated. Defaults to +true+.
279
+ def add_foreign_key(to_table, **options)
280
+ ActiveRecord::Base.connection.add_foreign_key(table_name, to_table, **options)
281
+ end
282
+
283
+ # Adds timestamps (+created_at+ and +updated_at+) columns to this table.
284
+ # Additional options (like +:null+) are forwarded to #add_column.
285
+ #
286
+ # Supplier.add_timestamps(null: true)
287
+ #
288
+ def add_timestamps(**options)
289
+ ActiveRecord::Base.connection.add_timestamps(table_name, **options)
290
+ end
291
+
292
+ # Changes the comment for a column or removes it if +nil+.
293
+ #
294
+ # Passing a hash containing +:from+ and +:to+ will make this change
295
+ # reversible in migration:
296
+ #
297
+ # Post.change_column_comment(:state, from: "old_comment", to: "new_comment")
298
+ def change_column_comment(column_name, comment_or_changes)
299
+ ActiveRecord::Base.connection.change_column_comment(table_name, column_name, comment_or_changes)
300
+ end
301
+
302
+ # Sets a new default value for a column:
303
+ #
304
+ # Supplier.change_column_default(:qualification, 'new')
305
+ # change_column_default(:accounts, :authorized, 1)
306
+ #
307
+ # Setting the default to +nil+ effectively drops the default:
308
+ #
309
+ # User.change_column_default(:email, nil)
310
+ #
311
+ # Passing a hash containing +:from+ and +:to+ will make this change
312
+ # reversible in migration:
313
+ #
314
+ # Post.change_column_default(:state, from: nil, to: "draft")
315
+ #
316
+ def change_column_default(column_name, default_or_changes)
317
+ ActiveRecord::Base.connection.change_column_default(table_name, column_name, default_or_changes)
318
+ end
319
+
320
+ # Sets or removes a <tt>NOT NULL</tt> constraint on a column. The +null+ flag
321
+ # indicates whether the value can be +NULL+. For example
322
+ #
323
+ # User.change_column_null(:nickname, false)
324
+ #
325
+ # says nicknames cannot be +NULL+ (adds the constraint), whereas
326
+ #
327
+ # User.change_column_null(:nickname, true)
328
+ #
329
+ # allows them to be +NULL+ (drops the constraint).
330
+ #
331
+ # The method accepts an optional fourth argument to replace existing
332
+ # <tt>NULL</tt>s with some other value. Use that one when enabling the
333
+ # constraint if needed, since otherwise those rows would not be valid.
334
+ #
335
+ # Please note the fourth argument does not set a column's default.
336
+ def change_column_null(column_name, null, default = nil)
337
+ ActiveRecord::Base.connection.change_column_null(table_name, column_name, null, default)
338
+ end
339
+
340
+ # Renames a column.
341
+ #
342
+ # Supplier.rename_column(:description, :name)
343
+ #
344
+ def rename_column(column_name, new_column_name)
345
+ ActiveRecord::Base.connection.rename_column(table_name, column_name, new_column_name)
346
+ end
347
+
348
+ # A block for changing columns in +table+.
349
+ #
350
+ # # change_table() yields a Table instance
351
+ # Supplier.change_table do |t|
352
+ # t.column :name, :string, limit: 60
353
+ # # Other column alterations here
354
+ # end
355
+ #
356
+ # The +options+ hash can include the following keys:
357
+ # [<tt>:bulk</tt>]
358
+ # Set this to true to make this a bulk alter query, such as
359
+ #
360
+ # ALTER TABLE `users` ADD COLUMN age INT, ADD COLUMN birthdate DATETIME ...
361
+ #
362
+ # Defaults to false.
363
+ #
364
+ # Only supported on the MySQL and PostgreSQL adapter, ignored elsewhere.
365
+ #
366
+ # ====== Add a column
367
+ #
368
+ # Supplier.change_table do |t|
369
+ # t.column :name, :string, limit: 60
370
+ # end
371
+ #
372
+ # ====== Add 2 integer columns
373
+ #
374
+ # Supplier.change_table do |t|
375
+ # t.integer :width, :height, null: false, default: 0
376
+ # end
377
+ #
378
+ # ====== Add created_at/updated_at columns
379
+ #
380
+ # Supplier.change_table do |t|
381
+ # t.timestamps
382
+ # end
383
+ #
384
+ # ====== Add a foreign key column
385
+ #
386
+ # Supplier.change_table do |t|
387
+ # t.references :company
388
+ # end
389
+ #
390
+ # Creates a <tt>company_id(bigint)</tt> column.
391
+ #
392
+ # ====== Add a polymorphic foreign key column
393
+ #
394
+ # Supplier.change_table do |t|
395
+ # t.belongs_to :company, polymorphic: true
396
+ # end
397
+ #
398
+ # Creates <tt>company_type(varchar)</tt> and <tt>company_id(bigint)</tt> columns.
399
+ #
400
+ # ====== Remove a column
401
+ #
402
+ # Supplier.change_table do |t|
403
+ # t.remove :company
404
+ # end
405
+ #
406
+ # ====== Remove several columns
407
+ #
408
+ # Supplier.change_table do |t|
409
+ # t.remove :company_id
410
+ # t.remove :width, :height
411
+ # end
412
+ #
413
+ # ====== Remove an index
414
+ #
415
+ # Supplier.change_table do |t|
416
+ # t.remove_index :company_id
417
+ # end
418
+ #
419
+ # See also Table for details on all of the various column transformations.
420
+ def change_table(**options)
421
+ ActiveRecord::Base.connection.change_table(table_name, **options)
422
+ end
423
+
424
+ # Renames a table.
425
+ #
426
+ # rename_table('octopi')
427
+ #
428
+ def rename_table(new_name)
429
+ ActiveRecord::Base.connection.rename_table(table_name, new_name)
430
+ end
431
+
432
+ # Changes the comment for a table or removes it if +nil+.
433
+ #
434
+ # Passing a hash containing +:from+ and +:to+ will make this change
435
+ # reversible in migration:
436
+ #
437
+ # Post.change_table_comment(from: "old_comment", to: "new_comment")
438
+ def change_table_comment(comment_or_changes)
439
+ ActiveRecord::Base.connection.change_table_comment(table_name, comment_or_changes)
440
+ end
441
+
442
+ # Drops a table from the database.
443
+ #
444
+ # [<tt>:force</tt>]
445
+ # Set to +:cascade+ to drop dependent objects as well.
446
+ # Defaults to false.
447
+ # [<tt>:if_exists</tt>]
448
+ # Set to +true+ to only drop the table if it exists.
449
+ # Defaults to false.
450
+ #
451
+ # Although this command ignores most +options+ and the block if one is given,
452
+ # it can be helpful to provide these in a migration's +change+ method so it can be reverted.
453
+ # In that case, +options+ and the block will be used by #create_table.
454
+ def drop_table(**options)
455
+ ActiveRecord::Base.connection.drop_table(table_name, **options)
456
+ end
457
+
458
+ # Returns an array of foreign keys for the given table.
459
+ # The foreign keys are represented as ForeignKeyDefinition objects.
460
+ def foreign_keys
461
+ ActiveRecord::Base.connection.foreign_keys(table_name)
462
+ end
463
+
464
+ # Removes the given foreign key from the table. Any option parameters provided
465
+ # will be used to re-add the foreign key in case of a migration rollback.
466
+ # It is recommended that you provide any options used when creating the foreign
467
+ # key so that the migration can be reverted properly.
468
+ #
469
+ # Removes the foreign key on +accounts.branch_id+.
470
+ #
471
+ # Account.remove_foreign_key :branches
472
+ #
473
+ # Removes the foreign key on +accounts.owner_id+.
474
+ #
475
+ # Account.remove_foreign_key column: :owner_id
476
+ #
477
+ # Removes the foreign key on +accounts.owner_id+.
478
+ #
479
+ # Account.remove_foreign_key to_table: :owners
480
+ #
481
+ # Removes the foreign key named +special_fk_name+ on the +accounts+ table.
482
+ #
483
+ # Account.remove_foreign_key name: :special_fk_name
484
+ #
485
+ # The +options+ hash accepts the same keys as SchemaStatements#add_foreign_key
486
+ # with an addition of
487
+ # [<tt>:to_table</tt>]
488
+ # The name of the table that contains the referenced primary key.
489
+ def remove_foreign_key(to_table = nil, **options)
490
+ ActiveRecord::Base.connection.remove_foreign_key(table_name, to_table, **options)
491
+ end
492
+
493
+ # Removes the given index from the table.
494
+ #
495
+ # Removes the index on +branch_id+ in the +accounts+ table if exactly one such index exists.
496
+ #
497
+ # Account.remove_index :branch_id
498
+ #
499
+ # Removes the index on +branch_id+ in the +accounts+ table if exactly one such index exists.
500
+ #
501
+ # Account.remove_index column: :branch_id
502
+ #
503
+ # Removes the index on +branch_id+ and +party_id+ in the +accounts+ table if exactly one such index exists.
504
+ #
505
+ # Account.remove_index column: [:branch_id, :party_id]
506
+ #
507
+ # Removes the index named +by_branch_party+ in the +accounts+ table.
508
+ #
509
+ # Account.remove_index name: :by_branch_party
510
+ #
511
+ # Removes the index named +by_branch_party+ in the +accounts+ table +concurrently+.
512
+ #
513
+ # Account.remove_index name: :by_branch_party, algorithm: :concurrently
514
+ #
515
+ # Note: only supported by PostgreSQL.
516
+ #
517
+ # Concurrently removing an index is not supported in a transaction.
518
+ #
519
+ # For more information see the {"Transactional Migrations" section}[rdoc-ref:Migration].
520
+ def remove_index(options = {})
521
+ ActiveRecord::Base.connection.remove_index(table_name, options)
522
+ end
523
+
524
+ # Removes the timestamp columns (+created_at+ and +updated_at+) from the table definition.
525
+ #
526
+ # Supplier.remove_timestamps
527
+ #
528
+ def remove_timestamps(**options)
529
+ ActiveRecord::Base.connection.remove_timestamps(**options)
530
+ end
531
+
532
+ # Renames an index.
533
+ #
534
+ # Rename the +index_people_on_last_name+ index to +index_users_on_last_name+:
535
+ #
536
+ # Person.rename_index 'index_people_on_last_name', 'index_users_on_last_name'
537
+ #
538
+ def rename_index(old_name, new_name)
539
+ ActiveRecord::Base.connection.rename_index(table_name, old_name, new_name)
540
+ end
541
+
542
+ # Returns the table comment that's stored in database metadata.
543
+ def table_comment
544
+ ActiveRecord::Base.connection.table_comment(table_name)
545
+ end
546
+
547
+ end
548
+ end
549
+ end
550
+ end
@@ -1,3 +1,4 @@
1
+ require 'arql/concerns'
1
2
  module Arql
2
3
  module Extension
3
4
  extend ActiveSupport::Concern
@@ -145,6 +146,7 @@ module Arql
145
146
  @@models = []
146
147
  ActiveRecord::Base.connection.tap do |conn|
147
148
  Object.const_set('ArqlModel', Class.new(ActiveRecord::Base) do
149
+ include ::Arql::Concerns::TableDataDefinition
148
150
  self.abstract_class = true
149
151
 
150
152
  define_singleton_method(:indexes) do
@@ -158,230 +160,6 @@ module Arql
158
160
  }
159
161
  end.t
160
162
  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
163
  end)
386
164
  conn.tables.each do |table_name|
387
165
  table_comment = conn.table_comment(table_name)
@@ -1,6 +1,9 @@
1
+ require 'arql/concerns'
1
2
  module Kernel
2
3
  CSV_BOM = "\xef\xbb\xbf"
3
4
 
5
+ include ::Arql::Concerns::GlobalDataDefinition
6
+
4
7
  def sql(sql)
5
8
  ActiveRecord::Base.connection.exec_query(sql)
6
9
  end
@@ -106,159 +109,4 @@ module Kernel
106
109
  end
107
110
  end
108
111
 
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
264
112
  end
@@ -1,3 +1,3 @@
1
1
  module Arql
2
- VERSION = "0.2.12"
2
+ VERSION = "0.2.13"
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.12
4
+ version: 0.2.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Liu Xiang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-02 00:00:00.000000000 Z
11
+ date: 2021-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mysql2
@@ -237,6 +237,9 @@ files:
237
237
  - lib/arql/commands/redefine.rb
238
238
  - lib/arql/commands/show_sql.rb
239
239
  - lib/arql/commands/table.rb
240
+ - lib/arql/concerns.rb
241
+ - lib/arql/concerns/global_data_definition.rb
242
+ - lib/arql/concerns/table_data_definition.rb
240
243
  - lib/arql/connection.rb
241
244
  - lib/arql/definition.rb
242
245
  - lib/arql/ext.rb