MODULE SQLiteScalar; (* Scalar binding/result metadata: int, int64, double, text, NULL. *) FROM SYSTEM IMPORT ADDRESS; FROM CStr IMPORT CString, Copy; FROM SQLite IMPORT SQLiteOk, SQLiteRow, SQLiteDone, SQLiteInteger, SQLiteFloat, SQLiteText, SQLiteNull, sqlite3_open, sqlite3_exec, sqlite3_close, sqlite3_prepare_v2, sqlite3_bind_int, sqlite3_bind_int64, sqlite3_bind_double, sqlite3_bind_null, sqlite3_bind_text, sqlite3_step, sqlite3_reset, sqlite3_clear_bindings, sqlite3_column_count, sqlite3_data_count, sqlite3_column_type, sqlite3_column_bytes, sqlite3_column_int, sqlite3_column_int64, sqlite3_column_double, sqlite3_column_text, sqlite3_column_name, sqlite3_column_decltype, sqlite3_finalize, sqlite3_free, sqlite3_extended_result_codes, SQLiteTransient; VAR ExitCode : INTEGER; db : ADDRESS; PROCEDURE ExecSQL (sql : ARRAY OF CHAR) : BOOLEAN; VAR errmsg : ADDRESS; ok : BOOLEAN; BEGIN errmsg := NIL; ok := sqlite3_exec(db, sql, NIL, NIL, errmsg) = SQLiteOk; IF errmsg # NIL THEN sqlite3_free(errmsg) END; RETURN ok END ExecSQL; VAR stmt : ADDRESS; rc : INTEGER; ok : BOOLEAN; svalue : CString; name : ARRAY [0..63] OF CHAR; text : ARRAY [0..63] OF CHAR; decl : ARRAY [0..63] OF CHAR; BEGIN ExitCode := 1; db := NIL; stmt := NIL; ok := FALSE; IF (sqlite3_open(":memory:", db) = SQLiteOk) AND (db # NIL) THEN IF sqlite3_extended_result_codes(db, 1) = SQLiteOk THEN IF ExecSQL("CREATE TABLE t(i INTEGER, j INTEGER, r REAL, s TEXT, n TEXT);") THEN rc := sqlite3_prepare_v2(db, "INSERT INTO t VALUES (?, ?, ?, ?, ?);", -1, stmt, NIL); ok := (rc = SQLiteOk) AND (stmt # NIL); IF ok THEN ok := (sqlite3_bind_int(stmt, 1, 42) = SQLiteOk) AND (sqlite3_bind_int64(stmt, 2, 43) = SQLiteOk) AND (sqlite3_bind_double(stmt, 3, 3.5) = SQLiteOk) AND (sqlite3_bind_text(stmt, 4, "hello", -1, SQLiteTransient()) = SQLiteOk) AND (sqlite3_bind_null(stmt, 5) = SQLiteOk) END; IF ok THEN ok := sqlite3_step(stmt) = SQLiteDone END; IF stmt # NIL THEN IF sqlite3_reset(stmt) # SQLiteOk THEN ok := FALSE END; IF sqlite3_clear_bindings(stmt) # SQLiteOk THEN ok := FALSE END; IF sqlite3_finalize(stmt) # SQLiteOk THEN ok := FALSE END; stmt := NIL END END END END; IF ok THEN rc := sqlite3_prepare_v2(db, "SELECT i, j, r, s, n FROM t;", -1, stmt, NIL); ok := (rc = SQLiteOk) AND (stmt # NIL); IF ok THEN IF sqlite3_column_count(stmt) = 5 THEN rc := sqlite3_step(stmt); IF rc = SQLiteRow THEN ok := (sqlite3_data_count(stmt) = 5) AND (sqlite3_column_type(stmt, 0) = SQLiteInteger) AND (sqlite3_column_type(stmt, 1) = SQLiteInteger) AND (sqlite3_column_type(stmt, 2) = SQLiteFloat) AND (sqlite3_column_type(stmt, 3) = SQLiteText) AND (sqlite3_column_type(stmt, 4) = SQLiteNull) AND (sqlite3_column_int(stmt, 0) = 42) AND (sqlite3_column_int64(stmt, 1) = 43) AND (sqlite3_column_double(stmt, 2) = 3.5) AND (sqlite3_column_bytes(stmt, 3) = 5); svalue := sqlite3_column_text(stmt, 3); IF (svalue = NIL) OR (Copy(svalue, text) # 5) THEN ok := FALSE ELSIF (text[0] # 'h') OR (text[4] # 'o') THEN ok := FALSE END; svalue := sqlite3_column_name(stmt, 3); IF (svalue = NIL) OR (Copy(svalue, name) # 1) OR (name[0] # 's') THEN ok := FALSE END; svalue := sqlite3_column_decltype(stmt, 3); IF (svalue = NIL) OR (Copy(svalue, decl) # 4) OR (decl[0] # 'T') OR (decl[3] # 'T') THEN ok := FALSE END; IF sqlite3_step(stmt) # SQLiteDone THEN ok := FALSE END ELSE ok := FALSE END ELSE ok := FALSE END; IF stmt # NIL THEN IF sqlite3_finalize(stmt) # SQLiteOk THEN ok := FALSE END; stmt := NIL END END END; IF stmt # NIL THEN IF sqlite3_finalize(stmt) # SQLiteOk THEN ok := FALSE END END; IF db # NIL THEN IF sqlite3_close(db) # SQLiteOk THEN ok := FALSE END END; IF ok THEN ExitCode := 42 END END SQLiteScalar.