Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Removed old stuff.

  • Loading branch information...
commit f5a51b1014e8d63a0236d6a5b708bccf206145b9 1 parent 35bfc5a
Sharon Rosner ciconia authored
Showing with 0 additions and 7,287 deletions.
  1. +0 −30 examples/basic.rb
  2. +0 −23 examples/countries.rb
  3. +0 −16 examples/csv.rb
  4. +0 −30 examples/filters.rb
  5. +0 −40 examples/view.rb
  6. +0 −101 extra/stats.rb
  7. +0 −59 lib/sequel.rb
  8. +0 −68 lib/sequel/adapters/adapter_skeleton.rb
  9. +0 −100 lib/sequel/adapters/ado.rb
  10. +0 −158 lib/sequel/adapters/db2.rb
  11. +0 −126 lib/sequel/adapters/dbi.rb
  12. +0 −87 lib/sequel/adapters/informix.rb
  13. +0 −108 lib/sequel/adapters/jdbc.rb
  14. +0 −269 lib/sequel/adapters/mysql.rb
  15. +0 −145 lib/sequel/adapters/odbc.rb
  16. +0 −93 lib/sequel/adapters/odbc_mssql.rb
  17. +0 −90 lib/sequel/adapters/openbase.rb
  18. +0 −99 lib/sequel/adapters/oracle.rb
  19. +0 −519 lib/sequel/adapters/postgres.rb
  20. +0 −192 lib/sequel/adapters/sqlite.rb
  21. +0 −6 lib/sequel/ado.rb
  22. +0 −296 lib/sequel/array_keys.rb
  23. +0 −152 lib/sequel/connection_pool.rb
  24. +0 −59 lib/sequel/core_ext.rb
  25. +0 −191 lib/sequel/core_sql.rb
  26. +0 −423 lib/sequel/database.rb
  27. +0 −409 lib/sequel/dataset.rb
  28. +0 −321 lib/sequel/dataset/convenience.rb
  29. +0 −357 lib/sequel/dataset/sequelizer.rb
  30. +0 −586 lib/sequel/dataset/sql.rb
  31. +0 −6 lib/sequel/db2.rb
  32. +0 −6 lib/sequel/dbi.rb
  33. +0 −45 lib/sequel/exceptions.rb
  34. +0 −6 lib/sequel/informix.rb
  35. +0 −191 lib/sequel/migration.rb
  36. +0 −325 lib/sequel/model.rb
  37. +0 −97 lib/sequel/model/base.rb
  38. +0 −42 lib/sequel/model/caching.rb
  39. +0 −122 lib/sequel/model/hooks.rb
  40. +0 −44 lib/sequel/model/plugins.rb
  41. +0 −309 lib/sequel/model/record.rb
  42. +0 −107 lib/sequel/model/relations.rb
  43. +0 −52 lib/sequel/model/schema.rb
  44. +0 −117 lib/sequel/model/validations.rb
  45. +0 −6 lib/sequel/mysql.rb
  46. +0 −6 lib/sequel/odbc.rb
  47. +0 −6 lib/sequel/oracle.rb
  48. +0 −6 lib/sequel/postgres.rb
  49. +0 −73 lib/sequel/pretty_table.rb
  50. +0 −8 lib/sequel/schema.rb
  51. +0 −131 lib/sequel/schema/schema_generator.rb
  52. +0 −131 lib/sequel/schema/schema_sql.rb
  53. +0 −6 lib/sequel/sqlite.rb
  54. +0 −58 lib/sequel/worker.rb
  55. +0 −22 stress/access_perf.rb
  56. +0 −29 stress/dataset_perf.rb
  57. +0 −26 stress/filter_perf.rb
  58. +0 −63 stress/hashes_vs_array_keys.rb
  59. +0 −16 stress/mem_array.rb
  60. +0 −19 stress/mem_array_fields.rb
  61. +0 −17 stress/mem_array_keys.rb
  62. +0 −16 stress/mem_hashes.rb
  63. +0 −16 stress/postgres_perf.rb
  64. +0 −10 stress/proc_filter.rb
