arfi 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4913826264984ac5b1770bdb6d8f7791091e5211744a2f1dc56743a1d623b3e6
4
- data.tar.gz: ed864c812bdead458a6dcbb664a6a334fe4ec5789e0832699a619558005cfa74
3
+ metadata.gz: 331aff2d0db8aae05dd27918368edd128c8a30f49617026967817b32faf95bfc
4
+ data.tar.gz: b3d68c00606ba1607640b458da75b094cb8a40c88aaf0dbf33758a7902172e07
5
5
  SHA512:
6
- metadata.gz: 29a2edda4c4fd87bedc107439269665033acc8f2c4d501a65727b6569ea47f512eaa857cb8b3c6e92111050ab11d7a63a0646c65cca62a559e149c3d0ce112ed
7
- data.tar.gz: 33a01c96166d42f757972b24fe70e7743ddd64f519bccde85ff45539f76fed5577556ba33081021a0d9ce9f9040282469b2c5cbe3683c1bc4e0eb9ac85439dd7
6
+ metadata.gz: c2db125c26d24967ec3874ac2d210a9c1b35a9c72e929ffbc7b3b7e5c08fdc4e67acacd0f53dfb34ed208051428a785eb5c21c52ae3cc4b578016a45e4c090d2
7
+ data.tar.gz: d8dc170dd81542d52979542dc03c59b041f78b6df62b219c7e5dacbc36c5927e8136a74c3f4e60cc4c108198def13e0ff0879f01c044e3561ff9455c8c088dc3
data/.rubocop.yml CHANGED
@@ -1,3 +1,6 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 3.1
3
3
  NewCops: enable
4
+ Exclude:
5
+ - lib/arfi/extensions/active_record/connection_adapters/postgresql/database_statements.rb
6
+ - 'vendor/**/*'
data/README.md CHANGED
@@ -94,12 +94,12 @@ ARFI is built on top of the following gems:
94
94
 
95
95
  ## Roadmap
96
96
 
97
- | Task | Completed |
98
- |----------------|-----------|
99
- | db:migrate | [x] |
100
- | db:setup | [] |
101
- | db:prepare | [] |
102
- | db:schema:load | [] |
97
+ | Task | Completed |
98
+ |----------------|--------------------|
99
+ | db:migrate | :white_check_mark: |
100
+ | db:setup | :white_check_mark: |
101
+ | db:prepare | :white_check_mark: |
102
+ | db:schema:load | :white_check_mark: |
103
103
 
104
104
  ## Contributing
105
105
 
data/lib/arfi/errors.rb CHANGED
@@ -18,5 +18,13 @@ module Arfi
18
18
  super
19
19
  end
20
20
  end
21
+
22
+ # This error is raised when database adapter is not supported (for e.g., SQLite3).
23
+ class AdapterNotSupported < StandardError
24
+ def initialize(message = 'Adapter not supported')
25
+ @message = message
26
+ super
27
+ end
28
+ end
21
29
  end
