arql 0.3.29 → 0.3.30

Sign up to get free protection for your applications and to get access to all the features.
data/README.org ADDED
@@ -0,0 +1,1170 @@
1
+ * Arql
2
+
3
+ [[./README-zh_CN.org][中文]]
4
+
5
+ Arql is a simple utility gem that combines Rails ActiveRecord with Pry and adds useful Pry commands. It can
6
+ automatically define model classes based on database table schema. If you are a Ruby guy, you can use this gem
7
+ as your database query tool.
8
+
9
+ ** Pre-requisite
10
+
11
+ + Ruby >= 2.6.0
12
+ + For different types of databases, you need to install the corresponding database adapter or client binary library:
13
+ - MySQL: Depending on your operating system, you may need to install: =libmariadb-dev=, =libmysqlclient-dev=, =mysql-devel=
14
+ =default-libmysqlclient-dev= ; see the software package guide for your distribution to find the specific package; or refer to [[https://github.com/brianmario/mysql2][mysql2 doc]]
15
+ - SQLite3: No additional libraries need to be installed
16
+ - PostgreSQL: ~gem install pg~
17
+ - Oracle: ~gem install activerecord-oracle_enhanced-adapter~
18
+ - SQL Server: ~gem install activerecord-sqlserver-adapter~
19
+
20
+ ** Installation
21
+
22
+ Run the following command to install the gem:
23
+
24
+ #+begin_example
25
+ $ gem install arql
26
+ #+end_example
27
+
28
+ Try using sudo if you encounter system permission issues:
29
+
30
+ #+begin_example
31
+ $ sudo gem install arql
32
+ #+end_example
33
+
34
+ ** Usage
35
+
36
+ *** CLI options
37
+
38
+ #+begin_example
39
+ Usage: arql [options] [ruby file]
40
+
41
+ If neither [ruby file] nor -E option is specified, and STDIN is a tty, a Pry REPL will be started,
42
+ otherwise the specified ruby file or -E option value or ruby code read from STDIN will be executed,
43
+ and the REPL will not be started
44
+
45
+ -c, --conf=CONFIG_FILE Specify the configuration file, default is $HOME/.arql.yml or $HOME/.arql.d/init.yml
46
+ -i, --initializer=INITIALIZER Specify the initializer Ruby file, default is $HOME/.arql.rb or $HOME/.arql.d/init.rb
47
+ -e, --env=ENVIRON Specify the configuration environment
48
+ -a, --db-adapter=DB_ADAPTER Specify the database adapter, default is sqlite3
49
+ -h, --db-host=DB_HOST Specify the database host
50
+ -p, --db-port=DB_PORT Specify the database port
51
+ -d, --db-name=DB_NAME Specify the database name
52
+ -u, --db-user=DB_USER Specify the database user
53
+ -P, --db-password=DB_PASSWORD Specify the database password
54
+ -n, --db-encoding=DB_ENCODING Specify the database encoding, default is utf8
55
+ -o, --db-pool=DB_POOL Specify the database connection pool size, default is 5
56
+ -H, --ssh-host=SSH_HOST Specify the SSH host
57
+ -O, --ssh-port=SSH_PORT Specify the SSH port
58
+ -U, --ssh-user=SSH_USER Specify the SSH user
59
+ -W, --ssh-password=SSH_PASSWORD Specify the SSH password
60
+ -L, --ssh-local-port=SSH_LOCAL_PORT Specify the local SSH proxy port
61
+ -E, --eval=CODE Evaluate code
62
+ -S, --show-sql Print SQL on STDOUT
63
+ -w, --write-sql=OUTPUT Write SQL to OUTPUT file
64
+ -A, --append-sql=OUTPUT Append SQL to OUTPUT file
65
+ --help Print this message
66
+ #+end_example
67
+
68
+ **** =-c, --config=CONFIG_FILE=
69
+
70
+ Specify the configuration file location, default is =$HOME/.arql.yml= or =$HOME/.arql.d/init.yml=. The configuration file
71
+ is usually the same as the Rails database configuration file, but with some additional configuration options, such as the
72
+ =ssh= option, etc. Refer to the =Configuration file= section.
73
+
74
+ **** =-i, --initializer=INITIALIZER=
75
+
76
+ Specify a Ruby source file, Arql executes the code in this file after defining the ActiveRecord model class, default is
77
+ =$HOME/.arql.rb= or =$HOME/.arql.d/init.rb=. You can add methods and association definitions for ActiveRecord model
78
+ classes in this file.
79
+
80
+ **** =-e, --env=ENVIRON=
81
+
82
+ Specify an environment name in the configuration file.
83
+
84
+ **** =-E, --eval=CODE=
85
+
86
+ Specify a Ruby code snippet, if this option is specified, the Pry REPL will not be started.
87
+
88
+ **** =-S, --show-sql=
89
+
90
+ arql does not display SQL logs by default, use this option to turn it on.
91
+
92
+ **** =-w, --write-sql=OUTPUT=
93
+
94
+ You can also use this option to let arql write SQL logs to a file.
95
+
96
+ **** =-A, --append-sql-OUTOUT=
97
+
98
+ Similar to =-w=, but uses append writing, does not truncate the existing file.
99
+
100
+ **** Database options
101
+
102
+ The options described in this section are usually configured in the configuration file. These options are just shortcuts
103
+ for the corresponding configuration items in the configuration file, so that certain configuration items can be directly
104
+ modified in the CLI.
105
+
106
+ ***** -a, --db-adapter=DB_ADAPTER
107
+
108
+ Specify the database adapter, available values:
109
+
110
+ - =mysql2=
111
+ - =postgresql=
112
+ - =sqlite3=
113
+ - =sqlserver=
114
+ - =oracle_enhanced=
115
+
116
+ ***** -h, --db-host=DB_HOST
117
+
118
+ Specify the database host
119
+
120
+ ***** -p, --db-port=DB_PORT
121
+
122
+ Specify the database port
123
+
124
+ ***** -d, --db-name=DB_NAME
125
+
126
+ Specify the database name
127
+
128
+ ***** -u, --db-user=DB_USER
129
+
130
+ Specify the database username
131
+
132
+ ***** -P, --db-password=DB_PASSWORD
133
+
134
+ Specify the database password
135
+
136
+ ***** -n, --db-encoding=DB_ENCODING
137
+
138
+ Specify the database character encoding, default is =utf8=
139
+
140
+ ***** -o, --db-pool=DB_POOL
141
+
142
+ Specify the database connection pool size, default is =5=
143
+
144
+ ***** -H, --ssh-host=SSH_HOST
145
+
146
+ Specify the SSH host, when the SSH related options are specified, arql will establish an SSH tunnel and connect to the
147
+ database using the SSH tunnel.
148
+
149
+ ***** -O, --ssh-port=SSH_PORT
150
+
151
+ Specify the SSH port
152
+
153
+ ***** -U, --ssh-user=SSH_USER
154
+
155
+ Specify the SSH username
156
+
157
+ ***** -W, --ssh-password=SSH_PASSWORD
158
+
159
+ Specify the SSH password
160
+
161
+ ***** -L, --ssh-local-port=SSH_LOCAL_PORT
162
+
163
+ Specify the SSH local port, default is a /random/ port
164
+
165
+ *** Configuration file
166
+
167
+ The path of the configuration file defaults to =$HOME/.arql.yml= or =$HOME/.arql.d/init.yml=. The configuration file is
168
+ usually the same as the Rails database configuration file, but there are some additional configuration options:
169
+
170
+ 1. =created_at= : An array of custom column names containing the ActiveRecord =created_at= field, default is =created_at=, if specified, the current timestamp will be used to fill the value of the column when created
171
+ 2. =updated_at= : An array of custom column names containing the ActiveRecord =updated_at= field, default is =updated_at=, if specified, the current timestamp will be used to fill the value of the column when updated
172
+ 3. =ssh.host= : ssh host, you can use the host name in the =ssh_config= file, or directly use the IP address or host name
173
+ 4. =ssh.port= : ssh port, default is =22=
174
+ 5. =ssh.user= : ssh username
175
+ 6. =ssh.password= : ssh password
176
+ 7. =ssh.local_port= : ssh local port
177
+ 8. =singularized_table_names=: Whether to use singular table names, default is =false=, if =false=, the =students= table will be defined as the =Student= model, if =true=, the =students= table will be defined as the =Students= model
178
+
179
+ **** Example
180
+
181
+ #+begin_example
182
+ default: &default
183
+ adapter: mysql2
184
+ encoding: utf8
185
+ created_at: ["gmt_created"]
186
+ updated_at: ["gmt_modified"]
187
+ singularized_table_names: true
188
+
189
+ local:
190
+ <<: *default
191
+ username: root
192
+ database: blog
193
+ password:
194
+ socket: /tmp/mysql.sock
195
+
196
+ dev:
197
+ <<: *default
198
+ host: devdb.mycompany.com
199
+ port: 3306
200
+ username: root
201
+ password: 123456
202
+ database: blog
203
+ ssh:
204
+ host: dev.mycompany.com
205
+ port: 22
206
+ user: deploy
207
+ password: 12345678
208
+ local_port: 3307
209
+ #+end_example
210
+
211
+
212
+ The example defines a common configuration item =default=, and two specific database environments =local= and =dev=. =local=
213
+ and =dev= inherit the configuration items of =default= in the way of =<<: *default=.
214
+
215
+
216
+ When the command =arql -e dev= is executed, arql will use the =dev= configuration in the configuration file; when the command
217
+ =arql -e local= is executed, arql will use the =local= configuration in the configuration file.
218
+
219
+
220
+ The =dev= environment uses an SSH tunnel. When connecting to the =devdb.mycompany.com= database, an SSH tunnel will be established
221
+ to =dev.mycompany.com= first, and then connected to the database through the SSH tunnel.
222
+
223
+ *** Use Arql as REPL
224
+
225
+ If neither =[ruby file]= nor the =-E= option is specified, and STDIN is a =tty=, arql will start a Pry REPL. For example, execute:
226
+
227
+ #+BEGIN_EXAMPLE
228
+ arql -e dev
229
+ #+END_EXAMPLE
230
+
231
+
232
+ Arql provides some Pry commands:
233
+
234
+ **** =info=
235
+
236
+ The =info= command prints the current database connection information and SSH proxy information, for example:
237
+
238
+ #+begin_example
239
+ Database Connection Information:
240
+ Host:
241
+ Port:
242
+ Username: root
243
+ Password:
244
+ Database: test
245
+ Adapter: mysql2
246
+ Encoding: utf8
247
+ Pool Size: 5
248
+ #+end_example
249
+
250
+ **** =m= or =l=
251
+
252
+ The =m= (or =l=) command prints all table names and their corresponding model class names and abbreviated class names, for example:
253
+
254
+ #+begin_example
255
+ +--------------------+------------------+------+----------------+
256
+ | Table Name | Model Class | Abbr | Comment |
257
+ +--------------------+------------------+------+----------------+
258
+ | post | Post | P | Posts |
259
+ | org | Org | O | Orginations |
260
+ | user_org | UserOrg | UO | |
261
+ | student | Student | S | Students |
262
+ | course | Course | C | |
263
+ | score | Score | S2 | |
264
+ | users | Users | U | |
265
+ | posts | Posts | P2 | |
266
+ | authors | Authors | A | |
267
+ +--------------------+------------------+------+----------------+
268
+ #+end_example
269
+
270
+ Where:
271
+
272
+ - =Table Name= : Table name
273
+ - =Model Class= : Model class name
274
+ - =Abbr= : Abbreviated class name
275
+ - =Comment= : Comment
276
+
277
+ The =m= / =l= command can also accept a parameter to filter the list by table name or table comment, for example:
278
+
279
+ =m perm= will only list tables that contain =perm= in the table name or table comment; if you want to use regular expressions to match,
280
+ you can use =m /perm/i= to match.
281
+
282
+ **** =t=
283
+
284
+ The =t= command accepts a table name or model class name as a parameter and prints the table definition information, for example:
285
+
286
+ Executing the =t Person= command will print the definition information of the =person= table:
287
+
288
+ #+begin_example
289
+ Table: person
290
+ +----|------------|------------------|-----------|-------|-----------|-------|---------|----------|---------+
291
+ | PK | Name | SQL Type | Ruby Type | Limit | Precision | Scale | Default | Nullable | Comment |
292
+ +----|------------|------------------|-----------|-------|-----------|-------|---------|----------|---------+
293
+ | Y | id | int(11) unsigned | integer | 4 | | | | false | |
294
+ | | name | varchar(64) | string | 64 | | | | true | |
295
+ | | age | int(11) | integer | 4 | | | | true | |
296
+ | | gender | int(4) | integer | 4 | | | | true | |
297
+ | | grade | int(4) | integer | 4 | | | | true | |
298
+ | | blood_type | varchar(4) | string | 4 | | | | true | |
299
+ +----|------------|------------------|-----------|-------|-----------|-------|---------|----------|---------+
300
+ #+end_example
301
+
302
+ In addition, =t= is also a class method of the model class. Executing =Person.t= will also print the above information.
303
+
304
+
305
+ Where:
306
+
307
+ - =PK= : Whether it is a primary key
308
+ - =Name= : Column name
309
+ - =SQL Type= : Database type
310
+ - =Ruby Type= : Ruby type
311
+ - =Limit= : Length limit
312
+ - =Precision= : Precision
313
+ - =Scale= : Number of decimal places
314
+ - =Default= : Default value
315
+ - =Nullable= : Whether it can be empty
316
+ - =Comment= : Comment
317
+
318
+ **** =vd=
319
+
320
+
321
+ The =t= command prints the table definition information in the terminal in the form of a table. The disadvantage
322
+ is that if the number of columns in the table is too large, it will cause the table to wrap, which is not
323
+ convenient to view. =vd= (visidata) is a terminal data analysis tool written in Python, which can print the table
324
+ definition information in the terminal in the form of a table, but supports horizontal scrolling, which is
325
+ convenient for viewing.
326
+
327
+ If you want to use the =vd= command of Arql, you need to install visidata first:
328
+
329
+ #+begin_src sh
330
+ pipx install visidata
331
+ #+end_src
332
+
333
+
334
+ The =vd= command and usage are basically the same as the =t= command. In addition, objects such as =Array= /
335
+ =ActiveRecord::Base= can also use the =vd= method.
336
+
337
+ **** =show-sql= / =hide-sql=
338
+
339
+ This pair of commands can switch the display of SQL logs in the Pry REPL.
340
+
341
+ By default, SQL logs are not displayed:
342
+
343
+ #+begin_example
344
+ ARQL@demo247(main) [2] ❯ Student.count
345
+ => 0
346
+ #+end_example
347
+
348
+ After opening the SQL log, the SQL statement executed each time will be displayed:
349
+
350
+ #+begin_example
351
+ ARQL@demo247(main) [3] ❯ show-sql
352
+ ARQL@demo247(main) [4] ❯ Student.count
353
+ D, [2024-04-07T13:31:32.053903 #20440] DEBUG -- : Student Count (29.8ms) SELECT COUNT(*) FROM `student`
354
+ => 0
355
+ #+end_example
356
+
357
+ **** =reconnect=
358
+
359
+ The =reconnect= command is used to reconnect the current database connection. When the connection is disconnected
360
+ due to network reasons, you can use this command to reconnect. When reconnecting, the objects in the current Pry
361
+ session will not be lost. =reconnect= first checks whether the current connection is still valid. If it is valid,
362
+ it will not reconnect. If the validity judgment of =reconnect= for the connection is wrong, you can use the
363
+ =reconnect!= command to force a reconnection.
364
+
365
+ **** =redefine=
366
+ The =redefine= command is used to redefine the ActiveRecord model class and regenerate the model class based on
367
+ the information of the database table. If you have added new relationship definitions in =init.rb= and want the
368
+ new definitions to take effect in the current Pry session, you can use the =redefine= command.
369
+
370
+ **** Sandbox
371
+
372
+ The =sandbox-enter= command is used to enable sandbox mode. In sandbox mode, all database operations are executed
373
+ in a transaction, and the transaction is not automatically committed. You need to manually commit or roll back.
374
+
375
+ 1. Enter sandbox mode:
376
+ #+begin_example
377
+ ARQL@demo247(main) [6] ❯ sandbox-enter
378
+ ARQL@demo247 [sandbox] (main) [7] ❯
379
+ #+end_example
380
+ 2. Quit sandbox mode:
381
+ #+begin_example
382
+ ARQL@demo247 [sandbox] (main) [7] ❯ sandbox-quit
383
+ begin_transaction callbacks removed.
384
+ You still have open 1 transactions open, don't forget commit or rollback them.
385
+ #+end_example
386
+ 3. Commit the transaction:
387
+ #+begin_example
388
+ ARQL@demo247(main) [7] ❯ $C.commit_transaction
389
+ #+end_example
390
+ 4. Roll back the transaction:
391
+ #+begin_example
392
+ ARQL@demo247(main) [7] ❯ $C.rollback_transaction
393
+ #+end_example
394
+
395
+ *** Use Arql as Code Interpreter
396
+
397
+
398
+ If a Ruby file is specified as a command-line parameter, or the =-E= option is used, or STDIN is not a tty, Arql
399
+ will not start Pry, but will directly execute the specified file or code snippet (or read code from standard
400
+ input). Before executing the code snippet, the model class definition will be loaded first. You can think of this
401
+ usage as similar to the =runner= subcommand of =rails=.
402
+
403
+ **** Use =-E= option
404
+
405
+ The =-E= option can be used to execute code snippets directly without starting Pry:
406
+
407
+ #+begin_example
408
+ $ arql -e dev -E 'puts Person.count'
409
+ #+end_example
410
+
411
+ **** Pass a Ruby file as a command-line parameter
412
+
413
+ By specifying a Ruby file as a command-line parameter, you can directly execute the code in the Ruby file:
414
+
415
+ =test.rb=:
416
+
417
+ #+BEGIN_SRC ruby
418
+ puts Person.count
419
+ #+END_SRC
420
+
421
+ #+begin_example
422
+ $ arql -e dev test.rb
423
+ #+end_example
424
+
425
+ **** Read code from standard input
426
+
427
+ Reading code from standard input, you can directly execute code snippets:
428
+
429
+ #+begin_example
430
+ $ echo 'puts Person.count' | arql -e dev
431
+ #+end_example
432
+
433
+ *** Additional extensions
434
+ **** =to_insert_sql= / =to_upsert_sql=
435
+
436
+
437
+ You can call the =to_insert_sql= / =to_upsert_sql= method on any ActiveRecord model instance to get the insert or
438
+ update SQL statement for the object. These two methods can also be called on an array object containing ActiveRecord
439
+ model instance objects.
440
+
441
+ #+begin_example
442
+ ARQL ❯ Person.all.to_a.to_insert_sql
443
+ => "INSERT INTO `person` (`id`,`name`,`age`,`gender`,`grade`,`blood_type`) VALUES (1, 'Jack', 30, NULL, NULL, NULL), (2, 'Jack', 11, 1, NULL, NULL), (3, 'Jack', 12, 1, NULL, NULL), (4, 'Jack', 30, 1, NULL, NULL), (5, 'Jack', 12, 2, NULL, NULL), (6, 'Jack', 2, 2, 2, NULL), (7, 'Jack', 3, 2, 2, NULL), (8, 'Jack', 30, 2, 2, 'AB'), (9, 'Jack', 30, 2, 2, 'AB'), (10, 'Jack', 30, 2, 2, 'AB'), (11, 'Jackson', 30, 2, 2, 'AB') ON DUPLICATE KEY UPDATE `id`=`id`;"
444
+ #+end_example
445
+
446
+ **** =to_create_sql=
447
+
448
+ You can call the =to_create_sql= method on any ActiveRecord model class to get the create SQL statement for the table
449
+ corresponding to the model class.
450
+
451
+ #+begin_example
452
+ ARQL@demo247(main) [16] ❯ puts Post.to_create_sql
453
+ D, [2024-04-07T14:15:11.106693 #20440] DEBUG -- : SQL (24.9ms) show create table post
454
+ CREATE TABLE `post` (
455
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
456
+ `name` varchar(256) DEFAULT NULL,
457
+ `gender` varchar(256) DEFAULT NULL,
458
+ `phone` varchar(256) DEFAULT NULL,
459
+ `id_no` varchar(256) DEFAULT NULL,
460
+ `note` varchar(256) DEFAULT NULL,
461
+ `gmt_created` datetime NOT NULL COMMENT '创建时间',
462
+ `gmt_modified` datetime NOT NULL COMMENT '最后修改时间',
463
+ PRIMARY KEY (`id`),
464
+ KEY `index_post_on_name` (`name`)
465
+ ) ENGINE=InnoDB AUTO_INCREMENT=83 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
466
+ #+end_example
467
+
468
+ **** =t=
469
+
470
+ =t= can be called as a class method on an ActiveRecord model class, or as an instance method on an ActiveRecord model
471
+ instance object.
472
+
473
+ #+begin_example
474
+ ARQL ❯ Person.last.t
475
+ +----------------|-----------------|------------------|---------+
476
+ | Attribute Name | Attribute Value | SQL Type | Comment |
477
+ +----------------|-----------------|------------------|---------+
478
+ | id | 11 | int(11) unsigned | |
479
+ | name | Jackson | varchar(64) | |
480
+ | age | 30 | int(11) | |
481
+ | gender | 2 | int(4) | |
482
+ | grade | 2 | int(4) | |
483
+ | blood_type | AB | varchar(4) | |
484
+ +----------------|-----------------|------------------|---------+
485
+ #+end_example
486
+
487
+ The =t= method can accept the following two options:
488
+
489
+ + =:except= option, used to specify the attribute names that are not displayed. The value can be a string or a regular
490
+ #+BEGIN_EXAMPLE
491
+ Person.last.t(except: 'id')
492
+ Student.where(condition).t(except: /id|name/)
493
+ #+END_EXAMPLE
494
+ + =:compact= option, used to specify whether to display in compact mode. The value can be =true= or =false=. If compact
495
+ mode is enabled, columns with all NULL values will not be displayed. This is useful for viewing tables with sparse
496
+
497
+ #+BEGIN_EXAMPLE
498
+ Person.last.t(compact: true)
499
+ Student.where(condition).t(compact: false)
500
+ #+END_EXAMPLE
501
+
502
+ **** =v=
503
+
504
+ The =v= method is used to integrate with Emacs org babel.
505
+
506
+ ***** =v= as instance method
507
+
508
+
509
+ Call the =v= method on any ActiveRecord model instance object to print an array. The first element of the array is
510
+ =['Attribute Name', 'Attribute Value', 'SQL Type', 'Comment']=, the second element is =nil=, and the remaining elements
511
+ are the attribute names and values of the object. In Emacs org-mode, if the =:result= type is =value= (the default), this
512
+ return value will be rendered as a beautiful table.
513
+
514
+ #+begin_example
515
+ ARQL ❯ Person.last.v
516
+ => [["Attribute Name", "Attribute Value", "SQL Type", "Comment"],
517
+ nil,
518
+ ["id", 11, "int(11) unsigned", ""],
519
+ ["name", "Jackson", "varchar(64)", ""],
520
+ ["age", 30, "int(11)", ""],
521
+ ["gender", 2, "int(4)", ""],
522
+ ["grade", 2, "int(4)", ""],
523
+ ["blood_type", "AB", "varchar(4)", ""]]
524
+ #+end_example
525
+
526
+ ***** Array containing only model instances
527
+
528
+ #+begin_example
529
+ ARQL ❯ Person.all.to_a.v
530
+ => [["id", "name", "age", "gender", "grade", "blood_type"],
531
+ nil,
532
+ [1, "Jack", 30, nil, nil, nil],
533
+ [2, "Jack", 11, 1, nil, nil],
534
+ [3, "Jack", 12, 1, nil, nil],
535
+ [4, "Jack", 30, 1, nil, nil],
536
+ [5, "Jack", 12, 2, nil, nil],
537
+ [6, "Jack", 2, 2, 2, nil],
538
+ [7, "Jack", 3, 2, 2, nil],
539
+ [8, "Jack", 30, 2, 2, "AB"],
540
+ [9, "Jack", 30, 2, 2, "AB"],
541
+ [10, "Jack", 30, 2, 2, "AB"],
542
+ [11, "Jackson", 30, 2, 2, "AB"]]
543
+ #+end_example
544
+
545
+ ***** Array containing only homogeneous Hash objects
546
+
547
+ #+begin_example
548
+ ARQL ❯ arr = [{name: 'Jack', age: 10}, {name: 'Lucy', age: 20}]
549
+ => [{:name=>"Jack", :age=>10}, {:name=>"Lucy", :age=>20}]
550
+ ARQL ❯ arr.v
551
+ => [[:name, :age], nil, ["Jack", 10], ["Lucy", 20]]
552
+ #+end_example
553
+
554
+ **** =q=
555
+
556
+ #+begin_example
557
+ ARQL ❯ rs = q 'select count(0) from person;'
558
+ => #<ActiveRecord::Result:0x00007fd1f8026ad0 @column_types={}, @columns=["count(0)"], @hash_rows=nil, @rows=[[11]]>
559
+ ARQL ❯ rs.rows
560
+ => [[11]]
561
+ #+end_example
562
+
563
+ **** JSON conversion and formatting
564
+
565
+ Call the =j= method on any object to get a JSON-formatted string, and call the =jj= method to get a formatted JSON string.
566
+
567
+ Use the =jp= method to print JSON and the =jjp= method to print formatted JSON.
568
+
569
+ **** The =$C= Global Variables
570
+
571
+
572
+ Arql assigns the =ActiveRecord::Base.connection= object to the globally available =$C= global variable, which represents the
573
+
574
+ The =q= method mentioned above is actually the =$C.exec_query= method. Other methods of the =$C= object are also useful:
575
+
576
+ ***** Create Table
577
+ #+begin_example
578
+ ARQL ❯ $C.create_table :post, id: false, primary_key: :id do |t|
579
+ ARQL ❯ t.column :id, :bigint, precison: 19, comment: 'ID'
580
+ ARQL ❯ t.column :name, :string, comment: '名称'
581
+ ARQL ❯ t.column :gmt_created, :datetime, comment: '创建时间'
582
+ ARQL ❯ t.column :gmt_modified, :datetime, comment: '最后修改时间'
583
+ ARQL ❯ end
584
+ #+end_example
585
+
586
+ The =create_table= method is also added to the =Kernel= module, so you can also call the =create_table= method directly:
587
+
588
+ #+begin_example
589
+ ARQL ❯ create_table :post, id: false, primary_key: :id do |t|
590
+ ARQL ❯ t.column :id, :bigint, precison: 19, comment: 'ID'
591
+ ARQL ❯ t.column :name, :string, comment: '名称'
592
+ ARQL ❯ t.column :gmt_created, :datetime, comment: '创建时间'
593
+ ARQL ❯ t.column :gmt_modified, :datetime, comment: '最后修改时间'
594
+ ARQL ❯ end
595
+ #+end_example
596
+
597
+ ***** Add Column
598
+
599
+ #+begin_example
600
+ $C.add_column :post, :note, :string, comment: 'the note'
601
+ #+end_example
602
+
603
+ The =add_column= method is also added to the class methods of the model class, so you can also call the
604
+ =add_column= method directly on the model class:
605
+
606
+ #+begin_example
607
+ Post.add_column :note, :string, comment: 'the note'
608
+ #+end_example
609
+
610
+ ***** Change Column
611
+
612
+ #+begin_example
613
+ $C.change_column :post, :note, :text, comment: '备注'
614
+ #+end_example
615
+
616
+ The =change_column= method is also added to the class methods of the model class, so you can also call the
617
+ =change_column= method directly on the model class:
618
+
619
+ #+begin_example
620
+ Post.change_column :note, :text, comment: '备注'
621
+ #+end_example
622
+
623
+ ***** Remove Column
624
+
625
+ #+begin_example
626
+ $C.remove_column :post, :note
627
+ #+end_example
628
+
629
+ The =remove_column= method is also added to the class methods of the model class, so you can also call the
630
+ =remove_column= method directly on the model class:
631
+
632
+ #+begin_example
633
+ Post.remove_column :note
634
+ #+end_example
635
+
636
+ ***** Drop Table
637
+
638
+ #+begin_example
639
+ $C.drop_table :post
640
+ #+end_example
641
+
642
+ The =drop_table= method is also added to the class methods of the model class, so you can also call the
643
+ =drop_table= method directly on the model class:
644
+
645
+ #+begin_example
646
+ Post.drop_table
647
+ #+end_example
648
+
649
+ ***** Add Index
650
+
651
+ #+begin_example
652
+ ARQL ❯ $C.add_index :post, :name
653
+ ARQL ❯ $C.add_index(:accounts, [:branch_id, :party_id], unique: true, name: 'by_branch_party')
654
+ #+end_example
655
+
656
+ The =add_index= method is also added to the class methods of the model class, so you can also call the
657
+ =add_index= method directly on the model class:
658
+
659
+ #+begin_example
660
+ Post.add_index :name
661
+ Post.add_index [:branch_id, :party_id], unique: true, name: 'by_branch_party'
662
+ #+end_example
663
+
664
+ **** Kernel Extensions
665
+
666
+ The functions under the =Kernel= module can be called directly like built-in functions without specifying the module name.
667
+ The following are the =Kernel= methods extended by Arql:
668
+
669
+ Pry has built-in =show-source= (alias =$= ) and =show-doc= (alias =?= ) commands to view the source code and documentation of methods. You can view the documentation of a method using =show-doc=. For example:
670
+
671
+
672
+ #+BEGIN_EXAMPLE
673
+ ARQL ❯ ? create_table
674
+ #+END_EXAMPLE
675
+
676
+
677
+ ***** =create_table=
678
+ #+BEGIN_EXAMPLE
679
+ create_table :post, id: false, primary_key: :id do |t|
680
+ t.column :id, :bigint, precison: 19, comment: 'ID'
681
+ t.column :name, :string, comment: '名称'
682
+ t.column :gmt_created, :datetime, comment: '创建时间'
683
+ t.column :gmt_modified, :datetime, comment: '最后修改时间'
684
+ end
685
+ #+END_EXAMPLE
686
+ ***** =create_join_table=
687
+ #+BEGIN_EXAMPLE
688
+ create_join_table :products, :categories do |t|
689
+ t.index :product_id
690
+ t.index :category_id
691
+ end
692
+ #+END_EXAMPLE
693
+ ***** =drop_table=
694
+ #+BEGIN_EXAMPLE
695
+ drop_table :post
696
+ #+END_EXAMPLE
697
+ ***** =drop_join_table=
698
+ #+BEGIN_EXAMPLE
699
+ drop_join_table :products, :categories
700
+ #+END_EXAMPLE
701
+ ***** =rename_table=
702
+ #+BEGIN_EXAMPLE
703
+ rename_table :post, :posts
704
+ #+END_EXAMPLE
705
+
706
+ ***** =print_tables=
707
+
708
+ Arql provides a =print_tables= method that exports information about all tables in the current database as:
709
+
710
+ + markdown table format: ~print_tables(:md)~
711
+ + org-mode table format: ~print_tables(:org)~
712
+ + create table SQL: ~print_tables(:sql)~
713
+
714
+ **** Model Class Methods Extensions
715
+
716
+ Arql adds some class methods to the model class for creating, modifying, and deleting columns, indexes, and other
717
+ operations on tables. These methods can be called directly on the model class without the need to call them
718
+ through an instance object of the =ActiveRecord::Migration= class.
719
+
720
+ Pry has built-in =show-source= (alias =$= ) and =show-doc= (alias =?= ) commands to view the source code and
721
+ documentation of methods. You can view the documentation of a method using =show-doc=. For example:
722
+
723
+ #+BEGIN_EXAMPLE
724
+ ARQL ❯ ? Student.add_column
725
+ #+END_EXAMPLE
726
+
727
+ ***** =add_column=
728
+ #+BEGIN_EXAMPLE
729
+ Student.add_column :note, :text, comment: '备注'
730
+ #+END_EXAMPLE
731
+
732
+ ***** =change_column=
733
+ #+BEGIN_EXAMPLE
734
+ Student.change_column :note, :string, comment: '备注'
735
+ #+END_EXAMPLE
736
+
737
+ ***** =remove_column=
738
+ #+BEGIN_EXAMPLE
739
+ Student.remove_column :note
740
+ #+END_EXAMPLE
741
+
742
+ ***** =add_index=
743
+ #+BEGIN_EXAMPLE
744
+ Student.add_index :name
745
+ Student.add_index [:branch_id, :party_id], unique: true, name: 'by_branch_party'
746
+ #+END_EXAMPLE
747
+
748
+ ***** =change_column_comment=
749
+ #+BEGIN_EXAMPLE
750
+ Student.change_column_comment :note, '备注'
751
+ #+END_EXAMPLE
752
+
753
+ ***** =change_column_default=
754
+ #+BEGIN_EXAMPLE
755
+ Student.change_column_default :note, '默认值'
756
+ #+END_EXAMPLE
757
+
758
+ ***** =rename_column=
759
+ #+BEGIN_EXAMPLE
760
+ Student.rename_column :note, :remark
761
+ #+END_EXAMPLE
762
+
763
+ ***** =rename_table=
764
+ #+BEGIN_EXAMPLE
765
+ Student.rename_table :seitou
766
+ #+END_EXAMPLE
767
+
768
+ ***** =change_table_comment=
769
+ #+BEGIN_EXAMPLE
770
+ Student.change_table_comment from: '', to: '学生表'
771
+ #+END_EXAMPLE
772
+
773
+ ***** =drop_table=
774
+ #+BEGIN_EXAMPLE
775
+ Student.drop_table
776
+ #+END_EXAMPLE
777
+
778
+ ***** =remove_index=
779
+ #+BEGIN_EXAMPLE
780
+ Student.remove_index :age
781
+ Student.remove_index name: 'by_branch_party'
782
+ #+END_EXAMPLE
783
+
784
+ ***** =table_comment=
785
+ #+BEGIN_EXAMPLE
786
+ Student.table_comment
787
+ #+END_EXAMPLE
788
+
789
+ ***** =indexes=
790
+ #+BEGIN_EXAMPLE
791
+ Student.indexes
792
+ #+END_EXAMPLE
793
+
794
+ **** Read and Write Excel and CSV Files
795
+
796
+ Arql integrates two Excel libraries, =roo= and =caxlsx= to provide methods for parsing and generating Excel files.
797
+ Arql also provides methods for reading and writing CSV files.
798
+
799
+ ***** Parse Excel
800
+
801
+ Arql adds a =parse_excel= method to the =Kernel= module, which can be used to parse Excel files. For example:
802
+
803
+ #+BEGIN_EXAMPLE
804
+ ARQL ❯ parse_excel 'path/to/excel.xlsx'
805
+ #+END_EXAMPLE
806
+
807
+ You can use =~/= in the file path to represent the user's home directory, and Arql will automatically expand it.
808
+
809
+ You can also call the =parse_excel= method on a String object representing a file path:
810
+
811
+ #+BEGIN_EXAMPLE
812
+ ARQL ❯ 'path/to/excel.xlsx'.parse_excel
813
+ #+END_EXAMPLE
814
+
815
+ The =parse_excel= method returns a Hash object, where the key is the sheet name and the value is the data of the
816
+ sheet, which is a two-dimensional array. For example:
817
+
818
+ #+BEGIN_EXAMPLE
819
+ {
820
+ 'Sheet1' => [
821
+ ['A1', 'B1', 'C1'],
822
+ ['A2', 'B2', 'C2'],
823
+ ['A3', 'B3', 'C3']
824
+ ],
825
+ 'Sheet2' => [
826
+ ['A1', 'B1', 'C1'],
827
+ ['A2', 'B2', 'C2'],
828
+ ['A3', 'B3', 'C3']
829
+ ]
830
+ }
831
+ #+END_EXAMPLE
832
+
833
+ ***** Generate Excel
834
+
835
+ Arql adds a =write_excel= method to Hash / Array / ActiveRecord::Relation / ActiveRecord::Base objects, which can
836
+ be used to generate Excel files:
837
+
838
+
839
+ ****** Genrate Excel from =Hash= Object
840
+
841
+ #+BEGIN_EXAMPLE
842
+ ARQL ❯ obj.write_excel 'path/to/excel.xlsx'
843
+ #+END_EXAMPLE
844
+
845
+ =Hash#write_excel= requires that the key of the Hash object is the sheet name and the value is the data of the
846
+ sheet. The type of the value can be:
847
+
848
+ + An array, where the elements of the array can be:
849
+ + An array, representing a row of data
850
+ + A Hash object, representing a row of data, where the key is the column name and the value is the column value
851
+ + An =ActiveRecord::Base= object, representing a row of data
852
+ + A Hash object, which contains two key-value pairs:
853
+ + =:fields=, an array representing the column names
854
+ + =:data=, a two-dimensional array representing the data
855
+
856
+ ****** Generate Excel from =Array= Object
857
+
858
+ #+BEGIN_EXAMPLE
859
+ ARQL ❯ obj.write_excel 'path/to/excel.xlsx', :name, :age, :gender, sheet_name: '订单数据'
860
+ #+END_EXAMPLE
861
+
862
+ Where:
863
+
864
+ + =:name, :age, :gender= These parameters are column names. If not specified, the column names will be determined
865
+ based on the first element of the array:
866
+ - If the element is an ActiveRecord::Base object, all attribute names of the object (i.e., the database field
867
+ list) will be used as column names
868
+ - If the element is a Hash object, all keys of the Hash will be used as column names
869
+ + =sheet_name= Specifies the sheet name. If not specified, the default sheet name =Sheet1= will be used
870
+
871
+ Each element of the Array object represents a row of data. =Array#write_excel= requires that each element of the
872
+ Array object:
873
+
874
+ + An =ActiveRecord::Base= object
875
+ + A =Hash= object, representing a row of data, where the key is the column name and the value is the column value
876
+ + An array, representing a row of data
877
+
878
+ ****** Generate Excel from =ActiveRecord::Base= Object
879
+
880
+ #+BEGIN_EXAMPLE
881
+ ARQL ❯ Student.find(123).write_excel 'path/to/excel.xlsx', sheet_name: '学生数据'
882
+ #+END_EXAMPLE
883
+
884
+ The =write_excel= method of =ActiveRecord::Base= actually wraps the =ActiveRecord::Base= object into an =Array= object with
885
+ only one element, and then calls the =write_excel= method of Array.
886
+
887
+ ****** Generate Excel from =ActiveRecord::Relation= Object
888
+
889
+ #+BEGIN_EXAMPLE
890
+ ARQL ❯ Student.where(gender: 'M').write_excel 'path/to/excel.xlsx', sheet_name: '男学生'
891
+ #+END_EXAMPLE
892
+
893
+ The =write_excel= method of =ActiveRecord::Relation= actually converts the =ActiveRecord::Relation= object into an Array
894
+ object, and then calls the =write_excel= method of =Array=.
895
+
896
+ ***** Parse CSV
897
+
898
+ Arql provides the =parse_csv= method, which can be used to parse CSV files:
899
+
900
+ #+BEGIN_EXAMPLE
901
+ ARQL ❯ parse_csv 'path/to/csv.csv'
902
+ #+END_EXAMPLE
903
+
904
+
905
+ The =parse_csv= method returns a CSV object in the standard library.
906
+
907
+ =parse_csv= can have the following optional parameters:
908
+
909
+ - =encoding=, specifies the encoding of the CSV file, which is =UTF-16= (with BOM) by default
910
+ - =headers=, specifies whether to include the header, which is =false= by default
911
+ - =col_sep=, specifies the column separator, which is =\t= by default
912
+ - =row_sep=, specifies the row separator, which is =\r\n= by default
913
+
914
+
915
+ (The default values above are actually the configurations used by Microsoft Office Excel when saving CSV files)
916
+
917
+
918
+ You can also call the =parse_csv= method on a String object representing the file path:
919
+
920
+ #+BEGIN_EXAMPLE
921
+ ARQL ❯ 'path/to/csv.csv'.parse_csv
922
+ #+END_EXAMPLE
923
+
924
+ ***** Generate CSV
925
+
926
+ Arql adds the =write_csv= method to =Array= / =ActiveRecord::Relation= / =ActiveRecord::Base= objects, which can be used to
927
+ generate CSV files:
928
+
929
+ ****** Generate CSV from =Array= Object
930
+
931
+ #+BEGIN_EXAMPLE
932
+ ARQL ❯ obj.write_csv 'path/to/csv.csv', :name, :age, :gender, sheet_name: '订单数据'
933
+ #+END_EXAMPLE
934
+
935
+ The usage is similar to the write_excel method of =Array= objects.
936
+
937
+
938
+ ****** Generate CSV from =ActiveRecord::Base= Object
939
+
940
+ #+BEGIN_EXAMPLE
941
+ ARQL ❯ Student.find(123).write_csv 'path/to/csv.csv', sheet_name: '学生数据'
942
+ #+END_EXAMPLE
943
+
944
+ The usage is similar to the =write_excel= method of =ActiveRecord::Base= objects.
945
+
946
+ ****** Generate CSV from =ActiveRecord::Relation= Object
947
+
948
+
949
+ #+BEGIN_EXAMPLE
950
+ ARQL ❯ Student.where(gender: 'M').write_csv 'path/to/csv.csv', sheet_name: '男学生'
951
+ #+END_EXAMPLE
952
+
953
+
954
+ The usage is similar to the =write_excel= method of =ActiveRecord::Relation= objects.
955
+
956
+ **** dump data from database
957
+
958
+ Note: Only MySQL databases are supported
959
+
960
+ Arql adds the =dump= method to =Array= / =ActiveRecord::Base= / =ActiveRecord::Relation= objects, which can be used to
961
+ export data to SQL files:
962
+
963
+
964
+ ***** Dump data from =Array= Object
965
+
966
+ #+BEGIN_EXAMPLE
967
+ ARQL ❯ obj.dump 'path/to/dump.sql', batch_size: 5000
968
+ #+END_EXAMPLE
969
+
970
+
971
+ Each element of the =Array= object must be an =ActiveRecord::Base= object
972
+
973
+ The =batch_size= parameter specifies the data queried in each batch, with a default value of 500
974
+
975
+ ***** Dump data from =ActiveRecord::Base= Object
976
+
977
+ #+BEGIN_EXAMPLE
978
+ ARQL ❯ Student.find(123).dump 'path/to/dump.sql', batch_size: 5000
979
+ #+END_EXAMPLE
980
+
981
+
982
+ The =dump= method of =ActiveRecord::Base= objects actually wraps the =ActiveRecord::Base= object into an =Array= object
983
+ with only one element, and then calls the =dump= method of =Array=.
984
+
985
+ ***** Dump data from =ActiveRecord::Relation= Object
986
+
987
+ #+BEGIN_EXAMPLE
988
+ ARQL ❯ Student.where(gender: 'M').dump 'path/to/dump.sql', batch_size: 5000
989
+ #+END_EXAMPLE
990
+
991
+
992
+ The =dump= method of =ActiveRecord::Relation= objects actually converts the =ActiveRecord::Relation= object into an =Array= object,
993
+ and then calls the =dump= method of Array.
994
+
995
+
996
+ ***** Use the =dump= class method of =ActiveRecord::Base=
997
+
998
+ #+BEGIN_EXAMPLE
999
+ ARQL ❯ Student.dump 'path/to/dump.sql', no_create_table: false
1000
+ #+END_EXAMPLE
1001
+
1002
+ This method will export all data in the Student table to the SQL file using the =mysqldump= command.
1003
+
1004
+ The =no_create_table= parameter specifies whether to include the create table statement in the SQL file, with a default value of =false=.
1005
+
1006
+
1007
+
1008
+ ***** Use the dump method on the global connection object =$C=
1009
+
1010
+ #+BEGIN_EXAMPLE
1011
+ ARQL ❯ $C.dump 'path/to/dump.sql', no_create_db: false
1012
+ #+END_EXAMPLE
1013
+
1014
+
1015
+ This method will export the data of all tables in the current database to the SQL file using the =mysqldump= command.
1016
+
1017
+ The =no_create_db= parameter specifies whether to include the create database statement in the SQL file, with a default value of =false=.
1018
+
1019
+
1020
+ **** Plot
1021
+
1022
+ Arql integrates the youplot library of Ruby and adds some methods to Array that can be used to draw charts:
1023
+
1024
+ + =barplot=
1025
+ + =countplot=
1026
+ + =histo=
1027
+ + =lineplot=
1028
+ + =lineplots=
1029
+ + =scatter=
1030
+ + =density=
1031
+ + =boxplot=
1032
+
1033
+ Example:
1034
+
1035
+ Count plot:
1036
+
1037
+ #+BEGIN_EXAMPLE
1038
+ ARQL@demo247(main) [44] ❯ Student.pluck(:gender)
1039
+ => ["M", "M", "M", "M", "M", "M", "M", "F", "M", "F", "M", "M", "M", "M", "M"]
1040
+ ARQL@demo247(main) [45] ❯ Student.pluck(:gender).countplot
1041
+ ┌ ┐
1042
+ M ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 13.0
1043
+ F ┤■■■■■ 2.0
1044
+ └ ┘
1045
+ #+END_EXAMPLE
1046
+
1047
+ Histo plot:
1048
+
1049
+ #+BEGIN_EXAMPLE
1050
+ ARQL@jicai.dev(main) [18] ❯ Order.last(20).pluck(:order_sum)
1051
+ => [0.21876e5, 0.336571e5, 0.1934e5, 0.966239e4, 0.38748e3, 0.31092e4, 0.483e5, 0.445121e5, 0.1305e4, 0.2296e6, 0.943e5, 0.352e4, 0.3756e5, 0.323781e5, 0.7937622e5, 0.982e4, 0.338393e5, 0.316597e5, 0.213678e5, 0.336845e5]
1052
+ ARQL@jicai.dev(main) [19] ❯ Order.last(20).pluck(:order_sum).histo
1053
+ ┌ ┐
1054
+ [ 0.0, 50000.0) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 17
1055
+ [ 50000.0, 100000.0) ┤▇▇▇▇ 2
1056
+ [100000.0, 150000.0) ┤ 0
1057
+ [150000.0, 200000.0) ┤ 0
1058
+ [200000.0, 250000.0) ┤▇▇ 1
1059
+ └ ┘
1060
+ Frequency
1061
+
1062
+ #+END_EXAMPLE
1063
+
1064
+ **** =String=
1065
+
1066
+ ***** =Srting#p=
1067
+
1068
+ The definition of the =p= method is as follows:
1069
+
1070
+ #+begin_example
1071
+ class String
1072
+ def p
1073
+ puts self
1074
+ end
1075
+ end
1076
+ #+end_example
1077
+
1078
+
1079
+ =​"hello".p= is equivalent to =puts "hello"​=.
1080
+
1081
+ ***** =String#parse=
1082
+
1083
+ For a string representing a file path, you can call the =parse= method to parse Excel, CSV, and JSON files based
1084
+ on the file extension in the file path.
1085
+
1086
+ #+BEGIN_EXAMPLE
1087
+ excel = 'path/to/excel.xlsx'.parse
1088
+ csv = 'path/to/csv.csv'.parse
1089
+ json = 'path/to/json.json'.parse
1090
+ #+END_EXAMPLE
1091
+
1092
+ **** =ID=
1093
+
1094
+ Arql provides an ID class for generating snowflake algorithm IDs and UUIDs.
1095
+
1096
+ #+BEGIN_EXAMPLE
1097
+ id = ID.long # 生成一个雪花算法 ID
1098
+ id = ID.uuid # 生成一个 UUID
1099
+ #+END_EXAMPLE
1100
+
1101
+ **** Ransack
1102
+
1103
+ Arql integrates Ransack:
1104
+
1105
+ #+BEGIN_EXAMPLE
1106
+ Student.ransack(name_cont: 'Tom').result # 模糊查询名字中包含 'Tom' 的学生
1107
+ Student.ransack(name_start: 'Tom').result # 模糊查询名字以 'Tom' 开头的学生
1108
+ #+END_EXAMPLE
1109
+
1110
+ *** Emacs Org Babel Integration
1111
+
1112
+ Here is an [[https://github.com/lululau/spacemacs-layers/blob/master/ob-arql/local/ob-arql/ob-arql.el][ob-arql]], which is used to integrate Emacs org babel.
1113
+
1114
+ ** Guides and Tips
1115
+ *** [[./define-associations.org][Define Associations in Initializer File]]
1116
+ *** [[./initializer-structure.org][Put Initialization Code for Different Environments in Different Files]]
1117
+ *** [[./helper-for-datetime-range-query.org][Define Convenient Methods for Quickly Querying by Time]]
1118
+ *** [[./auto-set-id-before-save.org][Automatically Set ID for New Objects Before Saving]]
1119
+ *** [[./custom-configurations.org][Custom Configuration Items in the Configuration File]]
1120
+ *** [[./sql-log.org][Automatically Record SQL Logs and REPL Input History]]
1121
+ *** [[./fuzzy-field-query.org][Fuzzy Field Name Query]]
1122
+ *** [[./oss-files.org][OSS Data Download and View]]
1123
+ *** Use Arql to query SQLite3 database file
1124
+
1125
+ You can use Arql to view SQLite3 database files, for example:
1126
+
1127
+ #+BEGIN_EXAMPLE
1128
+ arql -d db/development.sqlite3
1129
+ #+END_EXAMPLE
1130
+
1131
+ *** Find fields by name or comment
1132
+
1133
+ When we are familiar with a project, we often encounter the following situation: we know the name or comment of a
1134
+ field, but we do not know the corresponding table name and field name. At this time, we can use the following method
1135
+ to find:
1136
+
1137
+ #+BEGIN_SRC ruby
1138
+ puts model_classes.flat_map { |m| m.columns.select {|c| c.name =~ /amount/ || c.comment =~ /金额/ }.map {|c| "Table: #{m.table_name}, Column: #{c.name} (#{c.comment})"} }
1139
+
1140
+ # 输出:
1141
+ # Table: order, Column: entry_amount (订单金额)
1142
+ # Table: sub_order, Column: entry_price (金额)
1143
+ #+END_SRC
1144
+
1145
+ ** Development
1146
+
1147
+ After checking out the code, run =bin/setup= to install dependencies. You can also run =bin/console= for an
1148
+ interactive prompt that will allow you to experiment.
1149
+
1150
+ To install this gem onto your local machine, run =bundle exec rake install=. To release a new version, update the
1151
+ version number in =version.rb=, and then run =bundle exec rake release=, which will create a git tag for the
1152
+ version, push git commits and tags, and push the =.gem= file to [[https://rubygems.org][rubygems.org]].
1153
+
1154
+
1155
+ ** Contributing
1156
+
1157
+ Bug reports and pull requests are welcome on GitHub at https://github.com/lululau/arql. This project is intended to
1158
+ be a safe, welcoming space for collaboration, and contributors are expected to adhere to the
1159
+ [[https://github.com/lululau/arql/blob/master/CODE_OF_CONDUCT.md][Code of Conduct]].
1160
+
1161
+
1162
+ ** License
1163
+
1164
+ The gem is available as open source under the terms of the [[https://opensource.org/licenses/MIT][MIT License]].
1165
+
1166
+ ** Code of Conduct
1167
+
1168
+
1169
+ Everyone interacting in the Arql project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow
1170
+ the [[https://github.com/lululau/arql/blob/master/CODE_OF_CONDUCT.md][Code of Conduct]].