querier 0.4.4 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +78 -8
  3. data/lib/querier.rb +8 -9
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 17df356b959c87427cc72225d58d40a38a0e7ad8ba7c0f4f15ceab9c603176eb
4
- data.tar.gz: 0a6286066f90301cd9cf433ad118afe10ab49015fb839a5a7a38233f3821f48d
3
+ metadata.gz: 9288e68d9c81a85ddd04dbac7bda54ed629dc5bcbf3862828234b416646b31e1
4
+ data.tar.gz: 9776a4f2a9d025f4b30c1c41c91e04213d767f696879b1507d27b34210e87617
5
5
  SHA512:
6
- metadata.gz: 92d410ee75923192069927f59609ba491424f672475eda7cc96d333e6ef0ef7f2f1fcab485c4c7463d2e216ce95b660f6a598abdc4591c5a84980395e02a5cef
7
- data.tar.gz: 5e1a04e6e19141b75cae7c9c1ac547b0e0b0bc07d61c0f19800619480743be123d60f218621bf9d6b833f54cb0d1b9d5ee50bc1168370ddc27532a9748eb6588
6
+ metadata.gz: 105265c744ee14f48a2f410839f4c6d075ec1a38a739c83275a86caf34ff24a17cb1270f1e0f01c6cf601cab741a75abfdb64976179ac2e8fb379f5b85703a28
7
+ data.tar.gz: 9d33bef69465070fc629b524004664fca7e256cc7dcc1a6c975a2349aaf8e9d192748fd596015e08714957feda9f8dbc61225186f8d3b35cab513d405d7f7689
data/README.md CHANGED
@@ -1,15 +1,85 @@
1
- # Querier
1
+ # Querier Class for ActiveRecord Custom SQL Queries
2
2
 
3
- Active Record query executer utility.
3
+ This README explains the functionality and use of the `Querier` class, designed to facilitate the construction and execution of custom SQL queries in a Ruby on Rails environment using ActiveRecord.
4
+
5
+ ## Module: `QuerierDatasetExtensions`
6
+
7
+ The `QuerierDatasetExtensions` module extends the results returned by SQL queries with utility methods for easy data transformation:
8
+
9
+ - `as_hash`: Converts each record into a hash with symbolized keys, making it easier to work with the data.
10
+ - `as_struct`: Converts each record into an `OpenStruct` instance, allowing attribute access using dot notation.
11
+
12
+ ## Class: `Querier`
13
+
14
+ The `Querier` class is designed to simplify the execution of custom SQL queries on a specific ActiveRecord model. Below are the detailed explanations of its components:
15
+
16
+ ### 1. Class Variable and Singleton Attribute
17
+
18
+ The class uses a singleton attribute (`@active_record_class`) to maintain a reference to the ActiveRecord class that will be used to execute queries.
19
+
20
+ Instead of using class variables (`@@`), which are generally discouraged due to inheritance and concurrency issues, the implementation uses the recommended approach of using singleton class attributes with `attr_accessor` defined within the `class << self` context.
21
+
22
+ ### 2. Attributes and Initialization
23
+
24
+ - **`@query_params`**: Stores the parameters that will be used to fill in the query template.
25
+ - **`@active_record_class`**: Initialized with the ActiveRecord class defined by the class or superclass. This allows the `Querier` class to be reused for different ActiveRecord models.
26
+
27
+ ### 3. Public Execution Methods
28
+
29
+ The `Querier` class provides several methods to execute SQL queries, wrapping the ActiveRecord connection methods:
30
+
31
+ - `execute`: Executes the query without returning structured records.
32
+ - `exec_query`: Executes the query and returns results as an `ActiveRecord::Result`, extended with the `QuerierDatasetExtensions` module.
33
+ - `select_all`, `select_one`, `select_rows`, `select_values`, `select_value`: These methods provide different formats for returning the query results, such as all records, a single record, rows, values, or a specific value.
34
+
35
+ ### 4. Filling Query Parameters (`fill_query_params`)
36
+
37
+ The private `fill_query_params` method is responsible for parameter interpolation within the `@query_template`.
38
+
39
+ - There are two types of placeholders for parameters in the query:
40
+ - `${param_name}`: This placeholder is replaced by the parameter value, escaped using the ActiveRecord connection's `quote` method to prevent SQL injection.
41
+ - `${param_name/no_quote}`: This placeholder substitutes the value directly without escaping, which is useful when the value is not susceptible to SQL injection (e.g., column names).
42
+
43
+ ### Security Considerations
44
+
45
+ - The use of `${param_name/no_quote}` should be done cautiously, as it may introduce vulnerabilities if used with unvalidated inputs. It is recommended to restrict its use to validated column names only.
46
+
47
+ ### Error Handling
48
+
49
+ Currently, there is no error handling. Adding a `begin-rescue` block in the execution methods could improve robustness, handling issues such as connection failures or SQL syntax errors gracefully.
50
+
51
+ ### Query Template Separation
52
+
53
+ The `@query_template` is not explicitly defined in the provided code. It is recommended to use subclasses or clearly pass a query template, following good design practices to reuse query templates effectively.
54
+
55
+ ### Interface Improvement
56
+
57
+ Adding methods that accept queries directly as arguments could make the class more flexible and easier to use in scenarios where a dynamic query is needed.
58
+
59
+ ## Example Usage
60
+
61
+ Below is an example of how to use the `Querier` class:
4
62
 
