faststep 0.0.2 → 0.0.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/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