30 examples/basic.rb
View
@@ -1,30 +0,0 @@
-require 'rubygems'
-require 'sequel/sqlite'
-
-# Let's open an in-memory database
-DB = Sequel.open 'sqlite:/'
-
-# Create a new table
-DB.create_table :items do
- primary_key :id, :integer, :auto_increment => true
- column :name, :text
- column :price, :float
-end
-
-# Create a dataset
-items = DB[:items]
-
-# Populate the table
-items << {:name => 'abc', :price => rand * 100}
-items << {:name => 'def', :price => rand * 100}
-items << {:name => 'ghi', :price => rand * 100}
-
-# Print out the number of records
-puts "Item count: #{items.count}"
-
-# Print out the records
-items.print(:name, :price)
-
-# Print out the average price
-puts "The average price is: #{items.avg(:price)}"
-
23 examples/countries.rb
View
@@ -1,23 +0,0 @@
-require 'sequel/sqlite'
-
-DB = Sequel.open 'sqlite:///countries.db'
-countries = DB[:countries]
-
-# select name, region and popuplation
-countries.select(:name, :region, :population).all
-
-# show the name for the countries that have a population of
-# at least 200 million.
-large_populations = countries.filter {population >= 200_000_000}
-large_populations.map(:name)
-
-# Give the name and the per capita GDP for those countries
-# with a population of at least 200 million.
-large_populations.hash_map(:name, :gdp)
-
-# Show the name and population in millions for the countries of Asia
-countries.filter(:region => 'Asia').select(:name, 'population/1000000').all
-
-# Show the name and population for France, Germany, Italy
-countries.filter(:name => ['France', 'Germany', 'Italy']).hash_map(:name, :population)
-
16 examples/csv.rb
View
@@ -1,16 +0,0 @@
-require 'rubygems'
-require 'faster_csv'
-require File.join(File.dirname(__FILE__), '../lib/sequel/sqlite')
-
-DB = Sequel.open 'sqlite:///test.db'
-DB.create_table :countries do
- column :name, :text
- column :population, :integer
-end unless DB.table_exists?(:countries)
-
-FCSV.foreach('/home/sharon/reality/server/trunk/test.csv',
- :headers => true, :header_converters => :symbol) do |l|
- DB[:countries] << l.to_hash
-end
-
-DB[:countries].print(:name, :population)
30 examples/filters.rb
View
@@ -1,30 +0,0 @@
-require 'rubygems'
-require 'sequel/sqlite' # gem install sequel (and sqlite3 as well)
-
-DB = Sequel.open 'sqlite:/' # memory DB
-
-DB.create_table :items do
- text :name
- decimal :price
-end
-
-items = DB[:items]
-
-1000.times {|i| items << {:name => "item#{i}", :price => rand * 100}}
-
-puts "#{items.count} total items"
-
-puts "Average price: #{items.avg(:price)}"
-
-puts "3 most expensive items:"
-items.order(:price.DESC).limit(3).print(:name, :price)
-
-puts "#{items.filter {price < items.avg(:price)}.count} below the average"
-#{}
-
-puts "Changing price for expensive items"
-items.filter {price > items.avg(:price)}.update(:price => 'price + 10'.expr)
-
-puts "Highest price: #{items.max(:price)}"
-
-puts "Updated average price: #{items.avg(:price)}"
40 examples/view.rb
View
@@ -1,40 +0,0 @@
-require 'rubygems'
-require File.join(File.dirname(__FILE__), '../lib/sequel/sqlite')
-
-db = Sequel.open("sqlite:/:memory:")
-db << "create table k1 (id integer primary key autoincrement, f1 text)"
-db << "create table k2 (id integer primary key autoincrement, f2 text)"
-db << "create table k3 (id integer primary key autoincrement, f3 text)"
-db << "create table records (id integer primary key autoincrement,
- k1_id integer, k2_id integer, k3_id integer, value text)"
-db << "create unique index records_key_unique on records(k1_id,k2_id,k3_id)"
-db << "create view data as select records.id as id, k1.f1 as f1, k2.f2 as f2,
- k3.f3 as f3, records.value as value
- from records inner join k1 on records.k1_id = k1.id
- inner join k2 on records.k2_id = k2.id
- inner join k3 on records.k3_id = k3.id
- order by k1.f1, k2.f2, k3.f3"
-k1 = db[:k1]
-k1 << [1, 'Alfred']
-k1 << [2,'Barry']
-k1 << [3, 'Charles']
-k1 << [4,'Dave']
-k1 << [5,'Douglas']
-k2 = db[:k2]
-k2 << [1,'USA']
-k2 << [2,'Japan']
-k2 << [3,'Brazil']
-k3 = db[:k3]
-k3 << [1,'APL']
-k3 << [2,'BASIC']
-k3 << [3,'COBOL']
-k3 << [4,'Ruby']
-records = db[:records]
-records << [1,1,1,1,'Red']
-records << [2,2,2,2,'Yellow']
-records << [3,3,3,3,'Green']
-records << [4,4,1,4,'Magenta']
-records << [5,5,2,4,'Blue']
-data = db[:data].filter(:f1 => ['Dave','Douglas'])
-puts data.sql
-data.print(:id, :f1, :f2, :f3, :value)
101 extra/stats.rb
View
@@ -1,101 +0,0 @@
-# Unashamedly appropriated from Rails
-
-class CodeStatistics
- def initialize(*pairs)
- @pairs = pairs
- @statistics = calculate_statistics
- @total = calculate_total if pairs.length > 1
- end
-
- def to_s
- print_header
- @statistics.each{ |k, v| print_line(k, v) }
- print_splitter
-
- if @total
- print_line('Total', @total)
- print_splitter
- print_code_to_test
- end
- end
-
- private
- def calculate_statistics
- @pairs.inject({}) do |stats, pair|
- stats[pair.first] = calculate_directory_statistics(pair.last); stats
- end
- end
-
- def get_file_statistics(fn, stats)
- f = File.open(fn)
- while line = f.gets
- stats[:lines] += 1
- stats[:classes] += 1 if line =~ /class [A-Z]/ || line =~ /context/
- stats[:methods] += 1 if line =~ /def [a-z]/ || line =~ /specify/
- stats[:codelines] += 1 unless line =~ /^\s*$/ || line =~ /^\s*#/
- end
- end
-
- def get_directory_statistics(dir, stats)
- Dir.foreach(dir) do |fn|
- next if fn =~ /^\./
- fn = File.join(dir, fn)
- if File.directory?(fn)
- get_directory_statistics fn, stats
- else
- next unless fn =~ /.*rb/
- get_file_statistics fn, stats
- end
- end
- stats
- end
-
- def calculate_directory_statistics(directory, pattern = /.*rb/)
- stats = { :lines => 0, :codelines => 0, :classes => 0, :methods => 0 }
- get_directory_statistics directory, stats
- stats
- end
-
- def calculate_total
- total = { :lines => 0, :codelines => 0, :classes => 0, :methods => 0 }
- @statistics.each_value { |pair| pair.each { |k, v| total[k] += v } }
- total
- end
-
- def print_header
- print_splitter
- puts '| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |'
- print_splitter
- end
-
- def print_splitter
- puts '+---------------+-------+-------+---------+---------+-----+-------+'
- end
-
- def print_line(name, statistics)
- m_over_c = (statistics[:methods] / statistics[:classes]) rescue m_over_c = 0
- loc_over_m = (statistics[:codelines] / statistics[:methods]) - 2 rescue loc_over_m = 0
-
- puts "| #{name.ljust(13)} " +
- "| #{statistics[:lines].to_s.rjust(5)} " +
- "| #{statistics[:codelines].to_s.rjust(5)} " +
- "| #{statistics[:classes].to_s.rjust(7)} " +
- "| #{statistics[:methods].to_s.rjust(7)} " +
- "| #{m_over_c.to_s.rjust(3)} " +
- "| #{loc_over_m.to_s.rjust(5)} |"
- end
-
- def print_code_to_test
- c_loc = 0
- t_loc = 0
- @statistics.each do |n, s|
- if n =~ /spec/i
- t_loc += s[:codelines]
- else
- c_loc += s[:codelines]
- end
- end
- ratio = (((t_loc.to_f / c_loc)*10).round.to_f/10).to_s[0,4]
- puts " Code LOC: #{c_loc} Spec LOC: #{t_loc} Code to Spec Ratio: 1:#{ratio}"
- end
-end
59 lib/sequel.rb
View
@@ -1,59 +0,0 @@
-require "metaid"
-require "bigdecimal"
-require "bigdecimal/util"
-
-files = %w[
- core_ext core_sql array_keys exceptions connection_pool pretty_table
- dataset migration model schema database worker
-]
-dir = File.join(File.dirname(__FILE__), "sequel")
-files.each {|f| require(File.join(dir, f))}
-
-module Sequel #:nodoc:
- class << self
- # call-seq:
- # Sequel::Database.connect(conn_string)
- # Sequel.connect(conn_string)
- # Sequel.open(conn_string)
- #
- # Creates a new database object based on the supplied connection string.
- # The specified scheme determines the database class used, and the rest
- # of the string specifies the connection options. For example:
- # DB = Sequel.open 'sqlite:///blog.db'
- def connect(*args)
- Database.connect(*args)
- end
- alias_method :open, :connect
-
- def single_threaded=(value)
- Database.single_threaded = value
- end
-
- def method_missing(m, *args)
- c = Database.adapter_class(m)
- begin
- # three ways to invoke this:
- # 0 arguments: Sequel.dbi
- # 1 argument: Sequel.dbi(db_name)
- # more args: Sequel.dbi(db_name, opts)
- case args.size
- when 0
- opts = {}
- when 1
- opts = args[0].is_a?(Hash) ? args[0] : {:database => args[0]}
- else
- opts = args[1].merge(:database => args[0])
- end
- rescue
- raise Error, "Unknown adapter (#{m})"
- end
- c.new(opts)
- end
- end
-end
-
-class Object
- def Sequel(*args)
- Sequel.connect(*args)
- end
-end
68 lib/sequel/adapters/adapter_skeleton.rb
View
@@ -1,68 +0,0 @@
-# require 'adapter_lib'
-
-module Sequel
- module Adapter
- class Database < Sequel::Database
- set_adapter_scheme :adapter
-
- def connect
- AdapterDB.new(@opts[:database], @opts[:user], @opts[:password])
- end
-
- def disconnect
- @pool.disconnect {|c| c.disconnect}
- end
-
- def dataset(opts = nil)
- Adapter::Dataset.new(self, opts)
- end
-
- def execute(sql)
- @logger.info(sql) if @logger
- @pool.hold {|conn| conn.exec(sql)}
- end
-
- alias_method :do, :execute
- end
-
- class Dataset < Sequel::Dataset
- def literal(v)
- case v
- when Time
- literal(v.iso8601)
- else
- super
- end
- end
-
- def fetch_rows(sql, &block)
- @db.synchronize do
- cursor = @db.execute sql
- begin
- @columns = cursor.get_col_names.map {|c| c.to_sym}
- while r = cursor.fetch
- row = {}
- r.each_with_index {|v, i| row[@columns[i]] = v}
- yield row
- end
- ensure
- cursor.close
- end
- end
- self
- end
-
- def insert(*values)
- @db.do insert_sql(*values)
- end
-
- def update(*args, &block)
- @db.do update_sql(*args, &block)
- end
-
- def delete(opts = nil)
- @db.do delete_sql(opts)
- end
- end
- end
-end
100 lib/sequel/adapters/ado.rb
View
@@ -1,100 +0,0 @@
-require 'win32ole'
-
-module Sequel
- # The ADO adapter provides connectivity to ADO databases in Windows. ADO
- # databases can be opened using a URL with the ado schema:
- #
- # DB = Sequel.open('ado://mydb')
- #
- # or using the Sequel.ado method:
- #
- # DB = Sequel.ado('mydb')
- #
- module ADO
- class Database < Sequel::Database
- set_adapter_scheme :ado
-
- AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
-
- def auto_increment_sql
- AUTO_INCREMENT
- end
-
- def connect
- dbname = @opts[:database]
- handle = WIN32OLE.new('ADODB.Connection')
- handle.Open(dbname)
- handle
- end
-
- def disconnect
- # how do we disconnect? couldn't find anything in the docs
- end
-
- def dataset(opts = nil)
- ADO::Dataset.new(self, opts)
- end
-
- def execute(sql)
- @logger.info(sql) if @logger
- @pool.hold {|conn| conn.Execute(sql)}
- end
-
- alias_method :do, :execute
- end
-
- class Dataset < Sequel::Dataset
- def literal(v)
- case v
- when Time
- literal(v.iso8601)
- else
- super
- end
- end
-
- def fetch_rows(sql, &block)
- @db.synchronize do
- s = @db.execute sql
-
- @columns = s.Fields.extend(Enumerable).map {|x| x.Name.to_sym}
-
- s.moveFirst
- s.getRows.transpose.each {|r| yield hash_row(r)}
- end
- self
- end
-
- def hash_row(row)
- @columns.inject({}) do |m, c|
- m[c] = row.shift
- m
- end
- end
-
- def array_tuples_fetch_rows(sql, &block)
- @db.synchronize do
- s = @db.execute sql
-
- @columns = s.Fields.extend(Enumerable).map {|x| x.Name.to_sym}
-
- s.moveFirst
- s.getRows.transpose.each {|r| r.keys = @columns; yield r}
- end
- self
- end
-
- def insert(*values)
- @db.do insert_sql(*values)
- end
-
- def update(*args, &block)
- @db.do update_sql(*args, &block)
- end
-
- def delete(opts = nil)
- @db.do delete_sql(opts)
- end
- end
- end
-end
158 lib/sequel/adapters/db2.rb
View
@@ -1,158 +0,0 @@
-require 'db2/db2cli'
-
-module Sequel
- module DB2
- class Database < Sequel::Database
- set_adapter_scheme :db2
- include DB2CLI
-
- # AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
- #
- # def auto_increment_sql
- # AUTO_INCREMENT
- # end
-
- def check_error(rc, msg)
- case rc
- when SQL_SUCCESS, SQL_SUCCESS_WITH_INFO
- nil
- else
- raise Error, msg
- end
- end
-
- rc, @@env = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE)
- check_error(rc, "Could not allocate DB2 environment")
-
- def connect
- rc, dbc = SQLAllocHandle(SQL_HANDLE_DBC, @@env)
- check_error(rc, "Could not allocate database connection")
-
- rc = SQLConnect(dbc, @opts[:database], @opts[:user], @opts[:password])
- check_error(rc, "Could not connect to database")
-
- dbc
- end
-
- def disconnect
- @pool.disconnect do |conn|
- rc = SQLDisconnect(conn)
- check_error(rc, "Could not disconnect from database")
-
- rc = SQLFreeHandle(SQL_HANDLE_DBC, conn)
- check_error(rc, "Could not free Database handle")
- end
- end
-
- def test_connection
- @pool.hold {|conn|}
- true
- end
-
- def dataset(opts = nil)
- DB2::Dataset.new(self, opts)
- end
-
- def execute(sql, &block)
- @logger.info(sql) if @logger
- @pool.hold do |conn|
- rc, sth = SQLAllocHandle(SQL_HANDLE_STMT, @handle)
- check_error(rc, "Could not allocate statement")
-
- begin
- rc = SQLExecDirect(sth, sql)
- check_error(rc, "Could not execute statement")
-
- block[sth] if block
-
- rc, rpc = SQLRowCount(sth)
- check_error(rc, "Could not get RPC")
- rpc
- ensure
- rc = SQLFreeHandle(SQL_HANDLE_STMT, sth)
- check_error(rc, "Could not free statement")
- end
- end
- end
- alias_method :do, :execute
- end
-
- class Dataset < Sequel::Dataset
- def literal(v)
- case v
- when Time
- literal(v.iso8601)
- else
- super
- end
- end
-
- def fetch_rows(sql, &block)
- @db.synchronize do
- @db.execute(sql) do |sth|
- @column_info = get_column_info(sth)
- @columns = @column_info.map {|c| c[:name]}
- while (rc = SQLFetch(@handle)) != SQL_NO_DATA_FOUND
- @db.check_error(rc, "Could not fetch row")
- yield hash_row(sth)
- end
- end
- end
- self
- end
-
- MAX_COL_SIZE = 256
-
- def get_column_info(sth)
- rc, column_count = SQLNumResultCols(sth)
- @db.check_error(rc, "Could not get number of result columns")
-
- (1..column_count).map do |i|
- rc, name, buflen, datatype, size, digits, nullable = SQLDescribeCol(sth, i, MAX_COL_SIZE)
- @b.check_error(rc, "Could not describe column")
-
- {:name => name, :db2_type => datatype, :precision => size}
- end
- end
-
- def hash_row(sth)
- row = {}
- @column_info.each_with_index do |c, i|
- rc, v = SQLGetData(sth, i+1, c[:db2_type], c[:precision])
- @db.check_error(rc, "Could not get data")
-
- @row[c[:name]] = convert_type(v)
- end
- row
- end
-
- def convert_type(v)
- case v
- when DB2CLI::Date
- DBI::Date.new(v.year, v.month, v.day)
- when DB2CLI::Time
- DBI::Time.new(v.hour, v.minute, v.second)
- when DB2CLI::Timestamp
- DBI::Timestamp.new(v.year, v.month, v.day,
- v.hour, v.minute, v.second, v.fraction)
- when DB2CLI::Null
- nil
- else
- v
- end
- end
-
- def insert(*values)
- @db.do insert_sql(*values)
- end
-
- def update(*args, &block)
- @db.do update_sql(*args, &block)
- end
-
- def delete(opts = nil)
- @db.do delete_sql(opts)
- end
- end
- end
-end
126 lib/sequel/adapters/dbi.rb
View
@@ -1,126 +0,0 @@
-require 'dbi'
-
-module Sequel
- module DBI
- class Database < Sequel::Database
- set_adapter_scheme :dbi
-
- DBI_ADAPTERS = {
- :ado => "ADO",
- :db2 => "DB2",
- :frontbase => "FrontBase",
- :interbase => "InterBase",
- :msql => "Msql",
- :mysql => "Mysql",
- :odbc => "ODBC",
- :oracle => "Oracle",
- :pg => "Pg",
- :proxy => "Proxy",
- :sqlite => "SQLite",
- :sqlrelay => "SQLRelay"
- }
-
- # Converts a uri to an options hash. These options are then passed
- # to a newly created database object.
- def self.uri_to_options(uri)
- database = (uri.path =~ /\/(.*)/) && ($1)
- if uri.scheme =~ /dbi-(.+)/
- adapter = DBI_ADAPTERS[$1.to_sym] || $1
- database = "#{adapter}:#{database}"
- end
- {
- :user => uri.user,
- :password => uri.password,
- :host => uri.host,
- :port => uri.port,
- :database => database
- }
- end
-
-
- def connect
- dbname = @opts[:database]
- dbname = 'DBI:' + dbname unless dbname =~ /^DBI:/
- ::DBI.connect(dbname, @opts[:user], @opts[:password])
- end
-
- def disconnect
- @pool.disconnect {|c| c.disconnect}
- end
-
- def dataset(opts = nil)
- DBI::Dataset.new(self, opts)
- end
-
- def execute(sql)
- @logger.info(sql) if @logger
- @pool.hold do |conn|
- conn.execute(sql)
- end
- end
-
- def do(sql)
- @logger.info(sql) if @logger
- @pool.hold do |conn|
- conn.do(sql)
- end
- end
- end
-
- class Dataset < Sequel::Dataset
- def literal(v)
- case v
- when Time
- literal(v.iso8601)
- else
- super
- end
- end
-
- def fetch_rows(sql, &block)
- @db.synchronize do
- s = @db.execute sql
- begin
- @columns = s.column_names.map {|c| c.to_sym}
- s.fetch {|r| yield hash_row(s, r)}
- ensure
- s.finish rescue nil
- end
- end
- self
- end
-
- def array_tuples_fetch_rows(sql, &block)
- @db.synchronize do
- s = @db.execute sql
- begin
- @columns = s.column_names.map {|c| c.to_sym}
- s.fetch {|r| r.keys = @columns; yield r}
- ensure
- s.finish rescue nil
- end
- end
- self
- end
-
- def hash_row(stmt, row)
- @columns.inject({}) do |m, c|
- m[c] = row.shift
- m
- end
- end
-
- def insert(*values)
- @db.do insert_sql(*values)
- end
-
- def update(*args, &block)
- @db.do update_sql(*args, &block)
- end
-
- def delete(opts = nil)
- @db.do delete_sql(opts)
- end
- end
- end
-end
87 lib/sequel/adapters/informix.rb
View
@@ -1,87 +0,0 @@
-require 'informix'
-
-module Sequel
- module Informix
- class Database < Sequel::Database
- set_adapter_scheme :informix
-
- # AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
- #
- # def auto_increment_sql
- # AUTO_INCREMENT
- # end
-
- def connect
- ::Informix.connect(@opts[:database], @opts[:user], @opts[:password])
- end
-
- def disconnect
- @pool.disconnect {|c| c.close}
- end
-
- def dataset(opts = nil)
- Sequel::Informix::Dataset.new(self, opts)
- end
-
- # Returns number of rows affected
- def execute(sql)
- @logger.info(sql) if @logger
- @pool.hold {|c| c.do(sql)}
- end
- alias_method :do, :execute
-
- def query(sql, &block)
- @logger.info(sql) if @logger
- @pool.hold {|c| block[c.cursor(sql)]}
- end
- end
-
- class Dataset < Sequel::Dataset
- def literal(v)
- case v
- when Time
- literal(v.iso8601)
- else
- super
- end
- end
-
- def select_sql(opts = nil)
- limit = opts.delete(:limit)
- offset = opts.delete(:offset)
- sql = super
- if limit
- limit = "FIRST #{limit}"
- offset = offset ? "SKIP #{offset}" : ""
- sql.sub!(/^select /i,"SELECT #{offset} #{limit} ")
- end
- sql
- end
-
- def fetch_rows(sql, &block)
- @db.synchronize do
- @db.query(sql) do |cursor|
- begin
- cursor.open.each_hash {|r| block[r]}
- ensure
- cursor.drop
- end
- end
- end
- self
- end
-
- def insert(*values)
- @db.do insert_sql(*values)
- end
-
- def update(*args, &block)
- @db.do update_sql(*args, &block)
- end
-
- def delete(opts = nil)
- @db.do delete_sql(opts)
- end
- end
- end
-end
108 lib/sequel/adapters/jdbc.rb
View
@@ -1,108 +0,0 @@
-require 'java'
-
-module Sequel
- module JDBC
- module JavaLang; include_package 'java.lang'; end
- module JavaSQL; include_package 'java.sql'; end
-
- def self.load_driver(driver)
- JavaLang::Class.forName(driver)
- # "com.mysql.jdbc.Driver"
- end
-
- class Database < Sequel::Database
- set_adapter_scheme :jdbc
-
- def connect
- unless conn_string = @opts[:uri] || @opts[:url] || @opts[:database]
- raise Error, "No connection string specified"
- end
- unless conn_string =~ /^jdbc:/
- conn_string = "jdbc:#{conn_string}"
- end
- JavaSQL::DriverManager.getConnection(
- conn_string,
- @opts[:user],
- @opts[:password]
- )
- # "jdbc:mysql://127.0.0.1:3306/ruby?user=root"
- # "mysql://127.0.0.1:3306/ruby?user=root"
- end
-
- def disconnect
- @pool.disconnect {|c| c.close}
- end
-
- def dataset(opts = nil)
- JDBC::Dataset.new(self, opts)
- end
-
- def execute_and_forget(sql)
- @logger.info(sql) if @logger
- @pool.hold do |conn|
- stmt = conn.createStatement
- begin
- stmt.executeQuery(sql)
- ensure
- stmt.close
- end
- end
- end
-
- def execute(sql)
- @logger.info(sql) if @logger
- @pool.hold do |conn|
- stmt = conn.createStatement
- begin
- yield stmt.executeQuery(sql)
- ensure
- stmt.close
- end
- end
- end
- end
-
- class Dataset < Sequel::Dataset
- def literal(v)
- case v
- when Time
- literal(v.iso8601)
- else
- super
- end
- end
-
- def fetch_rows(sql, &block)
- @db.synchronize do
- @db.execute(sql) do |result|
- # get column names
- meta = result.getMetaData
- column_count = meta.getColumnCount
- @columns = []
- column_count.times {|i| @columns << meta.getColumnName(i).to_sym}
-
- # get rows
- while result.next
- row = {}
- @columns.each_with_index {|v, i| row[v] = result.getObject(i)}
- yield row
- end
- end
- end
- self
- end
-
- def insert(*values)
- @db.execute_and_forget insert_sql(*values)
- end
-
- def update(*args, &block)
- @db.execute_and_forget update_sql(*args, &block)
- end
-
- def delete(opts = nil)
- @db.execute_and_forget delete_sql(opts)
- end
- end
- end
-end
269 lib/sequel/adapters/mysql.rb
View
@@ -1,269 +0,0 @@
-require 'mysql'
-
-# Monkey patch Mysql::Result to yield hashes with symbol keys
-class Mysql::Result
- MYSQL_TYPES = {
- 0 => :to_d, # MYSQL_TYPE_DECIMAL
- 1 => :to_i, # MYSQL_TYPE_TINY
- 2 => :to_i, # MYSQL_TYPE_SHORT
- 3 => :to_i, # MYSQL_TYPE_LONG
- 4 => :to_f, # MYSQL_TYPE_FLOAT
- 5 => :to_f, # MYSQL_TYPE_DOUBLE
- # 6 => ??, # MYSQL_TYPE_NULL
- 7 => :to_time, # MYSQL_TYPE_TIMESTAMP
- 8 => :to_i, # MYSQL_TYPE_LONGLONG
- 9 => :to_i, # MYSQL_TYPE_INT24
- 10 => :to_time, # MYSQL_TYPE_DATE
- 11 => :to_time, # MYSQL_TYPE_TIME
- 12 => :to_time, # MYSQL_TYPE_DATETIME
- 13 => :to_i, # MYSQL_TYPE_YEAR
- 14 => :to_time, # MYSQL_TYPE_NEWDATE
- # 15 => :to_s # MYSQL_TYPE_VARCHAR
- # 16 => :to_s, # MYSQL_TYPE_BIT
- 246 => :to_d, # MYSQL_TYPE_NEWDECIMAL
- 247 => :to_i, # MYSQL_TYPE_ENUM
- 248 => :to_i # MYSQL_TYPE_SET
- # 249 => :to_s, # MYSQL_TYPE_TINY_BLOB
- # 250 => :to_s, # MYSQL_TYPE_MEDIUM_BLOB
- # 251 => :to_s, # MYSQL_TYPE_LONG_BLOB
- # 252 => :to_s, # MYSQL_TYPE_BLOB
- # 253 => :to_s, # MYSQL_TYPE_VAR_STRING
- # 254 => :to_s, # MYSQL_TYPE_STRING
- # 255 => :to_s # MYSQL_TYPE_GEOMETRY
- }
-
- def convert_type(v, type)
- v ? ((t = MYSQL_TYPES[type]) ? v.send(t) : v) : nil
- end
-
- def columns(with_table = nil)
- unless @columns
- @column_types = []
- @columns = fetch_fields.map do |f|
- @column_types << f.type
- (with_table ? (f.table + "." + f.name) : f.name).to_sym
- end
- end
- @columns
- end
-
- def each_array(with_table = nil)
- c = columns
- while row = fetch_row
- c.each_with_index do |f, i|
- if (t = MYSQL_TYPES[@column_types[i]]) && (v = row[i])
- row[i] = v.send(t)
- end
- end
- row.keys = c
- yield row
- end
- end
-
- def each_hash(with_table = nil)
- c = columns
- while row = fetch_row
- h = {}
- c.each_with_index {|f, i| h[f] = convert_type(row[i], @column_types[i])}
- yield h
- end
- end
-end
-
-module Sequel
- module MySQL
- class Database < Sequel::Database
- set_adapter_scheme :mysql
-
- def serial_primary_key_options
- {:primary_key => true, :type => :integer, :auto_increment => true}
- end
-
- AUTO_INCREMENT = 'AUTO_INCREMENT'.freeze
-
- def auto_increment_sql
- AUTO_INCREMENT
- end
-
- def connect
- conn = Mysql.real_connect(@opts[:host], @opts[:user], @opts[:password],
- @opts[:database], @opts[:port], nil, Mysql::CLIENT_MULTI_RESULTS)
- conn.query_with_result = false
- if encoding = @opts[:encoding] || @opts[:charset]
- conn.query("set character_set_connection = '#{encoding}'")
- conn.query("set character_set_client = '#{encoding}'")
- conn.query("set character_set_results = '#{encoding}'")
- end
- conn.reconnect = true
- conn
- end
-
- def disconnect
- @pool.disconnect {|c| c.close}
- end
-
- def tables
- @pool.hold do |conn|
- conn.list_tables.map {|t| t.to_sym}
- end
- end
-
- def dataset(opts = nil)
- MySQL::Dataset.new(self, opts)
- end
-
- def execute(sql)
- @logger.info(sql) if @logger
- @pool.hold do |conn|
- conn.query(sql)
- end
- end
-
- def execute_select(sql)
- @logger.info(sql) if @logger
- @pool.hold do |conn|
- conn.query(sql)
- conn.use_result
- end
- end
-
- def execute_insert(sql)
- @logger.info(sql) if @logger
- @pool.hold do |conn|
- conn.query(sql)
- conn.insert_id
- end
- end
-
- def execute_affected(sql)
- @logger.info(sql) if @logger
- @pool.hold do |conn|
- conn.query(sql)
- conn.affected_rows
- end
- end
-
- def alter_table_sql(table, op)
- case op[:op]
- when :rename_column
- "ALTER TABLE #{table} CHANGE COLUMN #{literal(op[:name])} #{literal(op[:new_name])} #{op[:type]}"
- when :set_column_type
- "ALTER TABLE #{table} CHANGE COLUMN #{literal(op[:name])} #{literal(op[:name])} #{op[:type]}"
- when :drop_index
- "DROP INDEX #{default_index_name(table, op[:columns])} ON #{table}"
- else
- super(table, op)
- end
- end
-
- def transaction
- @pool.hold do |conn|
- @transactions ||= []
- if @transactions.include? Thread.current
- return yield(conn)
- end
- conn.query(SQL_BEGIN)
- begin
- @transactions << Thread.current
- result = yield(conn)
- conn.query(SQL_COMMIT)
- result
- rescue => e
- conn.query(SQL_ROLLBACK)
- raise e unless Error::Rollback === e
- ensure
- @transactions.delete(Thread.current)
- end
- end
- end
- end
-
- class Dataset < Sequel::Dataset
- def quote_column_ref(c); "`#{c}`"; end
-
- TRUE = '1'
- FALSE = '0'
-
- def literal(v)
- case v
- when LiteralString
- v
- when String
- "'#{v.gsub(/'|\\/, '\&\&')}'"
- when true
- TRUE
- when false
- FALSE
- else
- super
- end
- end
-
- def match_expr(l, r)
- case r
- when Regexp
- r.casefold? ? \
- "(#{literal(l)} REGEXP #{literal(r.source)})" :
- "(#{literal(l)} REGEXP BINARY #{literal(r.source)})"
- else
- super
- end
- end
-
- # MySQL supports ORDER and LIMIT clauses in UPDATE statements.
- def update_sql(values, opts = nil)
- sql = super
-
- opts = opts ? @opts.merge(opts) : @opts
-
- if order = opts[:order]
- sql << " ORDER BY #{column_list(order)}"
- end
-
- if limit = opts[:limit]
- sql << " LIMIT #{limit}"
- end
-
- sql
- end
-
- def insert(*values)
- @db.execute_insert(insert_sql(*values))
- end
-
- def update(*args, &block)
- @db.execute_affected(update_sql(*args, &block))
- end
-
- def delete(opts = nil)
- @db.execute_affected(delete_sql(opts))
- end
-
- def fetch_rows(sql)
- @db.synchronize do
- r = @db.execute_select(sql)
- begin
- @columns = r.columns
- r.each_hash {|row| yield row}
- ensure
- r.free
- end
- end
- self
- end
-
- def array_tuples_fetch_rows(sql, &block)
- @db.synchronize do
- r = @db.execute_select(sql)
- begin
- @columns = r.columns
- r.each_array(&block)
- ensure
- r.free
- end
- end
- self
- end
- end
- end
-end
145 lib/sequel/adapters/odbc.rb
View
@@ -1,145 +0,0 @@
-require 'odbc'
-
-module Sequel
- module ODBC
- class Database < Sequel::Database
- set_adapter_scheme :odbc
-
- def connect
- conn = ::ODBC::connect(@opts[:database], @opts[:user], @opts[:password])
- conn.autocommit = true
- conn
- end
-
- def disconnect
- @pool.disconnect {|c| c.disconnect}
- end
-
- def dataset(opts = nil)
- ODBC::Dataset.new(self, opts)
- end
-
- def execute(sql)
- @logger.info(sql) if @logger
- @pool.hold do |conn|
- conn.run(sql)
- end
- end
-
- def do(sql)
- @logger.info(sql) if @logger
- @pool.hold do |conn|
- conn.do(sql)
- end
- end
- end
-
- class Dataset < Sequel::Dataset
- BOOL_TRUE = '1'.freeze
- BOOL_FALSE = '0'.freeze
-
- def literal(v)
- case v
- when true
- BOOL_TRUE
- when false
- BOOL_FALSE
- else
- super
- end
- end
-
- def fetch_rows(sql, &block)
- @db.synchronize do
- s = @db.execute sql
- begin
- @columns = s.columns(true).map {|c| c.name.to_sym}
- rows = s.fetch_all
- rows.each {|row| yield hash_row(row)}
- ensure
- s.drop unless s.nil? rescue nil
- end
- end
- self
- end
-
- def hash_row(row)
- hash = {}
- row.each_with_index do |v, idx|
- hash[@columns[idx]] = convert_odbc_value(v)
- end
- hash
- end
-
- def convert_odbc_value(v)
- # When fetching a result set, the Ruby ODBC driver converts all ODBC
- # SQL types to an equivalent Ruby type; with the exception of
- # SQL_TYPE_DATE, SQL_TYPE_TIME and SQL_TYPE_TIMESTAMP.
- #
- # The conversions below are consistent with the mappings in
- # ODBCColumn#mapSqlTypeToGenericType and Column#klass.
- case v
- when ::ODBC::TimeStamp
- DateTime.new(v.year, v.month, v.day, v.hour, v.minute, v.second)
- when ::ODBC::Time
- DateTime.now
- Time.gm(now.year, now.month, now.day, v.hour, v.minute, v.second)
- when ::ODBC::Date
- Date.new(v.year, v.month, v.day)
- else
- v
- end
- end
-
- def array_tuples_fetch_rows(sql, &block)
- @db.synchronize do
- s = @db.execute sql
- begin
- @columns = s.columns(true).map {|c| c.name.to_sym}
- rows = s.fetch_all
- rows.each {|r| yield array_tuples_make_row(r)}
- ensure
- s.drop unless s.nil? rescue nil
- end
- end
- self
- end
-
- def array_tuples_make_row(row)
- row.keys = @columns
- row.each_with_index do |v, idx|
- # When fetching a result set, the Ruby ODBC driver converts all ODBC
- # SQL types to an equivalent Ruby type; with the exception of
- # SQL_TYPE_DATE, SQL_TYPE_TIME and SQL_TYPE_TIMESTAMP.
- #
- # The conversions below are consistent with the mappings in
- # ODBCColumn#mapSqlTypeToGenericType and Column#klass.
- case v
- when ::ODBC::TimeStamp
- row[idx] = DateTime.new(v.year, v.month, v.day, v.hour, v.minute, v.second)
- when ::ODBC::Time
- now = DateTime.now
- row[idx] = Time.gm(now.year, now.month, now.day, v.hour, v.minute, v.second)
- when ::ODBC::Date
- row[idx] = Date.new(v.year, v.month, v.day)
- end
- end
- row
- end
-
-
- def insert(*values)
- @db.do insert_sql(*values)
- end
-
- def update(*args, &block)
- @db.do update_sql(*args, &block)
- self
- end
-
- def delete(opts = nil)
- @db.do delete_sql(opts)
- end
- end
- end
-end
93 lib/sequel/adapters/odbc_mssql.rb
View
@@ -1,93 +0,0 @@
-if !Sequel.const_defined?('ODBC')
- require File.join(File.dirname(__FILE__), 'odbc')
-end
-
-module Sequel
- module ODBC
- module MSSQL
- class Database < ODBC::Database
- set_adapter_scheme :odbc_mssql
-
- def dataset(opts = nil)
- MSSQL::Dataset.new(self, opts)
- end
- end
-
- class Dataset < ODBC::Dataset
- # Allows you to do .nolock on a query
- def nolock
- clone_merge(:with => "(NOLOCK)")
- end
-
- # Formats a SELECT statement using the given options and the dataset
- # options.
- def select_sql(opts = nil)
- opts = opts ? @opts.merge(opts) : @opts
-
- if sql = opts[:sql]
- return sql
- end
-
- # ADD TOP to SELECT string for LIMITS
- if limit = opts[:limit]
- top = "TOP #{limit} "
- raise Error, "Offset not supported" if opts[:offset]
- end
-
- columns = opts[:select]
- select_columns = columns ? column_list(columns) : WILDCARD
-
- if distinct = opts[:distinct]
- distinct_clause = distinct.empty? ? "DISTINCT" : "DISTINCT ON (#{column_list(distinct)})"
- sql = "SELECT #{top}#{distinct_clause} #{select_columns}"
- else
- sql = "SELECT #{top}#{select_columns}"
- end
-
- if opts[:from]
- sql << " FROM #{source_list(opts[:from])}"
- end
-
- # ADD WITH to SELECT string for NOLOCK
- if with = opts[:with]
- sql << " WITH #{with}"
- end
-
- if join = opts[:join]
- sql << join
- end
-
- if where = opts[:where]
- sql << " WHERE #{where}"
- end
-
- if group = opts[:group]
- sql << " GROUP BY #{column_list(group)}"
- end
-
- if order = opts[:order]
- sql << " ORDER BY #{column_list(order)}"
- end
-
- if having = opts[:having]
- sql << " HAVING #{having}"
- end
-
- if union = opts[:union]
- sql << (opts[:union_all] ? \
- " UNION ALL #{union.sql}" : " UNION #{union.sql}")
- elsif intersect = opts[:intersect]
- sql << (opts[:intersect_all] ? \
- " INTERSECT ALL #{intersect.sql}" : " INTERSECT #{intersect.sql}")
- elsif except = opts[:except]
- sql << (opts[:except_all] ? \
- " EXCEPT ALL #{except.sql}" : " EXCEPT #{except.sql}")
- end
-
- sql
- end
- alias_method :sql, :select_sql
- end
- end
- end
-end
90 lib/sequel/adapters/openbase.rb
View
@@ -1,90 +0,0 @@
-require 'openbase'
-
-module Sequel
- module OpenBase
- class Database < Sequel::Database
- set_adapter_scheme :openbase
-
- def connect
- OpenBase.new(
- opts[:database],
- opts[:host] || 'localhost',
- opts[:user],
- opts[:password]
- )
- end
-
- def disconnect
- # would this work?
- @pool.disconnect {|c| c.disconnect}
- end
-
- def dataset(opts = nil)
- OpenBase::Dataset.new(self, opts)
- end
-
- def execute(sql)
- @logger.info(sql) if @logger
- @pool.hold {|conn| conn.execute(sql)}
- end
-
- alias_method :do, :execute
- end
-
- class Dataset < Sequel::Dataset
- def literal(v)
- case v
- when Time
- literal(v.iso8601)
- else
- super
- end
- end
-
- def fetch_rows(sql, &block)
- @db.synchronize do
- result = @db.execute sql
- begin
- @columns = result.column_infos.map {|c| c.name.to_sym}
- result.each do |r|
- row = {}
- r.each_with_index {|v, i| row[@columns[i]] = v}
- yield row
- end
- ensure
- # result.close
- end
- end
- self
- end
-
- def array_tuples_fetch_rows(sql, &block)
- @db.synchronize do
- result = @db.execute sql
- begin
- @columns = result.column_infos.map {|c| c.name.to_sym}
- result.each do |r|
- r.keys = @columns
- yield r
- end
- ensure
- # cursor.close
- end
- end
- self
- end
-
- def insert(*values)
- @db.do insert_sql(*values)
- end
-
- def update(*args, &block)
- @db.do update_sql(*args, &block)
- end
-
- def delete(opts = nil)
- @db.do delete_sql(opts)
- end
- end
- end
-end
99 lib/sequel/adapters/oracle.rb
View
@@ -1,99 +0,0 @@
-require 'oci8'
-
-module Sequel
- module Oracle
- class Database < Sequel::Database
- set_adapter_scheme :oracle
-
- # AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
- #
- # def auto_increment_sql
- # AUTO_INCREMENT
- # end
-
- def connect
- if @opts[:database]
- dbname = @opts[:host] ? \
- "//#{@opts[:host]}/#{@opts[:database]}" : @opts[:database]
- else
- dbname = @opts[:host]
- end
- conn = OCI8.new(@opts[:user], @opts[:password], dbname, @opts[:privilege])
- conn.autocommit = true
- conn.non_blocking = true
- conn
- end
-
- def disconnect
- @pool.disconnect {|c| c.logoff}
- end
-
- def dataset(opts = nil)
- Oracle::Dataset.new(self, opts)
- end
-
- def execute(sql)
- @logger.info(sql) if @logger
- @pool.hold {|conn| conn.exec(sql)}
- end
-
- alias_method :do, :execute
- end
-
- class Dataset < Sequel::Dataset
- def literal(v)
- case v
- when Time
- literal(v.iso8601)
- else
- super
- end
- end
-
- def fetch_rows(sql, &block)
- @db.synchronize do
- cursor = @db.execute sql
- begin
- @columns = cursor.get_col_names.map {|c| c.to_sym}
- while r = cursor.fetch
- row = {}
- r.each_with_index {|v, i| row[@columns[i]] = v}
- yield row
- end
- ensure
- cursor.close
- end
- end
- self
- end
-
- def array_tuples_fetch_rows(sql, &block)
- @db.synchronize do
- cursor = @db.execute sql
- begin
- @columns = cursor.get_col_names.map {|c| c.to_sym}
- while r = cursor.fetch
- r.keys = columns
- yield r
- end
- ensure
- cursor.close
- end
- end
- self
- end
-
- def insert(*values)
- @db.do insert_sql(*values)
- end
-
- def update(*args, &block)
- @db.do update_sql(*args, &block)
- end
-
- def delete(opts = nil)
- @db.do delete_sql(opts)
- end
- end
- end
-end
519 lib/sequel/adapters/postgres.rb
View
@@ -1,519 +0,0 @@
-require 'postgres'
-
-class PGconn
- # the pure-ruby postgres adapter does not have a quote method.
- TRUE = 't'.freeze
- FALSE = 'f'.freeze
- NULL = 'NULL'.freeze
-
- unless methods.include?('quote')
- def self.quote(obj)
- case obj
- when true
- TRUE
- when false
- FALSE
- when nil
- NULL
- when String
- "'#{obj}'"
- else
- obj.to_s
- end
- end
- end
-
- class << self
- # The postgres gem's string quoting doesn't render string literals properly, which this fixes.
- #
- # "a basic string" #=> 'a basic string'
- # "this\or that" #=> E'this\\or that'
- #
- # See <http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html> for details.
- def quote_with_proper_escaping(s)
- value = quote_without_proper_escaping(s)
- value = "E#{value}" if value =~ /\\/
- return value
- end
- alias_method :quote_without_proper_escaping, :quote
- alias_method :quote, :quote_with_proper_escaping
- end
-
- def connected?
- status == PGconn::CONNECTION_OK
- end
-
- def execute(sql)
- begin
- async_exec(sql)
- rescue PGError => e
- unless connected?
- reset
- async_exec(sql)
- else
- raise e
- end
- end
- end
-
- attr_accessor :transaction_in_progress
-
- SELECT_CURRVAL = "SELECT currval('%s')".freeze
-
- def last_insert_id(table)
- @table_sequences ||= {}
- if !@table_sequences.include?(table)
- pkey_and_seq = pkey_and_sequence(table)
- if pkey_and_seq
- @table_sequences[table] = pkey_and_seq[1]
- end
- end
- if seq = @table_sequences[table]
- r = async_query(SELECT_CURRVAL % seq)
- return r[0][0].to_i unless r.nil? || r.empty?
- end
- nil # primary key sequence not found
- end
-
- # Shamelessly appropriated from ActiveRecord's Postgresql adapter.
-
- SELECT_PK_AND_SERIAL_SEQUENCE = <<-end_sql
- SELECT attr.attname, name.nspname, seq.relname
- FROM pg_class seq, pg_attribute attr, pg_depend dep,
- pg_namespace name, pg_constraint cons
- WHERE seq.oid = dep.objid
- AND seq.relnamespace = name.oid
- AND seq.relkind = 'S'
- AND attr.attrelid = dep.refobjid
- AND attr.attnum = dep.refobjsubid
- AND attr.attrelid = cons.conrelid
- AND attr.attnum = cons.conkey[1]
- AND cons.contype = 'p'
- AND dep.refobjid = '%s'::regclass
- end_sql
-
- SELECT_PK_AND_CUSTOM_SEQUENCE = <<-end_sql
- SELECT attr.attname, name.nspname, split_part(def.adsrc, '''', 2)
- FROM pg_class t
- JOIN pg_namespace name ON (t.relnamespace = name.oid)
- JOIN pg_attribute attr ON (t.oid = attrelid)
- JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum)
- JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
- WHERE t.oid = '%s'::regclass
- AND cons.contype = 'p'
- AND def.adsrc ~* 'nextval'
- end_sql
-
- SELECT_PK = <<-end_sql
- SELECT pg_attribute.attname
- FROM pg_class, pg_attribute, pg_index
- WHERE pg_class.oid = pg_attribute.attrelid AND
- pg_class.oid = pg_index.indrelid AND
- pg_index.indkey[0] = pg_attribute.attnum AND
- pg_index.indisprimary = 't' AND
- pg_class.relname = '%s'
- end_sql
-
- def pkey_and_sequence(table)
- r = async_query(SELECT_PK_AND_SERIAL_SEQUENCE % table)
- return [r[0].first, r[0].last] unless r.nil? or r.empty?
-
- r = async_query(SELECT_PK_AND_CUSTOM_SEQUENCE % table)
- return [r[0].first, r[0].last] unless r.nil? or r.empty?
- rescue
- nil
- end
-
- def primary_key(table)
- r = async_query(SELECT_PK % table)
- pkey = r[0].first unless r.nil? or r.empty?
- return pkey.to_sym if pkey
- rescue
- nil
- end
-end
-
-class String
- POSTGRES_BOOL_TRUE = 't'.freeze
- POSTGRES_BOOL_FALSE = 'f'.freeze
-
- def postgres_to_bool
- if self == POSTGRES_BOOL_TRUE
- true
- elsif self == POSTGRES_BOOL_FALSE
- false
- else
- nil
- end
- end
-end
-
-module Sequel
- module Postgres
- PG_TYPES = {
- 16 => :postgres_to_bool,
- 20 => :to_i,
- 21 => :to_i,
- 22 => :to_i,
- 23 => :to_i,
- 700 => :to_f,
- 701 => :to_f,
- 1114 => :to_time
- }
-
- if PGconn.respond_to?(:translate_results=)
- PGconn.translate_results = true
- AUTO_TRANSLATE = true
- else
- AUTO_TRANSLATE = false
- end
-
- class Database < Sequel::Database
- set_adapter_scheme :postgres
-
- def connect
- conn = PGconn.connect(
- @opts[:host] || 'localhost',
- @opts[:port] || 5432,
- '', '',
- @opts[:database],
- @opts[:user],
- @opts[:password]
- )
- if encoding = @opts[:encoding] || @opts[:charset]
- conn.set_client_encoding(encoding)
- end
- conn
- end
-
- def disconnect
- @pool.disconnect {|c| c.close}
- end
-
- def dataset(opts = nil)
- Postgres::Dataset.new(self, opts)
- end
-
- RELATION_QUERY = {:from => [:pg_class], :select => [:relname]}.freeze
- RELATION_FILTER = "(relkind = 'r') AND (relname !~ '^pg|sql')".freeze
- SYSTEM_TABLE_REGEXP = /^pg|sql/.freeze
-
- def tables
- dataset(RELATION_QUERY).filter(RELATION_FILTER).map {|r| r[:relname].to_sym}
- end
-
- def locks
- dataset.from("pg_class, pg_locks").
- select("pg_class.relname, pg_locks.*").
- filter("pg_class.relfilenode=pg_locks.relation")
- end
-
- def execute(sql)
- @logger.info(sql) if @logger
- @pool.hold {|conn| conn.execute(sql)}
- rescue => e
- @logger.error(e.message) if @logger
- raise e
- end
-
- def execute_and_forget(sql)
- @logger.info(sql) if @logger
- @pool.hold {|conn| conn.execute(sql).clear}
- rescue => e
- @logger.error(e.message) if @logger
- raise e
- end
-
- def primary_key_for_table(conn, table)
- @primary_keys ||= {}
- @primary_keys[table] ||= conn.primary_key(table)
- end
-
- RE_CURRVAL_ERROR = /currval of sequence "(.*)" is not yet defined in this session/.freeze
-
- def insert_result(conn, table, values)
- begin
- result = conn.last_insert_id(table)
- return result if result
- rescue PGError => e
- # An error could occur if the inserted values include a primary key
- # value, while the primary key is serial.
- if e.message =~ RE_CURRVAL_ERROR
- raise Error, "Could not return primary key value for the inserted record. Are you specifying a primary key value for a serial primary key?"
- else
- raise e
- end
- end
-
- case values
- when Hash
- values[primary_key_for_table(conn, table)]
- when Array
- values.first
- else
- nil
- end
- end
-
- def execute_insert(sql, table, values)
- @logger.info(sql) if @logger
- @pool.hold do |conn|
- conn.execute(sql).clear
- insert_result(conn, table, values)
- end
- rescue => e
- @logger.error(e.message) if @logger
- raise e
- end
-
- def synchronize(&block)
- @pool.hold(&block)
- end
-
- SQL_BEGIN = 'BEGIN'.freeze
- SQL_COMMIT = 'COMMIT'.freeze
- SQL_ROLLBACK = 'ROLLBACK'.freeze
-
- def transaction
- @pool.hold do |conn|
- if conn.transaction_in_progress
- yield conn
- else
- @logger.info(SQL_BEGIN) if @logger
- conn.async_exec(SQL_BEGIN)
- begin
- conn.transaction_in_progress = true
- result = yield
- begin
- @logger.info(SQL_COMMIT) if @logger
- conn.async_exec(SQL_COMMIT)
- rescue => e
- @logger.error(e.message) if @logger
- raise e
- end
- result
- rescue => e
- @logger.info(SQL_ROLLBACK) if @logger
- conn.async_exec(SQL_ROLLBACK) rescue nil
- raise e unless Error::Rollback === e
- ensure
- conn.transaction_in_progress = nil
- end
- end
- end
- end
-
- def serial_primary_key_options
- {:primary_key => true, :type => :serial}
- end
-
- def drop_table_sql(name)
- "DROP TABLE #{name} CASCADE"
- end
- end
-
- class Dataset < Sequel::Dataset
- def literal(v)
- case v
- when LiteralString
- v
- when String, Fixnum, Float, TrueClass, FalseClass
- PGconn.quote(v)
- else
- super
- end
- end
-
- def match_expr(l, r)
- case r
- when Regexp
- r.casefold? ? \
- "(#{literal(l)} ~* #{literal(r.source)})" :
- "(#{literal(l)} ~ #{literal(r.source)})"
- else
- super
- end
- end
-
- FOR_UPDATE = ' FOR UPDATE'.freeze
- FOR_SHARE = ' FOR SHARE'.freeze
-
- def select_sql(opts = nil)
- row_lock_mode = opts ? opts[:lock] : @opts[:lock]
- sql = super
- case row_lock_mode
- when :update
- sql << FOR_UPDATE
- when :share
- sql << FOR_SHARE
- end
- sql
- end
-
- def for_update
- clone_merge(:lock => :update)
- end
-
- def for_share
- clone_merge(:lock => :share)
- end
-
- EXPLAIN = 'EXPLAIN '.freeze
- EXPLAIN_ANALYZE = 'EXPLAIN ANALYZE '.freeze
- QUERY_PLAN = 'QUERY PLAN'.to_sym
-
- def explain(opts = nil)
- analysis = []
- fetch_rows(EXPLAIN + select_sql(opts)) do |r|
- analysis << r[QUERY_PLAN]
- end
- analysis.join("\r\n")
- end
-
- def analyze(opts = nil)
- analysis = []
- fetch_rows(EXPLAIN_ANALYZE + select_sql(opts)) do |r|
- analysis << r[QUERY_PLAN]
- end
- analysis.join("\r\n")
- end
-
- LOCK = 'LOCK TABLE %s IN %s MODE'.freeze
-
- ACCESS_SHARE = 'ACCESS SHARE'.freeze
- ROW_SHARE = 'ROW SHARE'.freeze
- ROW_EXCLUSIVE = 'ROW EXCLUSIVE'.freeze
- SHARE_UPDATE_EXCLUSIVE = 'SHARE UPDATE EXCLUSIVE'.freeze
- SHARE = 'SHARE'.freeze
- SHARE_ROW_EXCLUSIVE = 'SHARE ROW EXCLUSIVE'.freeze
- EXCLUSIVE = 'EXCLUSIVE'.freeze
- ACCESS_EXCLUSIVE = 'ACCESS EXCLUSIVE'.freeze
-
- # Locks the table with the specified mode.
- def lock(mode, &block)
- sql = LOCK % [@opts[:from], mode]
- @db.synchronize do
- if block # perform locking inside a transaction and yield to block
- @db.transaction {@db.execute_and_forget(sql); yield}
- else
- @db.execute_and_forget(sql) # lock without a transaction
- self
- end
- end
- end
-
- def insert(*values)
- @db.execute_insert(insert_sql(*values), @opts[:from],
- values.size == 1 ? values.first : values)
- end
-
- def update(*args, &block)
- @db.synchronize do
- result = @db.execute(update_sql(*args, &block))
- begin
- affected = result.cmdtuples
- ensure
- result.clear
- end
- affected
- end
- end
-
- def delete(opts = nil)
- @db.synchronize do
- result = @db.execute(delete_sql(opts))
- begin
- affected = result.cmdtuples
- ensure
- result.clear
- end
- affected
- end
- end
-
- def fetch_rows(sql, &block)
- @db.synchronize do
- result = @db.execute(sql)
- begin
- conv = row_converter(result)
- result.each {|r| yield conv[r]}
- ensure
- result.clear
- end
- end
- end
-
- @@converters_mutex = Mutex.new
- @@converters = {}
-
- def row_converter(result)
- @columns = []; translators = []
- result.fields.each_with_index do |f, idx|
- @columns << f.to_sym
- translators << PG_TYPES[result.type(idx)]
- end
-
- # create result signature and memoize the converter
- sig = [@columns, translators].hash
- @@converters_mutex.synchronize do
- @@converters[sig] ||= compile_converter(@columns, translators)
- end
- end
-
- def compile_converter(columns, translators)
- used_columns = []
- kvs = []
- columns.each_with_index do |column, idx|
- next if used_columns.include?(column)
- used_columns << column
-
- if !AUTO_TRANSLATE and translator = translators[idx]
- kvs << ":\"#{column}\" => ((t = r[#{idx}]) ? t.#{translator} : nil)"
- else
- kvs << ":\"#{column}\" => r[#{idx}]"
- end
- end
- eval("lambda {|r| {#{kvs.join(COMMA_SEPARATOR)}}}")
- end
-
- def array_tuples_fetch_rows(sql, &block)
- @db.synchronize do
- result = @db.execute(sql)
- begin
- conv = array_tuples_row_converter(result)
- result.each {|r| yield conv[r]}
- ensure
- result.clear
- end
- end
- end
-
- @@array_tuples_converters_mutex = Mutex.new
- @@array_tuples_converters = {}
-
- def array_tuples_row_converter(result)
- @columns = []; translators = []
- result.fields.each_with_index do |f, idx|
- @columns << f.to_sym
- translators << PG_TYPES[result.type(idx)]
- end
-
- # create result signature and memoize the converter
- sig = [@columns, translators].hash
- @@array_tuples_converters_mutex.synchronize do
- @@array_tuples_converters[sig] ||= array_tuples_compile_converter(@columns, translators)
- end
- end
-
- def array_tuples_compile_converter(columns, translators)
- tr = []
- columns.each_with_index do |column, idx|
- if !AUTO_TRANSLATE and t = translators[idx]
- tr << "if (v = r[#{idx}]); r[#{idx}] = v.#{t}; end"
- end
- end
- eval("lambda {|r| r.keys = columns; #{tr.join(';')}; r}")
- end
- end
- end
-end
192 lib/sequel/adapters/sqlite.rb
View
@@ -1,192 +0,0 @@
-require 'sqlite3'
-
-module Sequel
- module SQLite
- class Database < Sequel::Database
- set_adapter_scheme :sqlite
-
- def serial_primary_key_options
- {:primary_key => true, :type => :integer, :auto_increment => true}
- end
-
- def connect
- if @opts[:database].nil? || @opts[:database].empty?
- @opts[:database] = ':memory:'
- end
- db = ::SQLite3::Database.new(@opts[:database])
- db.type_translation = true
- # fix for timestamp translation
- db.translator.add_translator("timestamp") do |t, v|
- v =~ /^\d+$/ ? Time.at(v.to_i) : Time.parse(v)
- end
- db
- end
-
- def disconnect
- @pool.disconnect {|c| c.close}
- end
-
- def dataset(opts = nil)
- SQLite::Dataset.new(self, opts)
- end
-
- TABLES_FILTER = "type = 'table' AND NOT name = 'sqlite_sequence'"
-
- def tables
- self[:sqlite_master].filter(TABLES_FILTER).map {|r| r[:name].to_sym}
- end
-
- def execute(sql)
- @logger.info(sql) if @logger
- @pool.hold {|conn| conn.execute_batch(sql); conn.changes}
- end
-
- def execute_insert(sql)
- @logger.info(sql) if @logger
- @pool.hold {|conn| conn.execute(sql); conn.last_insert_row_id}
- end
-
- def single_value(sql)
- @logger.info(sql) if @logger
- @pool.hold {|conn| conn.get_first_value(sql)}
- end
-
- def execute_select(sql, &block)
- @logger.info(sql) if @logger
- @pool.hold {|conn| conn.query(sql, &block)}
- end
-
- def pragma_get(name)
- single_value("PRAGMA #{name}")
- end
-
- def pragma_set(name, value)
- execute("PRAGMA #{name} = #{value}")
- end
-
- AUTO_VACUUM = {'0' => :none, '1' => :full, '2' => :incremental}.freeze
-
- def auto_vacuum
- AUTO_VACUUM[pragma_get(:auto_vacuum)]
- end
-
- def auto_vacuum=(value)
- value = AUTO_VACUUM.index(value) || (raise Error, "Invalid value for auto_vacuum option. Please specify one of :none, :full, :incremental.")
- pragma_set(:auto_vacuum, value)
- end
-
- SYNCHRONOUS = {'0' => :off, '1' => :normal, '2' => :full}.freeze
-
- def synchronous
- SYNCHRONOUS[pragma_get(:synchronous)]
- end
-
- def synchronous=(value)
- value = SYNCHRONOUS.index(value) || (raise Error, "Invalid value for synchronous option. Please specify one of :off, :normal, :full.")
- pragma_set(:synchronous, value)
- end
-
- TEMP_STORE = {'0' => :default, '1' => :file, '2' => :memory}.freeze
-
- def temp_store
- TEMP_STORE[pragma_get(:temp_store)]
- end
-
- def temp_store=(value)
- value = TEMP_STORE.index(value) || (raise Error, "Invalid value for temp_store option. Please specify one of :default, :file, :memory.")
- pragma_set(:temp_store, value)
- end
-
- def alter_table_sql(table, op)
- case op[:op]
- when :add_column
- "ALTER TABLE #{table} ADD #{column_definition_sql(op)}"
- else
- raise Error, "Unsupported ALTER TABLE operation"
- end
- end
-
- def transaction(&block)
- @pool.hold do |conn|
- if conn.transaction_active?
- return yield(conn)
- end
- begin
- result = nil
- conn.transaction {result = yield(conn)}
- result
- rescue => e
- raise e unless Error::Rollback === e
- end
- end
- end
- end
-
- class Dataset < Sequel::Dataset
- def literal(v)
- case v
- when Time
- literal(v.iso8601)
- else
- super
- end
- end
-
- def insert_sql(*values)
- if (values.size == 1) && values.first.is_a?(Sequel::Dataset)
- "INSERT INTO #{@opts[:from]} #{values.first.sql};"
- else
- super(*values)
- end
- end
-
- def fetch_rows(sql, &block)
- @db.execute_select(sql) do |result|
- @columns = result.columns.map {|c| c.to_sym}
- column_count = @columns.size
- result.each do |values|
- row = {}
- column_count.times {|i| row[@columns[i]] = values[i]}
- block.call(row)
- end
- end
- end
-
- def array_tuples_fetch_rows(sql, &block)
- @db.execute_select(sql) do |result|
- @columns = result.columns.map {|c| c.to_sym}
- result.each {|r| r.keys = @columns; block[r]}
- end
- end
-
- def insert(*values)
- @db.execute_insert insert_sql(*values)
- end
-
- def update(*args, &block)
- @db.execute update_sql(*args, &block)
- end
-
- def delete(opts = nil)
- # check if no filter is specified
- unless (opts && opts[:where]) || @opts[:where]
- @db.transaction do
- unfiltered_count = count
- @db.execute delete_sql(opts)
- unfiltered_count
- end
- else
- @db.execute delete_sql(opts)
- end
- end
-
- EXPLAIN = 'EXPLAIN %s'.freeze
-
- def explain
- res = []
- @db.result_set(EXPLAIN % select_sql(opts), nil) {|r| res << r}
- res
- end
- end
- end
-end
6 lib/sequel/ado.rb
View
@@ -1,6 +0,0 @@
-warn "Requiring 'sequel/ado' is deprecated. Please modify your code to only require 'sequel' instead."
-
-if !Object.const_defined?('Sequel')
- require File.join(File.dirname(__FILE__), '../sequel')
-end
-require File.join(File.dirname(__FILE__), 'adapters/ado')
296 lib/sequel/array_keys.rb
View
@@ -1,296 +0,0 @@
-# ArrayKeys provide support for accessing array elements by keys. ArrayKeys are
-# based on the arrayfields gem by Ara Howard, and can be used as substitutes
-# for fetching records tuples as Ruby hashes.
-#
-# The main advantage offered by ArrayKeys over hashes is that the values are
-# always ordered according to the column order in the query. Another purported
-# advantage is that they reduce the memory footprint, but this has turned out
-# to be a false claim.
-module ArrayKeys
- # The KeySet module contains methods that extend an array of keys to return
- # a key's position in the key set.
- module KeySet
- # Returns the key's position in the key set. Provides indifferent access
- # for symbols and strings.
- def key_pos(key)
- @key_indexes ||= inject({}) {|h, k| h[k.to_sym] = h.size; h}
- @key_indexes[key] || @key_indexes[key.to_sym] || @key_indexes[key.to_s]
- end
-
- # Adds a key to the key set.
- def add_key(key)
- self << key
- @key_indexes[key] = @key_indexes.size
- end
-
- # Removes a key from the key set by its index.
- def del_key(idx)
- delete_at(idx)
- @key_indexes = nil # reset key indexes
- end
- end
-
- # The KeyAccess provides a large part of the Hash API for arrays with keys.
- module KeyAccess
- # Returns a value referenced by an array index or a key.
- def [](idx, *args)
- if String === idx or Symbol === idx
- (idx = @keys.key_pos(idx)) ? super(idx, *args) : nil
- else
- super
- end
- end
-
- # Sets the value referenced by an array index or a key.
- def []=(idx,*args)
- if String === idx or Symbol === idx
- idx = @keys.key_pos(idx) || @keys.add_key(idx.to_sym)
- end
- super(idx, *args)
- end
-
- # Stores a value by index or key.
- def store(k, v); self[k] = v; end
-
- # Slices the array, and returns an array with its keys sliced accordingly.
- def slice(*args)
- s = super(*args)
- s.keys = @keys.slice(*args)
- s
- end
-
- # Converts the array into a hash.
- def to_hash
- h = {}
- each_with_index {|v, i| h[@keys[i].to_sym] = v}
- h
- end
- alias_method :to_h, :to_hash
-
- # Iterates over each key-value pair in the array.
- def each_pair
- each_with_index {|v, i| yield @keys[i], v}
- end
-
- # Iterates over the array's associated keys.
- def each_key(&block)
- @keys.each(&block)
- end
-
- # Iterates over the array's values.
- def each_value(&block)
- each(&block)
- end
-
- # Deletes a value by its key.
- def delete(key, *args)
- if (idx = @keys.key_pos(key))
- delete_at(idx)
- end
- end