shoden 0.2.0 → 0.3.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: 47609f0a06edadfafbcc844d6b91d23eca91244e
4
- data.tar.gz: e7507a40336852be18a4cd30e7c3b78168f4bc3f
3
+ metadata.gz: c7c861e4cb7f7edd9609864081c18f45913c8a82
4
+ data.tar.gz: af092fb9fb7046d81bc703d90900e9f2bb83905f
5
5
  SHA512:
6
- metadata.gz: aa632c8f3b300e52655d5a3c5ce27777e348e5cea84f8e75d6533c594911bc367c1f765f0bf94633081d192bf112e339a8952528058c878369c734604e840cfb
7
- data.tar.gz: 2bc95a32031322ca1601cff586950f305fb12623829848c1207d9a9bac383f9c36382fdd137244f45e23a0ab0755b1c2bad604a90a642e5a147d5e0ed67a14f4
6
+ metadata.gz: faef768a2f83007e65b9bbaa5ae81414166175b55fac9de499faff85445af98390409572a608f7f54a13b63d9feeeb5933599b7c263aafc4ecd345237c8ab21a
7
+ data.tar.gz: a24ed94a720330c281f39a88df8ba7868a72438818acb3ecafd6b97984f2afcb96a419ecb4881cc68071e990256569a8dc7e6f0f16bf67cc26678c673398de91
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Shôden
1
+ # Shôden - [![Gem Version](https://badge.fury.io/rb/shoden.svg)](http://badge.fury.io/rb/shoden)
2
2
 
3
3
  ![Elephant god](http://www.redprintdna.com/wp-content/uploads/2011/09/L-Elephant-Against-Sky.jpg)
4
4
 
@@ -46,3 +46,15 @@ class Post < Shoden::Model
46
46
  reference :owner, :User
47
47
  end
48
48
  ```
49
+
50
+ ## Indexing
51
+
52
+ ```ruby
53
+ class User < Shoden::Model
54
+ attribute :email
55
+ attribute :country
56
+
57
+ index :country
58
+ unique :email
59
+ end
60
+ ```
@@ -3,8 +3,10 @@ require 'sequel'
3
3
  Sequel.extension :pg_hstore, :pg_hstore_ops
4
4
 
5
5
  module Shoden
6
- MissingID = Class.new(StandardError)
7
- NotFound = Class.new(StandardError)
6
+ Error = Class.new(StandardError)
7
+ MissingID = Class.new(Error)
8
+ NotFound = Class.new(Error)
9
+ UniqueIndexViolation = Class.new(Error)
8
10
 
9
11
  Proxy = Struct.new(:klass, :parent) do
10
12
  def create(args = {})
@@ -62,9 +64,16 @@ module Shoden
62
64
  if defined? @_id
63
65
  table.where(id: @_id).update data: sanitized_attrs
64
66
  else
65
- @_id = table.insert data: sanitized_attrs
67
+ begin
68
+ @_id = table.insert data: sanitized_attrs
69
+ rescue Sequel::UniqueConstraintViolation
70
+ raise UniqueIndexViolation
71
+ end
66
72
  end
67
73
 
74
+ self.class.indices.each { |i| create_index(i) }
75
+ self.class.uniques.each { |i| create_index(i, :unique) }
76
+
68
77
  self
69
78
  end
70
79
 
@@ -74,6 +83,18 @@ module Shoden
74
83
  self
75
84
  end
76
85
 
86
+ def self.all
87
+ collect
88
+ end
89
+
90
+ def self.first
91
+ collect("ORDER BY id ASC LIMIT 1").first
92
+ end
93
+
94
+ def self.last
95
+ collect("ORDER BY id DESC LIMIT 1").first
96
+ end
97
+
77
98
  def self.create(attrs = {})
78
99
  new(attrs).save
79
100
  end
@@ -82,10 +103,26 @@ module Shoden
82
103
  @attributes ||= []
83
104
  end
84
105
 
106
+ def self.indices
107
+ @indices ||= []
108
+ end
109
+
110
+ def self.uniques
111
+ @uniques ||= []
112
+ end
113
+
85
114
  def self.[](id)
86
115
  new(id: id).load!
87
116
  end
88
117
 
118
+ def self.index(name)
119
+ indices << name if !indices.include?(name)
120
+ end
121
+
122
+ def self.unique(name)
123
+ uniques << name if !uniques.include?(name)
124
+ end
125
+
89
126
  def self.attribute(name, caster = ->(x) { x })
90
127
  attributes << name if !attributes.include?(name)
91
128
 
@@ -117,6 +154,19 @@ module Shoden
117
154
 
118
155
  private
119
156
 
157
+ def self.collect(condition = '')
158
+ models = []
159
+ Shoden.connection.fetch("SELECT * FROM \"#{table_name}\" #{condition}") do |r|
160
+ attrs = r[:data].merge(id: r[:id])
161
+ models << new(attrs)
162
+ end
163
+ models
164
+ end
165
+
166
+ def self.table_name
167
+ :"Shoden::#{self.name}"
168
+ end
169
+
120
170
  def self.to_reference
121
171
  name.to_s.
122
172
  match(/^(?:.*::)*(.*)$/)[1].
@@ -124,11 +174,18 @@ module Shoden
124
174
  downcase.to_sym
125
175
  end
126
176
 
177
+ def create_index(name, type = '')
178
+ conn.execute <<EOS
179
+ CREATE #{type.upcase} INDEX index_#{self.class.name}_#{name}
180
+ ON "#{table_name}" (( data -> '#{name}'))
181
+ WHERE ( data ? '#{name}' );
182
+ EOS
183
+ end
184
+
127
185
  def sanitized_attrs
128
186
  sanitized = @attributes.map do |k, _|
129
187
  val = send(k)
130
- return if !val
131
-
188
+ return if val.nil?
132
189
  [k, val.to_s]
133
190
  end.compact
134
191
 
@@ -153,7 +210,7 @@ module Shoden
153
210
  end
154
211
 
155
212
  def table_name
156
- :"Shoden::#{self.class.name}"
213
+ self.class.table_name
157
214
  end
158
215
 
159
216
  def table
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "shoden"
3
- s.version = "0.2.0"
3
+ s.version = "0.3.0"
4
4
  s.summary = "Object hash mapper for postgres"
5
5
  s.description = "Slim postgres models"
6
6
  s.authors = ["elcuervo"]
@@ -78,3 +78,29 @@ test 'casting' do
78
78
 
79
79
  assert_equal a_prime.n, 1
80
80
  end
81
+
82
+ test 'indices' do
83
+ class Person < Shoden::Model
84
+ attribute :email
85
+ attribute :origin
86
+
87
+ index :origin
88
+ unique :email
89
+ end
90
+
91
+ person = Person.create(email: 'elcuervo@elcuervo.net', origin: 'The internerd')
92
+
93
+ assert person.id
94
+
95
+ assert_raise Shoden::UniqueIndexViolation do
96
+ Person.create(email: 'elcuervo@elcuervo.net', origin: 'Montevideo City')
97
+ end
98
+ end
99
+
100
+ test 'basic querying' do
101
+ 5.times { User.create }
102
+
103
+ assert_equal User.all.size, 5
104
+ assert_equal User.first.id, 1
105
+ assert_equal User.last.id, 5
106
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shoden
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - elcuervo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-28 00:00:00.000000000 Z
11
+ date: 2014-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel