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-zh_CN.org ADDED
@@ -0,0 +1,1096 @@
1
+ * Arql
2
+
3
+ Arql是一个简单的工具性 Gem,它将 Rails ActiveRecord 和 Pry 结合在一起,并添加了有用的 Pry 命令。它可以根据数据库表的信
4
+ 息自动定义模型类。如果你是 Ruby 用户,你可以将这个 Arql 用作你的数据库查询工具。
5
+
6
+ ** 依赖
7
+
8
+ + Ruby 2.6.0 或更高版本
9
+ + 对于不同类型的数据库,需要安装相应的数据库适配器或客户端二进制库:
10
+ - MySQL: 根据你的操作系统,你可能需要安装: =libmariadb-dev= 、 =libmysqlclient-dev= 、 =mysql-devel=
11
+ =default-libmysqlclient-dev= ; 请参阅发行版的软件包指南以查找特定的软件包;或者参考 [[https://github.com/brianmario/mysql2][mysql2 的文档]]
12
+ - SQLite3: 不需要安装任何额外的库
13
+ - PostgreSQL: ~gem install pg~
14
+ - Oracle: ~gem install activerecord-oracle_enhanced-adapter~
15
+ - SQL Server: ~gem install activerecord-sqlserver-adapter~
16
+
17
+ ** 安装
18
+
19
+ 执行:
20
+
21
+ #+begin_example
22
+ $ gem install arql
23
+ #+end_example
24
+
25
+ 如果遇到系统权限问题,请尝试使用 sudo:
26
+
27
+ #+begin_example
28
+ $ sudo gem install arql
29
+ #+end_example
30
+
31
+ ** 使用方法
32
+
33
+ *** 命令行选项
34
+
35
+ #+begin_example
36
+ Usage: arql [options] [ruby file]
37
+
38
+ 如果既没有指定 [ruby file] 也没有指定 -E 选项,并且 STDIN 是一个 tty,将启动 Pry REPL,
39
+ 否则将运行指定的 ruby file 或 -E 选项值或从 STDIN 读取的 ruby 代码,并且不会启动 REPL
40
+
41
+ -c, --conf=CONFIG_FILE 指定配置文件,默认为 $HOME/.arql.yml 或 $HOME/.arql.d/init.yml
42
+ -i, --initializer=INITIALIZER 指定初始化 Ruby 文件,默认为 $HOME/.arql.rb 或 $HOME/.arql.d/init.rb
43
+ -e, --env=ENVIRON 指定配置环境
44
+ -a, --db-adapter=DB_ADAPTER 指定数据库适配器,默认为 sqlite3
45
+ -h, --db-host=DB_HOST 指定数据库主机
46
+ -p, --db-port=DB_PORT 指定数据库端口
47
+ -d, --db-name=DB_NAME 指定数据库名称
48
+ -u, --db-user=DB_USER 指定数据库用户
49
+ -P, --db-password=DB_PASSWORD 指定数据库密码
50
+ -n, --db-encoding=DB_ENCODING 指定数据库编码,默认为 utf8
51
+ -o, --db-pool=DB_POOL 指定数据库连接池大小,默认为 5
52
+ -H, --ssh-host=SSH_HOST 指定 SSH 主机
53
+ -O, --ssh-port=SSH_PORT 指定 SSH 端口
54
+ -U, --ssh-user=SSH_USER 指定 SSH 用户
55
+ -W, --ssh-password=SSH_PASSWORD 指定 SSH 密码
56
+ -L, --ssh-local-port=SSH_LOCAL_PORT 指定本地 SSH 代理端口
57
+ -E, --eval=CODE 执行代码
58
+ -S, --show-sql 在 STDOUT 上显示 SQL
59
+ -w, --write-sql=OUTPUT 将 SQL 写入 OUTPUT 文件
60
+ -A, --append-sql=OUTPUT 将 SQL 追加到 OUTPUT 文件
61
+ --help 打印帮助信息
62
+ #+end_example
63
+
64
+ **** =-c, --config=CONFIG_FILE=
65
+
66
+ 指定配置文件位置,默认为 =$HOME/.arql.yml= 或 =$HOME/.arql.d/init.yml= 。 配置文件通常与 Rails数据库配置文件相同,
67
+ 但有一些额外的配置选项,例如 =ssh= 选项等。 参考 =配置文件= 部分。
68
+
69
+ **** =-i, --initializer=INITIALIZER=
70
+
71
+ 指定一个 Ruby 源文件,Arql 定义 ActiveRecord 模型类之后执行此文件的代码,默认为 =$HOME/.arql.rb= 或者
72
+ =$HOME/.arql.d/init.rb= 。你可以在这个文件中为 ActiveRecord 模型类添加方法和关联关系定义。
73
+
74
+ **** =-e, --env=ENVIRON=
75
+
76
+ 指定一个在配置文件中的环境名称。
77
+
78
+ **** =-E, --eval=CODE=
79
+
80
+ 指定一个 Ruby 代码片段,如果指定了此选项,将不会启动 Pry REPL。
81
+
82
+ **** =-S, --show-sql=
83
+
84
+ arql 默认不显示 SQL 日志,使用此选项打开。
85
+
86
+ **** =-w, --write-sql=OUTPUT=
87
+
88
+ 你也可以使用此选项让 arql 将 SQL 日志写入文件。
89
+
90
+ **** =-A, --append-sql-OUTOUT=
91
+
92
+ 与 =-w= 类似,但是采用追加写入的方式,不会截断已有文件。
93
+
94
+ **** 数据库选项
95
+
96
+ 本节中描述的选项通常会在配置文件中配置,这些选项只是对应配置文件中的配置项的快捷方式,以便在 CLI 中直接修改某些配置项。
97
+
98
+ ***** -a, --db-adapter=DB_ADAPTER
99
+
100
+ 指定数据库适配器,可用值:
101
+
102
+ - =mysql2=
103
+ - =postgresql=
104
+ - =sqlite3=
105
+ - =sqlserver=
106
+ - =oracle_enhanced=
107
+
108
+ ***** -h, --db-host=DB_HOST
109
+
110
+ 指定数据库主机
111
+
112
+ ***** -p, --db-port=DB_PORT
113
+
114
+ 指定数据库端口
115
+
116
+ ***** -d, --db-name=DB_NAME
117
+
118
+ 指定数据库名称
119
+
120
+ ***** -u, --db-user=DB_USER
121
+
122
+ 指定数据库用户名
123
+
124
+ ***** -P, --db-password=DB_PASSWORD
125
+
126
+ 指定数据库密码
127
+
128
+ ***** -n, --db-encoding=DB_ENCODING
129
+
130
+ 指定数据库字符编码,默认为 =utf8=
131
+
132
+ ***** -o, --db-pool=DB_POOL
133
+
134
+ 指定数据库连接池大小,默认为 =5=
135
+
136
+ ***** -H, --ssh-host=SSH_HOST
137
+
138
+ 指定 SSH 主机, 当指定了 SSH 相关的选项时, arql 会建立 SSH 隧道,使用 SSH 隧道连接数据库。
139
+
140
+ ***** -O, --ssh-port=SSH_PORT
141
+
142
+ 指定 SSH 端口
143
+
144
+ ***** -U, --ssh-user=SSH_USER
145
+
146
+ 指定 SSH 用户名
147
+
148
+ ***** -W, --ssh-password=SSH_PASSWORD
149
+
150
+ 指定 SSH 密码
151
+
152
+ ***** -L, --ssh-local-port=SSH_LOCAL_PORT
153
+
154
+ 指定 SSH 本地端口,默认为一个 /随机/ 端口
155
+
156
+ *** 配置文件
157
+
158
+ 配置文件的路径默认为 =$HOME/.arql.yml= 或 =$HOME/.arql.d/init.yml= 。 配置文件通常与 Rails数据库配置文件相同,但有一
159
+ 些额外的配置选项:
160
+
161
+ 1. =created_at= : 一个包含 ActiveRecord =created_at= 字段的自定义列名的数组,默认值为 =created_at= ,如果指定了此项,创建时将使用当前时间戳填充列的值
162
+ 2. =updated_at= : 一个包含 ActiveRecord =updated_at= 字段的自定义列名的数组,默认值为 =updated_at= ,如果指定了此项,更新时将使用当前时间戳填充列的值
163
+ 3. =ssh.host= : ssh 主机, 可以使用 =ssh_config= 文件中的主机名,也可以是直接的 IP 地址或主机名
164
+ 4. =ssh.port= : ssh 端口,默认值为 =22=
165
+ 5. =ssh.user= : ssh 用户名
166
+ 6. =ssh.password= : ssh 密码
167
+ 7. =ssh.local_port= : ssh 本地端口
168
+ 8. =singularized_table_names=: 是否使用单数表名,默认为 =false=, 如果为 =false=, 则 =students= 表将定义为 =Student= 模型,如果为 =true=, 则 =students= 表将定义为 =Students= 模型
169
+
170
+ **** 配置文件示例
171
+
172
+ #+begin_example
173
+ default: &default
174
+ adapter: mysql2
175
+ encoding: utf8
176
+ created_at: ["gmt_created"]
177
+ updated_at: ["gmt_modified"]
178
+ singularized_table_names: true
179
+
180
+ local:
181
+ <<: *default
182
+ username: root
183
+ database: blog
184
+ password:
185
+ socket: /tmp/mysql.sock
186
+
187
+ dev:
188
+ <<: *default
189
+ host: devdb.mycompany.com
190
+ port: 3306
191
+ username: root
192
+ password: 123456
193
+ database: blog
194
+ ssh:
195
+ host: dev.mycompany.com
196
+ port: 22
197
+ user: deploy
198
+ password: 12345678
199
+ local_port: 3307
200
+ #+end_example
201
+
202
+ 示例中定义了一个通用的配置项 =default= ,以及两个具体的数据库环境 =local= 和 =dev= 。 =local= 和 =dev= 同 =<<:
203
+ *default= 的方式继承了 =default= 的配置项。
204
+
205
+ 执行命令 =arql -e dev= 时,arql 会使用配置文件中的 =dev= 配置; 执行命令 =arql -e local= 时,arql 会使用配置文件中的
206
+ =local= 配置。
207
+
208
+ =dev= 环境使用了 SSH 隧道,连接到 =devdb.mycompany.com= 数据库时,会先建立一个 SSH 隧道到 =dev.mycompany.com= ,然
209
+ 后通过 SSH 隧道连接到数据库。
210
+
211
+ *** 作为 REPL 使用
212
+
213
+ 如果既没有指定 =[ruby file]= 也没有指定 =-E= 选项,并且 STDIN 是一个 =tty= ,arql 会启动一个 Pry REPL。例如执行:
214
+
215
+ #+BEGIN_EXAMPLE
216
+ arql -e dev
217
+ #+END_EXAMPLE
218
+
219
+
220
+ Arql 提供了一些 Pry 命令:
221
+
222
+ **** =info=
223
+
224
+ =info= 命令打印当前的数据库连接信息和 SSH 代理信息,例如:
225
+
226
+ #+begin_example
227
+ Database Connection Information:
228
+ Host:
229
+ Port:
230
+ Username: root
231
+ Password:
232
+ Database: test
233
+ Adapter: mysql2
234
+ Encoding: utf8
235
+ Pool Size: 5
236
+ #+end_example
237
+
238
+ **** =m= 或者 =l=
239
+
240
+ =m= (或者 =l= ) 命令打印所有表名及对应的模型类名和缩写类名,例如:
241
+
242
+ #+begin_example
243
+ +--------------------+------------------+------+---------+
244
+ | Table Name | Model Class | Abbr | Comment |
245
+ +--------------------+------------------+------+---------+
246
+ | post | Post | P | 帖子 |
247
+ | org | Org | O | 组织 |
248
+ | user_org | UserOrg | UO | |
249
+ | student | Student | S | 学生 |
250
+ | course | Course | C | |
251
+ | score | Score | S2 | |
252
+ | users | Users | U | |
253
+ | posts | Posts | P2 | |
254
+ | authors | Authors | A | |
255
+ +--------------------+------------------+------+---------+
256
+ #+end_example
257
+
258
+ 其中:
259
+
260
+ - =Table Name= : 表名
261
+ - =Model Class= : 模型类名
262
+ - =Abbr= : 缩写类名
263
+ - =Comment= : 注释
264
+
265
+ =m= / =l= 命令还可以接受一个参数,用于通过表名或表注释来对列表进行过滤, 例如:
266
+
267
+ =m perm= 只会列出表名或表注释中包含 =perm= 的表;如果要使用正则表达式匹配,可以使用 =m /perm/i= 来进行匹配。
268
+
269
+ **** =t=
270
+
271
+ =t= 命令接受一个表名或模型类名作为参数,打印表的定义信息,例如:
272
+
273
+ 执行 =t Person= 命令会打印 =person= 表的定义信息:
274
+
275
+ #+begin_example
276
+ Table: person
277
+ +----|------------|------------------|-----------|-------|-----------|-------|---------|----------|---------+
278
+ | PK | Name | SQL Type | Ruby Type | Limit | Precision | Scale | Default | Nullable | Comment |
279
+ +----|------------|------------------|-----------|-------|-----------|-------|---------|----------|---------+
280
+ | Y | id | int(11) unsigned | integer | 4 | | | | false | |
281
+ | | name | varchar(64) | string | 64 | | | | true | |
282
+ | | age | int(11) | integer | 4 | | | | true | |
283
+ | | gender | int(4) | integer | 4 | | | | true | |
284
+ | | grade | int(4) | integer | 4 | | | | true | |
285
+ | | blood_type | varchar(4) | string | 4 | | | | true | |
286
+ +----|------------|------------------|-----------|-------|-----------|-------|---------|----------|---------+
287
+ #+end_example
288
+
289
+ 另外, =t= 同时也是模型类的一个类方法,执行 =Person.t= 会同样会打印出上述信息。
290
+
291
+ 其中:
292
+
293
+ - =PK= : 是否为主键
294
+ - =Name= : 列名
295
+ - =SQL Type= : 数据库类型
296
+ - =Ruby Type= : Ruby 类型
297
+ - =Limit= : 长度限制
298
+ - =Precision= : 精度
299
+ - =Scale= : 小数位数
300
+ - =Default= : 默认值
301
+ - =Nullable= : 是否可为空
302
+ - =Comment= : 注释
303
+
304
+ **** =vd=
305
+
306
+ =t= 命令在终端中以表格的形式打印表的定义信息,缺点是如果表的列数过多,会导致表格这行,不方便查看。而 =vd=
307
+ (visidata) 是一个使用 Python 编写的终端数据分析工具,可以在终端中以表格的形式打印表的定义信息,但是支持水平滚动,方
308
+ 便查看。
309
+
310
+ 如果要使用 Arql 的 =vd= 命令,需要先安装 =visidata=:
311
+
312
+ #+begin_src sh
313
+ pipx install visidata
314
+ #+end_src
315
+
316
+ =vd= 命令和用法和 =t= 命令基本相同,另外, =Array= / =ActiveRecord::Base= 等对象也可以使用 =vd= 方法。
317
+
318
+ **** =show-sql= / =hide-sql=
319
+
320
+ 这对命令可以切换 Pry REPL 中 SQL 日志的显示。
321
+
322
+ 默认情况下,SQL 日志是不显示的:
323
+
324
+ #+begin_example
325
+ ARQL@demo247(main) [2] ❯ Student.count
326
+ => 0
327
+ #+end_example
328
+
329
+ 而打开 SQL 日志后,会显示每次执行的 SQL 语句:
330
+
331
+ #+begin_example
332
+ ARQL@demo247(main) [3] ❯ show-sql
333
+ ARQL@demo247(main) [4] ❯ Student.count
334
+ D, [2024-04-07T13:31:32.053903 #20440] DEBUG -- : Student Count (29.8ms) SELECT COUNT(*) FROM `student`
335
+ => 0
336
+ #+end_example
337
+
338
+ **** =reconnect=
339
+
340
+ =reconnect= 命令用于重新连接当前的数据库连接。当因网络原因导致连接断开时,可以使用该命令重新连接。重新连接,当前的
341
+ Pry 会话中的对象不会丢失。 =reconnect= 首先会判断当前连接是否还是有效的,如果是有效的,则不会重新连接;如果
342
+ =reconnect= 对连接的有效性判断错误,可以使用 =reconnect!= 命令强制重新连接。
343
+
344
+ **** =redefine=
345
+
346
+ =redefine= 命令用于重新定义 ActiveRecord 模型类,根据数据库表的信息重新生成模型类。对于在 =init.rb= 中添加了新的关
347
+ 系定义,想使新定义的关系在当前 Pry 会话中生效,可以使用 =redefine= 命令。
348
+
349
+ **** 沙盒模式
350
+
351
+ =sandbox-enter= 命令用于开启沙盒模式。在沙盒模式下,所有的数据库操作都会在事务中执行,该事务不会自动提交,需要手动提交或回滚。
352
+
353
+ 1. 开启沙盒模式:
354
+ #+begin_example
355
+ ARQL@demo247(main) [6] ❯ sandbox-enter
356
+ ARQL@demo247 [sandbox] (main) [7] ❯
357
+ #+end_example
358
+ 2. 退出沙盒模式:
359
+ #+begin_example
360
+ ARQL@demo247 [sandbox] (main) [7] ❯ sandbox-quit
361
+ begin_transaction callbacks removed.
362
+ You still have open 1 transactions open, don't forget commit or rollback them.
363
+ #+end_example
364
+ 3. 提交事务:
365
+ #+begin_example
366
+ ARQL@demo247(main) [7] ❯ $C.commit_transaction
367
+ #+end_example
368
+ 4. 回滚事务:
369
+ #+begin_example
370
+ ARQL@demo247(main) [7] ❯ $C.rollback_transaction
371
+ #+end_example
372
+
373
+
374
+
375
+ *** 作为代码解释器使用
376
+
377
+ 如果指定了一个 Ruby 文件作为命令行参数,或者使用了 =-E= 选项,或者 STDIN 不是一个 =tty= ,那么 Arql 不会启动 Pry,而是直
378
+ 接执行指定的文件或代码片段(或从标准输入读取代码)。在执行代码片段之前,会先加载模型类定义。你可以把这种用法看作类似
379
+ 是 =rails= 的 =runner= 子命令。
380
+
381
+ **** 使用 =-E= 选项
382
+
383
+ 通过 =-E= 选项可以直接执行代码片段,而不启动 Pry:
384
+
385
+ #+begin_example
386
+ $ arql -e dev -E 'puts Person.count'
387
+ #+end_example
388
+
389
+ **** 指定 Ruby 文件作为命令行参数
390
+
391
+ 通过指定 Ruby 文件作为命令行参数,可以直接执行 Ruby 文件中的代码:
392
+
393
+ =test.rb=:
394
+
395
+ #+BEGIN_SRC ruby
396
+ puts Person.count
397
+ #+END_SRC
398
+
399
+ #+begin_example
400
+ $ arql -e dev test.rb
401
+ #+end_example
402
+
403
+ **** 从标准输入读取代码
404
+
405
+ 从标准输入读取代码,可以直接执行代码片段:
406
+
407
+ #+begin_example
408
+ $ echo 'puts Person.count' | arql -e dev
409
+ #+end_example
410
+
411
+ *** 额外的扩展方法
412
+ **** =to_insert_sql= / =to_upsert_sql=
413
+
414
+ 可以在任何 ActiveRecord 模型实例上调用 =to_insert_sql= / =to_upsert_sql= 方法,获取该对象的插入或更新 SQL 语句。
415
+ 这两个方法也可以在包含 ActiveRecord 模型实例对象的数组对象上调用。
416
+
417
+ #+begin_example
418
+ ARQL ❯ Person.all.to_a.to_insert_sql
419
+ => "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`;"
420
+ #+end_example
421
+
422
+ **** =to_create_sql=
423
+
424
+ 可以在任何 ActiveRecord 模型类上调用 =to_create_sql= 方法,获取该模型类对应的表的创建 SQL 语句。
425
+
426
+ #+begin_example
427
+ ARQL@demo247(main) [16] ❯ puts Post.to_create_sql
428
+ D, [2024-04-07T14:15:11.106693 #20440] DEBUG -- : SQL (24.9ms) show create table post
429
+ CREATE TABLE `post` (
430
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
431
+ `name` varchar(256) DEFAULT NULL,
432
+ `gender` varchar(256) DEFAULT NULL,
433
+ `phone` varchar(256) DEFAULT NULL,
434
+ `id_no` varchar(256) DEFAULT NULL,
435
+ `note` varchar(256) DEFAULT NULL,
436
+ `gmt_created` datetime NOT NULL COMMENT '创建时间',
437
+ `gmt_modified` datetime NOT NULL COMMENT '最后修改时间',
438
+ PRIMARY KEY (`id`),
439
+ KEY `index_post_on_name` (`name`)
440
+ ) ENGINE=InnoDB AUTO_INCREMENT=83 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
441
+ #+end_example
442
+
443
+ **** =t=
444
+
445
+ =t= 除了可以作为类方法在 ActiveRecord 模型类上调用,也可以作为实例方法在 ActiveRecord 模型实例对象上调用。
446
+
447
+ #+begin_example
448
+ ARQL ❯ Person.last.t
449
+ +----------------|-----------------|------------------|---------+
450
+ | Attribute Name | Attribute Value | SQL Type | Comment |
451
+ +----------------|-----------------|------------------|---------+
452
+ | id | 11 | int(11) unsigned | |
453
+ | name | Jackson | varchar(64) | |
454
+ | age | 30 | int(11) | |
455
+ | gender | 2 | int(4) | |
456
+ | grade | 2 | int(4) | |
457
+ | blood_type | AB | varchar(4) | |
458
+ +----------------|-----------------|------------------|---------+
459
+ #+end_example
460
+
461
+ =t= 方法可以接受以下两个选项:
462
+
463
+ + =:except= 选项,用于指定不显示的属性名,值可以是字符串或正则表达式,例如:
464
+ #+BEGIN_EXAMPLE
465
+ Person.last.t(except: 'id')
466
+ Student.where(condition).t(except: /id|name/)
467
+ #+END_EXAMPLE
468
+ + =:compact= 选项,用于指定是否紧凑显示,值可以是 =true= 或 =false= ,如果启用紧凑显示,那些值全部为 =NULL= 的列将不
469
+ 会显示,这对于查看那些数据稀疏的表很有帮助,例如:
470
+ #+BEGIN_EXAMPLE
471
+ Person.last.t(compact: true)
472
+ Student.where(condition).t(compact: false)
473
+ #+END_EXAMPLE
474
+
475
+ **** =v=
476
+
477
+ =v= 方法用于与 Emacs org babel 集成。
478
+
479
+ ***** =v= 作为模型类的实例方法
480
+
481
+ 在任何 ActiveRecord 模型实例对象上调用 =v= 方法,可以打印一个数组,数组的第一个元素是 =['Attribute Name',
482
+ 'Attribute Value', 'SQL Type', 'Comment']= ,第二个元素是 =nil= ,剩下的元素是对象的属性名和值。在Emacs org-mode
483
+ 中,如果 =:result= 类型是 =value= (默认值),这个返回值会被渲染成一个漂亮的表格。
484
+
485
+ #+begin_example
486
+ ARQL ❯ Person.last.v
487
+ => [["Attribute Name", "Attribute Value", "SQL Type", "Comment"],
488
+ nil,
489
+ ["id", 11, "int(11) unsigned", ""],
490
+ ["name", "Jackson", "varchar(64)", ""],
491
+ ["age", 30, "int(11)", ""],
492
+ ["gender", 2, "int(4)", ""],
493
+ ["grade", 2, "int(4)", ""],
494
+ ["blood_type", "AB", "varchar(4)", ""]]
495
+ #+end_example
496
+
497
+ ***** 只包含模型实例的数组
498
+ #+begin_example
499
+ ARQL ❯ Person.all.to_a.v
500
+ => [["id", "name", "age", "gender", "grade", "blood_type"],
501
+ nil,
502
+ [1, "Jack", 30, nil, nil, nil],
503
+ [2, "Jack", 11, 1, nil, nil],
504
+ [3, "Jack", 12, 1, nil, nil],
505
+ [4, "Jack", 30, 1, nil, nil],
506
+ [5, "Jack", 12, 2, nil, nil],
507
+ [6, "Jack", 2, 2, 2, nil],
508
+ [7, "Jack", 3, 2, 2, nil],
509
+ [8, "Jack", 30, 2, 2, "AB"],
510
+ [9, "Jack", 30, 2, 2, "AB"],
511
+ [10, "Jack", 30, 2, 2, "AB"],
512
+ [11, "Jackson", 30, 2, 2, "AB"]]
513
+ #+end_example
514
+
515
+ ***** 只包含同构 Hash 对象的数组
516
+
517
+ #+begin_example
518
+ ARQL ❯ arr = [{name: 'Jack', age: 10}, {name: 'Lucy', age: 20}]
519
+ => [{:name=>"Jack", :age=>10}, {:name=>"Lucy", :age=>20}]
520
+ ARQL ❯ arr.v
521
+ => [[:name, :age], nil, ["Jack", 10], ["Lucy", 20]]
522
+ #+end_example
523
+
524
+ **** =q=
525
+
526
+ #+begin_example
527
+ ARQL ❯ rs = q 'select count(0) from person;'
528
+ => #<ActiveRecord::Result:0x00007fd1f8026ad0 @column_types={}, @columns=["count(0)"], @hash_rows=nil, @rows=[[11]]>
529
+ ARQL ❯ rs.rows
530
+ => [[11]]
531
+ #+end_example
532
+
533
+ **** JSON 转换和格式化
534
+
535
+ 在任何对象上调用 =j= 方法,可以得到 JSON 格式的字符串,调用 =jj= 方法可以得到格式化后的 JSON 字符串。
536
+
537
+ 使用 =jp= 方法打印 JSON,使用 =jjp= 方法打印格式化后的 JSON。
538
+
539
+ **** $C 全局变量
540
+
541
+ Arql 将 =ActiveRecord::Base.connection= 对象赋值给全局可用的 =$C= 全局变量,它代表当前的数据库连接。
542
+
543
+ 上文中的 =q= 方法实际上是 =$C.exec_query= 方法, =$C= 对象的其他方法也很有用:
544
+
545
+ ***** 创建表
546
+ #+begin_example
547
+ ARQL ❯ $C.create_table :post, id: false, primary_key: :id do |t|
548
+ ARQL ❯ t.column :id, :bigint, precison: 19, comment: 'ID'
549
+ ARQL ❯ t.column :name, :string, comment: '名称'
550
+ ARQL ❯ t.column :gmt_created, :datetime, comment: '创建时间'
551
+ ARQL ❯ t.column :gmt_modified, :datetime, comment: '最后修改时间'
552
+ ARQL ❯ end
553
+ #+end_example
554
+
555
+ =create_table= 同样也被加入到 =Kernel= 下面,所以也可以直接调用 =create_table= 方法:
556
+
557
+ #+begin_example
558
+ ARQL ❯ create_table :post, id: false, primary_key: :id do |t|
559
+ ARQL ❯ t.column :id, :bigint, precison: 19, comment: 'ID'
560
+ ARQL ❯ t.column :name, :string, comment: '名称'
561
+ ARQL ❯ t.column :gmt_created, :datetime, comment: '创建时间'
562
+ ARQL ❯ t.column :gmt_modified, :datetime, comment: '最后修改时间'
563
+ ARQL ❯ end
564
+ #+end_example
565
+
566
+ ***** 添加字段
567
+
568
+ #+begin_example
569
+ $C.add_column :post, :note, :string, comment: '备注'
570
+ #+end_example
571
+
572
+ =add_column= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =add_column= 方法:
573
+
574
+ #+begin_example
575
+ Post.add_column :note, :string, comment: '备注'
576
+ #+end_example
577
+
578
+ ***** 修改字段
579
+
580
+ #+begin_example
581
+ $C.change_column :post, :note, :text, comment: '备注'
582
+ #+end_example
583
+
584
+ =change_column= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =change_column= 方法:
585
+
586
+ #+begin_example
587
+ Post.change_column :note, :text, comment: '备注'
588
+ #+end_example
589
+
590
+ ***** 删除字段
591
+
592
+ #+begin_example
593
+ $C.remove_column :post, :note
594
+ #+end_example
595
+
596
+ =remove_column= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =remove_column= 方法:
597
+
598
+ #+begin_example
599
+ Post.remove_column :note
600
+ #+end_example
601
+
602
+ ***** 删除表
603
+
604
+ #+begin_example
605
+ $C.drop_table :post
606
+ #+end_example
607
+
608
+ =drop_table= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =drop_table= 方法:
609
+
610
+ #+begin_example
611
+ Post.drop_table
612
+ #+end_example
613
+
614
+ ***** 添加索引
615
+
616
+ #+begin_example
617
+ ARQL ❯ $C.add_index :post, :name
618
+ ARQL ❯ $C.add_index(:accounts, [:branch_id, :party_id], unique: true, name: 'by_branch_party')
619
+ #+end_example
620
+
621
+ =add_index= 也被加入到模型类的类方法中,所以也可以直接在模型类上调用 =add_index= 方法:
622
+
623
+ #+begin_example
624
+ Post.add_index :name
625
+ Post.add_index [:branch_id, :party_id], unique: true, name: 'by_branch_party'
626
+ #+end_example
627
+
628
+ **** =Kernel= 扩展方法
629
+
630
+ =Kernel= 模块下的函数可以想语言内置函数一样直接调用,不需要指定模块名。 以下是 Arql 扩展的 =Kernel= 方法:
631
+
632
+ Pry 内建了 =show-source= (别名 =$= ) 和 =show-doc= (别名 =?= )命令,可以查看方法的源码和文档。可以通过 =show-doc= 查看方法的文档。例如:
633
+
634
+ #+BEGIN_EXAMPLE
635
+ ARQL ❯ ? create_table
636
+ #+END_EXAMPLE
637
+
638
+
639
+ ***** 创建表 =create_table=
640
+ #+BEGIN_EXAMPLE
641
+ create_table :post, id: false, primary_key: :id do |t|
642
+ t.column :id, :bigint, precison: 19, comment: 'ID'
643
+ t.column :name, :string, comment: '名称'
644
+ t.column :gmt_created, :datetime, comment: '创建时间'
645
+ t.column :gmt_modified, :datetime, comment: '最后修改时间'
646
+ end
647
+ #+END_EXAMPLE
648
+ ***** 创建多对多关系的中间表 =create_join_table=
649
+ #+BEGIN_EXAMPLE
650
+ create_join_table :products, :categories do |t|
651
+ t.index :product_id
652
+ t.index :category_id
653
+ end
654
+ #+END_EXAMPLE
655
+ ***** 删除表 =drop_table=
656
+ #+BEGIN_EXAMPLE
657
+ drop_table :post
658
+ #+END_EXAMPLE
659
+ ***** 删除多对多关系的中间表 =drop_join_table=
660
+ #+BEGIN_EXAMPLE
661
+ drop_join_table :products, :categories
662
+ #+END_EXAMPLE
663
+ ***** 修改表名 =rename_table=
664
+ #+BEGIN_EXAMPLE
665
+ rename_table :post, :posts
666
+ #+END_EXAMPLE
667
+
668
+ ***** =print_tables=
669
+
670
+ Arql 提供了一个 =print_tables= 方法,可以将当前数据库中的所有表的信息,导出为:
671
+
672
+ + markdown 表格格式: ~print_tables(:md)~
673
+ + org-mode 表格格式: ~print_tables(:org)~
674
+ + create table SQL: ~print_tables(:sql)~
675
+
676
+ **** 模型类类方法扩展
677
+
678
+ Pry 内建了 =show-source= (别名 =$= ) 和 =show-doc= (别名 =?= )命令,可以查看方法的源码和文档。可以通过 =show-doc= 查看方法的文档。例如:
679
+
680
+ #+BEGIN_EXAMPLE
681
+ ARQL ❯ ? Student.add_column
682
+ #+END_EXAMPLE
683
+
684
+ ***** 添加字段 =add_column=
685
+ #+BEGIN_EXAMPLE
686
+ Student.add_column :note, :text, comment: '备注'
687
+ #+END_EXAMPLE
688
+
689
+ ***** 修改字段 =change_column=
690
+ #+BEGIN_EXAMPLE
691
+ Student.change_column :note, :string, comment: '备注'
692
+ #+END_EXAMPLE
693
+
694
+ ***** 删除字段 =remove_column=
695
+ #+BEGIN_EXAMPLE
696
+ Student.remove_column :note
697
+ #+END_EXAMPLE
698
+
699
+ ***** 添加索引 =add_index=
700
+ #+BEGIN_EXAMPLE
701
+ Student.add_index :name
702
+ Student.add_index [:branch_id, :party_id], unique: true, name: 'by_branch_party'
703
+ #+END_EXAMPLE
704
+
705
+ ***** 修改字段注释 =change_column_comment=
706
+ #+BEGIN_EXAMPLE
707
+ Student.change_column_comment :note, '备注'
708
+ #+END_EXAMPLE
709
+
710
+ ***** 修改字段默认值 =change_column_default=
711
+ #+BEGIN_EXAMPLE
712
+ Student.change_column_default :note, '默认值'
713
+ #+END_EXAMPLE
714
+
715
+ ***** 修改字段名称 =rename_column=
716
+ #+BEGIN_EXAMPLE
717
+ Student.rename_column :note, :remark
718
+ #+END_EXAMPLE
719
+
720
+ ***** 修改表名 =rename_table=
721
+ #+BEGIN_EXAMPLE
722
+ Student.rename_table :seitou
723
+ #+END_EXAMPLE
724
+
725
+ ***** 修改表注释 =change_table_comment=
726
+ #+BEGIN_EXAMPLE
727
+ Student.change_table_comment from: '', to: '学生表'
728
+ #+END_EXAMPLE
729
+
730
+ ***** 删除表 =drop_table=
731
+ #+BEGIN_EXAMPLE
732
+ Student.drop_table
733
+ #+END_EXAMPLE
734
+
735
+ ***** 删除索引 =remove_index=
736
+ #+BEGIN_EXAMPLE
737
+ Student.remove_index :age
738
+ Student.remove_index name: 'by_branch_party'
739
+ #+END_EXAMPLE
740
+
741
+ ***** 查询表注释 =table_comment=
742
+ #+BEGIN_EXAMPLE
743
+ Student.table_comment
744
+ #+END_EXAMPLE
745
+
746
+ ***** 列出表的索引 =indexes=
747
+ #+BEGIN_EXAMPLE
748
+ Student.indexes
749
+ #+END_EXAMPLE
750
+
751
+ **** 读写 Excel 和 CSV 文件
752
+
753
+ Arql 集成了 =roo= 和 =caxlsx= 两个 Excel 库,提供了用于解析和生成 Excel 文件的方法。同时,Arql 也提供了用于读写 CSV 文件的方法。
754
+
755
+ ***** 解析 Excel
756
+
757
+ Arql 为 =Kernel= 模块添加了 =parse_excel= 方法,可以用来解析 Excel 文件。例如:
758
+
759
+ #+BEGIN_EXAMPLE
760
+ ARQL ❯ parse_excel 'path/to/excel.xlsx'
761
+ #+END_EXAMPLE
762
+
763
+ 文件路径中可以使用 =~/= 表示用户的主目录,Arql 会自动展开。
764
+
765
+
766
+ 也可以在一个表示文件路径的 =String= 对象上调用 =parse_excel= 方法:
767
+
768
+ #+BEGIN_EXAMPLE
769
+ ARQL ❯ 'path/to/excel.xlsx'.parse_excel
770
+ #+END_EXAMPLE
771
+
772
+ =parse_excel= 方法会返回一个 =Hash= 对象,Key 为 Sheet 名称,Value 为 Sheet 的数据,Value 是一个二维数组。例如:
773
+
774
+ #+BEGIN_EXAMPLE
775
+ {
776
+ 'Sheet1' => [
777
+ ['A1', 'B1', 'C1'],
778
+ ['A2', 'B2', 'C2'],
779
+ ['A3', 'B3', 'C3']
780
+ ],
781
+ 'Sheet2' => [
782
+ ['A1', 'B1', 'C1'],
783
+ ['A2', 'B2', 'C2'],
784
+ ['A3', 'B3', 'C3']
785
+ ]
786
+ }
787
+ #+END_EXAMPLE
788
+
789
+ ***** 生成 Excel
790
+
791
+ Arql 为 =Hash= / =Array= / =ActiveRecord::Relation= / =ActiveRecord::Base= 对象添加了 =write_excel= 方法,可以用来
792
+ 生成 Excel 文件:
793
+
794
+ ****** 从 =Hash= 对象生成 Excel
795
+
796
+ #+BEGIN_EXAMPLE
797
+ ARQL ❯ obj.write_excel 'path/to/excel.xlsx'
798
+ #+END_EXAMPLE
799
+
800
+ =Hash#write_excel= 要求 Hash 对象 Key 是 Sheet 名称,Value 是 Sheet 的数据,Value 的类型可以是:
801
+
802
+ + 一个数组,数组的元素可以是:
803
+ + 一个数组,表示一行数据
804
+ + 一个 Hash 对象,表示一行数据,Key 是列名,Value 是列值
805
+ + 一个 ActiveRecord::Base 对象,表示一行数据
806
+ + 一个 Hash 对象,一共包含两个键值对:
807
+ + =:fields=, 一个数组,表示列名
808
+ + =:data=, 一个二维数组,表示数据
809
+
810
+ ****** 从 =Array= 对象生成 Excel
811
+
812
+ #+BEGIN_EXAMPLE
813
+ ARQL ❯ obj.write_excel 'path/to/excel.xlsx', :name, :age, :gender, sheet_name: '订单数据'
814
+ #+END_EXAMPLE
815
+
816
+ 其中:
817
+
818
+ + =:name, :age, :gender= 这几个参数是列名,如果不指定,会根据数组的第一个元素来确定列名:
819
+ - 如果元素是 =ActiveRecord::Base= 对象,会使用对象的全部属性名(即数据库字段列表)作为列名
820
+ - 如果元素是 =Hash= 对象,会使用 =Hash= 的 全部 Key 作为列名
821
+ + =sheet_name= 指定 Sheet 名称,如果不指定,会使用默认的 Sheet 名称 =Sheet1=
822
+
823
+ =Array= 对象的每一个元素表示一行数据, =Array#write_excel= 要求 Array 对象每个元素:
824
+
825
+ + 一个 =ActiveRecord::Base= 对象
826
+ + 一个 =Hash= 对象,表示一行数据,Key 是列名,Value 是列值
827
+ + 一个数组,表示一行数据
828
+
829
+ ****** 从 =ActiveRecord::Base= 对象生成 Excel
830
+
831
+ #+BEGIN_EXAMPLE
832
+ ARQL ❯ Student.find(123).write_excel 'path/to/excel.xlsx', sheet_name: '学生数据'
833
+ #+END_EXAMPLE
834
+
835
+ =ActiveRecord::Base= 的 =write_excel= 对象实际上就是把这个 =ActiveRecord::Base= 对象包装成一个只有一个元素的 =Array= 对
836
+ 象,然后调用 =Array= 的 =write_excel= 方法。
837
+
838
+ ****** 从 =ActiveRecord::Relation= 对象生成 Excel
839
+
840
+ #+BEGIN_EXAMPLE
841
+ ARQL ❯ Student.where(gender: 'M').write_excel 'path/to/excel.xlsx', sheet_name: '男学生'
842
+ #+END_EXAMPLE
843
+
844
+ =ActiveRecord::Relation= 的 =write_excel= 对象实际上就是把这个 =ActiveRecord::Relation= 对象转换成一个 =Array= 对象,然
845
+ 后调用 =Array= 的 =write_excel= 方法。
846
+
847
+ ***** 解析 CSV
848
+
849
+ Arql 提供了 =parse_csv= 方法,可以用来解析 CSV 文件:
850
+
851
+ #+BEGIN_EXAMPLE
852
+ ARQL ❯ parse_csv 'path/to/csv.csv'
853
+ #+END_EXAMPLE
854
+
855
+ =parse_csv= 方法返回一个标准库中的 CSV 对象。
856
+
857
+ =parse_csv= 可以有以下选项参数:
858
+
859
+ - =encoding=, 指定 CSV 文件的编码,默认是 =UTF-16= (with BOM)
860
+ - =headers=, 指定是否包含表头,默认是 =false=
861
+ - =col_sep=, 指定列分隔符,默认是 =\t=
862
+ - =row_sep=, 指定行分隔符,默认是 =\r\n=
863
+
864
+ (以上默认值实际就是 Microsoft Office Excel 保存 CSV 文件时默认使用的配置)
865
+
866
+ 也可以在一个表示文件路径的 =String= 对象上调用 =parse_csv= 方法:
867
+
868
+ #+BEGIN_EXAMPLE
869
+ ARQL ❯ 'path/to/csv.csv'.parse_csv
870
+ #+END_EXAMPLE
871
+
872
+ ***** 生成 CSV
873
+ Arql 为 =Array= / =ActiveRecord::Relation= / =ActiveRecord::Base= 对象添加了 =write_csv= 方法,可以用来生成 CSV 文件:
874
+
875
+ ****** 从 =Array= 对象生成 CSV
876
+
877
+ #+BEGIN_EXAMPLE
878
+ ARQL ❯ obj.write_csv 'path/to/csv.csv', :name, :age, :gender, sheet_name: '订单数据'
879
+ #+END_EXAMPLE
880
+
881
+ 用法和 =Array= 对象的 =write_excel= 方法类似。
882
+
883
+
884
+ ****** 从 =ActiveRecord::Base= 对象生成 CSV
885
+
886
+ #+BEGIN_EXAMPLE
887
+ ARQL ❯ Student.find(123).write_csv 'path/to/csv.csv', sheet_name: '学生数据'
888
+ #+END_EXAMPLE
889
+
890
+ 用法和 =ActiveRecord::Base= 对象的 =write_excel= 方法类似。
891
+
892
+ ****** 从 =ActiveRecord::Relation= 对象生成 CSV
893
+
894
+ #+BEGIN_EXAMPLE
895
+ ARQL ❯ Student.where(gender: 'M').write_csv 'path/to/csv.csv', sheet_name: '男学生'
896
+ #+END_EXAMPLE
897
+
898
+ 用法和 =ActiveRecord::Relation= 对象的 =write_excel= 方法类似。
899
+
900
+ **** dump 数据
901
+
902
+ 注意: 仅支持 MySQL 数据库
903
+
904
+ Arql 为 =Array= / =ActiveRecord::Base= / =ActiveRecord::Relation= 等对象添加了 =dump= 方法,可以用来导出数据到 SQL 文件:
905
+
906
+
907
+ ***** 从 Array 对象导出数据
908
+
909
+ #+BEGIN_EXAMPLE
910
+ ARQL ❯ obj.dump 'path/to/dump.sql', batch_size: 5000
911
+ #+END_EXAMPLE
912
+
913
+ =Array= 对象的每一个元素必须是一个 =ActiveRecord::Base= 对象
914
+
915
+ =batch_size= 参数指定每个批次查询出的数据,默认值为 500
916
+
917
+ ***** 从 ActiveRecord::Base 对象导出数据
918
+
919
+ #+BEGIN_EXAMPLE
920
+ ARQL ❯ Student.find(123).dump 'path/to/dump.sql', batch_size: 5000
921
+ #+END_EXAMPLE
922
+
923
+ =ActiveRecord::Base= 对象的 =dump= 方法实际上就是把这个 =ActiveRecord::Base= 对象包装成一个只有一个元素的 =Array= 对象,然后调用 =Array= 的 =dump= 方法。
924
+
925
+ ***** 从 ActiveRecord::Relation 对象导出数据
926
+
927
+ #+BEGIN_EXAMPLE
928
+ ARQL ❯ Student.where(gender: 'M').dump 'path/to/dump.sql', batch_size: 5000
929
+ #+END_EXAMPLE
930
+
931
+ =ActiveRecord::Relation= 的 =dump= 对象实际上就是把这个 =ActiveRecord::Relation= 对象转换成一个 =Array= 对象,然后调用 =Array= 的 =dump= 方法。
932
+
933
+
934
+ ***** 调用 ActiveRecord::Base 的 dump 类方法
935
+
936
+ #+BEGIN_EXAMPLE
937
+ ARQL ❯ Student.dump 'path/to/dump.sql', no_create_table: false
938
+ #+END_EXAMPLE
939
+
940
+ 这个方法会通过 =mysqldump= 命令 把 =Student= 表中的所有数据导出到 SQL 文件中。
941
+
942
+ =no_create_table= 参数指定是否在 SQL 文件中包含创建表的语句,默认值为 =false= 。
943
+
944
+
945
+
946
+ ***** 在全局连接对象 =$C= 上调用 dump 方法
947
+
948
+ #+BEGIN_EXAMPLE
949
+ ARQL ❯ $C.dump 'path/to/dump.sql', no_create_db: false
950
+ #+END_EXAMPLE
951
+
952
+ 这个方法会通过 mysqldump 命令把当前数据库中的所有表的数据导出到 SQL 文件中。
953
+
954
+ =no_create_db= 参数指定是否在 SQL 文件中包含创建数据库的语句,默认值为 =false= 。
955
+
956
+
957
+ **** Plot
958
+
959
+ Arql 集成了 Ruby 的 =youplot= 库,为 =Array= 添加了一些可以用来绘制图表的方法:
960
+
961
+ + =barplot=
962
+ + =countplot=
963
+ + =histo=
964
+ + =lineplot=
965
+ + =lineplots=
966
+ + =scatter=
967
+ + =density=
968
+ + =boxplot=
969
+
970
+ 示例:
971
+
972
+ 数量统计图:
973
+
974
+ #+BEGIN_EXAMPLE
975
+ ARQL@demo247(main) [44] ❯ Student.pluck(:gender)
976
+ => ["M", "M", "M", "M", "M", "M", "M", "F", "M", "F", "M", "M", "M", "M", "M"]
977
+ ARQL@demo247(main) [45] ❯ Student.pluck(:gender).countplot
978
+ ┌ ┐
979
+ M ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 13.0
980
+ F ┤■■■■■ 2.0
981
+ └ ┘
982
+ #+END_EXAMPLE
983
+
984
+ 分布图:
985
+
986
+ #+BEGIN_EXAMPLE
987
+ ARQL@jicai.dev(main) [18] ❯ Order.last(20).pluck(:order_sum)
988
+ => [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]
989
+ ARQL@jicai.dev(main) [19] ❯ Order.last(20).pluck(:order_sum).histo
990
+ ┌ ┐
991
+ [ 0.0, 50000.0) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 17
992
+ [ 50000.0, 100000.0) ┤▇▇▇▇ 2
993
+ [100000.0, 150000.0) ┤ 0
994
+ [150000.0, 200000.0) ┤ 0
995
+ [200000.0, 250000.0) ┤▇▇ 1
996
+ └ ┘
997
+ Frequency
998
+
999
+ #+END_EXAMPLE
1000
+
1001
+ **** =String=
1002
+
1003
+ ***** =Srting#p=
1004
+
1005
+ =p= 方法的定义如下:
1006
+
1007
+ #+begin_example
1008
+ class String
1009
+ def p
1010
+ puts self
1011
+ end
1012
+ end
1013
+ #+end_example
1014
+
1015
+ =​"hello".p= 等价于 =puts "hello"​= 。
1016
+
1017
+ ***** =String#parse=
1018
+
1019
+ 对于一个表示文件路径的字符串,可以调用 =parse= 方法通过文件路径中的后缀名来分别对 Excel、CSV、JSON 文件进行解析。
1020
+
1021
+ #+BEGIN_EXAMPLE
1022
+ excel = 'path/to/excel.xlsx'.parse
1023
+ csv = 'path/to/csv.csv'.parse
1024
+ json = 'path/to/json.json'.parse
1025
+ #+END_EXAMPLE
1026
+
1027
+ **** =ID=
1028
+
1029
+ Arql 提供了一个 =ID= 类,用来生成雪花算法 ID 和 UUID。
1030
+
1031
+ #+BEGIN_EXAMPLE
1032
+ id = ID.long # 生成一个雪花算法 ID
1033
+ id = ID.uuid # 生成一个 UUID
1034
+ #+END_EXAMPLE
1035
+
1036
+ **** Ransack
1037
+
1038
+ Arql 集成了 =Ransack=:
1039
+
1040
+ #+BEGIN_EXAMPLE
1041
+ Student.ransack(name_cont: 'Tom').result # 模糊查询名字中包含 'Tom' 的学生
1042
+ Student.ransack(name_start: 'Tom').result # 模糊查询名字以 'Tom' 开头的学生
1043
+ #+END_EXAMPLE
1044
+
1045
+ *** Emacs Org Babel 集成
1046
+
1047
+ 这里有一个 [[https://github.com/lululau/spacemacs-layers/blob/master/ob-arql/local/ob-arql/ob-arql.el][ob-arql]] 用于集成 Emacs org babel。
1048
+
1049
+ ** Guides and Tips
1050
+ *** [[./define-associations-zh_CN.org][在 Initializer 文件中定义关联关系]]
1051
+ *** [[./initializer-structure-zh_CN.org][将不同环境的初始化代码放在不同的文件中]]
1052
+ *** [[./helper-for-datetime-range-query-zh_CN.org][定义快速按时间查询的便利方法]]
1053
+ *** [[./auto-set-id-before-save-zh_CN.org][新建对象在保存之前自动设置 ID]]
1054
+ *** [[./custom-configurations-zh_CN.org][配置文件中的自定义配置项]]
1055
+ *** [[./sql-log-zh_CN.org][自动记录 SQL 日志和 REPL 输入历史]]
1056
+ *** [[./fuzzy-field-query-zh_CN.org][字段名 Fuzzy 化查询]]
1057
+ *** [[./oss-files-zh_CN.org][OSS 数据下载和查看]]
1058
+ *** 使用 Arql 查看 SQLite3 数据库文件
1059
+
1060
+ 可以使用 Arql 查看 SQLite3 数据库文件,例如:
1061
+
1062
+ #+BEGIN_EXAMPLE
1063
+ arql -d db/development.sqlite3
1064
+ #+END_EXAMPLE
1065
+
1066
+ *** 根据名称或注释查找字段
1067
+
1068
+ 我们在熟悉一个项目的时候,经常会遇到这样的情况:我们知道某个字段的名称或注释,但是不知道它对应的表名和字段名。这时候我们可以使用如下方法来查找:
1069
+
1070
+ #+BEGIN_SRC ruby
1071
+ 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})"} }
1072
+
1073
+ # 输出:
1074
+ # Table: order, Column: entry_amount (订单金额)
1075
+ # Table: sub_order, Column: entry_price (金额)
1076
+ #+END_SRC
1077
+
1078
+ ** 开发
1079
+
1080
+ 检出代码后,运行 =bin/setup= 安装依赖。你也可以运行 =bin/console= 进入交互式控制台。
1081
+
1082
+ 运行 =bundle exec rake install= 将这个 gem 安装到本地。发布新版本时,更新 =version.rb= 中的版本号,然后运行 =bundle
1083
+ exec rake release= ,这将为该版本创建一个 git 标签,推送 git 提交和标签,并将 =.gem= 文件推送到 [[https://rubygems.org][rubygems.org]]。
1084
+
1085
+ ** 贡献代码
1086
+
1087
+ 欢迎在 GitHub 上提交 bug 报告和 pull request: https://github.com/lululau/arql 。这个项目旨在成为一个安全、友好的协作
1088
+ 空间,期望贡献者遵守 [[https://github.com/lululau/arql/blob/master/CODE_OF_CONDUCT.md][行为准则]]。
1089
+
1090
+ ** 许可证
1091
+
1092
+ 这个 gem 是根据 [[https://opensource.org/licenses/MIT][MIT License]] 条款开源的。
1093
+
1094
+ ** Code of Conduct
1095
+
1096
+ 与 Arql 项目的代码库、问题跟踪器、聊天室和邮件列表中的每个人都应遵守 [[https://github.com/lululau/arql/blob/master/CODE_OF_CONDUCT.md][行为准则]]。