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,43 @@
|
|
|
1
|
+
require File.expand_path("../../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Friendly::Associations::Set" do
|
|
4
|
+
before do
|
|
5
|
+
@klass = Class.new
|
|
6
|
+
@association_klass = stub
|
|
7
|
+
@set = Friendly::Associations::Set.new(@klass, @association_klass)
|
|
8
|
+
@assoc = stub
|
|
9
|
+
@association_klass.stubs(:new).
|
|
10
|
+
with(@klass, :my_awesome_association, {}).returns(@assoc)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "adding an association" do
|
|
14
|
+
before do
|
|
15
|
+
@set.add(:my_awesome_association)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "creates an association and adds it to its hash by name" do
|
|
19
|
+
@set.associations[:my_awesome_association].should == @assoc
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "adds an instance method to the klass through which to acces the assoc" do
|
|
23
|
+
@doc = @klass.new
|
|
24
|
+
@scope = stub
|
|
25
|
+
@klass.stubs(:association_set).returns(@set)
|
|
26
|
+
@assoc.stubs(:scope).with(@doc).returns(@scope)
|
|
27
|
+
@doc.my_awesome_association.should == @scope
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "can return the association by name" do
|
|
32
|
+
@set.add(:my_awesome_association)
|
|
33
|
+
@set.get(:my_awesome_association).should == @assoc
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "provides the scope for an association by name" do
|
|
37
|
+
@doc = stub
|
|
38
|
+
@scope = stub
|
|
39
|
+
@assoc.stubs(:scope).with(@doc).returns(@scope)
|
|
40
|
+
@set.add(:my_awesome_association)
|
|
41
|
+
@set.get_scope(:my_awesome_association, @doc).should == @scope
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Friendly::Attribute" do
|
|
4
|
+
before do
|
|
5
|
+
@klass = Class.new
|
|
6
|
+
@name = Friendly::Attribute.new(@klass, :name, String)
|
|
7
|
+
@id = Friendly::Attribute.new(@klass, :id, Friendly::UUID)
|
|
8
|
+
@no_type = Friendly::Attribute.new(@klass, :no_type, nil)
|
|
9
|
+
@default = Friendly::Attribute.new(@klass, :default, String, :default => "asdf")
|
|
10
|
+
@false = Friendly::Attribute.new(@klass, :default, String, :default => false)
|
|
11
|
+
@klass.stubs(:attributes).returns({:name => @name,
|
|
12
|
+
:id => @id,
|
|
13
|
+
:default => @default,
|
|
14
|
+
:false => @false})
|
|
15
|
+
@object = @klass.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "creates a setter and a getter on klass" do
|
|
19
|
+
@object.name = "Something"
|
|
20
|
+
@object.name.should == "Something"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "typecasts values using the converter function" do
|
|
24
|
+
uuid = Friendly::UUID.new
|
|
25
|
+
@id.typecast(uuid.to_s).should == uuid
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "doesn't typecast values if they are of the right type" do
|
|
29
|
+
uuid = Friendly::UUID.new
|
|
30
|
+
@id.typecast(uuid).should == uuid
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "raises a useful error if it can't typecast" do
|
|
34
|
+
attribute = Friendly::Attribute.new(@klass, :weird, Class)
|
|
35
|
+
lambda {
|
|
36
|
+
attribute.typecast("ASDF")
|
|
37
|
+
}.should raise_error(Friendly::NoConverterExists)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "creates a getter with a default value" do
|
|
41
|
+
@object.id.should be_instance_of(Friendly::UUID)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "has a default value of type.new" do
|
|
45
|
+
@id.default.should be_instance_of(Friendly::UUID)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "has a default of nil if the type doesn't respond to :new" do
|
|
49
|
+
Friendly::Attribute.new(@klass, :age, Integer).default.should be_nil
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "doesn't try to convert when there's no type" do
|
|
53
|
+
@no_type.typecast(true).should == true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "can have a default value" do
|
|
57
|
+
@default.default.should == "asdf"
|
|
58
|
+
@klass.new.default.should == "asdf"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "has a default value even if it's false" do
|
|
62
|
+
@false.default.should be_false
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe "registering a type" do
|
|
66
|
+
before do
|
|
67
|
+
@klass = Class.new
|
|
68
|
+
Friendly::Attribute.register_type(@klass, "binary(16)") { |t| t.to_i }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
after { Friendly::Attribute.deregister_type(@klass) }
|
|
72
|
+
|
|
73
|
+
it "tells Attribute about the sql_type" do
|
|
74
|
+
Friendly::Attribute.sql_type(@klass).should == "binary(16)"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "registers the conversion method" do
|
|
78
|
+
Friendly::Attribute.new(@klass, :something, @klass).convert("1").should == 1
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "is custom_type?(@klass)" do
|
|
82
|
+
Friendly::Attribute.should be_custom_type(@klass)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
describe "deregistering a type" do
|
|
87
|
+
before do
|
|
88
|
+
@klass = Class.new
|
|
89
|
+
Friendly::Attribute.register_type(@klass, "whatever") {}
|
|
90
|
+
Friendly::Attribute.deregister_type(@klass)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "removes the converter method" do
|
|
94
|
+
Friendly::Attribute.converters.should_not be_has_key(@klass)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "removes the sql_type" do
|
|
98
|
+
Friendly::Attribute.sql_types.should_not be_has_key(@klass)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "is not custom_type?(@klass)" do
|
|
102
|
+
Friendly::Attribute.should_not be_custom_type(@klass)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Friendly::Cache::ByID" do
|
|
4
|
+
before do
|
|
5
|
+
@cache = stub(:set => nil)
|
|
6
|
+
@klass = stub(:name => "Product")
|
|
7
|
+
@id_cache = Friendly::Cache::ByID.new(@klass, [:id], {}, @cache)
|
|
8
|
+
@subject = @id_cache
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it { should be_satisfies(query(:id => "asdf")) }
|
|
12
|
+
it { should be_satisfies(query(:id => ["asdf"])) }
|
|
13
|
+
it { should_not be_satisfies(query(:id => ["asdf"], :name => "asdf")) }
|
|
14
|
+
it { should_not be_satisfies(query(:name => "asdf")) }
|
|
15
|
+
|
|
16
|
+
it "has a default version of 0" do
|
|
17
|
+
@id_cache.version.should == 0
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "is possible to override version" do
|
|
21
|
+
Friendly::Cache::ByID.new(@klass, [:id], {:version => 1}).version.should == 1
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "when an object is created" do
|
|
25
|
+
before do
|
|
26
|
+
@uuid = stub(:to_guid => "xxxx-xxx-xxx-xxxx")
|
|
27
|
+
@doc = stub(:id => @uuid)
|
|
28
|
+
@id_cache.create(@doc)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "sets the cache value in the db" do
|
|
32
|
+
@cache.should have_received(:set).with("Product/0/#{@uuid.to_guid}", @doc)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe "when an object is updated" do
|
|
37
|
+
before do
|
|
38
|
+
@uuid = stub(:to_guid => "xxxx-xxx-xxx-xxxx")
|
|
39
|
+
@doc = stub(:id => @uuid)
|
|
40
|
+
@id_cache.update(@doc)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "sets the cache value in the db" do
|
|
44
|
+
@cache.should have_received(:set).with("Product/0/#{@uuid.to_guid}", @doc)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "when an object is destroyed" do
|
|
49
|
+
before do
|
|
50
|
+
@cache.stubs(:delete)
|
|
51
|
+
@uuid = stub(:to_guid => "xxxx-xxx-xxx-xxxx")
|
|
52
|
+
@doc = stub(:id => @uuid)
|
|
53
|
+
@id_cache.destroy(@doc)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "deletes the object from cache" do
|
|
57
|
+
@cache.should have_received(:delete).with("Product/0/#{@uuid.to_guid}")
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe "finding a single object in cache" do
|
|
62
|
+
before do
|
|
63
|
+
@uuid = stub(:to_guid => "xxxx-xxx-xxx-xxxx")
|
|
64
|
+
@doc = stub
|
|
65
|
+
@cache.stubs(:get).with("Product/0/xxxx-xxx-xxx-xxxx").returns(@doc).yields
|
|
66
|
+
@block_called = true
|
|
67
|
+
@returned = @id_cache.first(query(:id => @uuid)) do
|
|
68
|
+
@block_called = true
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "returns the document" do
|
|
73
|
+
@returned.should == @doc
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "passes along the block to the memcached object" do
|
|
77
|
+
@block_called.should be_true
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe "finding many objects in the cache" do
|
|
82
|
+
before do
|
|
83
|
+
@uuid = stub(:to_guid => "xxxx-xxx-xxx-xxxx")
|
|
84
|
+
@doc = stub
|
|
85
|
+
@key = "Product/0/xxxx-xxx-xxx-xxxx"
|
|
86
|
+
@cache.stubs(:multiget).with([@key, @key]).
|
|
87
|
+
returns({@uuid.to_guid => @doc}).yields(@uuid.to_guid)
|
|
88
|
+
@block_called = []
|
|
89
|
+
@returned = @id_cache.all(query(:id => [@uuid, @uuid])) do |id|
|
|
90
|
+
@block_called << id
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "returns the values from the hash" do
|
|
95
|
+
@returned.should == [@doc]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "passes the block along to the cache" do
|
|
99
|
+
@block_called.should == [@uuid.to_guid]
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Friendly::Cache" do
|
|
4
|
+
describe "getting a cache object for :id" do
|
|
5
|
+
before do
|
|
6
|
+
@cache = Friendly::Cache.cache_for(stub, [:id], {})
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "instantiates a Cache::ByID" do
|
|
10
|
+
@cache.should be_instance_of(Friendly::Cache::ByID)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe "for other fields" do
|
|
15
|
+
it "raises NotSupported" do
|
|
16
|
+
lambda {
|
|
17
|
+
Friendly::Cache.cache_for(stub, [:asdf], {})
|
|
18
|
+
}.should raise_error(Friendly::NotSupported)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Friendly::DataStore" do
|
|
4
|
+
before do
|
|
5
|
+
@users = DatasetFake.new(:insert => 42)
|
|
6
|
+
@db = DatabaseFake.new("users" => @users)
|
|
7
|
+
@datastore = Friendly::DataStore.new(@db)
|
|
8
|
+
@klass = stub(:table_name => "users")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe "inserting data" do
|
|
12
|
+
before do
|
|
13
|
+
@return = @datastore.insert(@klass, :name => "Stewie")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "inserts it in to the table in the datastore" do
|
|
17
|
+
@users.inserts.length.should == 1
|
|
18
|
+
@users.inserts.should include(:name => "Stewie")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "returns the id from the dataset" do
|
|
22
|
+
@return.should == 42
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe "retrieving all based on a query" do
|
|
27
|
+
before do
|
|
28
|
+
@users.where = {{:name => "Stewie"} => stub(:map => [{:id => 1}])}
|
|
29
|
+
@return = @datastore.all(@klass, query(:name => "Stewie"))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "gets the data from the dataset for the klass and makes it an arary" do
|
|
33
|
+
@return.should == [{:id => 1}]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe "retrieving all with a limit" do
|
|
38
|
+
before do
|
|
39
|
+
@filtered = stub
|
|
40
|
+
@filtered.stubs(:limit).with(10, nil).returns(stub(:map => [{:id => 1}]))
|
|
41
|
+
@users.where = {{:name => "Stewie"} => @filtered}
|
|
42
|
+
@query = query(:name => "Stewie", :limit! => 10)
|
|
43
|
+
@return = @datastore.all(@klass, @query)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "limits the filtered dataset and returns the results" do
|
|
47
|
+
@return.should == [{:id => 1}]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe "retrieving all with a offset" do
|
|
52
|
+
before do
|
|
53
|
+
@filtered = stub
|
|
54
|
+
@filtered.stubs(:limit).with(nil, 10).returns(stub(:map => [{:id => 1}]))
|
|
55
|
+
@users.where = {{:name => "Stewie"} => @filtered}
|
|
56
|
+
@query = query(:name => "Stewie", :offset! => 10)
|
|
57
|
+
@return = @datastore.all(@klass, @query)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "offsets the filtered dataset and returns the results" do
|
|
61
|
+
@return.should == [{:id => 1}]
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe "retrieving all with order" do
|
|
66
|
+
before do
|
|
67
|
+
@filtered = stub
|
|
68
|
+
@filtered.stubs(:order).with(:created_at).returns(stub(:map => [{:id => 1}]))
|
|
69
|
+
@users.where = {{:name => "Stewie"} => @filtered}
|
|
70
|
+
@query = query(:name => "Stewie", :order! => :created_at)
|
|
71
|
+
@return = @datastore.all(@klass, @query)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "orders the filtered dataset and returns the results" do
|
|
75
|
+
@return.should == [{:id => 1}]
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe "retrieving first with conditions" do
|
|
80
|
+
before do
|
|
81
|
+
@users.first = {{:id => 1} => {:id => 1}}
|
|
82
|
+
@return = @datastore.first(@klass, query(:id => 1))
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "gets the first object matching the conditions from the dataset" do
|
|
86
|
+
@return.should == {:id => 1}
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe "updating data" do
|
|
91
|
+
before do
|
|
92
|
+
@filtered = DatasetFake.new(:update => true)
|
|
93
|
+
@users.where = {{:id => 1} => @filtered}
|
|
94
|
+
@return = @datastore.update(@klass, 1, :name => "Peter")
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "filter the dataset by id and update the filtered row" do
|
|
98
|
+
@filtered.updates.length.should == 1
|
|
99
|
+
@filtered.updates.should include(:name => "Peter")
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
describe "deleting data" do
|
|
104
|
+
before do
|
|
105
|
+
@filtered = stub
|
|
106
|
+
@filtered.stubs(:delete)
|
|
107
|
+
@users.where = {{:id => 1} => @filtered}
|
|
108
|
+
@datastore.delete(@klass, 1)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "filters the dataset by id and deletes" do
|
|
112
|
+
@filtered.should have_received(:delete)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe "when a batch transaction has been started" do
|
|
117
|
+
before do
|
|
118
|
+
@datastore.start_batch
|
|
119
|
+
@persistable = stub(:table_name => "some_table")
|
|
120
|
+
@datastore.insert(@persistable, {:some => "attrs"})
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
after { Thread.current[:friendly_batch] = nil }
|
|
124
|
+
|
|
125
|
+
it "adds the attributes to the batch for that table" do
|
|
126
|
+
inserts = Thread.current[:friendly_batch]["some_table"]
|
|
127
|
+
inserts.length.should == 1
|
|
128
|
+
inserts.should include(:some => "attrs")
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
describe "starting a batch" do
|
|
133
|
+
before do
|
|
134
|
+
@datastore.start_batch
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
after { Thread.current[:friendly_batch] = nil }
|
|
138
|
+
|
|
139
|
+
it "sets Thread.current[:friendly_batch] to empty hash" do
|
|
140
|
+
Thread.current[:friendly_batch].should == {}
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
describe "resetting a batch transaction" do
|
|
145
|
+
before do
|
|
146
|
+
@db.stubs(:from)
|
|
147
|
+
Thread.current[:friendly_batch] = {"users" => [{:a => "b"}]}
|
|
148
|
+
@datastore.reset_batch
|
|
149
|
+
end
|
|
150
|
+
after { Thread.current[:friendly_batch] = nil }
|
|
151
|
+
|
|
152
|
+
it "sets Thread.current[:friendly_batch] to nil without inserting" do
|
|
153
|
+
Thread.current[:friendly_batch].should be_nil
|
|
154
|
+
@db.should have_received(:from).never
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
describe "flushing a batch" do
|
|
159
|
+
before do
|
|
160
|
+
@records = [{:name => "Stewie"}, {:name => "Brian"}]
|
|
161
|
+
Thread.current[:friendly_batch] = {"users" => @records}
|
|
162
|
+
@users.stubs(:multi_insert)
|
|
163
|
+
@datastore.flush_batch
|
|
164
|
+
end
|
|
165
|
+
after { Thread.current[:friendly_batch] = nil }
|
|
166
|
+
|
|
167
|
+
it "performs the multi_insert on each table" do
|
|
168
|
+
@users.should have_received(:multi_insert).
|
|
169
|
+
with(@records, :commit_every => 1000)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "resets the batch" do
|
|
173
|
+
Thread.current[:friendly_batch].should be_nil
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
describe "counting" do
|
|
178
|
+
before do
|
|
179
|
+
@filtered = stub(:count => 10)
|
|
180
|
+
@users.stubs(:where).with(:name => "James").returns(@filtered)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it "fitlers and counts in the db" do
|
|
184
|
+
@datastore.count(@klass, query(:name => "James")).should == 10
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|