5
63
  ```ruby
6
- class UserQuerier < Querier
7
- @active_record_class = ApplicationRecord
8
- def initialize user_name:, active:
9
- @query_template = "SELECT * FROM users WHERE name = ${user_name} AND active = ${active/no_quote}"
64
+ class MyCustomQuery < Querier
65
+ QUERY_TEMPLATE = <<-END_TEMPLATE
66
+ SELECT * FROM users WHERE id = ${user_id}
67
+ END_TEMPLATE
68
+
69
+ def initialize(user_id)
70
+ @query_template = QUERY_TEMPLATE
10
71
  super
11
72
  end
12
73
  end
13
74
 
14
- UserQuerier.new(user_name: 'foo', active: true)select_all.to_struct
15
- ```
75
+ query = MyCustomQuery.new(1)
76
+ result = query.select_one
77
+ puts result # => Returns the user record with id 1
78
+ ```
79
+
80
+ This example demonstrates how the `Querier` class can be used to create specific queries for different purposes, making it easier to organize and reuse SQL queries.
81
+
82
+ ## Summary
83
+
84
+ The `Querier` class provides a convenient way to build and execute custom SQL queries while keeping the process organized. It also enables centralized control for constructing and executing SQL within the context of ActiveRecord. The addition of the `QuerierDatasetExtensions` module further enhances the ease of transforming and using query results.
85
+
data/lib/querier.rb CHANGED
@@ -1,5 +1,10 @@
1
1
  require 'active_record'
2
2
 
3
+ module QuerierDatasetExtensions
4
+ def as_hash = map(&:symbolize_keys)
5
+ def as_struct = map { |record| OpenStruct.new(record) }
6
+ end
7
+
3
8
  class Querier
4
9
  @active_record_class = ActiveRecord::Base
5
10
  # based on rubocop's tips at: https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Style/ClassVars
@@ -17,21 +22,15 @@ class Querier
17
22
  end
18
23
 
19
24
  def execute = @active_record_class.connection.execute(@query)
20
- def exec_query = decorate_dataset_format(@active_record_class.connection.exec_query(@query))
21
- def select_all = decorate_dataset_format(@active_record_class.connection.select_all(@query))
25
+ def exec_query = @active_record_class.connection.exec_query(@query).extend(QuerierDatasetExtensions)
26
+ def select_all = @active_record_class.connection.select_all(@query).extend(QuerierDatasetExtensions)
22
27
  def select_one = @active_record_class.connection.select_one(@query)
23
- def select_values = @active_record_class.connection.select_values(@query)
24
28
  def select_rows = @active_record_class.connection.select_rows(@query)
29
+ def select_values = @active_record_class.connection.select_values(@query)
25
30
  def select_value = @active_record_class.connection.select_value(@query)
26
31
 
27
32
  private
28
33
 
29
- def decorate_dataset_format(dataset)
30
- def dataset.as_hash = map(&:symbolize_keys)
31
- def dataset.as_struct = map { |record| OpenStruct.new(record) }
32
- dataset
33
- end
34
-
35
34
  def fill_query_params
36
35
  query = @query_template.dup
37
36
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: querier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gedean Dias
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-03 00:00:00.000000000 Z
11
+ date: 2024-10-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Active Record queries with variable number of params
14
14
  email: gedean.dias@gmail.com