diff options
Diffstat (limited to 'sqlite.cr')
-rw-r--r-- | sqlite.cr | 150 |
1 files changed, 0 insertions, 150 deletions
diff --git a/sqlite.cr b/sqlite.cr deleted file mode 100644 index 5dfbe4d..0000000 --- a/sqlite.cr +++ /dev/null @@ -1,150 +0,0 @@ -# SQLite3 wrapper -# Copyright (C) 2023 Nguyễn Gia Phong -# -# This file if part of hybring. -# -# Hybring is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Hybring is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with hybring. If not, see <https://www.gnu.org/licenses/>. - -@[Link("sqlite3")] -lib SQLite - OK = 0 - ROW = 100 - DONE = 101 - - type Database = Void* - type Statement = Void* - - fun errstr = sqlite3_errstr(rc : LibC::Int) : LibC::Char* - fun mprintf = sqlite3_mprintf(format : LibC::Char*, ...) : LibC::Char* - fun free = sqlite3_free(format : Void*, ...) - - fun open = sqlite3_open(filename : LibC::Char*, db : Database*) : LibC::Int - fun prepare = sqlite3_prepare(db : Database, query : LibC::Char*, - length : LibC::Int, stmt : Statement*, - query_tail : LibC::Char**) : LibC::Int - fun step = sqlite3_step(stmt : Statement) : Int32 - fun column_text = sqlite3_column_text(stmt : Statement, - col : LibC::Int) : LibC::Char* - fun column_int = sqlite3_column_int(stmt : Statement, - col : LibC::Int) : LibC::Int - fun finalize = sqlite3_finalize(stmt : Statement) : LibC::Int - fun close = sqlite3_close(db : Database) : LibC::Int -end - -class Database - MIGRATIONS = [""] # migration #0 is reserved for schema initialization - SCHEMA = "CREATE TABLE member ( - id INTEGER PRIMARY KEY, - nick TEXT NOT NULL UNIQUE, - opennic TEXT NOT NULL UNIQUE, - icann TEXT NOT NULL UNIQUE)" - INSERT_MEMBER = "INSERT INTO member (nick, opennic, icann) - VALUES (%Q, %Q, %Q)" - - class Statement - def initialize(db, query) - bytes = query.to_slice - Database.check SQLite.prepare db, bytes, bytes.size, - out @ref, out @tail - end - - def step : LibC::Int - SQLite.step @ref - end - - def row - Row.new @ref - end - - def finalize - Database.check SQLite.finalize @ref - end - end - - class Column - def initialize(stmt : SQLite::Statement, i : LibC::Int) - @stmt = stmt - @i = i - end - - def int - SQLite.column_int @stmt, @i - end - - def text - String.new SQLite.column_text @stmt, @i - end - end - - class Row - def initialize(stmt : SQLite::Statement) - @stmt = stmt - end - - def [](i : LibC::Int) - Column.new @stmt, i - end - end - - def initialize(path : String, opennic, icann) - Database.check SQLite.open path, out @ref - self.exec "PRAGMA user_version" do |row| - version = row[0].int - raise "negative schema version" if version < 0 - raise "schema version newer than supported" if version > MIGRATIONS.size - if version == 0 - self.exec SCHEMA do end - self.exec "PRAGMA user_version = #{MIGRATIONS.size}" do end - # Avoid out-of-bound when looking for neighbors. - self.exec INSERT_MEMBER, "self", opennic, icann do end - end - rescue ex - self.finalize - raise ex - end - end - - def exec(query : String, *values) - sql = SQLite.mprintf query, *values - stmt = Statement.new @ref, String.new sql - SQLite.free sql - loop do - rc = stmt.step - case rc - when SQLite::ROW - yield stmt.row - when SQLite::DONE - break - else - Database.check rc - end - end - end - - def members - result = [] of Tuple(String, String, String) - self.exec "SELECT nick, opennic, icann FROM member" do |row| - result << {row[0].text, row[1].text, row[2].text} - end - result - end - - def finalize - Database.check SQLite.close @ref - end -end - -def Database.check(rc : LibC::Int) - raise String.new SQLite.errstr rc if rc != SQLite::OK -end |