yakischloba-drizzle-ffi 0.0.2
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.rdoc +42 -0
- data/Rakefile +11 -0
- data/drizzle.gemspec +20 -0
- data/lib/drizzle/drizzle.rb +229 -0
- data/lib/drizzle.rb +3 -0
- data/tests/basic.rb +104 -0
- metadata +78 -0
data/README.rdoc
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
Currently a simple client-oriented hookup to libdrizzle with ffi, for querying drizzle and mysql servers.
|
2
|
+
|
3
|
+
Not really sure where I'm going with this. Ping me if you have input.
|
4
|
+
|
5
|
+
== Synopsis
|
6
|
+
|
7
|
+
=== Normal synchronous query
|
8
|
+
|
9
|
+
irb(main):001:0> require 'rubygems'
|
10
|
+
=> true
|
11
|
+
irb(main):002:0> require 'lib/drizzle'
|
12
|
+
=> true
|
13
|
+
irb(main):003:0> c = Drizzle::Connection.new("127.0.0.1", "root", "password", nil, :DRIZZLE_CON_MYSQL)
|
14
|
+
=> #<Native Pointer address=0x0>
|
15
|
+
irb(main):004:0> r = c.query("select now()")
|
16
|
+
=> #<Drizzle::Result:0x12f4dc8 @rows=[["2009-05-21 07:41:26"]], @columns=[:"now()"], @affected_rows=0, @insert_id=0>
|
17
|
+
irb(main):005:0> r.each {|row| puts row[0] }
|
18
|
+
2009-05-21 07:41:26
|
19
|
+
=> [["2009-05-21 07:41:26"]]
|
20
|
+
irb(main):006:0> r.columns
|
21
|
+
=> [:"now()"]
|
22
|
+
|
23
|
+
=== Async query with EventMachine
|
24
|
+
|
25
|
+
irb(main):001:0> require 'rubygems'
|
26
|
+
=> true
|
27
|
+
irb(main):002:0> require 'lib/drizzle'
|
28
|
+
r=> true
|
29
|
+
irb(main):003:0> require 'eventmachine'
|
30
|
+
=> true
|
31
|
+
irb(main):004:0> c = Drizzle::Connection.new("127.0.0.1", "root", "password", "mysql", :DRIZZLE_CON_MYSQL)
|
32
|
+
=> #<Native Pointer address=0x0>
|
33
|
+
irb(main):005:0> EM.run {
|
34
|
+
irb(main):006:1* c.em_query("show tables") do |result|
|
35
|
+
irb(main):007:2* p result.columns
|
36
|
+
irb(main):008:2> p result.rows
|
37
|
+
irb(main):009:2> end
|
38
|
+
irb(main):010:1> }
|
39
|
+
|
40
|
+
[:Tables_in_mysql]
|
41
|
+
|
42
|
+
[["columns_priv"], ["db"], ["func"], ["help_category"], ["help_keyword"], ["help_relation"], ["help_topic"], ["host"], ["proc"], ["procs_priv"], ["tables_priv"], ["time_zone"], ["time_zone_leap_second"], ["time_zone_name"], ["time_zone_transition"], ["time_zone_transition_type"], ["user"], ["user_info"]]
|
data/Rakefile
ADDED
data/drizzle.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "drizzle-ffi"
|
3
|
+
s.version = "0.0.2"
|
4
|
+
s.date = "2009-08-07"
|
5
|
+
s.authors = ["Jake Douglas"]
|
6
|
+
s.email = "jakecdouglas@gmail.com"
|
7
|
+
s.has_rdoc = false
|
8
|
+
s.add_dependency('ffi')
|
9
|
+
s.add_dependency('bacon')
|
10
|
+
s.summary = "libdrizzle ffi"
|
11
|
+
s.homepage = "http://www.github.com/yakischloba/libdrizzle-ruby-ffi"
|
12
|
+
s.description = "libdrizzle ffi"
|
13
|
+
s.files =
|
14
|
+
["drizzle.gemspec",
|
15
|
+
"README.rdoc",
|
16
|
+
"Rakefile",
|
17
|
+
"lib/drizzle.rb",
|
18
|
+
"lib/drizzle/drizzle.rb",
|
19
|
+
"tests/basic.rb"]
|
20
|
+
end
|
@@ -0,0 +1,229 @@
|
|
1
|
+
module Drizzle
|
2
|
+
extend FFI::Library
|
3
|
+
ffi_lib "libdrizzle"
|
4
|
+
|
5
|
+
class DrizzleException < RuntimeError; end
|
6
|
+
|
7
|
+
enum :drizzle_return_t, [
|
8
|
+
:DRIZZLE_RETURN_OK,
|
9
|
+
:DRIZZLE_RETURN_IO_WAIT,
|
10
|
+
:DRIZZLE_RETURN_PAUSE,
|
11
|
+
:DRIZZLE_RETURN_ROW_BREAK,
|
12
|
+
:DRIZZLE_RETURN_MEMORY,
|
13
|
+
:DRIZZLE_RETURN_ERRNO,
|
14
|
+
:DRIZZLE_RETURN_INTERNAL_ERROR,
|
15
|
+
:DRIZZLE_RETURN_GETADDRINFO,
|
16
|
+
:DRIZZLE_RETURN_NOT_READY,
|
17
|
+
:DRIZZLE_RETURN_BAD_PACKET_NUMBER,
|
18
|
+
:DRIZZLE_RETURN_BAD_HANDSHAKE_PACKET,
|
19
|
+
:DRIZZLE_RETURN_BAD_PACKET,
|
20
|
+
:DRIZZLE_RETURN_PROTOCOL_NOT_SUPPORTED,
|
21
|
+
:DRIZZLE_RETURN_UNEXPECTED_DATA,
|
22
|
+
:DRIZZLE_RETURN_NO_SCRAMBLE,
|
23
|
+
:DRIZZLE_RETURN_AUTH_FAILED,
|
24
|
+
:DRIZZLE_RETURN_NULL_SIZE,
|
25
|
+
:DRIZZLE_RETURN_ERROR_CODE,
|
26
|
+
:DRIZZLE_RETURN_TOO_MANY_COLUMNS,
|
27
|
+
:DRIZZLE_RETURN_ROW_END,
|
28
|
+
:DRIZZLE_RETURN_EOF,
|
29
|
+
:DRIZZLE_RETURN_COULD_NOT_CONNECT,
|
30
|
+
:DRIZZLE_RETURN_NO_ACTIVE_CONNECTIONS,
|
31
|
+
:DRIZZLE_RETURN_SERVER_GONE,
|
32
|
+
:DRIZZLE_RETURN_MAX
|
33
|
+
]
|
34
|
+
|
35
|
+
enum :drizzle_con_options_t, [
|
36
|
+
:DRIZZLE_CON_NONE, 0,
|
37
|
+
:DRIZZLE_CON_ALLOCATED, (1 << 0),
|
38
|
+
:DRIZZLE_CON_MYSQL, (1 << 1),
|
39
|
+
:DRIZZLE_CON_RAW_PACKET, (1 << 2),
|
40
|
+
:DRIZZLE_CON_RAW_SCRAMBLE, (1 << 3),
|
41
|
+
:DRIZZLE_CON_READY, (1 << 4),
|
42
|
+
:DRIZZLE_CON_NO_RESULT_READ, (1 << 5)
|
43
|
+
]
|
44
|
+
|
45
|
+
enum :drizzle_options_t, [
|
46
|
+
:DRIZZLE_NONE, 0,
|
47
|
+
:DRIZZLE_ALLOCATED, (1 << 0),
|
48
|
+
:DRIZZLE_NON_BLOCKING, (1 << 1)
|
49
|
+
]
|
50
|
+
|
51
|
+
def self.options
|
52
|
+
enum_type(:drizzle_options_t)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.return_codes
|
56
|
+
enum_type(:drizzle_return_t)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.con_options
|
60
|
+
enum_type(:drizzle_con_options_t)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Misc
|
64
|
+
attach_function :version, :drizzle_version, [], :string
|
65
|
+
|
66
|
+
# Drizzle objects
|
67
|
+
attach_function :create, :drizzle_create, [:pointer], :pointer
|
68
|
+
attach_function :free, :drizzle_free, [:pointer], :void
|
69
|
+
attach_function :error, :drizzle_error, [:pointer], :string
|
70
|
+
attach_function :add_options, :drizzle_add_options, [:pointer, :drizzle_options_t], :void
|
71
|
+
callback :event_watch_callback, [:pointer, :short, :pointer], :drizzle_return_t
|
72
|
+
|
73
|
+
attach_function :set_event_watch, :drizzle_set_event_watch, [:pointer, :event_watch_callback, :pointer], :void
|
74
|
+
|
75
|
+
# Connection objects
|
76
|
+
attach_function :con_create, :drizzle_con_create, [:pointer, :pointer], :pointer
|
77
|
+
attach_function :con_free, :drizzle_con_free, [:pointer], :void
|
78
|
+
attach_function :con_set_db, :drizzle_con_set_db, [:pointer, :string], :void
|
79
|
+
attach_function :con_set_auth, :drizzle_con_set_auth, [:pointer, :string, :string], :void
|
80
|
+
attach_function :con_add_options, :drizzle_con_add_options, [:pointer, :drizzle_con_options_t], :void
|
81
|
+
attach_function :con_status, :drizzle_con_status, [:pointer], :int
|
82
|
+
attach_function :con_fd, :drizzle_con_fd, [:pointer], :int
|
83
|
+
attach_function :con_clone, :drizzle_con_clone, [:pointer, :pointer, :pointer], :pointer
|
84
|
+
attach_function :con_set_revents, :drizzle_con_set_revents, [:pointer, :short], :void
|
85
|
+
|
86
|
+
# Querying
|
87
|
+
attach_function :query_str, :drizzle_query_str, [:pointer, :pointer, :string, :pointer], :pointer
|
88
|
+
|
89
|
+
# Results
|
90
|
+
attach_function :result_create, :drizzle_result_create, [:pointer, :pointer], :pointer
|
91
|
+
attach_function :result_buffer, :drizzle_result_buffer, [:pointer], :int
|
92
|
+
attach_function :result_free, :drizzle_result_free, [:pointer], :drizzle_return_t
|
93
|
+
attach_function :result_affected_rows, :drizzle_result_affected_rows, [:pointer], :uint64
|
94
|
+
attach_function :result_insert_id, :drizzle_result_insert_id, [:pointer], :uint64
|
95
|
+
attach_function :row_next, :drizzle_row_next, [:pointer], :pointer
|
96
|
+
attach_function :result_read, :drizzle_result_read, [:pointer, :pointer, :pointer], :pointer
|
97
|
+
|
98
|
+
# Columns
|
99
|
+
attach_function :column_next, :drizzle_column_next, [:pointer], :pointer
|
100
|
+
attach_function :column_name, :drizzle_column_name, [:pointer], :string
|
101
|
+
|
102
|
+
class Result
|
103
|
+
attr_reader :columns, :affected_rows, :insert_id, :rows
|
104
|
+
|
105
|
+
def initialize(ptr)
|
106
|
+
@columns, @rows = [], []
|
107
|
+
|
108
|
+
@insert_id = Drizzle.result_insert_id(ptr)
|
109
|
+
@affected_rows = Drizzle.result_affected_rows(ptr)
|
110
|
+
|
111
|
+
# Get columns
|
112
|
+
until (column = Drizzle.column_next(ptr)).null?
|
113
|
+
@columns << Drizzle.column_name(column).to_sym
|
114
|
+
end
|
115
|
+
|
116
|
+
# Get rows
|
117
|
+
until (row = Drizzle.row_next(ptr)).null?
|
118
|
+
@rows << row.get_array_of_string(0, @columns.size)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Free the underlying buffers since we just copied it all to Ruby
|
122
|
+
Drizzle.result_free(ptr)
|
123
|
+
end
|
124
|
+
|
125
|
+
def each
|
126
|
+
@rows.each do |row|
|
127
|
+
yield row if block_given?
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class Drizzleptr < FFI::AutoPointer
|
133
|
+
def self.release(ptr)
|
134
|
+
Drizzle.free(ptr)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class Connptr < FFI::AutoPointer
|
139
|
+
def self.release(ptr)
|
140
|
+
Drizzle.conn_free(ptr)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class Connection
|
145
|
+
attr_accessor :host, :user, :pass, :db, :opts, :fd
|
146
|
+
|
147
|
+
def initialize(host, user, pass, db=nil, opts=[], drizzle=nil)
|
148
|
+
opts = opts.is_a?(Array) ? opts : [opts]
|
149
|
+
@host, @user, @pass, @db, @opts = host, user, pass, db, opts
|
150
|
+
@from_pool = true if drizzle
|
151
|
+
@drizzle = drizzle || Drizzleptr.new(Drizzle.create(nil))
|
152
|
+
@conn = Connptr.new(Drizzle.con_create(@drizzle, nil))
|
153
|
+
Drizzle.con_add_options(@conn, opts.inject(0){|i,o| i | Drizzle.enum_value(o)} | Drizzle.enum_value(:DRIZZLE_CON_NO_RESULT_READ))
|
154
|
+
Drizzle.con_set_auth(@conn, @user, @pass)
|
155
|
+
Drizzle.con_set_db(@conn, @db) if @db
|
156
|
+
@retptr = FFI::MemoryPointer.new(:int)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Indicates whether or not this connection was created using a drizzle_st object from somewhere else.
|
160
|
+
def from_pool?
|
161
|
+
@from_pool
|
162
|
+
end
|
163
|
+
|
164
|
+
# This executes a normal synchronous query. We simply call the async methods together.
|
165
|
+
def query(query, proc=nil, &blk)
|
166
|
+
proc ||= blk
|
167
|
+
async_query(query, proc)
|
168
|
+
async_result
|
169
|
+
end
|
170
|
+
|
171
|
+
# Sends off a query to the server. The return value is the file descriptor number of the socket used for this connection, for monitoring with an event loop etc.
|
172
|
+
def async_query(query, proc=nil, &blk)
|
173
|
+
proc ||= blk
|
174
|
+
Drizzle.query_str(@conn, nil, query, @retptr)
|
175
|
+
# Make sure it was successful
|
176
|
+
check_error
|
177
|
+
@callback = proc
|
178
|
+
# return fd to caller
|
179
|
+
@fd ||= Drizzle.con_fd(@conn)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Do a blocking read for the result of an outstanding query. This results the Result object as well as fires a callback associated with it.
|
183
|
+
def async_result
|
184
|
+
# Do a partial blocking read into the the packet struct
|
185
|
+
result = Drizzle.result_read(@conn, nil, @retptr)
|
186
|
+
|
187
|
+
# See if the read was successful
|
188
|
+
check_error
|
189
|
+
|
190
|
+
# Buffer the result and check
|
191
|
+
ret = Drizzle.result_buffer(result)
|
192
|
+
if Drizzle.return_codes[ret] != :DRIZZLE_RETURN_OK
|
193
|
+
# Free the result struct if we fail.
|
194
|
+
Drizzle.result_free(result)
|
195
|
+
raise DrizzleException.new("Query failed: #{Drizzle.error(@drizzle)}")
|
196
|
+
end
|
197
|
+
|
198
|
+
# Fire and return
|
199
|
+
r = Result.new(result)
|
200
|
+
@callback.call(r) if @callback
|
201
|
+
@callback = nil
|
202
|
+
r
|
203
|
+
end
|
204
|
+
|
205
|
+
def em_query(query, proc=nil, &blk)
|
206
|
+
proc ||= blk
|
207
|
+
fd = async_query(query, proc)
|
208
|
+
EM.watch(fd, EMHandler, self) {|c| c.notify_readable = true}
|
209
|
+
end
|
210
|
+
|
211
|
+
def check_error
|
212
|
+
if Drizzle.return_codes[@retptr.get_int(0)] != :DRIZZLE_RETURN_OK
|
213
|
+
raise DrizzleException.new("Query failed: #{Drizzle.error(@drizzle)}")
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
module EMHandler
|
220
|
+
def initialize(conn)
|
221
|
+
@conn = conn
|
222
|
+
end
|
223
|
+
def notify_readable
|
224
|
+
detach
|
225
|
+
@conn.async_result
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
data/lib/drizzle.rb
ADDED
data/tests/basic.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'set'
|
2
|
+
begin
|
3
|
+
require 'eventmachine'
|
4
|
+
rescue LoadError
|
5
|
+
end
|
6
|
+
|
7
|
+
HOST = "127.0.0.1"
|
8
|
+
USER = "root"
|
9
|
+
PASS = "password"
|
10
|
+
|
11
|
+
describe "Basic libdrizzle operation" do
|
12
|
+
|
13
|
+
it "perform a simple synchronous query on a MySQL server" do
|
14
|
+
c = Drizzle::Connection.new(HOST, USER, PASS, "information_schema", :DRIZZLE_CON_MYSQL)
|
15
|
+
schemas, tables = Set.new, Set.new
|
16
|
+
result = c.query("SELECT table_schema,table_name FROM tables")
|
17
|
+
result.class.should.equal Drizzle::Result
|
18
|
+
result.affected_rows.should.equal 0
|
19
|
+
result.insert_id.should.equal 0
|
20
|
+
result.columns.size.should.equal 2
|
21
|
+
result.columns.should.include :table_schema
|
22
|
+
result.columns.should.include :table_name
|
23
|
+
|
24
|
+
result.each do |row|
|
25
|
+
schemas << row[0]
|
26
|
+
tables << row[1]
|
27
|
+
end
|
28
|
+
|
29
|
+
schemas.should.include "information_schema"
|
30
|
+
tables.should.include "COLUMNS"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "send and receive a query asynchronously" do
|
34
|
+
c = Drizzle::Connection.new(HOST, USER, PASS, "information_schema", :DRIZZLE_CON_MYSQL)
|
35
|
+
fd = c.async_query("SELECT table_schema,table_name FROM tables")
|
36
|
+
|
37
|
+
schemas, tables = Set.new, Set.new
|
38
|
+
result = c.async_result
|
39
|
+
result.class.should.equal Drizzle::Result
|
40
|
+
result.affected_rows.should.equal 0
|
41
|
+
result.insert_id.should.equal 0
|
42
|
+
|
43
|
+
result.columns.size.should.equal 2
|
44
|
+
result.columns.should.include :table_schema
|
45
|
+
result.columns.should.include :table_name
|
46
|
+
|
47
|
+
result.each do |row|
|
48
|
+
schemas << row[0]
|
49
|
+
tables << row[1]
|
50
|
+
end
|
51
|
+
|
52
|
+
schemas.should.include "information_schema"
|
53
|
+
tables.should.include "COLUMNS"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "send and receive a query asynchronously using a callback" do
|
57
|
+
c = Drizzle::Connection.new(HOST, USER, PASS, "information_schema", :DRIZZLE_CON_MYSQL)
|
58
|
+
schemas, tables = Set.new, Set.new
|
59
|
+
columns = []
|
60
|
+
fd = c.async_query("SELECT table_schema,table_name FROM tables") do |result|
|
61
|
+
result.columns.each {|col| columns << col}
|
62
|
+
result.each do |row|
|
63
|
+
schemas << row[0]
|
64
|
+
tables << row[1]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
schemas.should.be.empty
|
69
|
+
tables.should.be.empty
|
70
|
+
columns.should.be.empty
|
71
|
+
|
72
|
+
c.async_result
|
73
|
+
|
74
|
+
schemas.should.include "information_schema"
|
75
|
+
tables.should.include "COLUMNS"
|
76
|
+
columns.size.should.equal 2
|
77
|
+
columns.should.include :table_schema
|
78
|
+
columns.should.include :table_name
|
79
|
+
end
|
80
|
+
|
81
|
+
if defined?(EventMachine)
|
82
|
+
it "perform an async query with evented receive using EventMachine" do
|
83
|
+
schemas, tables = Set.new, Set.new
|
84
|
+
columns = []
|
85
|
+
EM.run {
|
86
|
+
c = Drizzle::Connection.new(HOST, USER, PASS, "information_schema", :DRIZZLE_CON_MYSQL)
|
87
|
+
c.em_query("SELECT table_schema,table_name FROM tables") do |result|
|
88
|
+
result.columns.each {|col| columns << col}
|
89
|
+
result.each do |row|
|
90
|
+
schemas << row[0]
|
91
|
+
tables << row[1]
|
92
|
+
end
|
93
|
+
EM.stop
|
94
|
+
end
|
95
|
+
}
|
96
|
+
schemas.should.include "information_schema"
|
97
|
+
tables.should.include "COLUMNS"
|
98
|
+
columns.size.should.equal 2
|
99
|
+
columns.should.include :table_schema
|
100
|
+
columns.should.include :table_name
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yakischloba-drizzle-ffi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jake Douglas
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-07 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: ffi
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: bacon
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
description: libdrizzle ffi
|
36
|
+
email: jakecdouglas@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- drizzle.gemspec
|
45
|
+
- README.rdoc
|
46
|
+
- Rakefile
|
47
|
+
- lib/drizzle.rb
|
48
|
+
- lib/drizzle/drizzle.rb
|
49
|
+
- tests/basic.rb
|
50
|
+
has_rdoc: false
|
51
|
+
homepage: http://www.github.com/yakischloba/libdrizzle-ruby-ffi
|
52
|
+
licenses:
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.3.5
|
74
|
+
signing_key:
|
75
|
+
specification_version: 2
|
76
|
+
summary: libdrizzle ffi
|
77
|
+
test_files: []
|
78
|
+
|