dynamic-records-meritfront 3.0.1 → 3.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +50 -29
- data/lib/dynamic-records-meritfront/version.rb +1 -1
- data/lib/dynamic-records-meritfront.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa816c1fc2d4e08950ff1f91c1bb4aa1d8025a4e845d62919e7254e449a6901f
|
4
|
+
data.tar.gz: 4649ad599b97346ca16ddbb5f07298fd0408d5028795fcfcb3e5f0b5d1f906c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2dbba9dee9ca11dab5665b0d96a2b13840f7bfff8eb28c859e8628119efb420924435ed06ca380dc9fec7408231cf7a7f9671429cc34c18c2e0536646324a3ba
|
7
|
+
data.tar.gz: cddf05b9c1f9eb9df8c1c7fb1a586dc618eed8a5f3fd0a0b8f8b4017d3bbb0beee66143c4925bd102af52d2ea6e302c5fda7384ca8c4f7cfafa8b481afefc0f8
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -11,14 +11,12 @@ Note that postgres is currently a requirement for this gem.
|
|
11
11
|
```ruby
|
12
12
|
# returns a json-like hash list of user data
|
13
13
|
users = ApplicationRecord.dynamic_sql(
|
14
|
-
'get_5_users',
|
15
14
|
'select * from users limit :our_limit',
|
16
15
|
our_limit: 5
|
17
16
|
)
|
18
17
|
|
19
18
|
#returns a list of users (each an instance of User)
|
20
19
|
users = User.dynamic_sql(
|
21
|
-
'get_users_from_ids',
|
22
20
|
'select * from users where id = ANY (:ids)',
|
23
21
|
ids: [1,2,3]
|
24
22
|
)
|
@@ -53,28 +51,34 @@ Or install it yourself as:
|
|
53
51
|
class ApplicationRecord < ActiveRecord::Base
|
54
52
|
self.abstract_class = true
|
55
53
|
include DynamicRecordsMeritfront
|
56
|
-
|
54
|
+
|
55
|
+
#DYNAMIC_SQL_RAW determines whether dynamic_sql method returns a ActiveRecord::Response object or an Array.
|
56
|
+
#They both have pros and cons. False returns the array.
|
57
|
+
DynamicRecordsMeritfront::DYNAMIC_SQL_RAW = false
|
57
58
|
end
|
58
59
|
```
|
59
60
|
|
60
61
|
### SQL methods
|
61
62
|
|
62
|
-
|
63
|
+
Methods written for easier sql usage.
|
63
64
|
|
64
|
-
#### self.dynamic_sql(name, sql, opts = { })
|
65
|
+
#### self.dynamic_sql( *optional* name, sql, opts = { })
|
65
66
|
A better and safer way to write sql. Can return either a Hash, ActiveRecord::Response object, or an instantiated model.
|
66
67
|
|
68
|
+
```ruby
|
69
|
+
User.dynamic_sql('select * from users') #returns all users
|
70
|
+
ApplicationRecord.dynamic_sql('select * from users') #returns all user column information in an array
|
71
|
+
```
|
72
|
+
|
67
73
|
with options:
|
68
74
|
- options not stated below: considered sql arguments, and will replace their ":option_name" with a sql argument. Always use sql arguments to avoid sql injection. Lists are converted into a format such as ```{1,2,3,4}```. Lists of lists are converted into ```(1,2,3), (4,5,6), (7,8,9)``` etc. So as to allow easy inserts/upserts.
|
69
75
|
- raw: whether to return a ActiveRecord::Response object or a hash when called on an abstract class (like ApplicationRecord). Default can be switched with DYNAMIC_SQL_RAW variable on the class level.
|
70
|
-
- instantiate_class: determines what format to return. Can return ActiveRecord objects (User, Post, etc), or whatever raw is set to. I prefer doing the alterantive ```User.dynamic_sql(...)``` which is also supported. For example, ```User.dynamic_sql(...)``` will return User records. ```ApplicationRecord.dynamic_sql(..., raw: false)``` will return a List of Hashes with the column names as keys. ```ApplicationRecord.dynamic_sql(..., raw: true)``` will return an ActiveRecord::Response.
|
71
76
|
|
72
|
-
other options:
|
77
|
+
other less critical options:
|
73
78
|
|
74
79
|
- prepare: Defaults to true. Gets passed to ActiveRecord::Base.connection.exec_query as a parameter. Should change whether the command will be prepared, which means that on subsequent calls the command will be faster. Downsides are when, for example, the sql query has hard-coded arguments, the query always changes, causing technical issues as the number of prepared statements stack up.
|
75
|
-
- name_modifiers: allows one to change the associated name dynamically.
|
76
80
|
- multi_query: allows more than one query (you can seperate an insert and an update with ';' I dont know how else to say it.)
|
77
|
-
this disables other options including
|
81
|
+
this disables other options including sql_arguments. Not sure how it effects prepared statements. Not super useful.
|
78
82
|
- async: Defaults to false. Gets passed to ActiveRecord::Base.connection.exec_query as a parameter. See that methods documentation for more. I was looking through the source code, and I think it only effects how it logs to the logfile?
|
79
83
|
|
80
84
|
<details>
|
@@ -91,7 +95,7 @@ Delete Friend Requests between two users after they have become friends.
|
|
91
95
|
</details>
|
92
96
|
|
93
97
|
<details>
|
94
|
-
<summary>
|
98
|
+
<summary>example usage with interpreted sql string</summary>
|
95
99
|
Get all users who have made a friend request to a particular user with an optional limit.
|
96
100
|
This is an example of why this method is good for dynamic prepared statements.
|
97
101
|
|
@@ -106,9 +110,7 @@ This is an example of why this method is good for dynamic prepared statements.
|
|
106
110
|
) AS all_friend_requests
|
107
111
|
ORDER BY all_friend_requests.created_at DESC
|
108
112
|
#{"LIMIT :limit" if limit > 0}
|
109
|
-
}, uid: u, limit: limit
|
110
|
-
limit > 0 ? 'limited' : nil
|
111
|
-
])
|
113
|
+
}, uid: u, limit: limit)
|
112
114
|
```
|
113
115
|
</details>
|
114
116
|
|
@@ -117,13 +119,13 @@ This is an example of why this method is good for dynamic prepared statements.
|
|
117
119
|
|
118
120
|
```ruby
|
119
121
|
#get a normal test vote
|
120
|
-
test = Vote.dynamic_sql(
|
122
|
+
test = Vote.dynamic_sql(%Q{
|
121
123
|
SELECT id FROM votes LIMIT 1
|
122
124
|
}).first
|
123
125
|
v.inspect # "#<Vote id: 696969>"
|
124
126
|
|
125
127
|
#get a cool test vote. Note that is_this_vote_cool is not on the vote table.
|
126
|
-
test = Vote.dynamic_sql(
|
128
|
+
test = Vote.dynamic_sql(%Q{
|
127
129
|
SELECT id, 'yes' AS is_this_vote_cool FROM votes LIMIT 1
|
128
130
|
}).first
|
129
131
|
test.inspect # #<Vote id: 696969, is_this_vote_cool: "yes"> #getting attributes added dynamically to the models, and also showing up on inspects, was... more difficult than i anticipated.
|
@@ -147,27 +149,28 @@ Get users who match a list of ids. Uses a postgresql Array, see the potential is
|
|
147
149
|
Do an upsert
|
148
150
|
|
149
151
|
```ruby
|
152
|
+
time = DateTime.now
|
150
153
|
rows = uzrs.map{|u| [
|
151
154
|
u.id, #user_id
|
152
155
|
self.id, #conversation_id
|
153
156
|
from, #invited_by
|
154
|
-
|
155
|
-
|
157
|
+
:time, #created_at (We use symbols to denote other sql arguments)
|
158
|
+
:time, #updated_at
|
156
159
|
]}
|
157
160
|
ApplicationRecord.dynamic_sql("upsert_conversation_invites_2", %Q{
|
158
161
|
INSERT INTO conversation_participants (user_id, conversation_id, invited_by, created_at, updated_at)
|
159
162
|
VALUES :rows
|
160
163
|
ON CONFLICT (conversation_id,user_id)
|
161
164
|
DO UPDATE SET updated_at = :time
|
162
|
-
}, rows: rows, time:
|
165
|
+
}, rows: rows, time: time)
|
163
166
|
```
|
164
|
-
This will output sql similar to below. Note this can be done for multiple conversation_participants. Also note that
|
167
|
+
This will output sql similar to below. Note this can be done for multiple conversation_participants. Also note that we sent only one time variable during our request instead of duplicating it.
|
165
168
|
```sql
|
166
169
|
INSERT INTO conversation_participants (user_id, conversation_id, invited_by, created_at, updated_at)
|
167
170
|
VALUES ($1,$2,$3,$4,$4)
|
168
171
|
ON CONFLICT (conversation_id,user_id)
|
169
172
|
DO UPDATE SET updated_at = $4
|
170
|
-
-- [["rows_1", 15], ["rows_2", 67], ["rows_3", 6], [
|
173
|
+
-- [["rows_1", 15], ["rows_2", 67], ["rows_3", 6], [:time, "2022-10-13 20:49:27.441372"]]
|
171
174
|
```
|
172
175
|
</details>
|
173
176
|
|
@@ -175,6 +178,10 @@ This will output sql similar to below. Note this can be done for multiple conver
|
|
175
178
|
#### self.dynamic_preload(records, associations)
|
176
179
|
Preloads from a list of records, and not from a ActiveRecord_Relation. This will be useful when using the above dynamic_sql method (as it returns a list of records, and not a record relation). This is basically the same as a normal relation preload but it works on a list.
|
177
180
|
|
181
|
+
```ruby
|
182
|
+
ApplicationRecord.dynamic_preload(comments, [:votes])
|
183
|
+
```
|
184
|
+
|
178
185
|
<details>
|
179
186
|
<summary>example usage</summary>
|
180
187
|
Preload :votes on some comments. :votes is an active record has_many relation.
|
@@ -184,7 +191,7 @@ Preload :votes on some comments. :votes is an active record has_many relation.
|
|
184
191
|
SELECT * FROM comments LIMIT 4
|
185
192
|
})
|
186
193
|
comments.class.to_s # 'Array' note: not a relation.
|
187
|
-
ApplicationRecord.
|
194
|
+
ApplicationRecord.dynamic_preload(comments, [:votes])
|
188
195
|
puts comments[0].votes #this line should be preloaded and hence not call the database
|
189
196
|
|
190
197
|
#note that this above is basically the same as doing the below assuming there is a comments relation on the user model.
|
@@ -199,6 +206,10 @@ good during enum migrations as the code to migrate wont run if enumerate is ther
|
|
199
206
|
as it is not yet enumerated (causing an error when it loads the class that will have the
|
200
207
|
enumeration in it). This can lead it to being impossible to commit clean code.
|
201
208
|
|
209
|
+
```ruby
|
210
|
+
ApplicationRecord.has_run_migration?('UserImageRelationsTwo')
|
211
|
+
```
|
212
|
+
|
202
213
|
<details><summary>example usage</summary>
|
203
214
|
only load relationa if it exists in the database
|
204
215
|
|
@@ -219,6 +230,10 @@ end
|
|
219
230
|
|
220
231
|
accepts a list of association names, checks if the model has those associations
|
221
232
|
|
233
|
+
```ruby
|
234
|
+
obj.has_association?(:votes)
|
235
|
+
```
|
236
|
+
|
222
237
|
<details><summary>example usage</summary>
|
223
238
|
Check if object is a votable class
|
224
239
|
|
@@ -230,19 +245,27 @@ obj.has_association?(:votes) #false
|
|
230
245
|
```
|
231
246
|
</details>
|
232
247
|
|
233
|
-
#### self.
|
248
|
+
#### self.instaload_sql( *optional* name, insta_array, opts = { })
|
234
249
|
*instaloads* a bunch of diffrent models at the same time by casting them to json before returning them. Kinda cool. Maybe a bit overcomplicated. Seems to be more efficient to preloading when i tested it.
|
235
250
|
- name is passed to dynamic_sql and is the name of the sql request
|
236
251
|
- opts are passed to dynamic_sql (except for the raw option which is set to true. Raw output is not allowed on this request)
|
237
252
|
- requires a list of instaload method output which provides information for how to treat each sql block.
|
238
|
-
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
out = ApplicationRecord.instaload_sql([
|
256
|
+
ApplicationRecord.instaload("SELECT id FROM users", relied_on: true, dont_return: true, table_name: "users_2"),
|
257
|
+
ApplicationRecord.instaload("SELECT id FROM users_2 WHERE id % 2 != 0 LIMIT :limit", table_name: 'a'),
|
258
|
+
User.instaload("SELECT id FROM users_2 WHERE id % 2 != 1 LIMIT :limit", table_name: 'b')
|
259
|
+
], limit: 2)
|
260
|
+
```
|
261
|
+
|
239
262
|
<details>
|
240
263
|
<summary>example usage</summary>
|
241
264
|
#get list of users, those users friends, and who those users follow, all in one request.
|
242
265
|
|
243
266
|
```ruby
|
244
267
|
# the ruby entered
|
245
|
-
output = ApplicationRecord.
|
268
|
+
output = ApplicationRecord.instaload_sql([
|
246
269
|
User.instaload('SELECT id FROM users WHERE users.id = ANY (:user_ids) AND users.created_at > :time', table_name: 'limited_users', relied_on: true),
|
247
270
|
User.instaload(%Q{
|
248
271
|
SELECT friends.smaller_user_id AS id, friends.bigger_user_id AS friended_to
|
@@ -297,13 +320,11 @@ the output:
|
|
297
320
|
{"followable_id"=>932, "follower_id"=>23},
|
298
321
|
{"followable_id"=>935, "follower_id"=>19},
|
299
322
|
...]}
|
300
|
-
|
301
|
-
|
302
323
|
```
|
303
324
|
</details>
|
304
325
|
|
305
326
|
#### self.instaload(sql, table_name: nil, relied_on: false, dont_return: false)
|
306
|
-
A method used to prepare data for the
|
327
|
+
A method used to prepare data for the instaload_sql method. It returns a hash of options.
|
307
328
|
- klass called on: if called on an abstract class (ApplicationRecord) it will return a list of hashes with the data. Otherwise returns a list of the classes records.
|
308
329
|
- table_name: sets the name of the temporary postgresql table. This can then be used in further instaload sql snippets.
|
309
330
|
- relied_on: will make it so other instaload sql snippets can reference this table (it makes it use posrgresql's WITH operator)
|
@@ -329,7 +350,7 @@ User.instaload('SELECT id FROM users WHERE users.id = ANY (:user_ids) AND users.
|
|
329
350
|
</details>
|
330
351
|
|
331
352
|
#### self.dynamic_attach(instaload_sql_output, base_name, attach_name, base_on: nil, attach_on: nil, one_to_one: false)
|
332
|
-
taking the output of the
|
353
|
+
taking the output of the instaload_sql method, this method creates relations between the models.
|
333
354
|
- base_name: the name of the table we will be attaching to
|
334
355
|
- attach_name: the name of the table that will be attached
|
335
356
|
- base_on: put a proc here to override the matching key for the base table. Default is, for a user and post type, {|user| user.id}
|
@@ -337,7 +358,7 @@ taking the output of the dynamic_instaload_sql, this method attaches the models
|
|
337
358
|
- one_to_one: switches between a one-to-one relationship or not
|
338
359
|
|
339
360
|
<details>
|
340
|
-
<summary> attach information for each limited_user in the
|
361
|
+
<summary> attach information for each limited_user in the instaload_sql example </summary>
|
341
362
|
|
342
363
|
```ruby
|
343
364
|
|
@@ -17,7 +17,7 @@ module DynamicRecordsMeritfront
|
|
17
17
|
#should work, probably able to override by redefining in ApplicationRecord class.
|
18
18
|
#Note we defined here as it breaks early on as Rails.application returns nil
|
19
19
|
PROJECT_NAME = Rails.application.class.to_s.split("::").first.to_s.downcase
|
20
|
-
DYNAMIC_SQL_RAW =
|
20
|
+
DYNAMIC_SQL_RAW = true
|
21
21
|
end
|
22
22
|
class DynamicSqlVariables
|
23
23
|
attr_accessor :sql_hash
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynamic-records-meritfront
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luke Clancy
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-12-
|
11
|
+
date: 2022-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashid-rails
|