faststep 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -50,7 +50,6 @@ It's not nearly as smart as the mongo Ruby driver and it doesn't handle errors t
50
50
 
51
51
  * Connection pooling
52
52
  * Safe mode
53
- * Allow updates to *not* be multi (currently unconfigurable)
54
53
  * Master/slave
55
54
  * Replica sets
56
55
 
@@ -2,7 +2,7 @@
2
2
  #include "faststep_defines.h"
3
3
 
4
4
  bson* create_bson_from_ruby_hash(const VALUE hash) {
5
- bson* document = bson_malloc(sizeof(bson));
5
+ bson* document = (bson*)bson_malloc(sizeof(bson));
6
6
 
7
7
  if(NIL_P(hash)) {
8
8
  bson_empty(document);
@@ -28,7 +28,7 @@ bson* bson_from_ruby_array(const VALUE array) {
28
28
  }
29
29
  }
30
30
 
31
- create_bson_from_ruby_hash(hash);
31
+ return create_bson_from_ruby_hash(hash);
32
32
  }
33
33
 
34
34
  VALUE ruby_array_to_bson_ordered_hash(const VALUE array) {
@@ -48,11 +48,11 @@ VALUE bool_to_ruby(const bson_bool_t result) {
48
48
  return result ? Qtrue : Qfalse;
49
49
  }
50
50
 
51
-
52
51
  VALUE ensure_document_ok(const VALUE document) {
53
52
  if(rb_funcall(rb_mFaststepSupport, rb_intern("ok?"), 1, document) == Qfalse) {
54
53
  rb_raise(rb_eFaststepOperationFailure, _invalid_command_description(document));
55
54
  }
55
+ return Qtrue;
56
56
  }
57
57
 
58
58
  static char* _invalid_command_description(const VALUE document) {
@@ -65,6 +65,6 @@ static char* _invalid_command_description(const VALUE document) {
65
65
  }
66
66
 
67
67
  static VALUE _map_assoc_ary_to_key_value_pair(const VALUE item, VALUE hash) {
68
- rb_hash_aset(hash, rb_ary_entry(item, 0), rb_ary_entry(item, 1));
68
+ rb_funcall(hash, rb_intern("[]="), 2, rb_ary_entry(item, 0), rb_ary_entry(item, 1));
69
69
  return hash;
70
70
  }
@@ -2,6 +2,7 @@
2
2
  #include "connection.h"
3
3
  #include "bson_ruby_conversion.h"
4
4
  #include "faststep_defines.h"
5
+ #include "utilities.h"
5
6
  #include <string.h>
6
7
 
7
8
  void faststep_collection_main() {
@@ -15,7 +16,7 @@ void faststep_collection_main() {
15
16
  rb_define_method(rb_cFaststepCollection, "find_one", faststep_collection_find_one, -1);
16
17
  rb_define_method(rb_cFaststepCollection, "count", faststep_collection_count, -1);
17
18
  rb_define_method(rb_cFaststepCollection, "insert", faststep_collection_insert, 1);
18
- rb_define_method(rb_cFaststepCollection, "update", faststep_collection_update, 2);
19
+ rb_define_method(rb_cFaststepCollection, "update", faststep_collection_update, -1);
19
20
  rb_define_method(rb_cFaststepCollection, "remove", faststep_collection_remove, -1);
20
21
  rb_define_method(rb_cFaststepCollection, "drop", faststep_collection_drop, 0);
21
22
  rb_define_method(rb_cFaststepCollection, "create_index", faststep_collection_create_index, 1);
@@ -116,15 +117,30 @@ static VALUE faststep_collection_insert(const VALUE self, const VALUE documents)
116
117
  return Qtrue;
117
118
  }
118
119
 
119
- static VALUE faststep_collection_update(const VALUE self, const VALUE query, const VALUE operations) {
120
+ static VALUE faststep_collection_update(int argc, VALUE* argv, VALUE self) {
121
+ VALUE query, operations, options;
122
+ rb_scan_args(argc, argv, "21", &query, &operations, &options);
123
+
120
124
  bson* bson_query = create_bson_from_ruby_hash(query);
121
125
  bson* bson_operations = create_bson_from_ruby_hash(operations);
122
126
 
127
+ int update_flags = 0;
128
+
129
+ if(TYPE(options) == T_HASH) {
130
+ if(rb_indiff_hash_aref(options, rb_str_new2("multi")) == Qtrue) {
131
+ update_flags |= MONGO_UPDATE_MULTI;
132
+ }
133
+
134
+ if(rb_indiff_hash_aref(options, rb_str_new2("upsert")) == Qtrue) {
135
+ update_flags |= MONGO_UPDATE_UPSERT;
136
+ }
137
+ }
138
+
123
139
  mongo_update(GetFaststepConnectionForCollection(self),
124
140
  RSTRING_PTR(faststep_collection_ns(self)),
125
141
  bson_query,
126
142
  bson_operations,
127
- MONGO_UPDATE_MULTI);
143
+ update_flags);
128
144
 
129
145
  bson_destroy(bson_query);
130
146
  bson_destroy(bson_operations);
@@ -10,7 +10,7 @@ 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
12
  static VALUE faststep_collection_insert(const VALUE, const VALUE);
13
- static VALUE faststep_collection_update(const VALUE, const VALUE, const VALUE);
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);
16
16
  static VALUE faststep_collection_create_index(const VALUE, const VALUE);
@@ -31,7 +31,7 @@ static VALUE faststep_connection_init(VALUE self, const VALUE host, const VALUE
31
31
  }
32
32
 
33
33
  static VALUE faststep_connection_new(VALUE class, const VALUE host, const VALUE port) {
34
- mongo_connection* conn = bson_malloc(sizeof(mongo_connection));
34
+ mongo_connection* conn = (mongo_connection*)bson_malloc(sizeof(mongo_connection));
35
35
 
36
36
  VALUE tdata = Data_Wrap_Struct(class, NULL, mongo_destroy, conn);
37
37
 
@@ -45,7 +45,7 @@ static VALUE faststep_connection_new(VALUE class, const VALUE host, const VALUE
45
45
  }
46
46
 
47
47
  static VALUE faststep_connection_connect(VALUE self) {
48
- mongo_connection_options* options = bson_malloc(sizeof(mongo_connection_options));
48
+ mongo_connection_options* options = (mongo_connection_options*)bson_malloc(sizeof(mongo_connection_options));
49
49
 
50
50
  strcpy(options->host, RSTRING_PTR(rb_iv_get(self, "@host")));
51
51
  options->port = NUM2INT(rb_iv_get(self, "@port"));
@@ -9,6 +9,8 @@ void faststep_cursor_main() {
9
9
  rb_define_attr(rb_cFaststepCursor, "collection", 1, 0);
10
10
  rb_include_module(rb_cFaststepCursor, rb_mEnumerable);
11
11
 
12
+ rb_define_singleton_method(rb_cFaststepCursor, "new", faststep_cursor_new, -1);
13
+
12
14
  rb_define_method(rb_cFaststepCursor, "initialize", faststep_cursor_init, -1);
13
15
  rb_define_method(rb_cFaststepCursor, "explain", faststep_cursor_explain, 0);
14
16
  rb_define_method(rb_cFaststepCursor, "skip", faststep_cursor_skip, 1);
@@ -42,11 +44,28 @@ static VALUE faststep_cursor_init(int argc, VALUE* argv, VALUE self) {
42
44
  return self;
43
45
  }
44
46
 
47
+ static VALUE faststep_cursor_new(int argc, VALUE* argv, VALUE class) {
48
+ faststep_cursor* fs_cursor = (faststep_cursor*)bson_malloc(sizeof(faststep_cursor));
49
+ mongo_cursor* cursor = (mongo_cursor*)bson_malloc(sizeof(mongo_cursor));
50
+
51
+ fs_cursor->cursor = cursor;
52
+ fs_cursor->initialized = 0;
53
+
54
+ VALUE tdata = Data_Wrap_Struct(class, NULL, _faststep_destroy_cursor, fs_cursor);
55
+
56
+ rb_obj_call_init(tdata, argc, argv);
57
+ return tdata;
58
+ }
59
+
45
60
  static VALUE faststep_cursor_each(const VALUE self) {
46
- mongo_cursor* cursor = _faststep_build_mongo_cursor(self);
61
+ faststep_cursor* fs_cursor;
62
+ Data_Get_Struct(self, faststep_cursor, fs_cursor);
47
63
 
48
- while(mongo_cursor_next(cursor)) {
49
- rb_yield(ruby_hash_from_bson(&cursor->current));
64
+ fs_cursor->cursor = _faststep_build_mongo_cursor(self);
65
+ fs_cursor->initialized = 1;
66
+
67
+ while(mongo_cursor_next(fs_cursor->cursor)) {
68
+ rb_yield(ruby_hash_from_bson(&fs_cursor->cursor->current));
50
69
  }
51
70
  }
52
71
 
@@ -85,15 +104,13 @@ static mongo_cursor* _faststep_build_mongo_cursor(VALUE self) {
85
104
  bson* selector = create_bson_from_ruby_hash(_faststep_build_full_query(self));
86
105
  bson* fields = bson_from_ruby_array(rb_iv_get(self, "@fields"));
87
106
 
88
- int limit = 0;
89
- if(RTEST(rb_iv_get(self, "@limit"))) {
90
- limit = -1*FIX2INT(rb_iv_get(self, "@limit"));
91
- }
107
+ int limit = 0,
108
+ skip = 0;
109
+ VALUE limit_value = rb_iv_get(self, "@limit"),
110
+ skip_value = rb_iv_get(self, "@skip");
92
111
 
93
- int skip = 0;
94
- if(RTEST(rb_iv_get(self, "@skip"))) {
95
- skip = FIX2INT(rb_iv_get(self, "@skip"));
96
- }
112
+ if(RTEST(limit_value)) { limit = -1*FIX2INT(limit_value); }
113
+ if(RTEST(skip_value)) { skip = FIX2INT(skip_value); }
97
114
 
98
115
  VALUE collection = rb_iv_get(self, "@collection");
99
116
 
@@ -110,15 +127,30 @@ static mongo_cursor* _faststep_build_mongo_cursor(VALUE self) {
110
127
  }
111
128
 
112
129
  static VALUE _faststep_build_full_query(VALUE self) {
113
- if(RTEST(rb_iv_get(self, "@explain")) || RTEST(rb_iv_get(self, "@order"))) {
130
+ VALUE order_value = rb_iv_get(self, "@order"),
131
+ explain_value = rb_iv_get(self, "@explain"),
132
+ selector_value = rb_iv_get(self, "@selector");
133
+
134
+ if(RTEST(explain_value) || RTEST(order_value)) {
114
135
  VALUE full_query = rb_hash_new();
115
- rb_hash_aset(full_query, rb_str_new2("$query"), rb_iv_get(self, "@selector"));
116
- rb_hash_aset(full_query, rb_str_new2("$explain"), rb_iv_get(self, "@explain"));
117
- if(RTEST(rb_iv_get(self, "@order"))) {
118
- rb_hash_aset(full_query, rb_str_new2("$orderby"), rb_iv_get(self, "@order"));
136
+ rb_hash_aset(full_query, rb_str_new2("$query"), selector_value);
137
+ rb_hash_aset(full_query, rb_str_new2("$explain"), explain_value);
138
+ if(RTEST(order_value)) {
139
+ rb_hash_aset(full_query, rb_str_new2("$orderby"), order_value);
119
140
  }
120
141
  return full_query;
121
142
  } else {
122
- return rb_iv_get(self, "@selector");
143
+ return selector_value;
144
+ }
145
+ }
146
+
147
+ static void _faststep_destroy_cursor(faststep_cursor* cursor) {
148
+ if(cursor->initialized == 1) {
149
+ mongo_cursor_destroy(cursor->cursor);
150
+ cursor->initialized = 0;
123
151
  }
152
+
153
+ free(cursor);
154
+
155
+ return;
124
156
  }
@@ -2,8 +2,15 @@
2
2
  #include <ruby.h>
3
3
  #include "mongo.h"
4
4
  #define CURSOR_h
5
+
6
+ typedef struct {
7
+ mongo_cursor* cursor;
8
+ int initialized;
9
+ } faststep_cursor;
10
+
5
11
  void faststep_cursor_main();
6
12
  static VALUE faststep_cursor_init(int, VALUE*, VALUE);
13
+ static VALUE faststep_cursor_new(int, VALUE*, VALUE);
7
14
  static VALUE faststep_cursor_each(const VALUE);
8
15
  static VALUE faststep_cursor_explain(VALUE);
9
16
  static VALUE faststep_cursor_skip(VALUE, const VALUE);
@@ -12,4 +19,6 @@ static VALUE faststep_cursor_fields(VALUE, const VALUE);
12
19
  static VALUE faststep_cursor_order(VALUE, const VALUE);
13
20
  static mongo_cursor* _faststep_build_mongo_cursor(VALUE);
14
21
  static VALUE _faststep_build_full_query(VALUE);
22
+ static void _faststep_destroy_cursor(faststep_cursor*);
23
+
15
24
  #endif
data/ext/faststep/db.c CHANGED
@@ -14,9 +14,10 @@ void faststep_db_main() {
14
14
 
15
15
  rb_define_alias(rb_cFaststepDb, "[]", "collection");
16
16
 
17
- rb_define_method(rb_cFaststepDb, "initialize", faststep_db_init, 2);
18
- rb_define_method(rb_cFaststepDb, "drop", faststep_db_drop, 0);
19
- rb_define_method(rb_cFaststepDb, "command", faststep_db_command, 1);
17
+ rb_define_method(rb_cFaststepDb, "initialize", faststep_db_init, 2);
18
+ rb_define_method(rb_cFaststepDb, "drop", faststep_db_drop, 0);
19
+ rb_define_method(rb_cFaststepDb, "command", faststep_db_command, 1);
20
+ rb_define_method(rb_cFaststepDb, "get_last_error", faststep_db_get_last_error, 0);
20
21
  }
21
22
 
22
23
  static VALUE faststep_db_init(VALUE self, VALUE name, VALUE connection) {
@@ -33,24 +34,37 @@ static VALUE faststep_db_drop(VALUE self) {
33
34
  }
34
35
 
35
36
  static VALUE faststep_db_command(VALUE self, VALUE command) {
36
- mongo_connection* conn = GetFaststepConnection(rb_iv_get(self, "@connection"));
37
-
38
- bson* result = bson_malloc(sizeof(bson));
39
- bson_init(result, "", 1);
40
-
37
+ bson* result = (bson*)bson_malloc(sizeof(bson));
41
38
  bson* bson_command = create_bson_from_ruby_hash(command);
42
39
 
43
40
  char ns[500] = "";
44
41
  build_collection_ns(ns, RSTRING_PTR(rb_iv_get(self, "@name")), "$cmd");
45
42
 
46
- mongo_find_one(conn, ns, bson_command, NULL, result);
47
-
48
- bson_destroy(bson_command);
43
+ mongo_find_one(GetFaststepConnection(rb_iv_get(self, "@connection")),
44
+ ns,
45
+ bson_command,
46
+ NULL,
47
+ result);
49
48
 
50
49
  VALUE hash = ruby_hash_from_bson(result);
50
+
51
51
  bson_destroy(result);
52
+ bson_destroy(bson_command);
52
53
 
53
54
  ensure_document_ok(hash);
54
55
 
55
56
  return hash;
56
57
  }
58
+
59
+ static VALUE faststep_db_get_last_error(VALUE self) {
60
+ bson* result = (bson*)bson_malloc(sizeof(bson));
61
+
62
+ mongo_cmd_get_last_error(GetFaststepConnection(rb_iv_get(self, "@connection")),
63
+ RSTRING_PTR(rb_iv_get(self, "@name")),
64
+ result);
65
+
66
+ VALUE last_error = ruby_hash_from_bson(result);
67
+ bson_destroy(result);
68
+
69
+ return last_error;
70
+ }
data/ext/faststep/db.h CHANGED
@@ -5,4 +5,5 @@ void faststep_db_main();
5
5
  static VALUE faststep_db_init(VALUE, VALUE, VALUE);
6
6
  static VALUE faststep_db_drop(VALUE);
7
7
  static VALUE faststep_db_command(VALUE, VALUE);
8
+ static VALUE faststep_db_get_last_error(VALUE);
8
9
  #endif
@@ -22,8 +22,6 @@ VALUE rb_eFaststepOperationFailure;
22
22
 
23
23
  void Init_faststep() {
24
24
  rb_mFaststep = rb_define_module("Faststep");
25
- rb_define_const(rb_mFaststep, "DESCENDING", NUM2INT(-1));
26
- rb_define_const(rb_mFaststep, "ASCENDING", NUM2INT(1));
27
25
 
28
26
  rb_mBson = rb_const_get(rb_cObject, rb_intern("BSON"));
29
27
  rb_cBsonOrderedHash = rb_const_get(rb_mBson, rb_intern("OrderedHash"));
@@ -0,0 +1,17 @@
1
+ #include "utilities.h"
2
+
3
+ VALUE rb_str_to_sym(const VALUE str) {
4
+ return ID2SYM(rb_intern(RSTRING_PTR(str)));
5
+ }
6
+
7
+ VALUE rb_indiff_hash_aref(const VALUE hash, const VALUE key) {
8
+ VALUE string_key, symbol_key;
9
+
10
+ if(RTEST(string_key = rb_hash_aref(hash, key))) {
11
+ return string_key;
12
+ } else if(RTEST(symbol_key = rb_hash_aref(hash, rb_str_to_sym(key)))) {
13
+ return symbol_key;
14
+ } else {
15
+ return Qnil;
16
+ }
17
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef UTILITIES_H
2
+ #include <ruby.h>
3
+ #define UTILITIES_H
4
+ VALUE rb_indiff_hash_aref(const VALUE, const VALUE);
5
+ VALUE rb_str_to_sym(const VALUE);
6
+ #endif
@@ -1,3 +1,3 @@
1
1
  module Faststep
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/faststep.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require "bson"
2
2
 
3
3
  module Faststep
4
+ ASCENDING = 1
5
+ DESCENDING = -1
4
6
  autoload :Db, "faststep/db"
5
7
  autoload :Connection, "faststep/connection"
6
8
  autoload :Cursor, "faststep/cursor"
@@ -3,23 +3,6 @@ require "spec_helper"
3
3
  describe Faststep::Collection do
4
4
  let(:db) { $faststep_test_db }
5
5
 
6
- it "inserts the correct documents" do
7
- db["something"].insert(:foo => "bar")
8
- db["another.thing"].insert(:baz => "qux")
9
-
10
- db["something"].count(:foo => "bar").should == 1
11
- db["something"].count(:baz => "qux").should == 0
12
- db["another.thing"].count(:foo => "bar").should == 0
13
- db["another.thing"].count(:foo => true).should == 0
14
- db["another.thing"].count(:baz => "qux").should == 1
15
- end
16
-
17
- it "supports batch inserting" do
18
- db["something"].insert([{:foo => "bar"}, {:baz => "qux"}])
19
- db["something"].count.should == 2
20
- db["something"].count(:foo => "bar").should == 1
21
- end
22
-
23
6
  it "finds documents" do
24
7
  db["something"].insert(:foo => "bar")
25
8
  db["another.thing"].insert(:baz => "qux")
@@ -34,13 +17,6 @@ describe Faststep::Collection do
34
17
  db["something"].find_one(BSON::ObjectId.new).should be_nil
35
18
  end
36
19
 
37
- it "updates documents" do
38
- db["something"].insert(:foo => "bar", :something => "fun")
39
- db["something"].update({ :something => "fun" }, { "$set" => { :foo => "awesome" } })
40
-
41
- db["something"].find({}).first["foo"].should == "awesome"
42
- end
43
-
44
20
  it "removes documents" do
45
21
  db["something"].insert(5.times.map { {:foo => "bar", :something => "fun"} })
46
22
  db["something"].insert(:foo => "bar", :baz => "what!")
@@ -90,7 +66,11 @@ describe Faststep::Collection, "queries" do
90
66
  end
91
67
 
92
68
  describe Faststep::Collection, "#insert" do
93
- let(:large) {
69
+ let(:small_document) {
70
+ { "foo" => "bar" }
71
+ }
72
+
73
+ let(:large_document) {
94
74
  {
95
75
  'base_url' => 'http://www.example.com/test-me',
96
76
  'total_word_count' => 6743,
@@ -114,9 +94,54 @@ describe Faststep::Collection, "#insert" do
114
94
  let(:db) { $faststep_test_db }
115
95
  let(:document_count) { 50 }
116
96
 
97
+ it "inserts the correct documents" do
98
+ db["something"].insert(:foo => "bar")
99
+ db["another.thing"].insert(:baz => "qux")
100
+
101
+ db["something"].count(:foo => "bar").should == 1
102
+ db["something"].count(:baz => "qux").should == 0
103
+ db["another.thing"].count(:foo => "bar").should == 0
104
+ db["another.thing"].count(:foo => true).should == 0
105
+ db["another.thing"].count(:baz => "qux").should == 1
106
+ end
107
+
108
+ it "supports batch inserting" do
109
+ db["something"].insert([small_document] * document_count)
110
+ db["something"].count("foo" => "bar").should == document_count
111
+ end
112
+
117
113
  it "batch inserts multiple large documents" do
118
- db["something"].insert([large] * document_count)
114
+ db["something"].insert([large_document] * document_count)
119
115
  db["something"].count.should == document_count
120
- db["something"].count("base_url" => large["base_url"]).should == document_count
116
+ db["something"].count("base_url" => large_document["base_url"]).should == document_count
117
+ end
118
+ end
119
+
120
+ describe Faststep::Collection, "#update" do
121
+ let(:db) { $faststep_test_db }
122
+
123
+ it "updates documents" do
124
+ 2.times { db["something"].insert(:foo => "bar", :something => "fun") }
125
+
126
+ db["something"].update({ :something => "fun" }, { "$set" => { :foo => "awesome" } })
127
+ db["something"].count(:foo => "awesome").should == 1
128
+ db["something"].count(:foo => "bar").should == 1
129
+ end
130
+
131
+ it "multi-updates documents" do
132
+ 2.times { db["something"].insert(:foo => "bar", :something => "fun") }
133
+
134
+ db["something"].update({ :something => "fun" }, { "$set" => { :foo => "awesome" } }, :multi => true)
135
+ db["something"].count(:foo => "awesome").should == 2
136
+ db["something"].count(:foo => "bar").should be_zero
137
+ end
138
+
139
+ it "upserts documents" do
140
+ 2.times do
141
+ db["something"].update({ "email" => "john@example.com" }, { "$inc" => { "count" => 1 } }, :upsert => true)
142
+ end
143
+
144
+ db["something"].count.should == 1
145
+ db["something"].find_one["count"].should == 2
121
146
  end
122
147
  end
data/spec/db_spec.rb CHANGED
@@ -25,4 +25,13 @@ describe Faststep::Db do
25
25
  subject["something"].count.should be_zero
26
26
  subject["another.thing"].count.should be_zero
27
27
  end
28
+
29
+ it "gets the last error" do
30
+ subject["something"].insert(:foo => "bar")
31
+ subject.get_last_error.tap do |result|
32
+ result.should have_key("ok")
33
+ result.should have_key("n")
34
+ result.should have_key("err")
35
+ end
36
+ end
28
37
  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.2
5
+ version: 0.0.3
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-03-20 00:00:00 -04:00
13
+ date: 2011-03-25 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -102,6 +102,8 @@ files:
102
102
  - ext/faststep/platform_hacks.h
103
103
  - ext/faststep/support.c
104
104
  - ext/faststep/support.h
105
+ - ext/faststep/utilities.c
106
+ - ext/faststep/utilities.h
105
107
  - faststep.gemspec
106
108
  - lib/faststep.rb
107
109
  - lib/faststep/connection.rb