diff --git a/Source/Impl/sqlite.adb b/Source/Impl/sqlite.adb index d194e66..80c5e5d 100644 --- a/Source/Impl/sqlite.adb +++ b/Source/Impl/sqlite.adb @@ -1,4 +1,6 @@ +with System; with Ada.Text_IO; use Ada.Text_IO; +with Ada.Exceptions; use Ada.Exceptions; with Interfaces.C; use Interfaces.C; with Interfaces.C.Strings; use Interfaces.C.Strings; @@ -7,25 +9,75 @@ with Ada.Unchecked_Conversion; package body Sqlite is - procedure Finalize (Db : in out Database) is + procedure Close (Stmt : in out Statement) is - function sqlite3_close (Db : in out Database_Int) return Int + function sqlite3_finalize (Stmt : not null Statement_Int) return Error_Codes with Import, Convention => C; - function sqlite3_close_v2 (Db : in out Database_Int) return Int - with Import, Convention => C; - - Error : int := 0; + Error : Error_Codes := sqlite3_finalize (Stmt.Internal); begin - if Db.Version = v1 then - Error := sqlite3_close (Db.Internal); - else - Error := sqlite3_close_v2 (Db.Internal); + Stmt.Internal := null; + + end Close; + + function Step (Stmt : in out Statement) return Statement_Status + is + + function sqlite3_step (Stmt : not null Statement_Int) return Error_Codes + with Import, Convention => C; + + begin + + if Stmt.Internal = null then + raise Allocation_Error with "Statement already finalized"; end if; - end Finalize; + case sqlite3_step(Stmt.Internal) is + when 5 => + return Busy; + when 100 => + return Row; + when 101 => + return Done; + when others => + raise Program_Error; + end case; + + end Step; + + function Column (Stmt : in out Statement; Col : Int) return Int + is + + function sqlite3_column_int ( + Stmt : not null Statement_Int; + iCol : Int) return Int + with Import, Convention => C; + + begin + + return sqlite3_column_int(Stmt.Internal, Col); + + end Column; + + function Column (Stmt : in out Statement; Col : Int) return String + is + + function sqlite3_column_text ( + Stmt : not null Statement_Int; + iCol : Int) return Chars_Ptr + with Import, Convention => C; + + Data : Chars_Ptr; + + begin + + Data := sqlite3_column_text(Stmt.Internal, Col); + + return Value(Data); + + end Column; procedure Open (Db : in out Database; Filename : String) is @@ -101,8 +153,6 @@ package body Sqlite is Flags.Open_PrivateCache := True; end case; - Put_Line (Convert (Flags)'Image); - Error := sqlite3_open_v2 ( New_String (Filename), Db.Internal, @@ -112,9 +162,67 @@ package body Sqlite is Db.Version := v2; end Open; - procedure Close (Db : in out Database) is + function Prepare ( + Db : in out Database'Class; + SQL_Statement : String ) return Statement + is + + function sqlite3_prepare_v2 ( + Db : Database_Int; + zSql : Chars_Ptr; + nByte : Int; + ppStmt : out Statement_Int; + pzTail : System.Address ) return Int + with Import, Convention => C; + + Error : Int; + Stmt_Int : Statement_Int; + Stmt : Statement; + begin - Db.Finalize; + + Error := sqlite3_prepare_v2 ( + Db.Internal, + New_String (SQL_Statement), + Int (SQL_Statement'Length), + Stmt_Int, + System.Null_Address); + + if Stmt_Int = null then + Put_Line("Statement is null"); + end if; + + if Error = 0 then + Put_Line("Statement is prepared"); + else + Put_Line("Error " & Error'Image); + end if; + + Stmt.Internal := Stmt_Int; + + return Stmt; + + end Prepare; + + procedure Close (Db : in out Database) is + + function sqlite3_close (Db : not null Database_Int) return Int + with Import, Convention => C; + + function sqlite3_close_v2 (Db : not null Database_Int) return Int + with Import, Convention => C; + + Error : Int; + + begin + + if Db.Version = v1 then + Error := sqlite3_close (Db.Internal); + else + Error := sqlite3_close_v2 (Db.Internal); + end if; + + Db.Internal := null; end Close; end Sqlite;