arql 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README-zh_CN.org +10 -162
- data/README.org +803 -628
- data/auto-set-id-before-save.org +1 -1
- data/custom-configurations.org +71 -32
- data/define-associations.org +52 -29
- data/initializer-structure-zh_CN.org +1 -1
- data/initializer-structure.org +46 -18
- data/lib/arql/cli.rb +6 -0
- data/lib/arql/repl.rb +1 -1
- data/lib/arql/version.rb +1 -1
- data/oss-files-zh_CN.org +2 -2
- data/oss-files.org +2 -2
- data/sql-log.org +8 -3
- metadata +2 -2
data/auto-set-id-before-save.org
CHANGED
data/custom-configurations.org
CHANGED
@@ -1,54 +1,93 @@
|
|
1
1
|
* Additional config items in Configuration File
|
2
2
|
|
3
|
-
You can define your own configuration items in
|
4
|
-
=~/.arql.d/init.yaml=), and then get the value of the configuration item in the code
|
5
|
-
=
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
3
|
+
You can define your own configuration items in a configuration file (such as the default =~/.arql.yaml= /
|
4
|
+
=~/.arql.d/init.yaml= ), and then get the value of the configuration item in the code with
|
5
|
+
=env_config(/my_env/)["CONF_KEY"]-= .
|
6
|
+
|
7
|
+
|
8
|
+
For example, let's say the system encrypts the field of the =account_no= BankAccount table, and you can define the key
|
9
|
+
for encryption in the configuration file:
|
10
|
+
|
11
|
+
#+begin_src yaml
|
12
|
+
dev:
|
13
|
+
<<: *default
|
14
|
+
host: 127.0.0.1
|
15
|
+
port: 3306
|
16
|
+
username: test
|
17
|
+
password: test123456
|
18
|
+
database: devel
|
19
|
+
encrypt_key: "1234567890abcdef"
|
20
|
+
#+end_src
|
21
|
+
|
22
|
+
|
23
|
+
You can then read the value of the config item in the Initialzier code ( =~/.arql.rb= / =~/.arql.d/init.rb= ):
|
24
|
+
|
25
|
+
#+begin_src ruby
|
25
26
|
class BankAccount
|
26
|
-
|
27
|
+
|
27
28
|
def self.encrypt_account_no(account_no)
|
28
29
|
cipher = OpenSSL::Cipher.new('AES-128-ECB')
|
29
30
|
cipher.encrypt
|
30
|
-
cipher.key =
|
31
|
+
cipher.key = env_config(/my_env/)["encrypt_key"]
|
31
32
|
encrypted = cipher.update(account_no) + cipher.final
|
32
33
|
encrypted.unpack('H*').first
|
33
34
|
end
|
34
|
-
|
35
|
+
|
35
36
|
def self.decrypt_account_no(encrypted_account_no)
|
36
37
|
cipher = OpenSSL::Cipher.new('AES-128-ECB')
|
37
38
|
cipher.decrypt
|
38
|
-
cipher.key =
|
39
|
+
cipher.key = env_config(/my_env/)["encrypt_key"]
|
39
40
|
decrypted = cipher.update([encrypted_account_no].pack('H*')) + cipher.final
|
40
41
|
decrypted
|
41
42
|
end
|
42
|
-
|
43
|
-
|
44
|
-
#
|
43
|
+
|
44
|
+
|
45
|
+
# 从数据库查询出数据之后,自动解密 account_no 字段
|
45
46
|
after_find do
|
46
47
|
self.password = decrypt_account_no(self.password)
|
47
48
|
end
|
48
|
-
|
49
|
-
#
|
49
|
+
|
50
|
+
# 保存数据之前,自动加密 account_no 字段
|
51
|
+
before_save do
|
52
|
+
self.password = encrypt_account_no(self.password)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
#+end_src
|
56
|
+
|
57
|
+
|
58
|
+
You can also use the config method of the Namespace Module to obtain the value of the configuration item, for example:
|
59
|
+
|
60
|
+
|
61
|
+
Assuming the Namespace Module is , then =NS= the above code can be rewritten as:
|
62
|
+
|
63
|
+
#+begin_src ruby
|
64
|
+
class BankAccount
|
65
|
+
|
66
|
+
def self.encrypt_account_no(account_no)
|
67
|
+
cipher = OpenSSL::Cipher.new('AES-128-ECB')
|
68
|
+
cipher.encrypt
|
69
|
+
cipher.key = NS::config["encrypt_key"]
|
70
|
+
encrypted = cipher.update(account_no) + cipher.final
|
71
|
+
encrypted.unpack('H*').first
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.decrypt_account_no(encrypted_account_no)
|
75
|
+
cipher = OpenSSL::Cipher.new('AES-128-ECB')
|
76
|
+
cipher.decrypt
|
77
|
+
cipher.key = NS::config["encrypt_key"]
|
78
|
+
decrypted = cipher.update([encrypted_account_no].pack('H*')) + cipher.final
|
79
|
+
decrypted
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# 从数据库查询出数据之后,自动解密 account_no 字段
|
84
|
+
after_find do
|
85
|
+
self.password = decrypt_account_no(self.password)
|
86
|
+
end
|
87
|
+
|
88
|
+
# 保存数据之前,自动加密 account_no 字段
|
50
89
|
before_save do
|
51
90
|
self.password = encrypt_account_no(self.password)
|
52
91
|
end
|
53
92
|
end
|
54
|
-
#+
|
93
|
+
#+end_src
|
data/define-associations.org
CHANGED
@@ -1,37 +1,60 @@
|
|
1
|
-
* Define
|
1
|
+
* 1. Define the relationship in the initializer file
|
2
2
|
|
3
|
-
You can define associations in Initializers. Arql will generate model classes based on the database schema when it starts, and then load the Initializer file.
|
4
3
|
|
5
|
-
|
4
|
+
Associations can be defined in the initializer file, and when Arql starts, it first generates the model class based on
|
5
|
+
the database schema and then loads the initializer file.
|
6
6
|
|
7
|
-
#+BEGIN_SRC ruby
|
8
|
-
class Student
|
9
|
-
has_many :courses, foreign_key: :student_id, class_name: 'Course'
|
10
|
-
belongs_to :school, foreign_key: :school_id, class_name: 'School'
|
11
7
|
|
12
|
-
|
13
|
-
end
|
8
|
+
The initializer file is a Ruby file, so you can define associations within it, for example:
|
14
9
|
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
#+begin_src ruby
|
11
|
+
module Blog
|
12
|
+
class Student
|
13
|
+
has_many :courses, foreign_key: :student_id, class_name: 'Course'
|
14
|
+
belongs_to :school, foreign_key: :school_id, class_name: 'School'
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
has_and_belongs_to_many :teachers, join_table: 'students_teachers', foreign_key: :student_id, association_foreign_key: :teacher_id, class_name: 'Teacher'
|
17
|
+
end
|
18
|
+
|
19
|
+
class Course
|
20
|
+
belongs_to :student, foreign_key: :student_id, class_name: 'Student'
|
21
|
+
end
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
class School
|
24
|
+
has_many :students, foreign_key: :school_id, class_name: 'Student'
|
25
|
+
end
|
26
|
+
|
27
|
+
class Teacher
|
28
|
+
has_and_belongs_to_many :students, join_table: 'students_teachers', foreign_key: :teacher_id, association_foreign_key: :student_id, class_name: 'Student'
|
29
|
+
end
|
25
30
|
end
|
26
|
-
#+
|
27
|
-
|
28
|
-
1.
|
29
|
-
2. =belongs_to=
|
30
|
-
3. =has_and_belongs_to_many=
|
31
|
-
4. =class_name=
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
31
|
+
#+end_src
|
32
|
+
|
33
|
+
1. =has_one= Indicates that this table is a one-to-one relationship with the owner
|
34
|
+
2. =belongs_to= Indicates that this table is a subordinate of a one-to-many or one-to-one relationship
|
35
|
+
3. =has_and_belongs_to_many= Indicates that this table is one of the parties to a many-to-many relationship
|
36
|
+
4. =class_name= The model class name of the other party that indicates the relationship (the model class name is
|
37
|
+
actually the CamelCase form of the table name)
|
38
|
+
5. =foreign_key= Indicates the name of the associated field on the side of the dependent table in the association
|
39
|
+
6. =primary_key= Indicates the name of the association field on the side of the master table in the association
|
40
|
+
7. =join_table= In a many-to-many relationship, the name of the intermediate table that is associated with two tables is
|
41
|
+
indicated
|
42
|
+
8. =association_foreign_key= In a many-to-many relationship, indicates the name of the field associated with the other
|
43
|
+
model's model in the intermediate table
|
44
|
+
|
45
|
+
可以参考: [[https://guides.rubyonrails.org/association_basics.html]]
|
46
|
+
|
47
|
+
|
48
|
+
Considering that the model classes are all defined under the Namespace module, a blog here is necessary.
|
49
|
+
|
50
|
+
|
51
|
+
Of course, Arql will load the =~/.arql.rb= OR =~/.arql.d/init.rb= file by default, regardless of which environment is
|
52
|
+
selected via the =-e= options, so putting a fixed namespace =Blog= in the default initialization file like in the
|
53
|
+
example above is not a good choice.
|
54
|
+
|
55
|
+
There are two ways to solve this problem:
|
56
|
+
|
57
|
+
1.
|
58
|
+
When using arql, for different environments, use =-i= the option to specify different initialization files, such as:
|
59
|
+
=arql -e blog -i ~/.arql.d/blog.rb=
|
60
|
+
2. Refer to Put the initialization code for different environments in different files
|
@@ -28,7 +28,7 @@
|
|
28
28
|
end
|
29
29
|
#+END_SRC
|
30
30
|
|
31
|
-
这样,当执行 =arql -e apollo.dev= 或 =arql
|
31
|
+
这样,当执行 =arql -e apollo.dev= 或 =arql -e apollo.prod= 时,就会加载 =apollo.rb= 文件中的初始化代码;当执行 =arql
|
32
32
|
-e space.dev= 或 =arql -e space.prod= 时,就会加载 =space.rb= 文件中的初始化代码。
|
33
33
|
|
34
34
|
=apollo.rb= 或 =space.rb= 文件中的代码将在对应的 Namespace Module 下执行:
|
data/initializer-structure.org
CHANGED
@@ -1,31 +1,59 @@
|
|
1
1
|
* Place your initialization code in a file named after the environment
|
2
2
|
|
3
|
-
If you have multiple environments in your configuration file, you can place the initialization code for each environment in a separate file to avoid conflicts.
|
4
3
|
|
5
|
-
|
4
|
+
There are often multiple environment configurations for multiple databases in the configuration file, so you can use the
|
5
|
+
method here to put the initialization code of different environments in different files to avoid conflicts.
|
6
6
|
|
7
|
-
|
8
|
-
+ apollo.prod
|
9
|
-
+ space.dev
|
10
|
-
+ space.prod
|
7
|
+
Let's say you have 4 database environments configured in the configuration file:
|
11
8
|
|
12
|
-
|
9
|
+
- apollo.dev
|
10
|
+
- apollo.prod
|
11
|
+
- space.dev
|
12
|
+
- space.prod
|
13
13
|
|
14
|
-
+ apollo.rb
|
15
|
-
+ space.rb
|
16
14
|
|
17
|
-
|
15
|
+
Then you can create the following file in the =~/.arql.d/= directory:
|
16
|
+
|
17
|
+
- apollo.rb
|
18
|
+
- space.rb
|
19
|
+
|
20
|
+
|
21
|
+
Place the initialization code for the Apollo project =apollo.rb= in the file; Place the initialization code for the
|
22
|
+
space project =space.rb= in the file.
|
23
|
+
|
18
24
|
|
19
25
|
Then write the following code in the =~/.arql.d/init.eb= file:
|
20
26
|
|
21
|
-
#+
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
27
|
+
#+begin_src ruby
|
28
|
+
Dir.glob(File.dirname(__FILE__) + '/*.rb').each do |f|
|
29
|
+
Arql::App.instance.definitions.each do |env, definition|
|
30
|
+
if env.starts_with?(File.basename(f, '.rb'))
|
31
|
+
load(f, definition.namespace_module)
|
32
|
+
end
|
26
33
|
end
|
27
34
|
end
|
28
|
-
#+
|
35
|
+
#+end_src
|
36
|
+
|
37
|
+
|
38
|
+
In this way, =arql -e apollo.prod= when or is executed, the initialization =apollo.rb= code in the file is loaded, and
|
39
|
+
=arql -e space.prod= when or is executed =arql -e apollo.dev= =arql -e space.dev= , the initialization code in the file
|
40
|
+
is loaded =space.rb= .
|
41
|
+
|
29
42
|
|
30
|
-
|
31
|
-
|
43
|
+
=apollo.rb= The code in the =space.rb= or file will be executed under the corresponding Namespace Module:
|
44
|
+
|
45
|
+
#+begin_src ruby
|
46
|
+
class Astronaut
|
47
|
+
has_many :missions
|
48
|
+
end
|
49
|
+
#+end_src
|
50
|
+
|
51
|
+
Equivalent to:
|
52
|
+
|
53
|
+
#+begin_src ruby
|
54
|
+
module Apollo
|
55
|
+
class Astronaut
|
56
|
+
has_many :missions
|
57
|
+
end
|
58
|
+
end
|
59
|
+
#+end_src
|
data/lib/arql/cli.rb
CHANGED
@@ -12,6 +12,7 @@ module Arql
|
|
12
12
|
def parse_options!
|
13
13
|
@options = OpenStruct.new(config_file: default_config_file,
|
14
14
|
initializer: default_initializer,
|
15
|
+
babel_compatable: false,
|
15
16
|
ssh: {})
|
16
17
|
|
17
18
|
|
@@ -96,6 +97,11 @@ module Arql
|
|
96
97
|
@options.code = code
|
97
98
|
end
|
98
99
|
|
100
|
+
opts.on('-b', '--babel', 'Enable compatibility for Org-Mode Babel') do
|
101
|
+
@options.babel_compatable = true
|
102
|
+
end
|
103
|
+
|
104
|
+
|
99
105
|
opts.on('-S', '--show-sql', 'Show SQL on STDOUT') do
|
100
106
|
@options.show_sql = true
|
101
107
|
end
|
data/lib/arql/repl.rb
CHANGED
data/lib/arql/version.rb
CHANGED
data/oss-files-zh_CN.org
CHANGED
@@ -66,13 +66,13 @@
|
|
66
66
|
def initialize(path, bucket: nil)
|
67
67
|
@path = path
|
68
68
|
unless bucket
|
69
|
-
bucket =
|
69
|
+
bucket = env_config(/./)['oss_bucket']
|
70
70
|
end
|
71
71
|
@bucket = bucket
|
72
72
|
end
|
73
73
|
|
74
74
|
def rclone_name
|
75
|
-
|
75
|
+
env_config(/./)['rclone_name']
|
76
76
|
end
|
77
77
|
|
78
78
|
def info
|
data/oss-files.org
CHANGED
@@ -66,13 +66,13 @@
|
|
66
66
|
def initialize(path, bucket: nil)
|
67
67
|
@path = path
|
68
68
|
unless bucket
|
69
|
-
bucket =
|
69
|
+
bucket = env_config(/./)['oss_bucket']
|
70
70
|
end
|
71
71
|
@bucket = bucket
|
72
72
|
end
|
73
73
|
|
74
74
|
def rclone_name
|
75
|
-
|
75
|
+
env_config(/./)['rclone_name']
|
76
76
|
end
|
77
77
|
|
78
78
|
def info
|
data/sql-log.org
CHANGED
@@ -7,13 +7,18 @@
|
|
7
7
|
Create a file =~/.arql.d/sql_log.rb= with the following content:
|
8
8
|
|
9
9
|
#+BEGIN_SRC ruby
|
10
|
-
unless Arql::App.
|
10
|
+
unless Arql::App.instance.options.append_sql
|
11
11
|
log_root_dir = File.expand_path('~/.arql.d/logs')
|
12
|
-
|
12
|
+
if Arql::App.instance.environments.present?
|
13
|
+
log_dir = "#{log_root_dir}/%s" % Arql::App.instance.environments.join('_')
|
14
|
+
elsif File.file?(Arql::App.instance.options[:database])
|
15
|
+
log_dir = "#{log_root_dir}/%s" % File.basename(Arql::App.instance.options[:database])
|
16
|
+
end
|
17
|
+
|
13
18
|
FileUtils.mkdir_p(log_dir)
|
14
19
|
now = Time.now
|
15
20
|
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.
|
21
|
+
Arql::App.instance.options.append_sql = log_file
|
17
22
|
|
18
23
|
lfile = File.new(log_file, 'a')
|
19
24
|
lfile.sync = true
|
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.4.
|
4
|
+
version: 0.4.1
|
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-04-
|
11
|
+
date: 2024-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mysql2
|