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.
@@ -5,7 +5,7 @@
5
5
  Create a file =~/.arql.d/auto_gen_id.rb= with the following content:
6
6
 
7
7
  #+BEGIN_SRC ruby
8
- class ::ArqlModel
8
+ class :Arql::BaseModel
9
9
  before_create do
10
10
  if id.blank?
11
11
  id_type = self.class.columns_hash['id'].sql_type.scan(/\w+/).first
@@ -1,54 +1,93 @@
1
1
  * Additional config items in Configuration File
2
2
 
3
- You can define your own configuration items in the 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 through
5
- =Arql::App.config["CONF_KEY"]=.
6
-
7
- For example, suppose the system encrypts the =account_no= field of the BankAccount table, you can define the
8
- encryption key in the configuration file:
9
-
10
- #+BEGIN_SRC yaml
11
- dev:
12
- <<: *default
13
- host: 127.0.0.1
14
- port: 3306
15
- username: test
16
- password: test123456
17
- database: devel
18
- encrypt_key: "1234567890abcdef"
19
- #+END_SRC
20
-
21
- Then you can read the value of the configuration item in the Initialzier code (=~/.arql.rb= /
22
- =~/.arql.d/init.rb=):
23
-
24
- #+BEGIN_SRC ruby
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 = Arql::App.config["encrypt_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 = Arql::App.config["encrypt_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
- # After querying the data from the database, automatically decrypt the account_no field
43
+
44
+
45
+ # 从数据库查询出数据之后,自动解密 account_no 字段
45
46
  after_find do
46
47
  self.password = decrypt_account_no(self.password)
47
48
  end
48
-
49
- # Before saving the data, automatically encrypt the account_no field
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
- #+END_SRC
93
+ #+end_src
@@ -1,37 +1,60 @@
1
- * Define associations in Initializers
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
- The Initializer file is a Ruby file, so you can define associations in it, for example:
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
- has_and_belongs_to_many :teachers, join_table: 'students_teachers', foreign_key: :student_id, association_foreign_key: :teacher_id, class_name: 'Teacher'
13
- end
8
+ The initializer file is a Ruby file, so you can define associations within it, for example:
14
9
 
15
- class Course
16
- belongs_to :student, foreign_key: :student_id, class_name: 'Student'
17
- end
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
- class School
20
- has_many :students, foreign_key: :school_id, class_name: 'Student'
21
- end
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
- class Teacher
24
- has_and_belongs_to_many :students, join_table: 'students_teachers', foreign_key: :teacher_id, association_foreign_key: :student_id, class_name: 'Student'
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
- #+END_SRC
27
-
28
- 1. =has_one= indicates that this table is the owner of a one-to-one relationship
29
- 2. =belongs_to= indicates that this table is the dependent side of a one-to-many or one-to-one relationship
30
- 3. =has_and_belongs_to_many= indicates that this table is one of the many-to-many relationships
31
- 4. =class_name= indicates the Model class name of the corresponding relationship (the Model class name is actually the CamelCase form of the table name)
32
- 5. =foreign_key= indicates the name of the association field on the dependent side of the association
33
- 6. =primary_key= indicates the name of the association field on the owner side of the association
34
- 7. =join_table= in many-to-many relationships, indicates the name of the intermediate table that associates the two tables
35
- 8. =association_foreign_key= in many-to-many relationships, indicates the association field name of the other Model in the intermediate table
36
-
37
- You can refer to: https://guides.rubyonrails.org/association_basics.html
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 =e apollo.prod= 时,就会加载 =apollo.rb= 文件中的初始化代码;当执行 =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 下执行:
@@ -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
- Suppose you have 4 database environments in your configuration file:
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
- + apollo.dev
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
- You can create the following files in the =~/.arql.d/= directory:
9
+ - apollo.dev
10
+ - apollo.prod
11
+ - space.dev
12
+ - space.prod
13
13
 
14
- + apollo.rb
15
- + space.rb
16
14
 
17
- Place the initialization code for the apollo project in the =apollo.rb= file; place the initialization code for the space project in the =space.rb= file.
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
- #+BEGIN_SRC ruby
22
- ["apollo", "space"].each do |project|
23
- if Arql::App.env.try { |e| e.include?(project + ".") }
24
- load(File.absolute_path(File.dirname(__FILE__) + "/#{project}.rb"))
25
- break
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
- #+END_SRC
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
- Now, when you run =arql -e apollo.dev= or =arql =e apollo.prod=, the initialization code in the =apollo.rb= file will be loaded; when you run =arql -e space.dev= or =arql -e space.prod=, the initialization code in the =space.rb= file will be loaded.
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
@@ -6,7 +6,7 @@ require 'rainbow'
6
6
  module Arql
7
7
  class Repl
8
8
  def initialize
9
- Pry.config.prompt = Pry::Prompt.new("", "", prompt)
9
+ Pry.config.prompt = Pry::Prompt.new('', '', prompt) unless App.instance.options.babel_compatable
10
10
  Pry.start
11
11
  end
12
12
 
data/lib/arql/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Arql
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
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 = Arql::App.config['oss_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
- Arql::App.config['rclone_name']
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 = Arql::App.config['oss_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
- Arql::App.config['rclone_name']
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.config[:append_sql]
10
+ unless Arql::App.instance.options.append_sql
11
11
  log_root_dir = File.expand_path('~/.arql.d/logs')
12
- log_dir = "#{log_root_dir}/%s" % Arql::App.env
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.config[:append_sql] = log_file
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.0
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-16 00:00:00.000000000 Z
11
+ date: 2024-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mysql2