friendly_postgres 0.4.3
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.
- data/.document +2 -0
- data/.gitignore +26 -0
- data/APACHE-LICENSE +202 -0
- data/CHANGELOG.md +19 -0
- data/CONTRIBUTORS.md +7 -0
- data/LICENSE +20 -0
- data/README.md +265 -0
- data/Rakefile +68 -0
- data/TODO.md +5 -0
- data/VERSION +1 -0
- data/examples/friendly.yml +7 -0
- data/friendly.gemspec +232 -0
- data/lib/friendly.rb +54 -0
- data/lib/friendly/associations.rb +7 -0
- data/lib/friendly/associations/association.rb +34 -0
- data/lib/friendly/associations/set.rb +37 -0
- data/lib/friendly/attribute.rb +91 -0
- data/lib/friendly/boolean.rb +10 -0
- data/lib/friendly/cache.rb +24 -0
- data/lib/friendly/cache/by_id.rb +33 -0
- data/lib/friendly/config.rb +5 -0
- data/lib/friendly/data_store.rb +72 -0
- data/lib/friendly/document.rb +257 -0
- data/lib/friendly/document_table.rb +56 -0
- data/lib/friendly/index.rb +73 -0
- data/lib/friendly/memcached.rb +48 -0
- data/lib/friendly/named_scope.rb +17 -0
- data/lib/friendly/newrelic.rb +6 -0
- data/lib/friendly/query.rb +42 -0
- data/lib/friendly/scope.rb +100 -0
- data/lib/friendly/scope_proxy.rb +45 -0
- data/lib/friendly/sequel_monkey_patches.rb +34 -0
- data/lib/friendly/storage.rb +31 -0
- data/lib/friendly/storage_factory.rb +24 -0
- data/lib/friendly/storage_proxy.rb +103 -0
- data/lib/friendly/table.rb +15 -0
- data/lib/friendly/table_creator.rb +48 -0
- data/lib/friendly/time.rb +14 -0
- data/lib/friendly/translator.rb +32 -0
- data/lib/friendly/uuid.rb +148 -0
- data/rails/init.rb +3 -0
- data/spec/config.yml.example +7 -0
- data/spec/fakes/data_store_fake.rb +29 -0
- data/spec/fakes/database_fake.rb +12 -0
- data/spec/fakes/dataset_fake.rb +28 -0
- data/spec/fakes/document.rb +18 -0
- data/spec/fakes/serializer_fake.rb +12 -0
- data/spec/fakes/time_fake.rb +12 -0
- data/spec/integration/ad_hoc_scopes_spec.rb +42 -0
- data/spec/integration/basic_object_lifecycle_spec.rb +114 -0
- data/spec/integration/batch_insertion_spec.rb +29 -0
- data/spec/integration/convenience_api_spec.rb +25 -0
- data/spec/integration/count_spec.rb +12 -0
- data/spec/integration/default_value_spec.rb +15 -0
- data/spec/integration/find_via_cache_spec.rb +101 -0
- data/spec/integration/finder_spec.rb +64 -0
- data/spec/integration/has_many_spec.rb +18 -0
- data/spec/integration/index_spec.rb +57 -0
- data/spec/integration/named_scope_spec.rb +34 -0
- data/spec/integration/pagination_spec.rb +63 -0
- data/spec/integration/scope_chaining_spec.rb +22 -0
- data/spec/integration/table_creator_spec.rb +64 -0
- data/spec/integration/write_through_cache_spec.rb +53 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +103 -0
- data/spec/unit/associations/association_spec.rb +57 -0
- data/spec/unit/associations/set_spec.rb +43 -0
- data/spec/unit/attribute_spec.rb +105 -0
- data/spec/unit/cache_by_id_spec.rb +102 -0
- data/spec/unit/cache_spec.rb +21 -0
- data/spec/unit/config_spec.rb +4 -0
- data/spec/unit/data_store_spec.rb +188 -0
- data/spec/unit/document_spec.rb +358 -0
- data/spec/unit/document_table_spec.rb +126 -0
- data/spec/unit/friendly_spec.rb +25 -0
- data/spec/unit/index_spec.rb +196 -0
- data/spec/unit/memcached_spec.rb +114 -0
- data/spec/unit/named_scope_spec.rb +16 -0
- data/spec/unit/query_spec.rb +104 -0
- data/spec/unit/scope_proxy_spec.rb +44 -0
- data/spec/unit/scope_spec.rb +113 -0
- data/spec/unit/storage_factory_spec.rb +59 -0
- data/spec/unit/storage_proxy_spec.rb +218 -0
- data/spec/unit/translator_spec.rb +96 -0
- data/website/index.html +210 -0
- data/website/scripts/clipboard.swf +0 -0
- data/website/scripts/shBrushAS3.js +61 -0
- data/website/scripts/shBrushBash.js +66 -0
- data/website/scripts/shBrushCSharp.js +67 -0
- data/website/scripts/shBrushColdFusion.js +102 -0
- data/website/scripts/shBrushCpp.js +99 -0
- data/website/scripts/shBrushCss.js +93 -0
- data/website/scripts/shBrushDelphi.js +57 -0
- data/website/scripts/shBrushDiff.js +43 -0
- data/website/scripts/shBrushErlang.js +54 -0
- data/website/scripts/shBrushGroovy.js +69 -0
- data/website/scripts/shBrushJScript.js +52 -0
- data/website/scripts/shBrushJava.js +59 -0
- data/website/scripts/shBrushJavaFX.js +60 -0
- data/website/scripts/shBrushPerl.js +74 -0
- data/website/scripts/shBrushPhp.js +91 -0
- data/website/scripts/shBrushPlain.js +35 -0
- data/website/scripts/shBrushPowerShell.js +76 -0
- data/website/scripts/shBrushPython.js +66 -0
- data/website/scripts/shBrushRuby.js +57 -0
- data/website/scripts/shBrushScala.js +53 -0
- data/website/scripts/shBrushSql.js +68 -0
- data/website/scripts/shBrushVb.js +58 -0
- data/website/scripts/shBrushXml.js +71 -0
- data/website/scripts/shCore.js +30 -0
- data/website/scripts/shLegacy.js +30 -0
- data/website/styles/friendly.css +103 -0
- data/website/styles/help.png +0 -0
- data/website/styles/ie.css +35 -0
- data/website/styles/magnifier.png +0 -0
- data/website/styles/page_white_code.png +0 -0
- data/website/styles/page_white_copy.png +0 -0
- data/website/styles/print.css +29 -0
- data/website/styles/printer.png +0 -0
- data/website/styles/screen.css +257 -0
- data/website/styles/shCore.css +330 -0
- data/website/styles/shThemeDefault.css +173 -0
- data/website/styles/shThemeDjango.css +176 -0
- data/website/styles/shThemeEclipse.css +190 -0
- data/website/styles/shThemeEmacs.css +175 -0
- data/website/styles/shThemeFadeToGrey.css +177 -0
- data/website/styles/shThemeMidnight.css +175 -0
- data/website/styles/shThemeRDark.css +175 -0
- metadata +302 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class DatasetFake
|
|
2
|
+
attr_accessor :where, :insert, :inserts, :update, :updates, :first
|
|
3
|
+
|
|
4
|
+
def initialize(opts = {})
|
|
5
|
+
opts.each { |k,v| send("#{k}=", v) }
|
|
6
|
+
@inserts ||= []
|
|
7
|
+
@updates ||= []
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def where(conditions)
|
|
11
|
+
@where.detect { |k,v| k == conditions }.last
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def insert(attributes)
|
|
15
|
+
inserts << attributes
|
|
16
|
+
@insert
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def update(attributes)
|
|
20
|
+
updates << attributes
|
|
21
|
+
@update
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def first(conditions)
|
|
25
|
+
@first.detect { |k,v| k == conditions }.last
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class FakeDocument
|
|
2
|
+
attr_accessor :id, :created_at, :to_hash, :new_record, :table_name,
|
|
3
|
+
:indexes, :name, :updated_at, :where_clause
|
|
4
|
+
|
|
5
|
+
def initialize(opts = {})
|
|
6
|
+
opts.each { |k,v| send("#{k}=", v) }
|
|
7
|
+
new_record = true if new_record.nil?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def new_record?
|
|
11
|
+
new_record
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def attributes=(attrs)
|
|
15
|
+
attrs.each { |k,v| send("#{k}=", v) }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Querying with an ad-hoc scope" do
|
|
4
|
+
before do
|
|
5
|
+
User.all(:name => "Fred").each { |u| u.destroy }
|
|
6
|
+
@users = (1..10).map { User.create(:name => "Fred") }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "can return all the objects matching the scope" do
|
|
10
|
+
User.scope(:name => "Fred").all.should == @users
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "can return the first object matching the scope" do
|
|
14
|
+
User.scope(:name => "Fred").first.should == User.first(:name => "Fred")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "can paginate over the matching objects" do
|
|
18
|
+
found = User.scope(:name => "Fred").paginate(:per_page! => 5)
|
|
19
|
+
found.should == User.paginate(:name => "Fred", :per_page! => 5)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "can build an object at scope" do
|
|
23
|
+
User.scope(:name => "Fred", :limit! => 5).build.name.should == "Fred"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "supports overriding parameters when building" do
|
|
27
|
+
scope = User.scope(:name => "Fred", :limit! => 5)
|
|
28
|
+
scope.build(:name => "Joe").name.should == "Joe"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "can create an object at scope" do
|
|
32
|
+
user = User.scope(:name => "Joe").create
|
|
33
|
+
user.should_not be_new_record
|
|
34
|
+
user.name.should == "Joe"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "supports overriding parameters when creating" do
|
|
38
|
+
user = User.scope(:name => "Joe").create(:name => "Fred")
|
|
39
|
+
user.should_not be_new_record
|
|
40
|
+
user.name.should == "Fred"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Creating and retrieving an object" do
|
|
4
|
+
before do
|
|
5
|
+
@user = User.new :name => "Stewie Griffin",
|
|
6
|
+
:age => 3
|
|
7
|
+
@user.save
|
|
8
|
+
@found_user = User.find(@user.id)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "finds the user in the database" do
|
|
12
|
+
@found_user.name.should == @user.name
|
|
13
|
+
@found_user.age.should == @user.age
|
|
14
|
+
@found_user.id.should == @user.id
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "locates an object that is == to the created object" do
|
|
18
|
+
@found_user.should == @user
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "sets the created_at timestamp for the record" do
|
|
22
|
+
@user.created_at.should_not be_nil
|
|
23
|
+
@user.created_at.should be_instance_of(Time)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "sets the created_at on the way out of the database" do
|
|
27
|
+
@found_user.created_at.should_not be_nil
|
|
28
|
+
@found_user.created_at.to_i.should == @user.created_at.to_i
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "sets the updated_at on the way out of the database" do
|
|
32
|
+
@found_user.updated_at.should_not be_nil
|
|
33
|
+
@found_user.updated_at.to_i.should == @user.updated_at.to_i
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "sets the updated_at" do
|
|
37
|
+
@user.updated_at.to_i.should == @user.created_at.to_i
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "doesn't serialize id, created_at, or updated_at in the attributes column" do
|
|
41
|
+
result = $db.from("users").first(:id => @user.id)
|
|
42
|
+
attrs = JSON.parse(result[:attributes])
|
|
43
|
+
attrs.keys.should_not include("id")
|
|
44
|
+
attrs.keys.should_not include("created_at")
|
|
45
|
+
attrs.keys.should_not include("updated_at")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "has an id of type Friendly::UUID" do
|
|
49
|
+
@user.id.should be_kind_of(Friendly::UUID)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe "Updating an object" do
|
|
54
|
+
before do
|
|
55
|
+
@user = User.new :name => "Stewie Griffin",
|
|
56
|
+
:age => 3
|
|
57
|
+
@user.save
|
|
58
|
+
@created_id = @user.id
|
|
59
|
+
@created_at = @user.created_at
|
|
60
|
+
|
|
61
|
+
sleep(0.1)
|
|
62
|
+
@user.name = "Brian Griffin"
|
|
63
|
+
@user.age = 8
|
|
64
|
+
@user.save
|
|
65
|
+
|
|
66
|
+
@found_user = User.find(@created_id)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "sets the updated_at column" do
|
|
70
|
+
@user.updated_at.should_not be_nil
|
|
71
|
+
@user.updated_at.should_not == @user.created_at
|
|
72
|
+
@user.updated_at.should > @user.created_at
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "doesn't change the created_at" do
|
|
76
|
+
@user.created_at.should == @created_at
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "doesn't change the id" do
|
|
80
|
+
@user.id.should == @created_id
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "saves the new attrs to the db" do
|
|
84
|
+
@found_user.name.should == "Brian Griffin"
|
|
85
|
+
@found_user.age.should == 8
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
describe "destroying a document" do
|
|
90
|
+
before do
|
|
91
|
+
@user = User.new :name => "Stewie Griffin"
|
|
92
|
+
@user.save
|
|
93
|
+
@user.destroy
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "removes it from the database" do
|
|
97
|
+
User.first(:id => @user.id).should be_nil
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
describe "Finding an object by id" do
|
|
102
|
+
it "raises Friendly::RecordNotFound if it doesn't exist" do
|
|
103
|
+
lambda { User.find(12345) }.should raise_error(Friendly::RecordNotFound)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe "An object that has a foreign key" do
|
|
108
|
+
it "is saveable in the database" do
|
|
109
|
+
lambda {
|
|
110
|
+
Address.create :user_id => Friendly::UUID.new
|
|
111
|
+
}.should_not raise_error
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Batch inserting several documents" do
|
|
4
|
+
it "inserts them when the block returns" do
|
|
5
|
+
Friendly.batch do
|
|
6
|
+
user = User.new(:name => "Lois")
|
|
7
|
+
user.save
|
|
8
|
+
User.all(:name => "Lois").should be_empty
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
User.all(:name => "Lois").should_not be_empty
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "doesn't insert anything if an error is raised" do
|
|
15
|
+
begin
|
|
16
|
+
Friendly.batch do
|
|
17
|
+
user = User.new(:name => "Meg")
|
|
18
|
+
user.save
|
|
19
|
+
raise "AHHHH!"
|
|
20
|
+
end
|
|
21
|
+
rescue RuntimeError => e
|
|
22
|
+
@bubbled_up = true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
@bubbled_up.should be_true
|
|
26
|
+
|
|
27
|
+
User.all(:name => "Meg").should be_empty
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Document.create" do
|
|
4
|
+
before do
|
|
5
|
+
@user = User.create(:name => "James")
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "initializes the document, saves it, and returns it" do
|
|
9
|
+
@user.name.should == "James"
|
|
10
|
+
@user.should_not be_new_record
|
|
11
|
+
User.find(@user.id).should_not be_nil
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "Document#update_attributes" do
|
|
16
|
+
before do
|
|
17
|
+
@user = User.create
|
|
18
|
+
@user.update_attributes :name => "James"
|
|
19
|
+
@user = User.find(@user.id)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "updates the attributes in the database" do
|
|
23
|
+
@user.name.should == "James"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Counting the objects matching a query" do
|
|
4
|
+
before do
|
|
5
|
+
User.all(:name => "Evil Monkey").each { |u| u.destroy }
|
|
6
|
+
5.times { User.create :name => "Evil Monkey" }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "does a count in the index to find out what matches" do
|
|
10
|
+
User.count(:name => "Evil Monkey").should == 5
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "An attribute with a default value" do
|
|
4
|
+
before do
|
|
5
|
+
@user = User.new
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "has the value by default" do
|
|
9
|
+
@user.happy.should be_true
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "has a default vaue even when it's false" do
|
|
13
|
+
@user.sad.should be_false
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Finding objects in the cache" do
|
|
4
|
+
def cache_key(user)
|
|
5
|
+
["Address", 0, user.id.to_guid].join("/")
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
describe "by id" do
|
|
9
|
+
before do
|
|
10
|
+
@address = Address.create :street => "Spooner"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "if the user is in cache" do
|
|
14
|
+
before do
|
|
15
|
+
$cache.set(cache_key(@address), "the address")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "returns the object from cache if its there" do
|
|
19
|
+
Address.first(:id => @address.id).should == "the address"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "if the user isn't there" do
|
|
24
|
+
before do
|
|
25
|
+
$cache.delete(cache_key(@address))
|
|
26
|
+
@found = Address.first(:id => @address.id)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "finds the object in the database" do
|
|
30
|
+
@found.should == @address
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "stores the object in cache (read through)" do
|
|
34
|
+
$cache.get(cache_key(@address)).should == @address
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe "several objects via id" do
|
|
40
|
+
before do
|
|
41
|
+
@addresses = (0..3).map { Address.create :street => "Spooner" }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe "when all objects are found" do
|
|
45
|
+
before do
|
|
46
|
+
@addresses.each { |a| $cache.set(cache_key(a), "the address") }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "returns all the objects from cache" do
|
|
50
|
+
Address.all(:id => @addresses.map { |u| u.id }).should == ["the address"] * 4
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe "when some objects are missing" do
|
|
55
|
+
before do
|
|
56
|
+
$cache.delete(cache_key(@addresses.first))
|
|
57
|
+
@found = Address.all(:id => @addresses.map { |u| u.id })
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "finds the object and returns it" do
|
|
61
|
+
expected = @addresses.sort { |a,b| a.id <=> b.id }
|
|
62
|
+
@found.sort { |a,b| a.id <=> b.id }.should == expected
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "writes the object through to the cache" do
|
|
66
|
+
lambda {
|
|
67
|
+
$cache.get(cache_key(@addresses.first))
|
|
68
|
+
}.should_not raise_error
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe "calling all when the array of ids is empty" do
|
|
74
|
+
it "returns nothing" do
|
|
75
|
+
Address.all(:id => [])
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe "finding several objects in order via cache" do
|
|
80
|
+
before do
|
|
81
|
+
@addresses = (0...5).map { Address.create :street => "Spooner" }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "returns them in order" do
|
|
85
|
+
fnd = Address.all(:id => @addresses.map { |a| a.id }, :preserve_order! => true)
|
|
86
|
+
fnd.should == @addresses
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe "when there's an object in the index that doesn't really exist" do
|
|
91
|
+
before do
|
|
92
|
+
table = $db.from("index_addresses_on_street")
|
|
93
|
+
table.where(:street => "Quahog").delete
|
|
94
|
+
table.insert(:street => "Quahog", :id => Friendly::UUID.new)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "just returns [] silently on #all" do
|
|
98
|
+
Address.all(:street => "Quahog").should == []
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
require 'active_support/duration'
|
|
3
|
+
require 'active_support/core_ext/integer'
|
|
4
|
+
require 'active_support/core_ext/time'
|
|
5
|
+
require 'active_support/core_ext/object'
|
|
6
|
+
require 'active_support/core_ext/numeric'
|
|
7
|
+
|
|
8
|
+
describe "Finding multiple objects by id" do
|
|
9
|
+
before do
|
|
10
|
+
@user_one = User.new
|
|
11
|
+
@user_two = User.new
|
|
12
|
+
@user_one.save
|
|
13
|
+
@user_two.save
|
|
14
|
+
@users = User.all(:id => [@user_one.id, @user_two.id])
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "finds the objects in the database" do
|
|
18
|
+
@users.length.should == 2
|
|
19
|
+
@users.should include(@user_one)
|
|
20
|
+
@users.should include(@user_two)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "when no objects are found" do
|
|
24
|
+
it "returns an empty array" do
|
|
25
|
+
User.all(:id => [9999, 12345, 999]).should == []
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "when one object is found, but others aren't" do
|
|
30
|
+
it "returns the found objects" do
|
|
31
|
+
User.all(:id => [@user_one.id, 12345]).should == [@user_one]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe "Limiting a query" do
|
|
37
|
+
before do
|
|
38
|
+
10.times { User.new(:name => "Stewie").save }
|
|
39
|
+
@results = User.all(:name => "Stewie", :limit! => 5)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "returns the number of results you asked for" do
|
|
43
|
+
@results.length.should == 5
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe "limiting a query with offset" do
|
|
48
|
+
before do
|
|
49
|
+
@objects = (0..10).map do |i|
|
|
50
|
+
User.new(:name => "Joe", :created_at => i.minutes.from_now).tap do |u|
|
|
51
|
+
u.save
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
after { @objects.each { |o| o.destroy } }
|
|
57
|
+
|
|
58
|
+
it "returns results starting from the offset to hte limit" do
|
|
59
|
+
User.all(:name => "Joe",
|
|
60
|
+
:offset! => 2,
|
|
61
|
+
:limit! => 2,
|
|
62
|
+
:order! => :created_at.desc).should == @objects.reverse.slice(2, 2)
|
|
63
|
+
end
|
|
64
|
+
end
|