arql 0.3.28 → 0.3.30

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,161 @@
1
+ * OSS 数据下载和查看
2
+
3
+ 有的系统使用云存储服务来存储系统中的文件数据,并在数据库中存储文件在 OSS 上的 Key。我们希望可以在 Arql 中直接下载和查看这些文件。
4
+
5
+ ** 首先需要安装和配置 =rclone= 工具
6
+
7
+ macOS 示例:
8
+
9
+ #+BEGIN_EXAMPLE
10
+ brew install rclone
11
+ #+END_EXAMPLE
12
+
13
+
14
+ ** 配置 rclone
15
+
16
+ 在 =~/.config/rclone/rclone.conf= 文件中添加系统所使用的 OSS 配置,例如:
17
+
18
+ #+BEGIN_EXAMPLE
19
+ [my_system]
20
+ type = s3
21
+ provider = Alibaba
22
+ env_auth = false
23
+ access_key_id = LTAxuiwqsayuuyea
24
+ secret_access_key = sauiqwYUwqhjsdayuwehjkwehjwehj
25
+ endpoint = oss-cn-beijing.aliyuncs.com
26
+ acl = private
27
+ storage_class = STANDARD
28
+ #+END_EXAMPLE
29
+
30
+
31
+ ** 在 =~/.arql.d/init.yaml= 中添加配置
32
+
33
+ #+BEGIN_SRC yaml
34
+ dev:
35
+ created_at: ["create_time", "gmt_created"]
36
+ updated_at: ["update_time", "gmt_modified"]
37
+ host: db.dev.com
38
+ port: 3306
39
+ username: admin
40
+ password: 123456
41
+ database: dev_db
42
+ rclone_name: "my_system"
43
+ oss_bucket: "my_system_dev_bucket"
44
+
45
+ prod:
46
+ created_at: ["create_time", "gmt_created"]
47
+ updated_at: ["update_time", "gmt_modified"]
48
+ host: db.prod.com
49
+ port: 3306
50
+ username: admin
51
+ password: 123456
52
+ database: prod_db
53
+ rclone_name: "my_system"
54
+ oss_bucket: "my_system_prod_bucket"
55
+ #+END_SRC
56
+
57
+
58
+ ** 创建一个文件 =~/.arql.d/oss.rb=
59
+
60
+ #+BEGIN_SRC ruby
61
+ class OSS
62
+ def pry_source_location; end
63
+
64
+ attr_accessor :path, :bucket
65
+
66
+ def initialize(path, bucket: nil)
67
+ @path = path
68
+ unless bucket
69
+ bucket = Arql::App.config['oss_bucket']
70
+ end
71
+ @bucket = bucket
72
+ end
73
+
74
+ def rclone_name
75
+ Arql::App.config['rclone_name']
76
+ end
77
+
78
+ def info
79
+ `rclone lsl #{rclone_name}:#{bucket}/#{path}`
80
+ end
81
+
82
+ def download(dir = nil, keep_structure = false)
83
+ dir = File.expand_path(dir) if dir
84
+ dir ||= Dir.mktmpdir('arql-attachment-')
85
+ if keep_structure
86
+ dest_dir = dir + '/' + File.dirname(path)
87
+ FileUtils.mkdir_p(dest_dir)
88
+ system <<~EOF
89
+ rclone copy #{rclone_name}:#{bucket}/#{path} #{dest_dir}/
90
+ EOF
91
+ dest_dir + '/' + File.basename(path)
92
+ else
93
+ system <<~EOF
94
+ rclone copy #{rclone_name}:#{bucket}/#{path} #{dir}/
95
+ EOF
96
+ dir + '/' + File.basename(path)
97
+ end
98
+ end
99
+
100
+ def copy(dest_name, dest_bucket)
101
+ path_prefix = File.dirname(path)
102
+ system "rclone copy -P #{rclone_name}:#{bucket}/#{path} #{dest_name}:#{dest_bucket}/#{path_prefix}/"
103
+ end
104
+
105
+ def cat
106
+ `rclone cat #{rclone_name}:#{bucket}/#{path}`
107
+ end
108
+
109
+ def to_rclone_url
110
+ "#{rclone_name}:#{bucket}/#{path}"
111
+ end
112
+
113
+ def open
114
+ file = download
115
+ system <<~EOF
116
+ open #{file}
117
+ EOF
118
+ file
119
+ end
120
+
121
+ def preview
122
+ file = download
123
+ system <<~EOF
124
+ qlmanage -p #{file} &> /dev/null
125
+ EOF
126
+ file
127
+ end
128
+
129
+ def emacs_open
130
+ file = download
131
+ system <<~EOF
132
+ emacsclient -q --eval "(switch-to-buffer-other-window (current-buffer))" &> /dev/null
133
+ emacsclient -n '#{file}'
134
+ EOF
135
+ file
136
+ end
137
+ end
138
+
139
+ class String
140
+ def oss(bucket: nil)
141
+ OSS.new(self, bucket: bucket)
142
+ end
143
+ end
144
+ #+END_SRC
145
+
146
+ ** 在 =~/.arql.d/init.rb= 中引入这个文件
147
+
148
+ #+BEGIN_SRC ruby
149
+ load(File.absolute_path(File.dirname(__FILE__) + "/oss.rb"))
150
+ #+END_SRC
151
+
152
+ ** 用法
153
+
154
+ 假设 user 表中有一个 avatar 字段存储了用户头像在 OSS 上的 Key,我们可以这样查看和下载头像:
155
+
156
+ #+BEGIN_SRC ruby
157
+ User.first.avatar.oss.preview # 使用 macOS Quick Look 预览
158
+ User.first.avatar.oss.download # 下载到临时目录,并返回文件路径
159
+ User.first.avatar.oss.open # 下载到临时目录,并使用系统(macOS)默认程序打开
160
+ User.first.avatar.oss.cat # 直接输出文件内容
161
+ #+END_SRC
data/oss-files.org ADDED
@@ -0,0 +1,163 @@
1
+ * Download and Preview Files in OSS
2
+
3
+ Some systems use cloud storage services to store file data in the system and store the key of the file on OSS in the database. We hope to be able to download and view these files directly in Arql.
4
+
5
+ ** First you need to install and configure =rclone= tool
6
+
7
+ macOS example:
8
+
9
+ #+BEGIN_EXAMPLE
10
+ brew install rclone
11
+ #+END_EXAMPLE
12
+
13
+
14
+ ** Configure rclone
15
+
16
+ Add the OSS configuration used by the system to the =~/.config/rclone/rclone.conf= file, for example:
17
+
18
+ #+BEGIN_EXAMPLE
19
+ [my_system]
20
+ type = s3
21
+ provider = Alibaba
22
+ env_auth = false
23
+ access_key_id = LTAxuiwqsayuuyea
24
+ secret_access_key = sauiqwYUwqhjsdayuwehjkwehjwehj
25
+ endpoint = oss-cn-beijing.aliyuncs.com
26
+ acl = private
27
+ storage_class = STANDARD
28
+ #+END_EXAMPLE
29
+
30
+
31
+ ** Add configuration in =~/.arql.d/init.yaml=
32
+
33
+ #+BEGIN_SRC yaml
34
+ dev:
35
+ created_at: ["create_time", "gmt_created"]
36
+ updated_at: ["update_time", "gmt_modified"]
37
+ host: db.dev.com
38
+ port: 3306
39
+ username: admin
40
+ password: 123456
41
+ database: dev_db
42
+ rclone_name: "my_system"
43
+ oss_bucket: "my_system_dev_bucket"
44
+
45
+ prod:
46
+ created_at: ["create_time", "gmt_created"]
47
+ updated_at: ["update_time", "gmt_modified"]
48
+ host: db.prod.com
49
+ port: 3306
50
+ username: admin
51
+ password: 123456
52
+ database: prod_db
53
+ rclone_name: "my_system"
54
+ oss_bucket: "my_system_prod_bucket"
55
+ #+END_SRC
56
+
57
+
58
+ ** Create a file =~/.arql.d/oss.rb=
59
+
60
+ #+BEGIN_SRC ruby
61
+ class OSS
62
+ def pry_source_location; end
63
+
64
+ attr_accessor :path, :bucket
65
+
66
+ def initialize(path, bucket: nil)
67
+ @path = path
68
+ unless bucket
69
+ bucket = Arql::App.config['oss_bucket']
70
+ end
71
+ @bucket = bucket
72
+ end
73
+
74
+ def rclone_name
75
+ Arql::App.config['rclone_name']
76
+ end
77
+
78
+ def info
79
+ `rclone lsl #{rclone_name}:#{bucket}/#{path}`
80
+ end
81
+
82
+ def download(dir = nil, keep_structure = false)
83
+ dir = File.expand_path(dir) if dir
84
+ dir ||= Dir.mktmpdir('arql-attachment-')
85
+ if keep_structure
86
+ dest_dir = dir + '/' + File.dirname(path)
87
+ FileUtils.mkdir_p(dest_dir)
88
+ system <<~EOF
89
+ rclone copy #{rclone_name}:#{bucket}/#{path} #{dest_dir}/
90
+ EOF
91
+ dest_dir + '/' + File.basename(path)
92
+ else
93
+ system <<~EOF
94
+ rclone copy #{rclone_name}:#{bucket}/#{path} #{dir}/
95
+ EOF
96
+ dir + '/' + File.basename(path)
97
+ end
98
+ end
99
+
100
+ def copy(dest_name, dest_bucket)
101
+ path_prefix = File.dirname(path)
102
+ system "rclone copy -P #{rclone_name}:#{bucket}/#{path} #{dest_name}:#{dest_bucket}/#{path_prefix}/"
103
+ end
104
+
105
+ def cat
106
+ `rclone cat #{rclone_name}:#{bucket}/#{path}`
107
+ end
108
+
109
+ def to_rclone_url
110
+ "#{rclone_name}:#{bucket}/#{path}"
111
+ end
112
+
113
+ def open
114
+ file = download
115
+ system <<~EOF
116
+ open #{file}
117
+ EOF
118
+ file
119
+ end
120
+
121
+ def preview
122
+ file = download
123
+ system <<~EOF
124
+ qlmanage -p #{file} &> /dev/null
125
+ EOF
126
+ file
127
+ end
128
+
129
+ def emacs_open
130
+ file = download
131
+ system <<~EOF
132
+ emacsclient -q --eval "(switch-to-buffer-other-window (current-buffer))" &> /dev/null
133
+ emacsclient -n '#{file}'
134
+ EOF
135
+ file
136
+ end
137
+ end
138
+
139
+ class String
140
+ def oss(bucket: nil)
141
+ OSS.new(self, bucket: bucket)
142
+ end
143
+ end
144
+ #+END_SRC
145
+
146
+
147
+ ** Import this file in =~/.arql.d/init.rb=
148
+
149
+ #+BEGIN_SRC ruby
150
+ load(File.absolute_path(File.dirname(__FILE__) + "/oss.rb"))
151
+ #+END_SRC
152
+
153
+ ** Usage
154
+
155
+
156
+ Assuming that the user table has an avatar field that stores the key of the user's avatar on OSS, we can view and download the avatar like this:
157
+
158
+ #+BEGIN_SRC ruby
159
+ User.first.avatar.oss.preview # Preview using macOS Quick Look
160
+ User.first.avatar.oss.download # Download to a temporary directory and return the file path
161
+ User.first.avatar.oss.open # Download to a temporary directory and open with the system (macOS) default program
162
+ User.first.avatar.oss.cat # Output file content directly
163
+ #+END_SRC
data/sql-log-zh_CN.org ADDED
@@ -0,0 +1,55 @@
1
+ * 自动记录 SQL 日志和 REPL 输入历史
2
+
3
+ 如果希望 Arql 可以自动记录 SQL 日志和 REPL 输入历史,可以:
4
+
5
+ 创建目录 =~/.arql.d/logs=
6
+
7
+ 创建一个文件 =~/.arql.d/sql_log.rb= ,内容如下:
8
+
9
+ #+BEGIN_SRC ruby
10
+ unless Arql::App.config[:append_sql]
11
+ log_root_dir = File.expand_path('~/.arql.d/logs')
12
+ log_dir = "#{log_root_dir}/%s" % Arql::App.env
13
+ FileUtils.mkdir_p(log_dir)
14
+ now = Time.now
15
+ log_file = "#{log_dir}/%s.%s.%s.log" % [Time.now.strftime('%Y_%m%d_%H%M%S'), `hostname -s`.chomp.downcase, Process.pid]
16
+ Arql::App.config[:append_sql] = log_file
17
+
18
+ lfile = File.new(log_file, 'a')
19
+ lfile.sync = true
20
+ InputLogger = Logger.new(lfile)
21
+
22
+ module Readline
23
+ class << self
24
+ alias_method :original_readline, :readline
25
+ def readline(*args)
26
+ Readline.original_readline(*args).tap do |user_input|
27
+ InputLogger.info(user_input)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ #+END_SRC
34
+
35
+
36
+ 然后在 =~/.arql.d/init.rb= 中引入这个文件:
37
+
38
+ #+BEGIN_SRC ruby
39
+ load(File.absolute_path(File.dirname(__FILE__) + "/sql_log.rb"))
40
+ #+END_SRC
41
+
42
+ 这样就可以在 =~/.arql.d/logs= 目录下看到 SQL 日志和 REPL 输入历史了。
43
+
44
+ 示例:
45
+
46
+ #+BEGIN_EXAMPLE
47
+ I, [2024-04-07T17:12:00.530341 #20440] INFO -- : P.count
48
+ D, [2024-04-07T17:12:00.577305 #20440] DEBUG -- : Post Count (22.6ms) SELECT COUNT(*) FROM `post`
49
+ I, [2024-04-07T17:12:02.879312 #20440] INFO -- : P.all.t
50
+ D, [2024-04-07T17:12:02.960014 #20440] DEBUG -- : Post Load (64.1ms) SELECT `post`.* FROM `post`
51
+ I, [2024-04-07T17:12:54.721861 #20440] INFO -- : P.pluck(:gender)
52
+ D, [2024-04-07T17:12:54.756435 #20440] DEBUG -- : Post Pluck (28.0ms) SELECT `post`.`gender` FROM `post`
53
+ #+END_EXAMPLE
54
+
55
+
data/sql-log.org ADDED
@@ -0,0 +1,55 @@
1
+ * Save SQL logs and REPL history automatically
2
+
3
+ If you want Arql to automatically save SQL logs and REPL history, you can:
4
+
5
+ Create a directory =~/.arql.d/logs=
6
+
7
+ Create a file =~/.arql.d/sql_log.rb= with the following content:
8
+
9
+ #+BEGIN_SRC ruby
10
+ unless Arql::App.config[:append_sql]
11
+ log_root_dir = File.expand_path('~/.arql.d/logs')
12
+ log_dir = "#{log_root_dir}/%s" % Arql::App.env
13
+ FileUtils.mkdir_p(log_dir)
14
+ now = Time.now
15
+ log_file = "#{log_dir}/%s.%s.%s.log" % [Time.now.strftime('%Y_%m%d_%H%M%S'), `hostname -s`.chomp.downcase, Process.pid]
16
+ Arql::App.config[:append_sql] = log_file
17
+
18
+ lfile = File.new(log_file, 'a')
19
+ lfile.sync = true
20
+ InputLogger = Logger.new(lfile)
21
+
22
+ module Readline
23
+ class << self
24
+ alias_method :original_readline, :readline
25
+ def readline(*args)
26
+ Readline.original_readline(*args).tap do |user_input|
27
+ InputLogger.info(user_input)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ #+END_SRC
34
+
35
+ Then include this file in =~/.arql.d/init.rb=:
36
+
37
+ #+BEGIN_SRC ruby
38
+ load(File.absolute_path(File.dirname(__FILE__) + "/sql_log.rb"))
39
+ #+END_SRC
40
+
41
+ This way you can see SQL logs and REPL history in the =~/.arql.d/logs= directory.
42
+
43
+ Example:
44
+
45
+ #+BEGIN_EXAMPLE
46
+ I, [2024-04-07T17:12:00.530341 #20440] INFO -- : P.count
47
+ D, [2024-04-07T17:12:00.577305 #20440] DEBUG -- : Post Count (22.6ms) SELECT COUNT(*) FROM `post`
48
+ I, [2024-04-07T17:12:02.879312 #20440] INFO -- : P.all.t
49
+ D, [2024-04-07T17:12:02.960014 #20440] DEBUG -- : Post Load (64.1ms) SELECT `post`.* FROM `post`
50
+ I, [2024-04-07T17:12:54.721861 #20440] INFO -- : P.pluck
51
+ D, [2024-04-07T17:12:54.756435 #20440] DEBUG -- : Post Pluck (28.0ms) SELECT `post`.`gender` FROM `post`
52
+ #+END_EXAMPLE
53
+
54
+
55
+
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.3.28
4
+ version: 0.3.30
5
5
  platform: ruby
6
6
  authors:
7
7
  - Liu Xiang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-05 00:00:00.000000000 Z
11
+ date: 2024-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mysql2
@@ -304,13 +304,26 @@ files:
304
304
  - Gemfile
305
305
  - Gemfile.lock
306
306
  - LICENSE.txt
307
- - README.md
307
+ - README-zh_CN.org
308
+ - README.org
308
309
  - Rakefile
309
310
  - arql.gemspec
311
+ - auto-set-id-before-save-zh_CN.org
312
+ - auto-set-id-before-save.org
310
313
  - bin/console
311
314
  - bin/setup
315
+ - custom-configurations-zh_CN.org
316
+ - custom-configurations.org
317
+ - define-associations-zh_CN.org
318
+ - define-associations.org
312
319
  - exe/arql
313
320
  - exe/arql_setsid_wrapper
321
+ - fuzzy-field-query-zh_CN.org
322
+ - fuzzy-field-query.org
323
+ - helper-for-datetime-range-query-zh_CN.org
324
+ - helper-for-datetime-range-query.org
325
+ - initializer-structure-zh_CN.org
326
+ - initializer-structure.org
314
327
  - lib/arql.rb
315
328
  - lib/arql/app.rb
316
329
  - lib/arql/cli.rb
@@ -345,6 +358,10 @@ files:
345
358
  - lib/arql/ssh_proxy_patch.rb
346
359
  - lib/arql/vd.rb
347
360
  - lib/arql/version.rb
361
+ - oss-files-zh_CN.org
362
+ - oss-files.org
363
+ - sql-log-zh_CN.org
364
+ - sql-log.org
348
365
  homepage: https://github.com/lululau/arql
349
366
  licenses:
350
367
  - MIT