faststep 0.0.4 → 0.0.5

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/README.markdown CHANGED
@@ -35,7 +35,7 @@ Have some fun!
35
35
  >> db["users"].find(:name => /0$/).to_a
36
36
  => [{"_id"=>BSON::ObjectId('4d83c53555ca381d572c1cf7'), "name"=>"Person 0"}, {"_id"=>BSON::ObjectId('4d83c53555ca381d572c1d01'), "name"=>"Person 10"}, ...]
37
37
  >> db["users"].remove(:name => /0$/)
38
- => nil
38
+ => true
39
39
  >> db["users"].count(:name => /0$/)
40
40
  => 0
41
41
  >> db["users"].count
@@ -47,13 +47,13 @@ Have some fun!
47
47
 
48
48
  ### Caveats
49
49
 
50
- This is under heavy development (what gem isn't?) but there's a lot of stuff to be implemented still. Some methods return nil (remove, for example) when they shouldn't.
50
+ This is under heavy development (what gem isn't?) but there's a lot of stuff to be implemented still.
51
51
  It's not nearly as smart as the mongo Ruby driver and it doesn't handle errors that well.
52
52
 
53
53
  ### Todo
54
54
 
55
55
  * Connection pooling
56
- * Safe mode
56
+ * Safe mode (per database or connection)
57
57
  * Master/slave
58
58
  * Replica sets
59
59
 
@@ -56,10 +56,19 @@ VALUE ensure_document_ok(const VALUE document) {
56
56
  }
57
57
 
58
58
  static char* _invalid_command_description(const VALUE document) {
59
- VALUE message = rb_str_new2("Invalid command (");
60
- rb_str_concat(message, rb_inspect(rb_hash_aref(document, rb_str_new2("bad cmd"))));
61
- rb_str_concat(message, rb_str_new2("): "));
62
- rb_str_concat(message, rb_hash_aref(document, rb_str_new2("errmsg")));
59
+ VALUE message = rb_str_new2("");
60
+
61
+ if(RTEST(rb_hash_aref(document, rb_str_new2("bad cmd")))) {
62
+ rb_str_concat(message, rb_str_new2("Invalid command ("));
63
+ rb_str_concat(message, rb_inspect(rb_hash_aref(document, rb_str_new2("bad cmd"))));
64
+ rb_str_concat(message, rb_str_new2("): "));
65
+ rb_str_concat(message, rb_hash_aref(document, rb_str_new2("errmsg")));
66
+ } else {
67
+ rb_str_concat(message, rb_str_new2("Error ("));
68
+ rb_str_concat(message, rb_inspect(rb_hash_aref(document, rb_str_new2("code"))));
69
+ rb_str_concat(message, rb_str_new2("): "));
70
+ rb_str_concat(message, rb_hash_aref(document, rb_str_new2("err")));
71
+ }
63
72
 
64
73
  return RSTRING_PTR(message);
65
74
  }
@@ -15,7 +15,7 @@ void faststep_collection_main() {
15
15
  rb_define_method(rb_cFaststepCollection, "find", faststep_collection_find, -1);
16
16
  rb_define_method(rb_cFaststepCollection, "find_one", faststep_collection_find_one, -1);
17
17
  rb_define_method(rb_cFaststepCollection, "count", faststep_collection_count, -1);
18
- rb_define_method(rb_cFaststepCollection, "insert", faststep_collection_insert, 1);
18
+ rb_define_method(rb_cFaststepCollection, "insert", faststep_collection_insert, -1);
19
19
  rb_define_method(rb_cFaststepCollection, "update", faststep_collection_update, -1);
20
20
  rb_define_method(rb_cFaststepCollection, "remove", faststep_collection_remove, -1);
21
21
  rb_define_method(rb_cFaststepCollection, "drop", faststep_collection_drop, 0);
@@ -103,9 +103,12 @@ void build_collection_ns(char* ns, const char* database, const char* collection)
103
103
  return;
104
104
  }
105
105
 
106
- static VALUE faststep_collection_insert(const VALUE self, const VALUE documents) {
106
+ static VALUE faststep_collection_insert(int argc, VALUE* argv, const VALUE self) {
107
107
  mongo_connection* conn = GetFaststepConnectionForCollection(self);
108
108
 
109
+ VALUE documents, options;
110
+ rb_scan_args(argc, argv, "11", &documents, &options);
111
+
109
112
  VALUE ns = faststep_collection_ns(self);
110
113
 
111
114
  if(TYPE(documents) == T_ARRAY) {
@@ -114,7 +117,7 @@ static VALUE faststep_collection_insert(const VALUE self, const VALUE documents)
114
117
  _faststep_collection_insert_one(conn, RSTRING_PTR(ns), documents);
115
118
  }
116
119
 
117
- return Qtrue;
120
+ return _faststep_safe_operation(self, options);
118
121
  }
119
122
 
120
123
  static VALUE faststep_collection_update(int argc, VALUE* argv, VALUE self) {
@@ -145,12 +148,12 @@ static VALUE faststep_collection_update(int argc, VALUE* argv, VALUE self) {
145
148
  bson_destroy(bson_query);
146
149
  bson_destroy(bson_operations);
147
150
 
148
- return Qtrue;
151
+ return _faststep_safe_operation(self, options);
149
152
  }
150
153
 
151
154
  static VALUE faststep_collection_remove(int argc, VALUE* argv, VALUE self) {
152
- VALUE query;
153
- rb_scan_args(argc, argv, "01", &query);
155
+ VALUE query, options;
156
+ rb_scan_args(argc, argv, "02", &query, &options);
154
157
 
155
158
  bson* bson_query = create_bson_from_ruby_hash(query);
156
159
 
@@ -158,7 +161,8 @@ static VALUE faststep_collection_remove(int argc, VALUE* argv, VALUE self) {
158
161
  RSTRING_PTR(faststep_collection_ns(self)),
159
162
  bson_query);
160
163
  bson_destroy(bson_query);
161
- return Qnil;
164
+
165
+ return _faststep_safe_operation(self, options);
162
166
  }
163
167
 
164
168
  static VALUE faststep_collection_drop(const VALUE self) {
@@ -244,3 +248,21 @@ mongo_connection* GetFaststepConnectionForCollection(const VALUE collection) {
244
248
 
245
249
  return GetFaststepConnection(connection);
246
250
  }
251
+
252
+ static VALUE _faststep_safe_operation(const VALUE self, const VALUE options) {
253
+ int safe_mode = 0;
254
+
255
+ if(TYPE(options) == T_HASH) {
256
+ if(rb_indiff_hash_aref(options, rb_str_new2("safe")) == Qtrue) {
257
+ safe_mode = 1;
258
+ }
259
+ }
260
+
261
+ if(safe_mode) {
262
+ VALUE document = rb_funcall(rb_iv_get(self, "@db"), rb_intern("get_last_error"), 0);
263
+ ensure_document_ok(document);
264
+ return document;
265
+ } else {
266
+ return Qtrue;
267
+ }
268
+ }
@@ -9,7 +9,7 @@ static VALUE faststep_collection_init(VALUE, const VALUE, const VALUE);
9
9
  static VALUE faststep_collection_find(int, VALUE*, const VALUE);
10
10
  static VALUE faststep_collection_find_one(int, VALUE*, const VALUE);
11
11
  static VALUE faststep_collection_count(int, VALUE*, VALUE);
12
- static VALUE faststep_collection_insert(const VALUE, const VALUE);
12
+ static VALUE faststep_collection_insert(int, VALUE*, const VALUE);
13
13
  static VALUE faststep_collection_update(int, VALUE*, const VALUE);
14
14
  static VALUE faststep_collection_remove(int, VALUE*, VALUE);
15
15
  static VALUE faststep_collection_drop(const VALUE);
@@ -20,6 +20,7 @@ static void _faststep_collection_insert_one(mongo_connection*, const char*, cons
20
20
  static void _faststep_collection_insert_batch(mongo_connection*, const char*, const VALUE);
21
21
  mongo_connection* GetFaststepConnectionForCollection(const VALUE);
22
22
  static void _faststep_collection_destroy(bson**, const int);
23
+ static VALUE _faststep_safe_operation(const VALUE, const VALUE);
23
24
 
24
25
  void build_collection_ns(char*, const char*, const char*);
25
26
  static char* _ivar_name(const VALUE);
@@ -8,13 +8,10 @@ void faststep_support_main() {
8
8
  }
9
9
 
10
10
  static VALUE faststep_support_ok(VALUE self, VALUE document) {
11
- VALUE ok_value = rb_hash_aref(document, rb_str_new2("ok"));
12
-
13
- bson_bool_t result = 0;
14
-
15
- switch(TYPE(ok_value)) {
16
- case T_FLOAT: result = FIX2INT(ok_value); break;
17
- case T_TRUE: result = 1; break;
11
+ bson_bool_t result = 1;
12
+ if(RTEST(rb_hash_aref(document, rb_str_new2("err"))) ||
13
+ RTEST(rb_hash_aref(document, rb_str_new2("errmsg")))) {
14
+ result = 0;
18
15
  }
19
16
 
20
17
  return bool_to_ruby(result);
@@ -1,3 +1,3 @@
1
1
  module Faststep
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -17,16 +17,6 @@ describe Faststep::Collection do
17
17
  db["something"].find_one(BSON::ObjectId.new).should be_nil
18
18
  end
19
19
 
20
- it "removes documents" do
21
- db["something"].insert(5.times.map { {:foo => "bar", :something => "fun"} })
22
- db["something"].insert(:foo => "bar", :baz => "what!")
23
-
24
- db["something"].remove(:baz => "what!")
25
- db["something"].count.should == 5
26
- db["something"].remove
27
- db["something"].count.should be_zero
28
- end
29
-
30
20
  it "drops collections" do
31
21
  db["something"].insert(:foo => "bar")
32
22
  db["something"].drop
@@ -105,6 +95,20 @@ describe Faststep::Collection, "#insert" do
105
95
  db["another.thing"].count(:baz => "qux").should == 1
106
96
  end
107
97
 
98
+ it "inserts documents in safe mode" do
99
+ document_id = BSON::ObjectId.new
100
+ db["something"].insert({ :_id => document_id, :something => "great" }, { :safe => true })
101
+
102
+ expect {
103
+ db["something"].insert({ :_id => document_id, :something => "great" })
104
+ }.to_not raise_error
105
+
106
+ expect {
107
+ db["something"].insert({ :_id => document_id, :something => "great" },
108
+ { :safe => true })
109
+ }.to raise_error(Faststep::OperationFailure, /Error \(11000\): .*duplicate key error index/)
110
+ end
111
+
108
112
  it "supports batch inserting" do
109
113
  db["something"].insert([small_document] * document_count)
110
114
  db["something"].count("foo" => "bar").should == document_count
@@ -144,4 +148,33 @@ describe Faststep::Collection, "#update" do
144
148
  db["something"].count.should == 1
145
149
  db["something"].find_one["count"].should == 2
146
150
  end
151
+
152
+ it "updates documents in safe mode" do
153
+ expect {
154
+ db["something"].update({},
155
+ { "$set" => { "invalid." => 1 } },
156
+ { :safe => true })
157
+ }.to raise_error(Faststep::OperationFailure, /Error \(10149\): Invalid mod field name/)
158
+ end
159
+ end
160
+
161
+ describe Faststep::Collection, "#remove" do
162
+ let(:db) { $faststep_test_db }
163
+
164
+ before do
165
+ db["something"].insert(5.times.map { {:foo => "bar", :something => "fun"} })
166
+ db["something"].insert(:foo => "bar", :baz => "what!")
167
+
168
+ end
169
+
170
+ it "removes documents" do
171
+ db["something"].remove(:baz => "what!")
172
+ db["something"].count.should == 5
173
+ db["something"].remove
174
+ db["something"].count.should be_zero
175
+ end
176
+
177
+ it "removes documents in safe mode" do
178
+ db["something"].remove({}, { :safe => true })["n"].should == 6
179
+ end
147
180
  end
@@ -28,8 +28,7 @@ describe Faststep::Connection, "getting a database" do
28
28
  subject { Faststep::Connection.new }
29
29
 
30
30
  it "uses a database" do
31
- subject[$faststep_test_db.name]["something"].insert(:foo => "bar")
32
- $faststep_test_db["something"].count.should == 1
31
+ subject[$faststep_test_db.name].should be_a(Faststep::Db)
33
32
  end
34
33
  end
35
34
 
data/spec/db_spec.rb CHANGED
@@ -13,7 +13,10 @@ describe Faststep::Db do
13
13
 
14
14
  it "runs specific commands" do
15
15
  expect { subject.command(:dbstats => 1) }.to_not raise_error
16
- expect { subject.command(:totally_bogus => 1) }.to raise_error(Faststep::OperationFailure)
16
+ expect {
17
+ subject.command(:totally_bogus => 1)
18
+ }.to raise_error(Faststep::OperationFailure,
19
+ %{Invalid command ({"totally_bogus"=>1}): no such cmd: totally_bogus})
17
20
  end
18
21
 
19
22
  it "drops the database" do
data/spec/support_spec.rb CHANGED
@@ -1,14 +1,13 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Faststep::Support, "ok?" do
4
- it "returns true when response is ok" do
4
+ it "returns true when no err or errmsg key is present" do
5
5
  Faststep::Support.ok?({ "ok" => true }).should be_true
6
6
  Faststep::Support.ok?({ "ok" => 1.0 }).should be_true
7
7
  end
8
8
 
9
9
  it "returns false when response is not ok" do
10
- Faststep::Support.ok?({ "ok" => false }).should be_false
11
- Faststep::Support.ok?({ "ok" => 0.0 }).should be_false
12
- Faststep::Support.ok?({ "ok" => nil }).should be_false
10
+ Faststep::Support.ok?({ "err" => "something broke" }).should be_false
11
+ Faststep::Support.ok?({ "errmsg" => "something else broke" }).should be_false
13
12
  end
14
13
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: faststep
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.4
5
+ version: 0.0.5
6
6
  platform: ruby
7
7
  authors:
8
8
  - Josh Clayton
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-18 00:00:00 -04:00
13
+ date: 2011-04-23 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency