Skip to content

Instantly share code, notes, and snippets.

@tenderlove
Created March 2, 2010 07:03
Show Gist options
  • Save tenderlove/319224 to your computer and use it in GitHub Desktop.
Save tenderlove/319224 to your computer and use it in GitHub Desktop.
###
# This is a demonstration of using SQLite3's Virtual File System API in Ruby.
#
# == Synopsis
#
# This program will store its SQLite database after the __END__ line.
#
# === In Detail
#
# SQLite3 uses the DATABase class as a proxy for our IO object. Upon
# instantiation, the DATABase class opens __FILE__, seeks to the point right
# after __END__ by using DATA.pos. It caches the value of DATA.pos for later
# calculations when the database engine needs to seek for reading and writing.
#
# == How can I run this code?
#
# This code requires my fork of the sqlite3-ruby bindings. The normal sqlite
# bindings do not expose the Virtual File System api. You can get my fork
# with the VFS extensions here:
#
# http://github.com/tenderlove/sqlite3-ruby/tree/vfs
#
require 'sqlite3'
class EvilVFS < SQLite3::VFS
def open name, flags
DATABase.new name, flags
end
end
class DATABase < SQLite3::VFS::File
def initialize name, flags
super
@store = File.open(name, File::RDWR | File::CREAT)
@offset = 0
if File.expand_path(__FILE__) == name
@store.seek DATA.pos
@offset = DATA.pos
end
end
def close
@store.close
end
def read amt, offset
@store.seek(offset + @offset)
@store.read amt
end
def write data, offset
@store.seek(offset + @offset)
@store.write data
end
def sync opts
@store.fsync
end
def file_size
File.size(@store.path) - @offset
end
end
SQLite3.vfs_register(EvilVFS.new)
db = SQLite3::Database.new(__FILE__, nil, 'EvilVFS')
db.execute('create table if not exists users(id integer primary key, name string)')
100.times { db.execute('insert into users(name) values (?)', 'tenderlove') }
p db.execute('select count(*) from users')
__END__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment