kweerie 0.1.2 → 0.1.4
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/.rake_tasks~ +20 -0
- data/README.md +98 -8
- data/lib/kweerie/base.rb +6 -0
- data/lib/kweerie/base_objects.rb +21 -13
- data/lib/kweerie/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8c4f949ad0ee144a37015f2444ad19721390ee94a59b1fc118599409b6b0f0a
|
4
|
+
data.tar.gz: a8b741b11e8dd572f6fccba9f06becbb75b06f0444e879f43b21f70d164d2ba7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 368206d1376231a56d197911245878f8efdf8eb33f86f47135c079f2d3c28b2ac5a70786b7bafaa694b980f6f192ea6ac2d43ffcdb41f77bbd24aee295c7b9c4
|
7
|
+
data.tar.gz: 82c8cb0e9a1171f3a0e90b0db23ebc5f35e2b82401f4db2066b3903db383b8e08f619ab25edefbc0bea4ebab93fde9072d86895bfa864a1f793c4370f5f02f03
|
data/.rake_tasks~
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
build
|
2
|
+
build:checksum
|
3
|
+
clean
|
4
|
+
clobber
|
5
|
+
default
|
6
|
+
install
|
7
|
+
install:local
|
8
|
+
release[remote]
|
9
|
+
release:guard_clean
|
10
|
+
release:rubygem_push
|
11
|
+
release:source_control_push[remote]
|
12
|
+
rubocop
|
13
|
+
rubocop:auto_correct
|
14
|
+
rubocop:autocorrect
|
15
|
+
rubocop:autocorrect_all
|
16
|
+
test
|
17
|
+
test:cmd
|
18
|
+
test:deps
|
19
|
+
test:isolated
|
20
|
+
test:slow
|
data/README.md
CHANGED
@@ -74,6 +74,96 @@ user.name # => "Claude"
|
|
74
74
|
user.created_at # => 2024-01-01 00:00:00 +0000 (Time object)
|
75
75
|
```
|
76
76
|
|
77
|
+
## Querying
|
78
|
+
|
79
|
+
Kweerie provides two main ways to execute queries based on whether they have parameters:
|
80
|
+
|
81
|
+
### Parameterized Queries
|
82
|
+
|
83
|
+
When your query needs parameters, use the `.with` method:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
class UsersByDepartment < Kweerie::Base
|
87
|
+
bind :department, as: '$1'
|
88
|
+
bind :active, as: '$2'
|
89
|
+
end
|
90
|
+
|
91
|
+
# app/queries/users_by_department.sql
|
92
|
+
SELECT *
|
93
|
+
FROM users
|
94
|
+
WHERE department = $1
|
95
|
+
AND active = $2;
|
96
|
+
|
97
|
+
# Using the query
|
98
|
+
users = UsersByDepartment.with(
|
99
|
+
department: 'Engineering',
|
100
|
+
active: true
|
101
|
+
)
|
102
|
+
```
|
103
|
+
|
104
|
+
### Parameter-free Queries
|
105
|
+
|
106
|
+
For queries that don't require any parameters, you can use the more semantically appropriate `.all` method:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
class AllUsers < Kweerie::Base
|
110
|
+
end
|
111
|
+
|
112
|
+
# app/queries/all_users.sql
|
113
|
+
SELECT *
|
114
|
+
FROM users
|
115
|
+
WHERE active = true
|
116
|
+
ORDER BY created_at DESC;
|
117
|
+
|
118
|
+
# Using the query
|
119
|
+
users = AllUsers.all
|
120
|
+
```
|
121
|
+
|
122
|
+
The `.all` method provides a cleaner interface when you're not binding any parameters. It will raise an error if you try to use it on a query class that has parameter bindings:
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
# This will raise an ArgumentError
|
126
|
+
UsersByDepartment.all
|
127
|
+
# => ArgumentError: Cannot use .all on queries with bindings. Use .with instead.
|
128
|
+
```
|
129
|
+
|
130
|
+
### Choosing Between .all and .with
|
131
|
+
|
132
|
+
- Use `.all` when your SQL query is completely static with no parameters
|
133
|
+
- Use `.with` when you need to pass parameters to your query
|
134
|
+
- Even for parameterized queries, you can use `.with` without arguments if all parameters are optional
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
# A query with no parameters
|
138
|
+
class RecentUsers < Kweerie::Base
|
139
|
+
end
|
140
|
+
RecentUsers.all # ✓ Clean and semantic
|
141
|
+
RecentUsers.with # ✓ Works but less semantic
|
142
|
+
|
143
|
+
# A query with parameters
|
144
|
+
class UsersByStatus < Kweerie::Base
|
145
|
+
bind :status, as: '$1'
|
146
|
+
end
|
147
|
+
UsersByStatus.all # ✗ Raises ArgumentError
|
148
|
+
UsersByStatus.with(status: 'active') # ✓ Correct usage
|
149
|
+
```
|
150
|
+
|
151
|
+
Both methods work with `Kweerie::Base` and `Kweerie::BaseObjects`, returning arrays of hashes or objects respectively:
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
# Returns array of hashes
|
155
|
+
class AllUsers < Kweerie::Base
|
156
|
+
end
|
157
|
+
users = AllUsers.all
|
158
|
+
# => [{"id" => 1, "name" => "Claude"}, ...]
|
159
|
+
|
160
|
+
# Returns array of objects
|
161
|
+
class AllUsers < Kweerie::BaseObjects
|
162
|
+
end
|
163
|
+
users = AllUsers.all
|
164
|
+
# => [#<AllUsers id=1 name="Claude">, ...]
|
165
|
+
```
|
166
|
+
|
77
167
|
### Automatic Type Casting
|
78
168
|
|
79
169
|
BaseObjects automatically casts common PostgreSQL types to their Ruby equivalents:
|
@@ -147,7 +237,7 @@ user.changes # => Hash of changes with [old, new] values
|
|
147
237
|
user.original_attributes # => Original attributes from DB
|
148
238
|
```
|
149
239
|
|
150
|
-
|
240
|
+
### PostgreSQL Array Support
|
151
241
|
|
152
242
|
BaseObjects handles PostgreSQL arrays by converting them to Ruby arrays with proper type casting:
|
153
243
|
|
@@ -167,7 +257,7 @@ user.tags # => ["ruby", "rails"]
|
|
167
257
|
user.scores # => [98.5, 87.2, 92.0]
|
168
258
|
```
|
169
259
|
|
170
|
-
|
260
|
+
### Performance Considerations
|
171
261
|
|
172
262
|
BaseObjects creates a unique class for each query result set, with the following optimizations:
|
173
263
|
|
@@ -179,7 +269,7 @@ BaseObjects creates a unique class for each query result set, with the following
|
|
179
269
|
|
180
270
|
For queries where you don't need the object interface, use `Kweerie::Base` instead for slightly better performance.
|
181
271
|
|
182
|
-
|
272
|
+
## Rails Generator
|
183
273
|
|
184
274
|
If you're using Rails, you can use the generator to create new query files:
|
185
275
|
|
@@ -193,7 +283,7 @@ rails generate kweerie UserSearch email name
|
|
193
283
|
|
194
284
|
This will create both the Ruby class and SQL file with the appropriate structure.
|
195
285
|
|
196
|
-
|
286
|
+
## Configuration
|
197
287
|
|
198
288
|
By default, Kweerie uses ActiveRecord's connection if available. You can configure this and other options:
|
199
289
|
|
@@ -222,7 +312,7 @@ end
|
|
222
312
|
- ✅ Configurable connection handling
|
223
313
|
- ✅ Parameter validation
|
224
314
|
|
225
|
-
|
315
|
+
### Why Kweerie?
|
226
316
|
|
227
317
|
- **SQL Views Overkill**: When a database view is too heavy-handed but you still want to keep SQL separate from Ruby
|
228
318
|
- **Version Control**: Keep your SQL under version control alongside your Ruby code
|
@@ -230,11 +320,11 @@ end
|
|
230
320
|
- **Simple Interface**: Clean, simple API for executing parameterized queries
|
231
321
|
- **Rails Integration**: Works seamlessly with Rails and ActiveRecord
|
232
322
|
|
233
|
-
|
323
|
+
### Development
|
234
324
|
|
235
325
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests.
|
236
326
|
|
237
|
-
|
327
|
+
### Contributing
|
238
328
|
|
239
329
|
1. Fork it
|
240
330
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
@@ -242,7 +332,7 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
242
332
|
4. Push to the branch (`git push origin my-new-feature`)
|
243
333
|
5. Create a new Pull Request
|
244
334
|
|
245
|
-
|
335
|
+
### License
|
246
336
|
|
247
337
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
248
338
|
|
data/lib/kweerie/base.rb
CHANGED
data/lib/kweerie/base_objects.rb
CHANGED
@@ -20,7 +20,7 @@ module Kweerie
|
|
20
20
|
private
|
21
21
|
|
22
22
|
def generate_result_class(attribute_names)
|
23
|
-
@generate_result_class ||= Class.new do
|
23
|
+
@generate_result_class ||= Class.new(self) do
|
24
24
|
# Include comparison and serialization modules
|
25
25
|
include Comparable
|
26
26
|
|
@@ -29,6 +29,20 @@ module Kweerie
|
|
29
29
|
attr_reader name
|
30
30
|
end
|
31
31
|
|
32
|
+
define_method :initialize do |attrs|
|
33
|
+
# Store both raw and casted versions
|
34
|
+
@_raw_original_attributes = attrs.dup
|
35
|
+
@_original_attributes = attrs.transform_keys(&:to_s).transform_values do |value|
|
36
|
+
type_cast_value(value)
|
37
|
+
end
|
38
|
+
|
39
|
+
attrs.each do |name, value|
|
40
|
+
casted_value = type_cast_value(value)
|
41
|
+
instance_variable_set("@#{name}", casted_value)
|
42
|
+
end
|
43
|
+
super() if defined?(super)
|
44
|
+
end
|
45
|
+
|
32
46
|
define_method :type_cast_value do |value|
|
33
47
|
case value
|
34
48
|
when /^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2})?$/ # DateTime check
|
@@ -64,17 +78,6 @@ module Kweerie
|
|
64
78
|
end
|
65
79
|
end
|
66
80
|
|
67
|
-
define_method :initialize do |attrs|
|
68
|
-
# Store original attributes with the same type casting
|
69
|
-
@_original_attributes = attrs.transform_keys(&:to_s).transform_values do |value|
|
70
|
-
type_cast_value(value)
|
71
|
-
end
|
72
|
-
|
73
|
-
attrs.each do |name, value|
|
74
|
-
casted_value = type_cast_value(value)
|
75
|
-
instance_variable_set("@#{name}", casted_value)
|
76
|
-
end
|
77
|
-
end
|
78
81
|
define_method :parse_pg_array do |value|
|
79
82
|
# Remove the curly braces
|
80
83
|
clean_value = value.gsub(/^{|}$/, "")
|
@@ -115,7 +118,7 @@ module Kweerie
|
|
115
118
|
attrs = attribute_names.map do |name|
|
116
119
|
"#{name}=#{instance_variable_get("@#{name}").inspect}"
|
117
120
|
end.join(" ")
|
118
|
-
"#<#{self.class.name
|
121
|
+
"#<#{self.class.superclass.name} #{attrs}>"
|
119
122
|
end
|
120
123
|
|
121
124
|
# Hash-like access
|
@@ -184,6 +187,11 @@ module Kweerie
|
|
184
187
|
@_original_attributes
|
185
188
|
end
|
186
189
|
|
190
|
+
# Raw attributes access
|
191
|
+
define_method :raw_original_attributes do
|
192
|
+
@_raw_original_attributes
|
193
|
+
end
|
194
|
+
|
187
195
|
# ActiveModel-like changes tracking
|
188
196
|
define_method :changed? do
|
189
197
|
to_h != @_original_attributes
|
data/lib/kweerie/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kweerie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Toby
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -59,6 +59,7 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
+
- ".rake_tasks~"
|
62
63
|
- ".rubocop.yml"
|
63
64
|
- CHANGELOG.md
|
64
65
|
- LICENSE.txt
|