epiphy 0.0.1 → 0.1.0

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
  SHA1:
3
- metadata.gz: 3c60ab2f9d0a39156bab381f3217ad2c8fd210d8
4
- data.tar.gz: 24fde7963aa8d74479e2a90030928b7fc8fc7d89
3
+ metadata.gz: 346e101f2179b4b096e7d9e38ef7c08879598e99
4
+ data.tar.gz: fc54f4cf44e3a1e25e79d10f5ecd2e85bd0bff0c
5
5
  SHA512:
6
- metadata.gz: 1e18a93aef681e795efd164d3467f7136fe6f938bea9d08448cfe854b4a2a4a50dd4b5ea4bc46c54a18f0bd6996c902c747449dd9448a0f3fd83cf1694ab39e5
7
- data.tar.gz: f3549f8a25a32cc5bc2f5a6c565e2a081dd029653d499be1aa28743e293fa975de93c7f8b1a12b0915bb3e9d1153d5e25cbc156ada19fa2fc8c656a9c70f5b8c
6
+ metadata.gz: a8823aac0ef0a54099141567fcc3155d3289ca71d08b39b506f14ed668bb073f78d99a622d3090a804997f69370ec36841d7c256b7ff98c507fc057c3e4e100e
7
+ data.tar.gz: e6fd39cb0525b115d1fb6bfb35d094ef3f1661902f4db8bfbb5924eef21f3b74281ed71db385a19ce00bcac225ad8398ba302f8e5d49d200d1a4baa1b842bc74
data/EXAMPLE.md ADDED
@@ -0,0 +1,173 @@
1
+ # Epiphy
2
+
3
+ This is a guide that helps you to getting started with [**Epiphy**](https://github.com/kureikain/epiphy). This file is inspired by Lotus::Model
4
+
5
+ ## Gems
6
+
7
+ First of all, we need to setup a `Gemfile`.
8
+
9
+ ```ruby
10
+ source 'https://rubygems.org'
11
+
12
+ gem 'epiphy'
13
+ ```
14
+
15
+ Then we can fetch the dependencies with `bundle install`.
16
+
17
+ ## Setup
18
+
19
+ We need to feed `Epiphy` with an adapter. Adapter is a lighweight wrap
20
+ contains a RethinkDB connection and its run option.
21
+
22
+ ```
23
+ # Default connect to localhost, 28015, no auth key, use database 'test'
24
+ # by default
25
+ connection = Epiphy::Connection.create
26
+ adapter = Epiphy::Adapter::RethinkDB.new connection, 'test'
27
+ RethinkDB::Repository.configure do |r|
28
+ r.adapter = adapter
29
+ end
30
+
31
+ # Or merge them all
32
+ RethinkDB::Repository.configure do |r|
33
+ r.adapter = Epiphy::Adapter::RethinkDB.new(Epiphy::Connection.create)
34
+ end
35
+
36
+ # Or connect to a different host, use database `cms`
37
+ RethinkDB::Repository.configure do |r|
38
+ r.adapter = Epiphy::Adapter::RethinkDB.new Epiphy::Connection.create({:host => '192.168.1.2'}, 'cms')
39
+ end
40
+
41
+ ```
42
+
43
+ ## Entities
44
+
45
+ We have two entities in our application: `Author` and `Article`.
46
+ `Author` is a `Struct`, Epiphy can persist it.
47
+ `Article` has a small API concerning its publishing process.
48
+
49
+ ```ruby
50
+ Author = Struct.new(:id, :name) do
51
+ def initialize(attributes = {})
52
+ @id, @name = attributes.values_at(:id, :name)
53
+ end
54
+ end
55
+
56
+ class Article
57
+ include Epiphy::Entity
58
+ self.attributes = :author_id, :title, :comments_count, :published # id is implicit
59
+
60
+ def published?
61
+ !!published
62
+ end
63
+
64
+ def publish!
65
+ @published = true
66
+ end
67
+ end
68
+ ```
69
+
70
+ ## Repositories
71
+
72
+ In order to persist and query the entities above, we define two corresponding repositories:
73
+
74
+ ```ruby
75
+ class AuthorRepository
76
+ include Epiphy::Repository
77
+ end
78
+
79
+ class ArticleRepository
80
+ include Epiphy::Repository
81
+
82
+ def self.most_recent_by_author(author, limit = 8)
83
+ query do
84
+ where(author_id: author.id).
85
+ desc(:id).
86
+ limit(limit)
87
+ end
88
+ end
89
+
90
+ def self.most_recent_published_by_author(author, limit = 8)
91
+ most_recent_by_author(author, limit).published
92
+ end
93
+
94
+ def self.published
95
+ query do
96
+ where(published: true)
97
+ end
98
+ end
99
+
100
+ def self.drafts
101
+ exclude published
102
+ end
103
+
104
+ def self.rank
105
+ published.desc(:comments_count)
106
+ end
107
+
108
+ def self.best_article_ever
109
+ rank.limit(1).first
110
+ end
111
+
112
+ def self.comments_average
113
+ query.average(:comments_count)
114
+ end
115
+ end
116
+ ```
117
+
118
+ ## Persist
119
+
120
+ Let's instantiate and persist some objects for our example:
121
+
122
+ ```ruby
123
+ author = Author.new(name: 'Luca')
124
+ AuthorRepository.create(author)
125
+
126
+ articles = [
127
+ Article.new(title: 'Announcing Epiphy', author_id: author.id, comments_count: 123, published: true),
128
+ Article.new(title: 'Introducing Epiphy::Router', author_id: author.id, comments_count: 63, published: true),
129
+ Article.new(title: 'Introducing Epiphy::Controller', author_id: author.id, comments_count: 82, published: true),
130
+ Article.new(title: 'Introducing Epiphy', author_id: author.id)
131
+ ]
132
+
133
+ articles.each do |article|
134
+ ArticleRepository.create(article)
135
+ end
136
+ ```
137
+
138
+ ## Query
139
+
140
+ We can use repositories to query the database and return the entities we're looking for:
141
+
142
+ ```ruby
143
+ ArticleRepository.first # => return the first article
144
+ ArticleRepository.last # => return the last article
145
+
146
+ ArticleRepository.published # => return all the published articles
147
+ ArticleRepository.drafts # => return all the drafts
148
+
149
+ ArticleRepository.rank # => all the published articles, sorted by popularity
150
+
151
+ ArticleRepository.best_article_ever # => the most commented article
152
+
153
+ ArticleRepository.comments_average # => calculates the average of comments across all the published articles.
154
+
155
+ ArticleRepository.most_recent_by_author(author) # => most recent articles by an author (drafts and published).
156
+ ArticleRepository.most_recent_published_by_author(author) # => most recent published articles by an author
157
+ ```
158
+
159
+ ## Business logic
160
+
161
+ As we've seen above, `Article` implements an API for publishing.
162
+ We're gonna use that logic to alter the state of an article (from draft to published) and then we use the repository to persist this new state.
163
+
164
+ ```ruby
165
+ article = ArticleRepository.drafts.first
166
+
167
+ article.published? # => false
168
+ article.publish!
169
+
170
+ article.published? # => true
171
+
172
+ ArticleRepository.update(article)
173
+ ```
@@ -1,5 +1,5 @@
1
1
  require 'epiphy/adapter/error'
2
- #require 'epiphy/adapter/helper'
2
+
3
3
  module Epiphy
4
4
  module Adapter
5
5
  class Rethinkdb
@@ -102,6 +102,7 @@ module Epiphy
102
102
  raise ArgumentError, 'Missing query block' unless block_given?
103
103
  if block_given?
104
104
  rql = get_table(table, database)
105
+ @current_rql = rql
105
106
  rql = yield(rql, r)
106
107
  end
107
108
  rql.run(@connection)
@@ -125,9 +126,15 @@ module Epiphy
125
126
  end
126
127
 
127
128
  # Insert a document.
129
+ #
130
+ # When the ID is already existed, we simply return the ID if insert
131
+ # succesful. Or, the generated ID will be returned.
132
+ #
128
133
  # @param collection [Symbol the target collection
129
134
  # @param entity [#id, #id=] the entity to create
130
135
  # @return [Object] the entity
136
+ #
137
+ # @raise
131
138
  #
132
139
  # @api private
133
140
  # @since 0.0.1
@@ -136,12 +143,17 @@ module Epiphy
136
143
  result = query table: collection do |r|
137
144
  r.insert(entity)
138
145
  end
139
- rescue
140
- return false
146
+ rescue RethinkDB::RqlRuntimeError => e
147
+ raise e
141
148
  end
142
149
 
143
150
  if result["inserted"]==1
144
- result["generated_keys"].first
151
+ return entity["id"] if result["generated_keys"].nil?
152
+ result["generated_keys"].first
153
+ else
154
+ if result['first_error'].include? 'Duplicate primary key'
155
+ raise Epiphy::Model::EntityExisted, 'Duplicate primary key'
156
+ end
145
157
  end
146
158
  end
147
159
 
@@ -179,8 +191,31 @@ module Epiphy
179
191
  query table: collection do |r|
180
192
  r
181
193
  end
182
- rescue
183
- return false
194
+ rescue RethinkDB::RqlRuntimeError => e
195
+ raise Epiphy::Model::RuntimeError, e.message
196
+ rescue Exception =>e
197
+ raise Epiphy::Model::RuntimeError, e.message
198
+ end
199
+ end
200
+
201
+ # Count entity in table
202
+ #
203
+ # @param collection [Symbol] the target collection (it must be mapped).
204
+ #
205
+ # @return [Integer] How many record?
206
+ #
207
+ # @api private
208
+ # @since 0.2.0
209
+ def count(collection)
210
+ # TODO consider to make this lazy (aka remove #all)
211
+ begin
212
+ query table: collection do |r|
213
+ r.count
214
+ end
215
+ rescue RethinkDB::RqlRuntimeError => e
216
+ raise Epiphy::Model::RuntimeError, e.message
217
+ rescue Exception =>e
218
+ raise Epiphy::Model::RuntimeError, e.message
184
219
  end
185
220
  end
186
221
 
@@ -243,8 +278,8 @@ module Epiphy
243
278
  return result['deleted']
244
279
  end
245
280
  return false
246
- rescue
247
- return false
281
+ rescue RethinkDB::RqlRuntimeError => e
282
+ raise Epiphy::Model::RuntimeError, e.message
248
283
  end
249
284
  end
250
285
 
@@ -256,10 +291,14 @@ module Epiphy
256
291
  #
257
292
  # @api private
258
293
  # @since 0.1.0
259
- def first(collection)
260
- _first(
261
- query(collection).asc(_identity(collection))
262
- )
294
+ def first(collection, order_by: nil)
295
+ begin
296
+ query table: collection do |q,r|
297
+ q.order_by(r.asc(order_by)).nth(0)
298
+ end
299
+ rescue RethinkDB::RqlRuntimeError => e
300
+ return nil
301
+ end
263
302
  end
264
303
 
265
304
  # Returns the last record in the given collection.
@@ -270,21 +309,18 @@ module Epiphy
270
309
  #
271
310
  # @api private
272
311
  # @since 0.1.0
273
- def last(collection)
274
- _first(
275
- query(collection).desc(_identity(collection))
276
- )
312
+ def last(collection, order_by: nil)
313
+ begin
314
+ query table: collection do |q, r|
315
+ q.order_by(r.desc(order_by)).nth(0)
316
+ end
317
+ rescue RethinkDB::RqlRuntimeError => e
318
+ return nil
319
+ end
320
+
277
321
  end
278
322
 
279
323
  private
280
- def _collection(name)
281
- raise NotImplementedError
282
- end
283
-
284
- def _mapped_collection(name)
285
- @mapper.collection(name)
286
- end
287
-
288
324
  def _find(collection, id)
289
325
  identity = _identity(collection)
290
326
  query(collection).where(identity => _id(collection, identity, id))
@@ -0,0 +1,14 @@
1
+ module Epiphy
2
+ module Entity
3
+
4
+ # Add created_at and updated_at field to an entity.
5
+ #
6
+ #
7
+ module Timestamp
8
+ def self.included(base)
9
+ base.send :attr_accessor, :_ts
10
+ end
11
+ end
12
+
13
+ end
14
+ end
data/lib/epiphy/model.rb CHANGED
@@ -9,6 +9,10 @@ module Epiphy
9
9
  #
10
10
  # @since 0.1.0
11
11
  module Model
12
+
13
+ class RuntimeError < RethinkDB::RqlRuntimeError
14
+
15
+ end
12
16
  # Error for not found entity
13
17
  #
14
18
  # @since 0.1.0
@@ -33,5 +37,9 @@ module Epiphy
33
37
  # @see epiphy::Repository.update
34
38
  class NonPersistedEntityError < ::StandardError
35
39
  end
40
+
41
+ class EntityExisted < ::StandardError
42
+
43
+ end
36
44
  end
37
45
  end
@@ -1,6 +1,7 @@
1
1
  require 'lotus/utils/class_attribute'
2
2
  require 'epiphy/repository/configuration'
3
3
  require 'epiphy/repository/cursor'
4
+ require 'epiphy/repository/helper'
4
5
 
5
6
  module Epiphy
6
7
  # Mediates between the entities and the persistence layer, by offering an API
@@ -215,6 +216,7 @@ module Epiphy
215
216
  end
216
217
 
217
218
  module ClassMethods
219
+ include Epiphy::Repository::Helper
218
220
  # Assigns an adapter.
219
221
  #
220
222
  # Epiphy::Repository is shipped with an adapters:
@@ -289,7 +291,8 @@ module Epiphy
289
291
  # Creates a record in the database for the given entity.
290
292
  # It assigns the `id` attribute, in case of success.
291
293
  #
292
- # If already persisted (`id` present) it does nothing.
294
+ # If already persisted (`id` present), it will try to insert use that id
295
+ # and will raise an error if the `id` is already exist
293
296
  #
294
297
  # @param entity [#id,#id=] the entity to create
295
298
  #
@@ -314,10 +317,16 @@ module Epiphy
314
317
  #
315
318
  # ArticleRepository.create(article) # no-op
316
319
  def create(entity)
317
- unless entity.id
320
+ #unless entity.id
321
+ begin
318
322
  result = @adapter.create(collection, to_document(entity))
319
323
  entity.id = result
324
+ rescue Epiphy::Model::EntityExisted => e
325
+ raise e
326
+ rescue RethinkDB::RqlRuntimeError => e
327
+ raise Epiphy::Model::RuntimeError, e.message
320
328
  end
329
+ #end
321
330
  end
322
331
 
323
332
  # Updates a record in the database corresponding to the given entity.
@@ -504,8 +513,13 @@ module Epiphy
504
513
  # end
505
514
  #
506
515
  # ArticleRepository.first # => nil
507
- def first
508
- @adapter.first(collection)
516
+ def first(order_by=:id)
517
+ result = @adapter.first(collection, order_by: order_by)
518
+ if result
519
+ to_entity result
520
+ else
521
+ result
522
+ end
509
523
  end
510
524
 
511
525
  # Returns the last entity in the database.
@@ -533,8 +547,12 @@ module Epiphy
533
547
  # end
534
548
  #
535
549
  # ArticleRepository.last # => nil
536
- def last
537
- @adapter.last(collection)
550
+ def last(order_by=:id)
551
+ if result = @adapter.last(collection, order_by: order_by)
552
+ to_entity result
553
+ else
554
+ nil
555
+ end
538
556
  end
539
557
 
540
558
  # Deletes all the records from the current collection.
@@ -553,22 +571,16 @@ module Epiphy
553
571
  # ArticleRepository.clear # deletes all the records
554
572
  def clear
555
573
  @adapter.clear(collection)
556
- end
574
+ end
557
575
 
558
- # Create a collection storage in database.
576
+ # Count the entity in this collection
559
577
  #
560
- def create_collection
561
- query do |r|
562
- r.table_create(self.collection)
563
- end
564
- end
565
-
566
- # Drop a collection storage in database
567
- #
568
- def drop_collection
569
- query do |r|
570
- r.table_drop(self.collection)
571
- end
578
+ # @param void
579
+ # @return Interget
580
+ # @api public
581
+ # @since 0.2.0
582
+ def count
583
+ @adapter.count(collection)
572
584
  end
573
585
 
574
586
  private
@@ -585,27 +597,34 @@ module Epiphy
585
597
  # The returned query SHOULD refer to the entire collection by default.
586
598
  #
587
599
  # Queries can be reused and combined together. See the example below.
588
- # IMPORTANT: This feature works only with the Sql adapter.
589
600
  #
590
601
  # A repository is storage independent.
591
602
  # All the queries are delegated to the current adapter, which is
592
603
  # responsible to implement a querying API.
593
604
  #
594
- # Epiphy::Model is shipped with two adapters:
605
+ # Epiphy::Model is shipped with adapter:
595
606
  #
596
- # * SqlAdapter, which yields a Epiphy::Model::Adapters::Sql::Query
597
- # * MemoryAdapter, which yields a Epiphy::Model::Adapters::Memory::Query
607
+ # * RethinkDB: which yields a RethinkDB::ReQL class.
598
608
  #
599
- # @param blk [Proc] a block of code that is executed in the context of a
600
- # query
609
+ # By default, all return items will be convert into its entity. The
610
+ # behavious can change by alter `to_entity` parameter
601
611
  #
612
+ # @param to_entity [Boolean][Optional] to convert the result back to a
613
+ # entity class or not.
614
+ #
615
+ # @param blk [Proc] a block of code that is executed in the context of a
616
+ # query.
617
+ # The block will be passed two parameters. First parameter is the `reql`
618
+ # which is building. the second parameter is th `r` top name space of
619
+ # RethinkDB. By doing this, Repository doesn't have to include
620
+ # RethinkDB::Shortcuts
621
+ #
602
622
  # @return a query, the type depends on the current adapter
603
623
  #
604
624
  # @api public
605
625
  # @since 0.1.0
606
626
  #
607
- # @see Epiphy::Model::Adapters::Sql::Query
608
- # @see Epiphy::Model::Adapters::Memory::Query
627
+ # @see Epiphy::Adapters::Rethinkdb
609
628
  #
610
629
  # @example
611
630
  # require 'epiphy/model'
@@ -646,9 +665,27 @@ module Epiphy
646
665
  # query.average(:comments_count)
647
666
  # end
648
667
  # end
649
- def query(&blk)
650
- @adapter.query(collection, self, &blk)
668
+ def query(to_entity: true, &blk)
669
+ result = @adapter.query(table: collection, &blk)
670
+ require 'pp'
671
+ if result.is_a? RethinkDB::Cursor
672
+ return Epiphy::Repository::Cursor.new result do |item|
673
+ to_entity(item)
674
+ end
675
+ end
676
+
677
+ if result.is_a? Array
678
+ result.map! do |item|
679
+ to_entity(item)
680
+ end
681
+ end
682
+
683
+ if result.is_a? Hash
684
+ return to_entity(result)
685
+ end
686
+ result
651
687
  end
688
+
652
689
 
653
690
  # Negates the filtering conditions of a given query with the logical
654
691
  # opposite operator.
@@ -0,0 +1,28 @@
1
+ module Epiphy
2
+ module Repository
3
+ module Helper
4
+
5
+ # Find the first record matching the
6
+ #
7
+ # @param Keyword argument [field_name: value]
8
+ # @return Entity [Object]
9
+ # @raise Epiphy::Model::EntityNotFound if not found
10
+ #
11
+ # @api public
12
+ # @since 0.2.0
13
+ def find_by(**option)
14
+ begin
15
+ query do |r|
16
+ r.filter(option).nth(0)
17
+ end
18
+ rescue RethinkDB::RqlRuntimeError => e
19
+ #raise RethinkDB::RqlRuntimeError
20
+ raise Epiphy::Model::EntityNotFound if e.message.include?("Index out of bounds")
21
+ end
22
+ end
23
+
24
+ #private :where, :desc#, :exlude
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,19 @@
1
+ module Epiphy
2
+ module Schema
3
+ # Create a collection storage in database.
4
+ #
5
+ def create_collection
6
+ query do |r|
7
+ r.table_create(self.collection)
8
+ end
9
+ end
10
+
11
+ # Drop a collection storage in database
12
+ #
13
+ def drop_collection
14
+ query do |r|
15
+ r.table_drop(self.collection)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -2,5 +2,5 @@ module Epiphy
2
2
  # Defines the version
3
3
  #
4
4
  # @since 0.0.1
5
- VERSION = '0.0.1'.freeze
5
+ VERSION = '0.1.0'.freeze
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epiphy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vinh
@@ -59,18 +59,20 @@ executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
+ - EXAMPLE.md
62
63
  - README.md
63
64
  - lib/epiphy.rb
64
65
  - lib/epiphy/adapter/error.rb
65
- - lib/epiphy/adapter/helper.rb
66
- - lib/epiphy/adapter/model.rb
67
66
  - lib/epiphy/adapter/rethinkdb.rb
68
67
  - lib/epiphy/connection.rb
69
68
  - lib/epiphy/entity.rb
69
+ - lib/epiphy/entity/timestamp.rb
70
70
  - lib/epiphy/model.rb
71
71
  - lib/epiphy/repository.rb
72
72
  - lib/epiphy/repository/configuration.rb
73
73
  - lib/epiphy/repository/cursor.rb
74
+ - lib/epiphy/repository/helper.rb
75
+ - lib/epiphy/scheme.rb
74
76
  - lib/epiphy/version.rb
75
77
  homepage: http://rubygems.org/gems/hola
76
78
  licenses:
@@ -1,114 +0,0 @@
1
- module Epiphy
2
- module Adapter
3
- class Rethinkdb
4
- # RethinkDB method related. Should be in its helper
5
- def insert_object
6
- get_table.insert(
7
- safe_params.merge(
8
- id: params[:id],
9
- created_at: Time.now,
10
- updated_at: Time.now
11
- ).merge(parents)
12
- ).run(@connection)
13
- :created
14
- end
15
-
16
- def update_object
17
- get_table.update(
18
- safe_params.merge(
19
- id: params[:id],
20
- updated_at: Time.now
21
- )
22
- ).run(@connection)
23
- :ok
24
- end
25
-
26
- def replace_object
27
- get_table.replace(
28
- safe_params.merge(
29
- id: params[:id],
30
- created_at: Time.now,
31
- updated_at: Time.now
32
- ).merge(parents)
33
- ).run(@connection)
34
- :ok
35
- end
36
-
37
- def delete_object
38
- get_table.get(params[:id]).delete(
39
- :durability => "hard", :return_vals => false
40
- ).run(@connection)
41
- :no_content
42
- end
43
-
44
- def sort(qry)
45
- ordering = params[:sort].split(",").map do |attr|
46
- if attr[0] == "-"
47
- r.desc(attr[1..-1].to_sym)
48
- else
49
- r.asc(attr.to_sym)
50
- end
51
- end
52
-
53
- qry.order_by(*ordering)
54
- end
55
-
56
- def select(qry)
57
- qry = qry.get_all(*params[:ids].split(",")) if params[:ids]
58
- qry
59
- end
60
-
61
- def parents
62
- params.select {|k,v| k.match(/\A[a-z0-9_]+_id\z/i) }.compact
63
- end
64
-
65
- def filter(qry)
66
- parents.empty? ? qry : qry.filter(parents)
67
- end
68
-
69
- def attrs
70
- [ :id ]
71
- end
72
-
73
- def get_range(qry)
74
- begin
75
- rhdr = request.headers[:HTTP_RANGE].split("=")
76
-
77
- if rhdr[0] == collection
78
- qry = qry[Range.new(*rhdr[1].split("-").map(&:to_i))]
79
- end
80
- rescue Exception => e
81
- puts e.message
82
- raise Exception.new(:bad_request)
83
- end
84
- qry
85
- end
86
-
87
- def get_records
88
- qry = get_table
89
- qry = sort(qry) if params[:sort]
90
-
91
- fields = if params[:fields]
92
- params[:fields].split(",").map {|f| f.to_sym }.select do |field|
93
- attrs.include? field
94
- end
95
- else
96
- attrs
97
- end
98
-
99
- qry = filter(select(qry)).pluck(fields)
100
- qry = get_range(qry) if request.headers[:HTTP_RANGE]
101
-
102
- qry.run(@connection).map do |record|
103
- record.merge(href: some_url(record["id"]))
104
- end
105
- end
106
-
107
- def get_object
108
- get_table.filter(parents.merge({id: params[:id]})).pluck(attrs).run(@connection).first
109
- end
110
-
111
- end
112
- end
113
- end
114
-
@@ -1,99 +0,0 @@
1
- require 'errors'
2
-
3
- class Rethink
4
- include RethinkDB::Shortcuts
5
- include RethinkdbHelper
6
- include Errors
7
-
8
- def initialize
9
- create_connect_if_need
10
- @r = @@r.table(self.class.name.downcase)
11
- end
12
-
13
- def all
14
- self
15
- end
16
-
17
- # Get a single element by primary key
18
- def single(id)
19
- @r = @r.get(id)
20
- self
21
- end
22
-
23
- # Return raw RethinkDB object
24
- def raw_query
25
- @r
26
- end
27
-
28
- def reset
29
- @r = @@r.table self.class.name.downcase
30
- end
31
-
32
- # Run a RQL
33
- def get(r=nil)
34
- if r.nil?
35
- r = @r
36
- end
37
- r.run(@@rdb_connection)
38
- end
39
-
40
- [:update, "get_all", :limit, :order_by, :slice, :count, :filter].each do |name|
41
- define_method(name) do |*arg, &block|
42
- @r = @r.send(name, *arg, &block)
43
- self
44
- end
45
- end
46
-
47
- # Command work ona single object
48
- #{:destroy => :delete}.each do |public_name, name|
49
- #define_method(public_name) do |*arg, &block|
50
- #r = @@r.table self.class.name.downcase
51
- #r.get(*arg)
52
- #r.send(name, *arg, &block)
53
- #r.run @@rdb_connection
54
- #end
55
- #end
56
-
57
- def destroy(id)
58
- r = @@r.table self.class.name.downcase
59
- r.get(id)
60
- .delete()
61
- .run(@@rdb_connection)
62
- end
63
-
64
- # Validation
65
- def self.validate(args)
66
- if args.has_key? :errors
67
- raise ValidationError.new('Bad request', args[:errors])
68
- end
69
-
70
- args
71
- end
72
-
73
- def self.validate_present(args, *keys)
74
- for k in keys
75
- unless args.has_key?(k) and args[k].present?
76
- args[:errors] ||= {}
77
- args[:errors][k] ||= []
78
- args[:errors][k] << "can't be blank."
79
- end
80
- end
81
- args
82
- end
83
-
84
- def self.validate_email(args)
85
- if args.has_key? :email
86
- args[:email].downcase!
87
-
88
- unless args[:email].present? and
89
- args[:email].match EMAIL_REGEX
90
-
91
- args[:errors] ||= {}
92
- args[:errors][:email] ||= []
93
- args[:errors][:email] << "is invalid."
94
- end
95
- end
96
- args
97
- end
98
- end
99
-