Class: Abtab::Driver::DbiDriver

Inherits:
Abtab::Driver show all
Defined in:
lib/abtab/drivers/dbi_driver.rb

Constant Summary collapse

CREDENTIALS_RC_FILE =
"#{ENV['HOME']}/.abtab.dbrc"
DB_MODULES =
{
  'Pg'      => { :require => 'Pg', :name => 'Pg' },
  'pg'      => { :require => 'pg', :name => 'Pg' },
  # TODO: test these
  #'mysql'   => 'mysql',
  #'Mysql'   => 'mysql',
  #'sqlite'  => 'sqlite3',
  #'SQLite'  => 'sqlite3',
  #'sqlite3' => 'sqlite3',
  #'SQLite3' => 'sqlite3',
}

Instance Method Summary collapse

Methods inherited from Abtab::Driver

#import, #url_parse

Constructor Details

#initialize(url) ⇒ DbiDriver

Returns a new instance of DbiDriver.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/abtab/drivers/dbi_driver.rb', line 29

def initialize url
  @options = {
    :dbi_driver => nil,
    :host       => nil,
    :user       => nil,
    :pass       => nil,
    :database   => nil,
    :table      => nil,
  }

  @rc_defaults = {}
  if File.exist? CREDENTIALS_RC_FILE
    @rc_defaults.merge!(YAML.load_file(CREDENTIALS_RC_FILE))
  end

  @url = url
  schema, rest = url.split '://', 2

  # expect 'driver' name, eg: pg
  driver, host, database_name, table = rest.split '/', 4

  if driver =~ /@/
    user_pass, driver = driver.split '@', 2
    user, pass = nil, nil
    if user_pass =~ /:/
      user, pass = user_pass.split ':', 2
      @options[:user] = user
      @options[:pass] = pass
    end
    @options[:dbi_driver] = driver
  end

  @options[:dbi_driver] = driver
  @options[:database]   = database_name
  @options[:host]       = host
  @options[:table]      = table

  @options[:user] ||= lookup_rc_default @options[:host], @options[:database], "user"
  @options[:pass] ||= lookup_rc_default @options[:host], @options[:database], "pass"

  #puts "OPTIONS: #{@options.inspect}"

  require DB_MODULES[@options[:dbi_driver]][:require]
  driver_name = DB_MODULES[@options[:dbi_driver]][:name]

  @conn = DBI.connect("DBI:#{driver_name}:database=#{@options[:database]};host=#{@options[:host]}",@options[:user],@options[:pass]);

end

Instance Method Details

#closeObject



128
129
130
131
# File 'lib/abtab/drivers/dbi_driver.rb', line 128

def close 
  close_statement_handle
  close_connection
end

#close_connectionObject



133
134
135
136
137
138
# File 'lib/abtab/drivers/dbi_driver.rb', line 133

def close_connection
  if @conn
    @conn.close if @conn.respond_to? :close
    @conn = nil
  end
end

#close_statement_handleObject



140
141
142
143
144
145
# File 'lib/abtab/drivers/dbi_driver.rb', line 140

def close_statement_handle
  if @statement_handle
    @statement_handle.finish
    @statement_handle = nil
  end
end

#columnsObject

def open_for_writing

  close_statement_handle
  @columns = get_col_names @options[:table]
  sql_stmt = sprintf("INSERT INTO #{@options[:table]} VALUES (%s)", get_col_names.map {'?'}.join(","))
  puts "sql_stmt: #{sql_stmt}"
  @statement_handle = @conn.prepare sql_stmt
end


98
99
100
# File 'lib/abtab/drivers/dbi_driver.rb', line 98

def columns
  @columns
end

#get_col_names(table) ⇒ Object



102
103
104
105
106
107
108
# File 'lib/abtab/drivers/dbi_driver.rb', line 102

def get_col_names table
  sth = @conn.prepare "SELECT * FROM #{table} where 1=0"
  sth.execute
  col_names = sth.column_names
  sth.finish
  col_names
end

#lookup_rc_default(*keys) ⇒ Object



19
20
21
22
23
24
25
26
27
# File 'lib/abtab/drivers/dbi_driver.rb', line 19

def lookup_rc_default *keys
  #puts "LOOKUP: #{keys.inspect}"
  m = @rc_defaults
  keys.each do |k|
    #puts "  k=#{k} m=#{m.inspect}"
    m = m[k] if m
  end
  m
end

#next_recordObject



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/abtab/drivers/dbi_driver.rb', line 110

def next_record
  return @statement_handle.fetch if @statement_handle
  if @rows && !@rows.empty?
    table = @rows.shift
    sth = @conn.prepare("SELECT COUNT('x') from #{table}")
    sth.execute
    count = sth.fetch_array.first
    sth.finish
    return [table,count]
  end
  return nil
end

#open_for_readingObject



78
79
80
81
82
83
84
85
86
87
# File 'lib/abtab/drivers/dbi_driver.rb', line 78

def open_for_reading
  if @options[:table]
    @columns = get_col_names @options[:table]
    @statement_handle = @conn.prepare "select * from #{@options[:table]}"
    @statement_handle.execute
  else
    @columns = ['NAME','ROWS']
    @rows = @conn.tables
  end
end

#rewindObject



123
124
125
126
# File 'lib/abtab/drivers/dbi_driver.rb', line 123

def rewind
  close_connection
  open_for_reading
end