nativeson 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bdd09728925e3cdbf77d8d45269217ce1badef3fe74ea8c81ebe036f8276c118
4
- data.tar.gz: f1c4dbf20d9ba42ddeba263c697fbcb57611bfc292af1231139318e59c674bbd
3
+ metadata.gz: b056f93f7704b53d3b7f0dd83bcdae69aef206e20bb4cef6b07cf6e873d11553
4
+ data.tar.gz: 6418c98c04695a468694719725cd637d7918148989a6d746f93e2dfa8894cacc
5
5
  SHA512:
6
- metadata.gz: e04bc7807eb087d6f25a75e6cf434190082b40d2bef77bbd1359e04fca1d8b1db60463d6f989095202d81d2f22aa9d96f39e55c8cad098e147742ad60aec2af1
7
- data.tar.gz: 8c0a89cd1e70357366d85812518cd429207636a774d173cd0e1bd15a022ab5c97d0feb7ed9400c1aef21917ce52a4eb93cbd0453fa95bb05cb19d1dda94ebe9a
6
+ metadata.gz: 1ad3911db1c2c77c771ec8399393d7c6ba18d3999cbea7942492ba20905d5f38774c20741ca5f257ec80d061314bce3d4d88da883ca3072b09e11311207008f7
7
+ data.tar.gz: 5cd61b22e42e0dbed9e66cd6fbf4d8bd21b73f81fd2a434b2beb3f9fa609711eb3835820a31070ffcf63c20eb0e30fe38d2edd402a9249834013222f7bd3375c
data/README.md CHANGED
@@ -61,9 +61,9 @@ end
61
61
  ```
62
62
  you can call Nativeson as follows:
63
63
  ```ruby
