#! /usr/bin/env ruby
# by pts@fazekas.hu at Thu May 28 17:28:03 CEST 2009
require 'rubygems'
require 'ffi'
module FQ3
extend FFI::Library
ffi_lib "libsqlite3.so" # finds it in /usr/lib
#int callback(void *dummy, int argc, char **data, char **colnames)
callback :result, [:pointer, :int, :pointer, :pointer], :int
attach_function :sqlite3_open, [:string, :pointer], :int
attach_function :sqlite3_close, [:pointer], :void
attach_function :sqlite3_errmsg, [:pointer], :string
attach_function :sqlite3_exec, [
:pointer, :string, :result, :int, :pointer], :int
end
SQLITE_OK = 0
Result = Proc.new do |dummy,argc,data,colnames|
h = {}
argc.times { |i|
h[colnames.get_pointer(FFI.type_size(:pointer) * i).get_string(0)] = (
data.get_pointer(FFI.type_size(:pointer) * i).get_string(0))
}
$stdout << "row #{h.inspect}\n"
0
end
dbfn = 't.sqlite3'
query = 'SELECT * FROM foo'
dbptr = FFI::MemoryPointer.new(:pointer)
rc = FQ3.sqlite3_open(dbfn, dbptr) # creates the db file if needed
fail "#{rc}" if rc != SQLITE_OK # use sqlite3_errmsg
db = dbptr.get_pointer(0)
errmsgptr = FFI::MemoryPointer.new(:pointer)
rc = FQ3::sqlite3_exec(db, query, Result, 0, errmsgptr)
#: row {"id"=>"1", "s"=>"hello"}
#: row {"id"=>"2", "s"=>"world"}
#: row {"id"=>"42", "s"=>"answer"}
fail "#{rc}" if rc != SQLITE_OK
FQ3.sqlite3_close(db)
# official: http://kenai.com/projects/ruby-ffi/pages/Home
# http://blog.headius.com/2008/10/ffi-for-ruby-now-available.html
# http://lifegoo.pluskid.org/?p=370