22
30
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/connection_adapters/postgresql/database_statements'
4
+
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module PostgreSQL
8
+ module DatabaseStatements
9
+ def raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: true)
10
+ log(sql, name, async: async) do |notification_payload|
11
+ with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
12
+ result = conn.async_exec(sql)
13
+ verified!
14
+ handle_warnings(result)
15
+ notification_payload[:row_count] = result.count
16
+ result
17
+ rescue => e
18
+ if e.message.match?(/ERROR:\s{2}function (\S+\(\w+\)) does not exist/)
19
+ function_name = e.message.match(/ERROR:\s{2}function (\S+\(\w+\)) does not exist/)[1][/^[^(]*/]
20
+ if (function_file = Dir.glob(Rails.root.join('db', 'functions', "#{function_name}_v*.sql").to_s).first)
21
+ conn.async_exec(File.read(function_file).chop)
22
+ retry
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -4,4 +4,4 @@ require 'active_record'
4
4
  require 'active_record/schema'
5
5
  require 'arfi/sql_function_loader'
6
6
  require_relative 'active_record/base'
7
- require_relative 'active_record/tasks/database_tasks'
7
+ require_relative 'active_record/connection_adapters/postgresql/database_statements'
@@ -4,36 +4,58 @@ module Arfi
4
4
  # +Arfi::SqlFunctionLoader+ is a class which loads user defined SQL functions into database.
5
5
  class SqlFunctionLoader
6
6
  class << self
7
+ # +Arfi::SqlFunctionLoader.load!+ -> (nil | void)
8
+ #
9
+ # Loads user defined SQL functions into database.
10
+ #
11
+ # @return [nil] if there is no `db/functions` directory.
12
+ # @return [void] if there is no errors.
13
+ # @raise [Arfi::Errors::AdapterNotSupported] if database adapter is SQLite.
7
14
  def load!
8
- return unless sql_files&.any?
15
+ return unless sql_files.any?
16
+ raise Arfi::Errors::AdapterNotSupported if conn.adapter_name == 'SQLite'
9
17
 
10
- puts '[ARFI] Loading SQL functions BEFORE schema load transaction...'
11
- db_config = Rails.configuration.database_configuration[Rails.env]
12
- conn = conn(db_config)
18
+ populate_db
19
+ conn.close
20
+ end
21
+
22
+ private
13
23
 
14
- sql_files&.each do |file|
24
+ # +Arfi::SqlFunctionLoader#populate_db+ -> void
25
+ #
26
+ # Loads user defined SQL functions into database.
27
+ #
28
+ # @!visibility private
29
+ # @private
30
+ # @return [void]
31
+ def populate_db
32
+ sql_files.each do |file|
15
33
  sql = File.read(file).strip
16
- conn.exec(sql)
34
+ conn.execute(sql)
17
35
  puts "[ARFI] Loaded: #{File.basename(file)}"
18
36
  end
19
-
20
- conn.close
21
37
  end
22
38
 
23
- private
24
-
39
+ # +Arfi::SqlFunctionLoader#sql_files+ -> Array<String>
40
+ #
41
+ # Helper method to get list of SQL files.
42
+ #
43
+ # @!visibility private
44
+ # @private
45
+ # @return [Array<String>] List of SQL files.
25
46
  def sql_files
26
47
  Dir.glob(Rails.root.join('db', 'functions').join('*.sql'))
27
48
  end
28
49
 
29
- def conn(db_config)
30
- PG.connect(
31
- user: db_config['username'],
32
- password: db_config['password'],
33
- host: db_config['host'],
34
- port: db_config['port'],
35
- dbname: db_config['database']
36
- )
50
+ # +Arfi::SqlFunctionLoader#conn+ -> ActiveRecord::ConnectionAdapters::AbstractAdapter
51
+ #
52
+ # Helper method to get database connection.
53
+ #
54
+ # @!visibility private
55
+ # @private
56
+ # @return [ActiveRecord::ConnectionAdapters::AbstractAdapter] Database connection.
57
+ def conn
58
+ ActiveRecord::Base.lease_connection
37
59
  end
38
60
  end
39
61
  end
data/lib/arfi/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Arfi
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -11,5 +11,11 @@ module Arfi
11
11
 
12
12
  def initialize: (?::String message) -> void
13
13
  end
14
+
15
+ class AdapterNotSupported < StandardError
16
+ @message: string
17
+
18
+ def initialize: (?::String message) -> void
19
+ end
14
20
  end
15
21
  end
@@ -1,19 +1,42 @@
1
1
  module Arfi
2
+ # +Arfi::SqlFunctionLoader+ is a class which loads user defined SQL functions into database.
2
3
  class SqlFunctionLoader
3
- type db_config = {
4
- user: String,
5
- password: String,
6
- host: String,
7
- port: Integer,
8
- dbname: String
9
- }
10
-
4
+ # +Arfi::SqlFunctionLoader.load!+ -> (nil | void)
5
+ #
6
+ # Loads user defined SQL functions into database.
7
+ #
8
+ # @return [nil] if there is no `db/functions` directory.
9
+ # @return [void] if there is no errors.
10
+ # @raise [Arfi::Errors::AdapterNotSupported] if database adapter is SQLite.
11
11
  def self.load!: () -> (nil | untyped)
12
12
 
13
13
  private
14
14
 
15
- def self.sql_files: () -> (Array[String] | nil)
15
+ # +Arfi::SqlFunctionLoader#populate_db+ -> void
16
+ #
17
+ # Loads user defined SQL functions into database.
18
+ #
19
+ # @!visibility private
20
+ # @private
21
+ # @return [void]
22
+ def self.populate_db: () -> untyped
23
+
24
+ # +Arfi::SqlFunctionLoader#sql_files+ -> Array<String>
25
+ #
26
+ # Helper method to get list of SQL files.
27
+ #
28
+ # @!visibility private
29
+ # @private
30
+ # @return [Array<String>] List of SQL files.
31
+ def self.sql_files: () -> Array[String]
16
32
 
17
- def self.conn: (db_config db_config) -> untyped
33
+ # +Arfi::SqlFunctionLoader#conn+ -> ActiveRecord::ConnectionAdapters::AbstractAdapter
34
+ #
35
+ # Helper method to get database connection.
36
+ #
37
+ # @!visibility private
38
+ # @private
39
+ # @return [ActiveRecord::ConnectionAdapters::AbstractAdapter] Database connection.
40
+ def self.conn: () -> ::ActiveRecord::ConnectionAdapters::AbstractAdapter
18
41
  end
19
42
  end
@@ -1,3 +1,3 @@
1
1
  module Arfi
2
- VERSION: "0.1.0"
2
+ VERSION: "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arfi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - unurgunite
@@ -34,7 +34,7 @@ files:
34
34
  - lib/arfi/commands/project.rb
35
35
  - lib/arfi/errors.rb
36
36
  - lib/arfi/extensions/active_record/base.rb
37
- - lib/arfi/extensions/active_record/tasks/database_tasks.rb
37
+ - lib/arfi/extensions/active_record/connection_adapters/postgresql/database_statements.rb
38
38
  - lib/arfi/extensions/extensions.rb
39
39
  - lib/arfi/railtie.rb
40
40
  - lib/arfi/sql_function_loader.rb
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveRecord
4
- module Tasks
5
- # @!visibility private
6
- # Under construction.
7
- module DatabaseTasks
8
- # class << self
9
- # alias original_load_schema load_schema
10
- #
11
- # def load_schema(*args)
12
- # Arfi::SqlFunctionLoader.load!
13
- # original_load_schema(*args)
14
- # end
15
- #
16
- # alias original_load_schema_current load_schema_current
17
- #
18
- # def load_schema_current(*args)
19
- # Arfi::SqlFunctionLoader.load!
20
- # original_load_schema_current(*args)
21
- # end
22
- #
23
- # alias original_dump_schema dump_schema
24
- #
25
- # def dump_schema(*args)
26
- # Arfi::SqlFunctionLoader.load!
27
- # original_dump_schema(*args)
28
- # end
29
- # end
30
- end
31
- end
32
- end