shoden 0.2.0 → 0.3.0

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
  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