Class: Gemite::SQLite3FFI::Handle

Inherits:
Object
  • Object
show all
Defined in:
lib/gemite/sqlite3_ffi.rb

Overview

sqlite3* ハンドルと、その上での操作をまとめる薄いラッパー。

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Handle

Returns a new instance of Handle.



85
86
87
88
89
90
91
92
# File 'lib/gemite/sqlite3_ffi.rb', line 85

def initialize(path)
  SQLite3FFI.ensure_loaded!
  @path = path
  ptr = Fiddle::Pointer.malloc(Fiddle::SIZEOF_VOIDP)
  rc = Lib.sqlite3_open(path, ptr)
  @db = ptr.ptr
  raise Gemite::RuntimeError, "データベース '#{path}' を開けませんでした" unless rc == SQLITE_OK
end

Instance Method Details

#closeObject



151
152
153
154
# File 'lib/gemite/sqlite3_ffi.rb', line 151

def close
  Lib.sqlite3_close(@db) if @db
  @db = nil
end

#exec(sql) ⇒ Object

生のSQLを実行する(SELECT以外、あるいは戻り値を使わない用途)。 ";" 区切りの複数文にも対応する。



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/gemite/sqlite3_ffi.rb', line 96

def exec(sql)
  remaining = sql
  loop do
    remaining = remaining.to_s
    break if remaining.strip.empty?

    stmt, tail = prepare_raw(remaining)
    unless stmt
      # このSQL断片に実行可能な文が含まれていなかった(空白・コメントのみ等)
      break
    end
    step_all(stmt)
    Lib.sqlite3_finalize(stmt)
    remaining = tail
  end
  nil
end

#execute(sql, params = []) ⇒ Object

INSERT/UPDATE/DELETE等、戻り値の行を必要としない文を実行する。 changes: を返す。



137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/gemite/sqlite3_ffi.rb', line 137

def execute(sql, params = [])
  stmt, = prepare_raw(sql)
  raise Gemite::RuntimeError, "SQL準備に失敗しました: #{last_error}" unless stmt

  bind_params(stmt, params)
  rc = Lib.sqlite3_step(stmt)
  Lib.sqlite3_finalize(stmt)
  unless rc == SQLITE_DONE
    raise Gemite::RuntimeError, "SQL実行に失敗しました: #{last_error}"
  end

  { rowid: Lib.sqlite3_last_insert_rowid(@db), changes: Lib.sqlite3_changes(@db) }
end

#query(sql, params = []) ⇒ Object

SELECT文を実行し、行の配列(各行は列名Symbol => 値 のHash)を返す。



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/gemite/sqlite3_ffi.rb', line 115

def query(sql, params = [])
  stmt, = prepare_raw(sql)
  raise Gemite::RuntimeError, "SQL準備に失敗しました: #{last_error}" unless stmt

  bind_params(stmt, params)
  rows = []
  col_count = Lib.sqlite3_column_count(stmt)
  col_names = Array.new(col_count) { |i| Lib.sqlite3_column_name(stmt, i).to_s.to_sym }

  while Lib.sqlite3_step(stmt) == SQLITE_ROW
    row = {}
    col_count.times do |i|
      row[col_names[i]] = read_column(stmt, i)
    end
    rows << row
  end
  Lib.sqlite3_finalize(stmt)
  rows
end