64
- sql_generator = Nativeson.fetch_json_by_query_hash(
64
+ nativeson_hash = Nativeson.fetch_json_by_query_hash(
65
65
  { klass: 'User',
66
- where: 'created_at > CURRENT_TIMESTAMP - INTERVAL \'1 day\' ',
66
+ where: 'created_at > CURRENT_TIMESTAMP - INTERVAL \'10 day\' ',
67
67
  order: 'created_at desc',
68
68
  limit: 10,
69
69
  associations: {
@@ -97,40 +97,73 @@ sql_generator = Nativeson.fetch_json_by_query_hash(
97
97
  }
98
98
  }
99
99
  )
100
+ ```
101
+ where
102
+ * `nativeson_hash[:query_hash]` is the query hash supplied as input
103
+ * `nativeson_hash[:container]` is the underlying `Nativeson` query tree structure
104
+ * `nativeson_hash[:sql]` is the SQL query used to generate the JSON string
105
+ * `nativeson_hash[:json]` is the JSON string, ready to be sent to the front-end
106
+
107
+ Nativeson also supports two other calling interfaces:
108
+
109
+ 1. Pass an ActiveRecord query object to `Nativeson.fetch_json_by_rails_query`. The query you're passing must `respond_to?(:to_sql)` by producing a String containing a SQL query.
110
+
111
+ ```
112
+ nativeson_hash = Nativeson.fetch_json_by_rails_query(User.where('id > ?', 1).order(:created_at => :desc))
113
+ ```
100
114
 
101
- result = ActiveRecord::Base.connection.execute(sql_generator[:sql])
102
- json_string = result.getvalue(0, 0)
103
- result.clear # <- good housekeeping practice to free the memory allocated by the PG gem
115
+ 2. Pass a raw SQL query string to `Nativeson.fetch_json_by_string`.
116
+
117
+ ```
118
+ nativeson_hash = Nativeson.fetch_json_by_string('select id, created_at from users limit 2')
119
+ ```
120
+ where
121
+ * `nativeson_hash[:sql]` is the SQL query used to generate the JSON string
122
+ * `nativeson_hash[:json]` is the JSON string, ready to be sent to the front-end
123
+
124
+ Here is a short example of the JSON output for a single User model instance with some associations and nested associations:
125
+ ```json
126
+ [{"id":1,"created_at":"2018-10-13T20:37:16.59672","updated_at":"2018-10-13T20:37:16.59672","name":"ayankfjpxlfjo","email":"taliahyatt@lueilwitz.org","col_int":918,"col_float":70.8228834313906,"col_string":"ygsvwobjiadfw","klass":"User","items":[{"id":1,"user_id":1,"created_at":"2018-10-13T20:37:16.847055","updated_at":"2018-10-13T20:37:16.847055","name":"ayankfjpxlfjo","col_int":111,"col_float":826.58466863469,"col_string":"ehbautrrelysd","klass":"Item","item_description":[{"id":1,"item_id":1,"description":"ayankfjpxlfjo","created_at":"2018-10-13T20:37:17.40971","updated_at":"2018-10-13T20:37:17.40971","col_int":70,"col_float":586.497122020896,"col_string":"vixbltiopskxy","klass":"ItemDescription"}],"item_prices":[{"id":1,"item_id":1,"current_price":55.834605139059,"previous_price":57.4058337411023,"created_at":"2018-10-13T20:37:17.514948","updated_at":"2018-10-13T20:37:17.514948","klass":"ItemPrice"}]},
127
+ {"id":2,"user_id":1,"created_at":"2018-10-13T20:37:16.847055","updated_at":"2018-10-13T20:37:16.847055","name":"ayankfjpxlfjo","col_int":136,"col_float":631.548964229925,"col_string":"watxmnafzzmeu","klass":"Item","item_description":[{"id":2,"item_id":2,"description":"ayankfjpxlfjo","created_at":"2018-10-13T20:37:17.40971","updated_at":"2018-10-13T20:37:17.40971","col_int":878,"col_float":511.772295898348,"col_string":"khzoaziqopnkl","klass":"ItemDescription"}],"item_prices":[{"id":2,"item_id":2,"current_price":33.8844481909688,"previous_price":97.403522117916,"created_at":"2018-10-13T20:37:17.514948","updated_at":"2018-10-13T20:37:17.514948","klass":"ItemPrice"}]}],"user_profile":[{"id":1,"user_id":1,"created_at":"2018-10-13T20:37:17.204195","updated_at":"2018-10-13T20:37:17.204195","name":"ayankfjpxlfjo","col_int":null,"col_float":null,"col_string":null,"klass":"UserProfile","user_profile_pic":[{"id":1,"user_profile_id":1,"image_url":"wljyqyzyxqfsn","image_width":104,"image_height":228,"created_at":"2018-10-13T20:37:17.235248","updated_at":"2018-10-13T20:37:17.235248","klass":"UserProfilePic"}]}],"widgets":[{"id":1,"user_id":1,"created_at":"2018-10-13T20:37:17.100901","updated_at":"2018-10-13T20:37:17.100901","name":"ayankfjpxlfjo","col_int":242,"col_float":223.65750025762,"col_string":"cxaqmdnmufnvt","klass":"Widget","sub_widgets":[{"id":3,"name":"ayankfjpxlfjo_5.92774893856709","widget_id":1,"created_at":"2018-10-13T20:37:17.912943","updated_at":"2018-10-13T20:37:17.912943","col_int":687,"col_float":851.650101581247,"col_string":"toozdtwuyaesn","klass":"SubWidget"},
128
+ {"id":2,"name":"ayankfjpxlfjo_4.07599669367832","widget_id":1,"created_at":"2018-10-13T20:37:17.912943","updated_at":"2018-10-13T20:37:17.912943","col_int":943,"col_float":257.325888075186,"col_string":"rscziazmauagm","klass":"SubWidget"},
129
+ {"id":1,"name":"ayankfjpxlfjo_2.9579304830078375","widget_id":1,"created_at":"2018-10-13T20:37:17.912943","updated_at":"2018-10-13T20:37:17.912943","col_int":896,"col_float":38.2691573106148,"col_string":"fmetacimdbjnv","klass":"SubWidget"}]},
130
+ {"id":2,"user_id":1,"created_at":"2018-10-13T20:37:17.100901","updated_at":"2018-10-13T20:37:17.100901","name":"ayankfjpxlfjo","col_int":956,"col_float":949.173224865556,"col_string":"oeoybsrtkjnfb","klass":"Widget","sub_widgets":[{"id":6,"name":"ayankfjpxlfjo_5.943535906853784","widget_id":2,"created_at":"2018-10-13T20:37:17.912943","updated_at":"2018-10-13T20:37:17.912943","col_int":601,"col_float":218.619706269916,"col_string":"qvslwrgieoidv","klass":"SubWidget"},
131
+ {"id":5,"name":"ayankfjpxlfjo_2.003554122744414","widget_id":2,"created_at":"2018-10-13T20:37:17.912943","updated_at":"2018-10-13T20:37:17.912943","col_int":220,"col_float":583.631142121848,"col_string":"yerhhrsmsyydc","klass":"SubWidget"},
132
+ {"id":4,"name":"ayankfjpxlfjo_4.047681099308994","widget_id":2,"created_at":"2018-10-13T20:37:17.912943","updated_at":"2018-10-13T20:37:17.912943","col_int":668,"col_float":839.024125756382,"col_string":"oegjbumatstvp","klass":"SubWidget"}]},
133
+ {"id":3,"user_id":1,"created_at":"2018-10-13T20:37:17.100901","updated_at":"2018-10-13T20:37:17.100901","name":"ayankfjpxlfjo","col_int":391,"col_float":99.9364653444063,"col_string":"incqzwrenmrxh","klass":"Widget","sub_widgets":[{"id":9,"name":"ayankfjpxlfjo_0.37354840663121935","widget_id":3,"created_at":"2018-10-13T20:37:17.912943","updated_at":"2018-10-13T20:37:17.912943","col_int":558,"col_float":991.578355632946,"col_string":"ihqoxbanvsqfn","klass":"SubWidget"},
134
+ {"id":8,"name":"ayankfjpxlfjo_1.8483953654699228","widget_id":3,"created_at":"2018-10-13T20:37:17.912943","updated_at":"2018-10-13T20:37:17.912943","col_int":21,"col_float":203.657249239792,"col_string":"khmzcemxpkvub","klass":"SubWidget"},
135
+ {"id":7,"name":"ayankfjpxlfjo_1.1359488386694","widget_id":3,"created_at":"2018-10-13T20:37:17.912943","updated_at":"2018-10-13T20:37:17.912943","col_int":335,"col_float":144.911845441697,"col_string":"gpbpeniemwpdk","klass":"SubWidget"}]}]}]
104
136
  ```
105
137
 
138
+
106
139
  ## Benchmarks
107
140
 
108
- We compared Nativeson to [`ActiveModel::Serializer`](https://github.com/rails-api/active_model_serializers) as a Rails standard and to [Panko](https://github.com/yosiat/panko_serializer), which according to https://yosiat.github.io/panko_serializer/performance.html is 5-10x as fast as AMS in microbenchmarking and ~3x as fast as AMS in an end-to-end Web page load test.
109
- It's important to note that both rely on `ActiveRecord` to fetch the data for them, which makes a huge difference in the benchmark comparisons to Nativeson.
141
+ We compared Nativeson to [ActiveModel::Serializer](https://github.com/rails-api/active_model_serializers) as a Rails standard and to [Panko](https://github.com/yosiat/panko_serializer), which according to https://yosiat.github.io/panko_serializer/performance.html is 5-10x as fast as AMS in microbenchmarking and ~3x as fast as AMS in an end-to-end Web page load test.
142
+ It's important to note that both rely on ActiveRecord to fetch the data for them, which makes a huge difference in the benchmark comparisons to Nativeson.
110
143
 
111
- In a "standard" flow, such as `Panko` and `ActiveModel::Serializer`.
112
- The cycle is:
113
- * `request`
114
- * `DB query`
115
- * `ActiveRecord`
116
- * `Panko` or `ActiveModel::Serializer` serialization.
117
- * `JSON response`
144
+ In a "standard" flow, such as Panko and ActiveModel::Serializer,
145
+ the lifecycle is:
146
+ 1. HTTP request received
147
+ 1. database query
148
+ 1. ActiveRecord model object instantiation
149
+ 1. Panko or ActiveModel::Serializer serialization
150
+ 1. JSON response
118
151
 
119
- With Nativeson the cycle is shorter:
120
- * `request`
121
- * `DB query`
122
- * `JSON response`
152
+ With Nativeson the lifecycle is shorter:
153
+ 1. HTTP request received
154
+ 1. database query
155
+ 1. JSON response
123
156
 
124
157
  Because of the above, there are a few important items to take into account:
125
158
  * Nativeson should be used when a SQL query is sufficient to retrieve/calculate all
126
159
  the data needed to create your response.
127
160
  If you need to query the database and then do complex postprocessing of the data in Ruby,
128
161
  then Nativeson may not fit your needs.
129
- * We compared performance with/without the `ActiveRecord`
130
- database query stage. We believe this stage should be included in any decision to use one or another of these gems, because in real world use, the cycle
131
- time will usually include it.
162
+ * We compared performance with/without the ActiveRecord
163
+ database query stage. We believe this stage should be included in any decision to use one or another of these gems, because in real world use, the lifecycle
164
+ will usually include it.
132
165
 
133
- The fastest result for each row is shown in bold in the table below. Note that, like in Panko's own published benchmark results, `Panko`'s speedup relative to `ActiveModel::Serializer` is partly obscured in real-world usage by the large fraction of time spent just querying the database and constructing `ActiveRecord` object instances; Nativeson sidesteps that work entirely, calling upon the database's native JSON generation functions to produce a JSON string directly.
166
+ The fastest result for each row is shown in bold in the table below. Note that, like in Panko's own published benchmark results, Panko's speedup relative to ActiveModel::Serializer is partly obscured in real-world usage by the large fraction of time spent just querying the database and constructing ActiveRecord object instances; Nativeson sidesteps that work entirely, calling upon the database's native JSON generation functions to produce a JSON string directly.
134
167
 
135
168
  Benchmark results table:
136
169
 
@@ -159,7 +192,7 @@ Benchmark results table:
159
192
  <td>2429</td>
160
193
  <td></td>
161
194
  <td>
162
- <a href='dummy/test/benchmarks/users_no_associations/excluding_active_records/benchmark.rb'>
195
+ <a href='test/dummy/test/benchmarks/users_no_associations/excluding_active_records/benchmark.rb'>
163
196
  benchmark
164
197
  </a>
165
198
  </td>
@@ -174,7 +207,7 @@ Benchmark results table:
174
207
  <td>510</td>
175
208
  <td></td>
176
209
  <td>
177
- <a href='dummy/test/benchmarks/users_no_associations/excluding_active_records/benchmark.rb'>
210
+ <a href='test/dummy/test/benchmarks/users_no_associations/excluding_active_records/benchmark.rb'>
178
211
  benchmark
179
212
  </a>
180
213
  </td>
@@ -189,7 +222,7 @@ Benchmark results table:
189
222
  <td>349</td>
190
223
  <td></td>
191
224
  <td>
192
- <a href='dummy/test/benchmarks/users_no_associations/excluding_active_records/benchmark.rb'>
225
+ <a href='test/dummy/test/benchmarks/users_no_associations/excluding_active_records/benchmark.rb'>
193
226
  benchmark
194
227
  </a>
195
228
  </td>
@@ -204,7 +237,7 @@ Benchmark results table:
204
237
  <td><b>2341</b></td>
205
238
  <td></td>
206
239
  <td>
207
- <a href='dummy/test/benchmarks/users_no_associations/including_active_records/benchmark.rb'>
240
+ <a href='test/dummy/test/benchmarks/users_no_associations/including_active_records/benchmark.rb'>
208
241
  benchmark
209
242
  </a>
210
243
  </td>
@@ -219,7 +252,7 @@ Benchmark results table:
219
252
  <td><b>550</b></td>
220
253
  <td></td>
221
254
  <td>
222
- <a href='dummy/test/benchmarks/users_no_associations/including_active_records/benchmark.rb'>
255
+ <a href='test/dummy/test/benchmarks/users_no_associations/including_active_records/benchmark.rb'>
223
256
  benchmark
224
257
  </a>
225
258
  </td>
@@ -234,7 +267,7 @@ Benchmark results table:
234
267
  <td><b>295</b></td>
235
268
  <td></td>
236
269
  <td>
237
- <a href='dummy/test/benchmarks/users_no_associations/including_active_records/benchmark.rb'>
270
+ <a href='test/dummy/test/benchmarks/users_no_associations/including_active_records/benchmark.rb'>
238
271
  benchmark
239
272
  </a>
240
273
  </td>
@@ -249,7 +282,7 @@ Benchmark results table:
249
282
  <td>237</td>
250
283
  <td></td>
251
284
  <td>
252
- <a href='dummy/test/benchmarks/users_all_associations/excluding_active_records/benchmark.rb'>
285
+ <a href='test/dummy/test/benchmarks/users_all_associations/excluding_active_records/benchmark.rb'>
253
286
  benchmark
254
287
  </a>
255
288
  </td>
@@ -264,7 +297,7 @@ Benchmark results table:
264
297
  <td>14</td>
265
298
  <td></td>
266
299
  <td>
267
- <a href='dummy/test/benchmarks/users_all_associations/excluding_active_records/benchmark.rb'>
300
+ <a href='test/dummy/test/benchmarks/users_all_associations/excluding_active_records/benchmark.rb'>
268
301
  benchmark
269
302
  </a>
270
303
  </td>
@@ -279,7 +312,7 @@ Benchmark results table:
279
312
  <td>13</td>
280
313
  <td></td>
281
314
  <td>
282
- <a href='dummy/test/benchmarks/users_all_associations/excluding_active_records/benchmark.rb'>
315
+ <a href='test/dummy/test/benchmarks/users_all_associations/excluding_active_records/benchmark.rb'>
283
316
  benchmark
284
317
  </a>
285
318
  </td>
@@ -294,7 +327,7 @@ Benchmark results table:
294
327
  <td><b>238</b></td>
295
328
  <td></td>
296
329
  <td>
297
- <a href='dummy/test/benchmarks/users_all_associations/including_active_records/benchmark.rb'>
330
+ <a href='test/dummy/test/benchmarks/users_all_associations/including_active_records/benchmark.rb'>
298
331
  benchmark
299
332
  </a>
300
333
  </td>
@@ -309,7 +342,7 @@ Benchmark results table:
309
342
  <td><b>15.2</b></td>
310
343
  <td></td>
311
344
  <td>
312
- <a href='dummy/test/benchmarks/users_all_associations/including_active_records/benchmark.rb'>
345
+ <a href='test/dummy/test/benchmarks/users_all_associations/including_active_records/benchmark.rb'>
313
346
  benchmark
314
347
  </a>
315
348
  </td>
@@ -324,7 +357,7 @@ Benchmark results table:
324
357
  <td><b>12.6</b></td>
325
358
  <td></td>
326
359
  <td>
327
- <a href='dummy/test/benchmarks/users_all_associations/including_active_records/benchmark.rb'>
360
+ <a href='test/dummy/test/benchmarks/users_all_associations/including_active_records/benchmark.rb'>
328
361
  benchmark
329
362
  </a>
330
363
  </td>
@@ -6,8 +6,11 @@ module Nativeson
6
6
  nativeson_hash = {}
7
7
  nativeson_hash[:query_hash] = query_hash
8
8
  nativeson_hash[:container] = NativesonContainer.new(container_type: :base, query: nativeson_hash[:query_hash], parent: nil)
9
- nativeson_hash[:sql] = nativeson_hash[:container].generate_sql
10
- nativeson_hash[:json] = ActiveRecord::Base.connection.select_value(nativeson_hash[:sql])
9
+ sql = nativeson_hash[:container].generate_sql
10
+ nativeson_hash[:sql] = sql
11
+ result = ActiveRecord::Base.connection.execute(sql)
12
+ nativeson_hash[:json] = result.getvalue(0, 0)
13
+ result.clear
11
14
  return nativeson_hash
12
15
  end
13
16
  ################################################################
@@ -1,3 +1,3 @@
1
1
  module Nativeson
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nativeson
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ohad Dahan
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-10-14 00:00:00.000000000 Z
12
+ date: 2018-10-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -73,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
73
  version: '0'
74
74
  requirements: []
75
75
  rubyforge_project:
76
- rubygems_version: 2.7.7
76
+ rubygems_version: 2.7.6
77
77
  signing_key:
78
78
  specification_version: 4
79
79
  summary: nativeson