simple_query 0.3.0 → 0.3.2

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: f15e71d4ac10ed8d359f177e46f36f12b9721da6f9f51c75d8a0571cf245aac0
4
- data.tar.gz: 8090bd8f93899061f15a048a7c57a73e48e8805e7fee3807bb39ba91e0012b1f
3
+ metadata.gz: 6aeb71d493d14743e43b8c9a37eed697f131db105ffc4dc0fa35dd0dd189255b
4
+ data.tar.gz: 82b1815e569f24a4c4da9e4cd727d95ad6c938403bd2b781eccfc39398cb264b
5
5
  SHA512:
6
- metadata.gz: 903a9d4754ed89bf718918de17d94bf09969dc5a725d933b68c101a71737d397e90a89ac3ab141b4e18f855b39a81d62a27982c207dca20e7df7f0c6d8571746
7
- data.tar.gz: 2965ff1462a4036112ba0bfe974087c72ba5e8f9b8db15d39a5f5879394dbe074cf9942682f9b50732c61f0d25749c514d38f1e11e2c8e0414308ee676f14ba1
6
+ metadata.gz: d422a6a3484d4242b6666bb6536f4828b666c0f16dd6a0c42104b12e3f077bd30e580dc9cf5eb4292ecbb1cd0eda218aabe29af6e221a86c3291fc116b62b856
7
+ data.tar.gz: cf6e7c8a7e198d1b5376053237d7bdfac59819e07571adb5656e859de9a3bb840dace69e2e600703b14a5ff01bfedbf448d1aadb471a3875874c7d390599878a
data/README.md CHANGED
@@ -54,11 +54,12 @@ User.simple_query.select(:name, :email).where(active: true).execute
54
54
  ```
55
55
 
56
56
  Query with join
57
+
58
+ SimpleQuery now supports **all major SQL join types** — including LEFT, RIGHT, and FULL — through the following DSL methods:
57
59
  ```ruby
58
60
  User.simple_query
59
- .select(:name, :email)
60
- .join(:users, :companies, foreign_key: :user_id, primary_key: :id)
61
- .where(Company.arel_table[:name].eq("TechCorp"))
61
+ .left_join(:users, :companies, foreign_key: :user_id, primary_key: :id)
62
+ .select("users.name", "companies.name")
62
63
  .execute
63
64
  ```
64
65
 
@@ -82,6 +83,27 @@ User.simple_query
82
83
  .lazy_execute
83
84
  ```
84
85
 
86
+ Placeholder-Based Conditions
87
+
88
+ SimpleQuery now supports **ActiveRecord-style placeholders**, letting you pass arrays with `?` or `:named` placeholders to your `.where` clauses:
89
+
90
+ ```ruby
91
+ # Positional placeholders:
92
+ User.simple_query
93
+ .where(["name LIKE ?", "%Alice%"])
94
+ .execute
95
+
96
+ # Named placeholders:
97
+ User.simple_query
98
+ .where(["email = :email", { email: "alice@example.com" }])
99
+ .execute
100
+
101
+ # Multiple placeholders in one condition:
102
+ User.simple_query
103
+ .where(["age >= :min_age AND age <= :max_age", { min_age: 18, max_age: 35 }])
104
+ .execute
105
+ ```
106
+
85
107
  ## Custom Read Models
86
108
  By default, SimpleQuery returns results as `Struct` objects for maximum speed. However, you can also define a lightweight model class for more explicit attribute handling or custom logic.
87
109
 
@@ -122,9 +144,13 @@ class User < ActiveRecord::Base
122
144
  where(admin: true)
123
145
  end
124
146
 
147
+ # Block-based scope with parameter
125
148
  simple_scope :by_name do |name|
126
149
  where(name: name)
127
150
  end
151
+
152
+ # Lambda-based scope with parameter
153
+ simple_scope :by_name, ->(name) { where(name: name) }
128
154
  end
