post_json 1.0.13 → 1.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +2 -2
- data/README.md +249 -38
- data/lib/core_ext/abstract_adapter_extend.rb +3 -4
- data/lib/core_ext/active_record_relation_extend.rb +3 -4
- data/lib/post_json/base.rb +6 -6
- data/lib/post_json/concerns/copyable.rb +1 -1
- data/lib/post_json/concerns/dynamic_index_methods.rb +2 -6
- data/lib/post_json/query_translator.rb +1 -1
- data/lib/post_json/version.rb +1 -1
- data/spec/models/base_spec.rb +4 -4
- metadata +59 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4e515a137dc47d28656df5a0cb6221765eb2d1e
|
4
|
+
data.tar.gz: 4c00c5e67ce84f313e93d34114962b13098dcdc8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eff7e305c189675ee80be4df40ec658b905e8f91479ec5fb2913162d042a6221717874dc43dcdaaba038a8895d14945083bdfb3479cf898a4bf8fb60cf70cfb3
|
7
|
+
data.tar.gz: 0efb647508cad8ace9357d41405577a0c11c83d6de0a863a24cecbb0875139b878d4de2a83e8e45e84ef172cd8a3fb7b7e7765fc026235c9deb58ee6fd169b2e
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright
|
1
|
+
Copyright 2014 Webnuts (www.webnuts.com / hello@webnuts.com)
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
17
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
19
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,11 +1,45 @@
|
|
1
1
|
# Welcome to PostJson
|
2
2
|
|
3
|
-
PostJson is everything you expect
|
3
|
+
PostJson is everything you expect from ActiveRecord and PostgreSQL with the added power and dynamic nature of a document database (Free as a bird! No schemas!).
|
4
4
|
|
5
5
|
PostJson combines features of Ruby, ActiveRecord and PostgreSQL to provide a great document database by taking advantage of PostgreSQL 9.2+ support for JavaScript (Google's V8 engine). We started the work on PostJson, because we love document databases **and** PostgreSQL.
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
## README contents
|
8
|
+
|
9
|
+
- [Installation](#installation)
|
10
|
+
- [Usage](#usage)
|
11
|
+
- [Model](#model)
|
12
|
+
- [Validations](#validations)
|
13
|
+
- [Querying](#querying)
|
14
|
+
- [Accessing attributes](#accessing-attributes)
|
15
|
+
- [Transformation with select](#transformation-with-select)
|
16
|
+
- [Dates](#dates)
|
17
|
+
- [Supported methods](#supported-methods)
|
18
|
+
- [Configuration Options](#configuration-options)
|
19
|
+
- [Performance](#performance)
|
20
|
+
- [Dynamic Indexes](#dynamic-indexes)
|
21
|
+
- [Example](#example)
|
22
|
+
- [Index configuration](#index-configuration)
|
23
|
+
- [Warning](#warning)
|
24
|
+
- [Manual creation of index](#manual-creation-of-index)
|
25
|
+
- [List existing indexes](#list-existing-indexes)
|
26
|
+
- [Destroying an index](#destroying-an-index)
|
27
|
+
- [Primary Keys](#primary-keys)
|
28
|
+
- [Migrating to PostJson](#migrating-to-postjson)
|
29
|
+
- [Roadmap](#roadmap)
|
30
|
+
- [Version 2.0: Reboot - Close To The Metal](#version-20-reboot--close-to-the-metal)
|
31
|
+
- [Version 2.1: JavaScript Bindings](#version-21-javascript-bindings)
|
32
|
+
- [Version 2.2: Relations](#version-22-relations)
|
33
|
+
- [Version 2.3: Versioning](#version-23-versioning)
|
34
|
+
- [Version 2.4: Bulk Import](#version-24-bulk-import)
|
35
|
+
- [Version 2.5: Export CSV and HTML](#version-25-export-csv-and-html)
|
36
|
+
- [Version 2.6: File Attachments](#version-26-file-attachments)
|
37
|
+
- [Version 2.7: Unused Index Deletion](#version-27-unused-index-deletion)
|
38
|
+
- [Version 3.x: Full Text Search](#version-3x-full-text-search)
|
39
|
+
- [The future](#the-future)
|
40
|
+
- [Requirements](#requirements)
|
41
|
+
- [License](#license)
|
42
|
+
- [Want to contribute?](#want-to-contribute)
|
9
43
|
|
10
44
|
## Installation
|
11
45
|
|
@@ -123,25 +157,24 @@ puts other_me
|
|
123
157
|
|
124
158
|
### Dates
|
125
159
|
|
126
|
-
|
160
|
+
JSON does not natively support dates so Time and DateTime values are serialized as strings with the format of `strftime('%Y-%m-%dT%H:%M:%S.%LZ')`. PostJson will parse an attribute's value to a `DateTime` object if the value is a string and matches the serialization format.
|
161
|
+
|
127
162
|
|
128
163
|
```ruby
|
129
164
|
me = Person.create(name: "Jacob", nested: {now: Time.now})
|
165
|
+
|
166
|
+
# `now` is a regular Time instance before being saved
|
130
167
|
puts me.attributes
|
131
168
|
# => {"name"=>"Jacob", "nested"=>{"now"=>2013-10-24 16:15:05 +0200}, "id"=>"fb9ef4bb-1441-4392-a95d-6402f72829db", "version"=>1, "created_at"=>Thu, 24 Oct 2013 14:15:05 UTC +00:00, "updated_at"=>Thu, 24 Oct 2013 14:15:05 UTC +00:00}
|
132
|
-
```
|
133
169
|
|
134
|
-
|
135
|
-
|
136
|
-
```ruby
|
170
|
+
me.save
|
137
171
|
me.reload
|
172
|
+
|
173
|
+
# after save `now` is the formatted string
|
138
174
|
puts me.attributes
|
139
175
|
# => {"name"=>"Jacob", "nested"=>{"now"=>"2013-10-24T14:15:05.783Z"}, "id"=>"fb9ef4bb-1441-4392-a95d-6402f72829db", "version"=>1, "created_at"=>"2013-10-24T14:15:05.831Z", "updated_at"=>"2013-10-24T14:15:05.831Z"}
|
140
176
|
```
|
141
177
|
|
142
|
-
PostJson will serialize Time and DateTime to format `strftime('%Y-%m-%dT%H:%M:%S.%LZ')` when persisting documents.
|
143
|
-
|
144
|
-
PostJson will also parse an attribute's value to a `DateTime` object, if the value is a string and matches the format.
|
145
178
|
|
146
179
|
### Supported methods
|
147
180
|
|
@@ -170,7 +203,7 @@ For a Rails project this configuration could go in an initializer (`config/initi
|
|
170
203
|
|
171
204
|
## Performance
|
172
205
|
|
173
|
-
|
206
|
+
As an example of PostJson performance we created 100,000 documents on a virtual machine running on a 3 year old laptop:
|
174
207
|
|
175
208
|
```ruby
|
176
209
|
test_model = PostJson::Collection["test"]
|
@@ -181,26 +214,18 @@ result = test_model.where(content: content).count
|
|
181
214
|
# Rails debug duration was 975.5ms
|
182
215
|
```
|
183
216
|
|
184
|
-
|
185
|
-
|
186
|
-
PostJson has a feature called "Dynamic Index". It is enabled by default and works automatic behind the scene. It has now created an index on 'content'.
|
187
|
-
|
188
|
-
Now lets see how the performance will be on the second and future queries using 'content':
|
217
|
+
Not bad but we know it can get better with some very specific indexing. After an index is created on `test.content` the performance is greatly improved:
|
189
218
|
|
190
219
|
```ruby
|
191
220
|
result = test_model.where(content: content).count
|
192
221
|
# Rails debug duration was 1.5ms
|
193
222
|
```
|
194
223
|
|
195
|
-
|
196
|
-
|
197
|
-
See the next section about "Dynamic Indexes" for details.
|
224
|
+
You *could* create this index manually but PostJson has a feature called `Dynamic Index` that is enabled by default to work behind the scenes automatically creating indexes on slow queries.
|
198
225
|
|
199
226
|
## Dynamic Indexes
|
200
227
|
|
201
|
-
PostJson will measure the duration of each `SELECT` query and instruct PostgreSQL to create an index
|
202
|
-
if the query duration is above a specified threshold. This feature is called `Dynamic Index`. Since most
|
203
|
-
applications perform the same queries over and over again we think you'll find this useful.
|
228
|
+
`Dynamic Index` is a feature of PostJson that will measure the duration of each `SELECT` query and instruct PostgreSQL to create an index if the query duration is above a specified threshold. Since most applications perform the same queries over and over again we think you'll find this useful.
|
204
229
|
|
205
230
|
Each collection (like `PostJson::Collection["people"]` above) has two index attributes:
|
206
231
|
|
@@ -231,10 +256,49 @@ or:
|
|
231
256
|
PostJson::Collection["people"].create_dynamic_index_milliseconds_threshold = 75
|
232
257
|
```
|
233
258
|
|
234
|
-
|
259
|
+
###### WARNING
|
235
260
|
|
236
261
|
Do not set the dynamic index threshold too low as PostJson will try to create an index for every query. A threshold of 1 millisecond would be less than the duration of almost all queries.
|
237
262
|
|
263
|
+
### Manual creation of index
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
class Person < PostJson::Collection["people"]
|
267
|
+
self.ensure_dynamic_index("name", "details.age")
|
268
|
+
end
|
269
|
+
```
|
270
|
+
or:
|
271
|
+
|
272
|
+
```ruby
|
273
|
+
PostJson::Collection["people"].ensure_dynamic_index("name", "details.age")
|
274
|
+
```
|
275
|
+
|
276
|
+
### List existing indexes
|
277
|
+
|
278
|
+
```ruby
|
279
|
+
puts Person.existing_dynamic_indexes
|
280
|
+
# => ["name", "details.age"]
|
281
|
+
```
|
282
|
+
|
283
|
+
or:
|
284
|
+
|
285
|
+
```ruby
|
286
|
+
puts PostJson::Collection["people"].existing_dynamic_indexes
|
287
|
+
# => ["name", "details.age"]
|
288
|
+
```
|
289
|
+
|
290
|
+
### Destroying an index
|
291
|
+
|
292
|
+
```ruby
|
293
|
+
Person.destroy_dynamic_index("name")
|
294
|
+
```
|
295
|
+
|
296
|
+
or:
|
297
|
+
|
298
|
+
```ruby
|
299
|
+
PostJson::Collection["people"].destroy_dynamic_index("name")
|
300
|
+
```
|
301
|
+
|
238
302
|
## Primary Keys
|
239
303
|
|
240
304
|
PostJson assigns UUID as primary key (id):
|
@@ -266,22 +330,169 @@ puts found_again.attributes
|
|
266
330
|
# => {"id"=>"John Doe", "version"=>1, "created_at"=>"2013-10-22T10:42:26.190Z", "updated_at"=>"2013-10-22T10:42:26.190Z"}
|
267
331
|
```
|
268
332
|
|
333
|
+
## Migrating to PostJson
|
334
|
+
|
335
|
+
Given a `User` model:
|
336
|
+
|
337
|
+
```ruby
|
338
|
+
class User < ActiveRecord::Base
|
339
|
+
...
|
340
|
+
end
|
341
|
+
```
|
342
|
+
|
343
|
+
Add each user to the new `users` collection:
|
344
|
+
|
345
|
+
```ruby
|
346
|
+
PostJson::Collection["users"].transaction do
|
347
|
+
User.all.find_each do |user|
|
348
|
+
PostJson::Collection["users"].create(user.attributes)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
```
|
352
|
+
|
353
|
+
Then replace `ActiveRecord::Base` with the `PostJson::Collection` class:
|
354
|
+
|
355
|
+
```ruby
|
356
|
+
class User < PostJson::Collection["users"]
|
357
|
+
...
|
358
|
+
end
|
359
|
+
```
|
360
|
+
|
361
|
+
Users will have the exact same content, including their primary keys (id).
|
362
|
+
|
363
|
+
## Roadmap
|
364
|
+
|
365
|
+
> Please note the roadmap might change as we move forward.
|
366
|
+
|
367
|
+
### Version 2.0: Reboot – Close To The Metal
|
368
|
+
|
369
|
+
#### Components
|
370
|
+
PostJson should be an add-on to your Rails project and not a replacement for ActiveRecord models. To accomplish this, we plan to split the implementation into components and concerns. This will make it possible to include as much (or as little) of PostJson into your ActiveRecord models as you like.
|
371
|
+
|
372
|
+
For example, perhaps you want `PostJson::Attributes`:
|
373
|
+
|
374
|
+
```ruby
|
375
|
+
class Person < ActiveRecord::Base
|
376
|
+
# PostJson::Attributes hides the column assigned to `document_hash_column` and includes the dynamic attributes in results like `to_json`.
|
377
|
+
|
378
|
+
include PostJson::Attributes
|
379
|
+
self.document_hash_column = "__dynamic_attributes"
|
380
|
+
end
|
381
|
+
```
|
382
|
+
|
383
|
+
We're excited to see how far we can take it to make everything re-usable in existing applications!
|
384
|
+
|
385
|
+
#### Collection tables
|
386
|
+
Version 1.x stores all documents in a table called `post_json_documents`. In Version 2, each collection will have its own table with the same name as the collection. Each collection's metadata (title, settings etc.) will be stored as a record in the dedicated table.
|
387
|
+
|
388
|
+
### Version 2.1: JavaScript Bindings
|
389
|
+
|
390
|
+
PostJson should support JavaScript bindings to its collection methods for query and find. We plan to integrate the `therubyracer` gem to translate JavaScript queries to ActiveRecord queries allowing seamless integration with rich JavaScript clients.
|
391
|
+
|
392
|
+
Imagine a Rails controller's index method:
|
393
|
+
|
394
|
+
```ruby
|
395
|
+
def index
|
396
|
+
js_query = params[:query]
|
397
|
+
puts js_query
|
398
|
+
# => function(people) { return people.limit(10).where({'gender': 'male'}); }
|
399
|
+
|
400
|
+
result = PostJson::Collection['people'].eval_js_query(js_query)
|
401
|
+
render json: result
|
402
|
+
end
|
403
|
+
```
|
404
|
+
|
405
|
+
### Version 2.2: Relations
|
406
|
+
|
407
|
+
PostJson should support relations between collections like `has_many`, `has_one`, and `belongs_to` as persistable queries being able to work as dependent associations. Relations should not be tied to class definitions. This will allow the creation of relations from client software and enable relations to be copied / included in backups and migrations.
|
408
|
+
|
409
|
+
Imagine we have two collection: `customers` and `orders`.
|
410
|
+
|
411
|
+
#### has_one
|
412
|
+
|
413
|
+
```ruby
|
414
|
+
class Customer < PostJson::Collection["customers"]
|
415
|
+
has_one :order
|
416
|
+
end
|
417
|
+
```
|
418
|
+
|
419
|
+
The order relation will use the `order_id` attribute from the customer, look-up the `orders` collection, and find the correct document using that id.
|
420
|
+
|
421
|
+
`has_one` will support override of the `foreign_key` ('order_id'), `collection_name` ('orders'), and mark dependent as `:delete` or `:destroy`. It will also support alias with `:as`, `:readonly` and a `-> { ... }` block for specializing.
|
422
|
+
|
423
|
+
#### has_many
|
424
|
+
|
425
|
+
```ruby
|
426
|
+
class Customer < PostJson::Collection["customers"]
|
427
|
+
has_many :orders
|
428
|
+
end
|
429
|
+
```
|
430
|
+
|
431
|
+
The order relation will use the `order_ids` attribute from the customer, look-up the `orders` collection, and find all related order documents using `where(id: order_ids)`.
|
432
|
+
|
433
|
+
`has_many` will support override of `foreign_keys` ('order_ids'), `collection_name` ('orders') and mark dependent as `:delete_all` or `:destroy_all`. It will also support alias with `:as`, `:readonly` and a `-> { ... }` block for specializing.
|
434
|
+
|
435
|
+
```ruby
|
436
|
+
class Order < PostJson::Collection["orders"]
|
437
|
+
belongs_to :customer
|
438
|
+
end
|
439
|
+
```
|
440
|
+
|
441
|
+
The customer relation will look-up a collection named `customers` and find a customer with the `order_id` attribute set to the current order primary key value.
|
442
|
+
|
443
|
+
`belongs_to` will support override of `foreign_key` ('order_id'), `collection_name` ('customers') and mark dependent as `:delete` or `:destroy`. It will also support alias with `:as`, `:readonly`, and a `-> { ... }` block for specializing.
|
444
|
+
|
445
|
+
PostJson will use ActiveSupport::Inflector to implement the naming conventions.
|
446
|
+
|
447
|
+
PostJson will serialize lambda (-> { ... } block for specializing) as part of the collection definitions.
|
448
|
+
|
449
|
+
### Version 2.3: Versioning
|
450
|
+
|
451
|
+
The history of data has great potential. It should be as easy as possible to get a view of the past. PostJson should be able to store the history of each document, including the possibility of restoring a document's previous state as a new document, roll back a document to its previous state, and view the changes for each version of a document.
|
452
|
+
|
453
|
+
This should also work for an entire collection. PostJson should be able to create a new collection from an existing collection's previous state. It should also be possible to query and view the previous state of a collection without restoring it to a new collection first.
|
454
|
+
|
455
|
+
### Version 2.4: Bulk Import
|
456
|
+
|
457
|
+
Importing data can often be boring and troublesome. PostJson should make it easy to setup a data transformation and use bulk inserts to improve performance.
|
458
|
+
|
459
|
+
### Version 2.5: Export CSV and HTML
|
460
|
+
|
461
|
+
PostJson already supports transformation with `select`. PostJson should be able to return results as CSV and HTML.
|
462
|
+
|
463
|
+
#### CSV
|
464
|
+
|
465
|
+
CSV stores tabular data and is not compatible with JSON. PostJson will flatten the data:
|
466
|
+
|
467
|
+
```json
|
468
|
+
{ parent: {child: 123} }
|
469
|
+
```
|
470
|
+
|
471
|
+
will be converted to
|
472
|
+
|
473
|
+
```json
|
474
|
+
{ "parent.child" => 123 }
|
475
|
+
```
|
476
|
+
|
477
|
+
#### HTML
|
478
|
+
|
479
|
+
HTML will be rendered by templates. PostJson will support Mustache and store templates in the database. This will allow PostgreSQL to do the rendering and return results as strings.
|
480
|
+
|
481
|
+
### Version 2.6: File Attachments
|
482
|
+
|
483
|
+
PostJson should be able to store files in a specialized `files` collection when it makes sense to store files in the database. Files can be attached to other collections by using a `has_one` or `has_many` relation.
|
484
|
+
|
485
|
+
### Version 2.7: Unused Index Deletion
|
486
|
+
|
487
|
+
PostJson should provide automatic deletion of unused dynamic indexes as an optional feature.
|
488
|
+
|
489
|
+
### version 3.x: Full Text Search
|
490
|
+
|
491
|
+
PostgreSQL has many great features to support Full Text Search and PostJson should take advantage of these.
|
492
|
+
|
269
493
|
## The future
|
270
494
|
|
271
|
-
|
272
|
-
- Versioning of documents with support for history, restore and rollback.
|
273
|
-
- Restore a copy of entire collection at a specific date.
|
274
|
-
- Copy a collection.
|
275
|
-
- Automatic deletion of dynamic indexes when unused for a period of time.
|
276
|
-
- Full text search. PostgreSQL has many great features.
|
277
|
-
- Bulk import.
|
278
|
-
- Whitelisting of attributes for models (strong attributes).
|
279
|
-
- Whitelisting of collection names.
|
280
|
-
- Support for files. Maybe as attachments to documents.
|
281
|
-
- Keep the similarities with ActiveRecord API, but it shouldn't depend on Rails or ActiveRecord.
|
282
|
-
- Better performance and less complex code.
|
283
|
-
|
284
|
-
And please let us know what you think and what you need.
|
495
|
+
We would love to hear new ideas or random thoughts about PostJson.
|
285
496
|
|
286
497
|
## Requirements
|
287
498
|
|
@@ -2,15 +2,14 @@ ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
|
|
2
2
|
|
3
3
|
attr_accessor :last_select_query, :last_select_query_duration
|
4
4
|
|
5
|
-
def
|
5
|
+
def select_all_with_measure_duration(arel, name = nil, binds = [])
|
6
6
|
result = nil
|
7
7
|
@last_select_query_duration = Benchmark.realtime do
|
8
|
-
result =
|
8
|
+
result = select_all_without_measure_duration(arel, name, binds)
|
9
9
|
end
|
10
10
|
@last_select_query = to_sql(arel, binds.dup).strip
|
11
11
|
result
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
alias_method :select_all, :measure_select_all
|
14
|
+
alias_method_chain :select_all, :measure_duration
|
16
15
|
end
|
@@ -5,12 +5,11 @@
|
|
5
5
|
# The override below can be removed in the future
|
6
6
|
|
7
7
|
ActiveRecord::Relation.class_eval do
|
8
|
-
def
|
9
|
-
records =
|
8
|
+
def exec_queries_with_disable_implicit_readonly
|
9
|
+
records = exec_queries_without_disable_implicit_readonly
|
10
10
|
records.each { |r| r.instance_variable_set(:@readonly, false) } unless self.readonly_value == true
|
11
11
|
records
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
alias_method :exec_queries, :exec_queries_without_implicit_readonly
|
14
|
+
alias_method_chain :exec_queries, :disable_implicit_readonly
|
16
15
|
end
|
data/lib/post_json/base.rb
CHANGED
@@ -186,21 +186,21 @@ module PostJson
|
|
186
186
|
end
|
187
187
|
|
188
188
|
class << self
|
189
|
-
def
|
190
|
-
QueryTranslator.new(
|
189
|
+
def all_with_query_translator
|
190
|
+
QueryTranslator.new(all_without_query_translator)
|
191
191
|
end
|
192
192
|
|
193
|
-
|
194
|
-
alias_method :all, :post_json_all
|
193
|
+
alias_method_chain :all, :query_translator
|
195
194
|
|
196
195
|
def page(*args)
|
197
196
|
all.page(*args)
|
198
197
|
end
|
199
198
|
|
200
199
|
def default_scopes
|
201
|
-
# query =
|
200
|
+
# query = query.where("\"#{table_name}\".__doc__model_settings_id = ?", settings_id)
|
202
201
|
model_settings = ModelSettings.table_name
|
203
|
-
query =
|
202
|
+
query = all_without_query_translator
|
203
|
+
query = query.joins("INNER JOIN \"#{model_settings}\" ON lower(\"#{model_settings}\".collection_name) = '#{collection_name.downcase}'")
|
204
204
|
query = query.where("\"#{table_name}\".__doc__model_settings_id = \"#{model_settings}\".id")
|
205
205
|
super + [Proc.new { query }]
|
206
206
|
end
|
@@ -10,7 +10,7 @@ module PostJson
|
|
10
10
|
|
11
11
|
if destination.persisted?
|
12
12
|
dest_id = destination.persisted_settings.id
|
13
|
-
query =
|
13
|
+
query = all_without_query_translator
|
14
14
|
query = query.joins("INNER JOIN #{table_name} as dest ON dest.id = #{table_name}.id")
|
15
15
|
query = query.where("dest.__doc__model_settings_id = '#{dest_id}'")
|
16
16
|
query = query.where("\"#{table_name}\".__doc__model_settings_id = '#{src_id}'")
|
@@ -3,7 +3,7 @@ module PostJson
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
module ClassMethods
|
6
|
-
def
|
6
|
+
def existing_dynamic_indexes
|
7
7
|
if settings.new_record?
|
8
8
|
[]
|
9
9
|
else
|
@@ -11,11 +11,7 @@ module PostJson
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
create_dynamic_indexes(selector)
|
16
|
-
end
|
17
|
-
|
18
|
-
def create_dynamic_indexes(*selectors)
|
14
|
+
def ensure_dynamic_index(*selectors)
|
19
15
|
DynamicIndex.ensure_index(persisted_settings.id, *selectors).count
|
20
16
|
end
|
21
17
|
|
@@ -33,7 +33,7 @@ module PostJson
|
|
33
33
|
if model_class.use_dynamic_index == true &&
|
34
34
|
model_class.create_dynamic_index_milliseconds_threshold < select_duration
|
35
35
|
selectors = select_query.scan(/.*?json_selector\('(.*?)', \"post_json_documents\"\.__doc__body\)/).flatten.uniq
|
36
|
-
model_class.
|
36
|
+
model_class.ensure_dynamic_index(*selectors)
|
37
37
|
end
|
38
38
|
result
|
39
39
|
end
|
data/lib/post_json/version.rb
CHANGED
data/spec/models/base_spec.rb
CHANGED
@@ -365,20 +365,20 @@ describe "Base model" do
|
|
365
365
|
context "dynamic indexes" do
|
366
366
|
subject { PostJson::Collection['Customer'] }
|
367
367
|
|
368
|
-
its(:
|
368
|
+
its(:existing_dynamic_indexes) { should == [] }
|
369
369
|
|
370
370
|
context "create index" do
|
371
371
|
let(:selector) { "name" }
|
372
372
|
before do
|
373
|
-
subject.
|
373
|
+
subject.ensure_dynamic_index(selector)
|
374
374
|
end
|
375
|
-
its(:
|
375
|
+
its(:existing_dynamic_indexes) { should == [selector] }
|
376
376
|
|
377
377
|
context "and destroy index" do
|
378
378
|
before do
|
379
379
|
subject.destroy_dynamic_index(selector)
|
380
380
|
end
|
381
|
-
its(:
|
381
|
+
its(:existing_dynamic_indexes) { should == [] }
|
382
382
|
end
|
383
383
|
end
|
384
384
|
end
|
metadata
CHANGED
@@ -1,83 +1,84 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: post_json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Jacob Madsen
|
7
|
+
- Jacob Madsen
|
8
|
+
- Martin Thoegersen
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2014-10-25 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rails
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
|
-
- -
|
18
|
+
- - ">="
|
18
19
|
- !ruby/object:Gem::Version
|
19
20
|
version: 4.0.0
|
20
21
|
type: :runtime
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
|
-
- -
|
25
|
+
- - ">="
|
25
26
|
- !ruby/object:Gem::Version
|
26
27
|
version: 4.0.0
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
29
|
name: uuidtools
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
31
|
-
- - ~>
|
32
|
+
- - "~>"
|
32
33
|
- !ruby/object:Gem::Version
|
33
34
|
version: 2.1.4
|
34
35
|
type: :runtime
|
35
36
|
prerelease: false
|
36
37
|
version_requirements: !ruby/object:Gem::Requirement
|
37
38
|
requirements:
|
38
|
-
- - ~>
|
39
|
+
- - "~>"
|
39
40
|
- !ruby/object:Gem::Version
|
40
41
|
version: 2.1.4
|
41
42
|
- !ruby/object:Gem::Dependency
|
42
43
|
name: hashie
|
43
44
|
requirement: !ruby/object:Gem::Requirement
|
44
45
|
requirements:
|
45
|
-
- - ~>
|
46
|
+
- - "~>"
|
46
47
|
- !ruby/object:Gem::Version
|
47
48
|
version: 2.0.5
|
48
49
|
type: :runtime
|
49
50
|
prerelease: false
|
50
51
|
version_requirements: !ruby/object:Gem::Requirement
|
51
52
|
requirements:
|
52
|
-
- - ~>
|
53
|
+
- - "~>"
|
53
54
|
- !ruby/object:Gem::Version
|
54
55
|
version: 2.0.5
|
55
56
|
- !ruby/object:Gem::Dependency
|
56
57
|
name: pg
|
57
58
|
requirement: !ruby/object:Gem::Requirement
|
58
59
|
requirements:
|
59
|
-
- -
|
60
|
+
- - ">="
|
60
61
|
- !ruby/object:Gem::Version
|
61
62
|
version: '0'
|
62
63
|
type: :development
|
63
64
|
prerelease: false
|
64
65
|
version_requirements: !ruby/object:Gem::Requirement
|
65
66
|
requirements:
|
66
|
-
- -
|
67
|
+
- - ">="
|
67
68
|
- !ruby/object:Gem::Version
|
68
69
|
version: '0'
|
69
70
|
- !ruby/object:Gem::Dependency
|
70
71
|
name: rspec-rails
|
71
72
|
requirement: !ruby/object:Gem::Requirement
|
72
73
|
requirements:
|
73
|
-
- - ~>
|
74
|
+
- - "~>"
|
74
75
|
- !ruby/object:Gem::Version
|
75
76
|
version: '2.0'
|
76
77
|
type: :development
|
77
78
|
prerelease: false
|
78
79
|
version_requirements: !ruby/object:Gem::Requirement
|
79
80
|
requirements:
|
80
|
-
- - ~>
|
81
|
+
- - "~>"
|
81
82
|
- !ruby/object:Gem::Version
|
82
83
|
version: '2.0'
|
83
84
|
description: A Fast and Flexible Document Database by Combining Features of Ruby and
|
@@ -88,73 +89,73 @@ executables: []
|
|
88
89
|
extensions: []
|
89
90
|
extra_rdoc_files: []
|
90
91
|
files:
|
91
|
-
- lib/core_ext/hash_extend.rb
|
92
|
-
- lib/core_ext/active_record_relation_extend.rb
|
93
|
-
- lib/core_ext/abstract_adapter_extend.rb
|
94
92
|
- lib/post_json.rb
|
95
|
-
- lib/generators/post_json/install/templates/create_procedures.rb
|
96
|
-
- lib/generators/post_json/install/templates/create_post_json_documents.rb
|
97
|
-
- lib/generators/post_json/install/templates/initializer.rb
|
98
|
-
- lib/generators/post_json/install/templates/create_post_json_model_settings.rb
|
99
|
-
- lib/generators/post_json/install/templates/create_post_json_dynamic_indexes.rb
|
100
|
-
- lib/generators/post_json/install/templates/enable_extensions.rb
|
101
|
-
- lib/generators/post_json/install/install_generator.rb
|
102
93
|
- lib/post_json/model_settings.rb
|
103
|
-
- lib/post_json/concerns/settings_methods.rb
|
104
|
-
- lib/post_json/concerns/query_methods.rb
|
105
94
|
- lib/post_json/concerns/argument_methods.rb
|
106
|
-
- lib/post_json/concerns/copyable.rb
|
107
95
|
- lib/post_json/concerns/finder_methods.rb
|
96
|
+
- lib/post_json/concerns/copyable.rb
|
108
97
|
- lib/post_json/concerns/dynamic_index_methods.rb
|
98
|
+
- lib/post_json/concerns/query_methods.rb
|
99
|
+
- lib/post_json/concerns/settings_methods.rb
|
109
100
|
- lib/post_json/version.rb
|
110
101
|
- lib/post_json/dynamic_index.rb
|
111
102
|
- lib/post_json/query_translator.rb
|
112
103
|
- lib/post_json/base.rb
|
113
|
-
-
|
114
|
-
-
|
104
|
+
- lib/generators/post_json/install/templates/create_post_json_model_settings.rb
|
105
|
+
- lib/generators/post_json/install/templates/create_post_json_documents.rb
|
106
|
+
- lib/generators/post_json/install/templates/initializer.rb
|
107
|
+
- lib/generators/post_json/install/templates/create_procedures.rb
|
108
|
+
- lib/generators/post_json/install/templates/create_post_json_dynamic_indexes.rb
|
109
|
+
- lib/generators/post_json/install/templates/enable_extensions.rb
|
110
|
+
- lib/generators/post_json/install/install_generator.rb
|
111
|
+
- lib/core_ext/abstract_adapter_extend.rb
|
112
|
+
- lib/core_ext/hash_extend.rb
|
113
|
+
- lib/core_ext/active_record_relation_extend.rb
|
115
114
|
- spec/models/derived_base_spec.rb
|
115
|
+
- spec/models/base_spec.rb
|
116
116
|
- spec/models/collection_spec.rb
|
117
|
+
- spec/models/queries_spec.rb
|
118
|
+
- spec/modules/argument_methods_spec.rb
|
119
|
+
- spec/modules/query_methods_spec.rb
|
117
120
|
- spec/spec_helper.rb
|
118
|
-
- spec/dummy/
|
119
|
-
- spec/dummy/app/assets/javascripts/application.js
|
120
|
-
- spec/dummy/app/assets/stylesheets/scaffold.css
|
121
|
-
- spec/dummy/app/assets/stylesheets/application.css
|
122
|
-
- spec/dummy/app/views/layouts/application.html.erb
|
123
|
-
- spec/dummy/app/controllers/application_controller.rb
|
121
|
+
- spec/dummy/bin/rake
|
124
122
|
- spec/dummy/bin/rails
|
125
123
|
- spec/dummy/bin/bundle
|
126
|
-
- spec/dummy/bin/rake
|
127
|
-
- spec/dummy/config.ru
|
128
|
-
- spec/dummy/Rakefile
|
129
|
-
- spec/dummy/config/environment.rb
|
130
|
-
- spec/dummy/config/environments/development.rb
|
131
124
|
- spec/dummy/config/environments/test.rb
|
125
|
+
- spec/dummy/config/environments/development.rb
|
132
126
|
- spec/dummy/config/environments/production.rb
|
133
|
-
- spec/dummy/config/
|
134
|
-
- spec/dummy/config/
|
135
|
-
- spec/dummy/config/
|
136
|
-
- spec/dummy/config/initializers/backtrace_silencers.rb
|
137
|
-
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
127
|
+
- spec/dummy/config/locales/en.yml
|
128
|
+
- spec/dummy/config/routes.rb
|
129
|
+
- spec/dummy/config/database.yml
|
138
130
|
- spec/dummy/config/initializers/post_json.rb
|
139
131
|
- spec/dummy/config/initializers/session_store.rb
|
132
|
+
- spec/dummy/config/initializers/mime_types.rb
|
140
133
|
- spec/dummy/config/initializers/wrap_parameters.rb
|
134
|
+
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
135
|
+
- spec/dummy/config/initializers/inflections.rb
|
141
136
|
- spec/dummy/config/initializers/secret_token.rb
|
142
|
-
- spec/dummy/config/
|
143
|
-
- spec/dummy/config/
|
144
|
-
- spec/dummy/config/
|
137
|
+
- spec/dummy/config/initializers/backtrace_silencers.rb
|
138
|
+
- spec/dummy/config/application.rb
|
139
|
+
- spec/dummy/config/environment.rb
|
145
140
|
- spec/dummy/config/boot.rb
|
146
|
-
- spec/dummy/public/favicon.ico
|
147
|
-
- spec/dummy/public/404.html
|
148
|
-
- spec/dummy/public/500.html
|
149
|
-
- spec/dummy/public/422.html
|
150
141
|
- spec/dummy/db/structure.sql
|
151
142
|
- spec/dummy/db/migrate/20131018135641_create_post_json_model_settings.rb
|
152
|
-
- spec/dummy/db/migrate/20131018135643_create_post_json_dynamic_indexes.rb
|
153
|
-
- spec/dummy/db/migrate/20131018135639_enable_extensions.rb
|
154
143
|
- spec/dummy/db/migrate/20131018135640_create_procedures.rb
|
144
|
+
- spec/dummy/db/migrate/20131018135639_enable_extensions.rb
|
145
|
+
- spec/dummy/db/migrate/20131018135643_create_post_json_dynamic_indexes.rb
|
155
146
|
- spec/dummy/db/migrate/20131018135642_create_post_json_documents.rb
|
156
|
-
- spec/
|
157
|
-
- spec/
|
147
|
+
- spec/dummy/public/500.html
|
148
|
+
- spec/dummy/public/404.html
|
149
|
+
- spec/dummy/public/favicon.ico
|
150
|
+
- spec/dummy/public/422.html
|
151
|
+
- spec/dummy/app/views/layouts/application.html.erb
|
152
|
+
- spec/dummy/app/controllers/application_controller.rb
|
153
|
+
- spec/dummy/app/assets/stylesheets/scaffold.css
|
154
|
+
- spec/dummy/app/assets/stylesheets/application.css
|
155
|
+
- spec/dummy/app/assets/javascripts/application.js
|
156
|
+
- spec/dummy/app/helpers/application_helper.rb
|
157
|
+
- spec/dummy/Rakefile
|
158
|
+
- spec/dummy/config.ru
|
158
159
|
- MIT-LICENSE
|
159
160
|
- Rakefile
|
160
161
|
- README.md
|
@@ -168,17 +169,17 @@ require_paths:
|
|
168
169
|
- lib
|
169
170
|
required_ruby_version: !ruby/object:Gem::Requirement
|
170
171
|
requirements:
|
171
|
-
- -
|
172
|
+
- - ">="
|
172
173
|
- !ruby/object:Gem::Version
|
173
174
|
version: '0'
|
174
175
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
176
|
requirements:
|
176
|
-
- -
|
177
|
+
- - ">="
|
177
178
|
- !ruby/object:Gem::Version
|
178
179
|
version: '0'
|
179
180
|
requirements: []
|
180
181
|
rubyforge_project:
|
181
|
-
rubygems_version: 2.1.
|
182
|
+
rubygems_version: 2.1.10
|
182
183
|
signing_key:
|
183
184
|
specification_version: 4
|
184
185
|
summary: PostgreSQL as Document database
|