129
155
  ```
130
156
  You can then chain these scopes seamlessly with the normal SimpleQuery DSL:
@@ -34,12 +34,24 @@ module SimpleQuery
34
34
  self
35
35
  end
36
36
 
37
- def join(table1, table2, foreign_key:, primary_key:)
38
- @joins.add(table1, table2, foreign_key: foreign_key, primary_key: primary_key)
37
+ def join(table1, table2, foreign_key:, primary_key:, type: :inner)
38
+ @joins.add(table1, table2, foreign_key: foreign_key, primary_key: primary_key, join_type: type)
39
39
  reset_query
40
40
  self
41
41
  end
42
42
 
43
+ def left_join(table1, table2, foreign_key:, primary_key:)
44
+ join(table1, table2, foreign_key: foreign_key, primary_key: primary_key, type: :left)
45
+ end
46
+
47
+ def right_join(table1, table2, foreign_key:, primary_key:)
48
+ join(table1, table2, foreign_key: foreign_key, primary_key: primary_key, type: :right)
49
+ end
50
+
51
+ def full_join(table1, table2, foreign_key:, primary_key:)
52
+ join(table1, table2, foreign_key: foreign_key, primary_key: primary_key, type: :full)
53
+ end
54
+
43
55
  def order(order_conditions)
44
56
  @orders.add(order_conditions)
45
57
  reset_query
@@ -8,20 +8,37 @@ module SimpleQuery
8
8
  @joins = []
9
9
  end
10
10
 
11
- def add(table1, table2, foreign_key:, primary_key:)
11
+ def add(table1, table2, foreign_key:, primary_key:, join_type: :inner)
12
12
  @joins << {
13
13
  table1: to_arel_table(table1),
14
14
  table2: to_arel_table(table2),
15
15
  foreign_key: foreign_key,
16
- primary_key: primary_key
16
+ primary_key: primary_key,
17
+ type: join_type
17
18
  }
18
19
  end
19
20
 
20
21
  def apply_to(query)
21
- @joins.each do |join|
22
- query.join(join[:table2])
23
- .on(join[:table2][join[:foreign_key]]
24
- .eq(join[:table1][join[:primary_key]]))
22
+ @joins.each do |join_def|
23
+ table1 = join_def[:table1]
24
+ table2 = join_def[:table2]
25
+ fk = join_def[:foreign_key]
26
+ pk = join_def[:primary_key]
27
+ type = join_def[:type]
28
+
29
+ join_class = case type
30
+ when :left
31
+ Arel::Nodes::OuterJoin
32
+ when :right
33
+ Arel::Nodes::RightOuterJoin
34
+ when :full
35
+ Arel::Nodes::FullOuterJoin
36
+ else
37
+ Arel::Nodes::InnerJoin
38
+ end
39
+
40
+ condition = table2[fk].eq(table1[pk])
41
+ query.join(table2, join_class).on(condition)
25
42
  end
26
43
  query
27
44
  end
@@ -30,6 +30,9 @@ module SimpleQuery
30
30
  condition.map { |field, value| @table[field].eq(value) }
31
31
  when Arel::Nodes::Node
32
32
  [condition]
33
+ when Array
34
+ sanitized_sql = ActiveRecord::Base.send(:sanitize_sql_array, condition)
35
+ [Arel.sql(sanitized_sql)]
33
36
  else
34
37
  [Arel.sql(condition.to_s)]
35
38
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleQuery
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.2"
5
5
  end
data/lib/simple_query.rb CHANGED
@@ -41,19 +41,13 @@ module SimpleQuery
41
41
  @_simple_scopes ||= {}
42
42
  end
43
43
 
44
- # A reusable scope that can be applied to a SimpleQuery::Builder instance
45
- # Example:
46
- # simple_scope :active do
47
- # where(active: true)
48
- # end
49
- #
50
- # Parameterized scope:
51
- # simple_scope :by_name do |name|
52
- # where(name: name)
53
- # end
54
- #
55
- def simple_scope(name, &block)
56
- _simple_scopes[name.to_sym] = block
44
+ def simple_scope(name, body = nil, &block)
45
+ raise ArgumentError, "Pass either a proc/lambda or a block, not both" if body && block_given?
46
+
47
+ scope_body = body || block
48
+ raise ArgumentError, "You must provide a block or a proc" unless scope_body
49
+
50
+ _simple_scopes[name.to_sym] = scope_body
57
51
  end
58
52
  end
59
53
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_query
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Kholodniak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-02-26 00:00:00.000000000 Z
11
+ date: 2025-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord