| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- MODULE SQLiteBlobErrors;
- (* BLOB error paths:
- read-only writes, bounds, invalid opens and expired handles. *)
- FROM SYSTEM IMPORT ADDRESS, ADR;
- FROM SQLite IMPORT
- SQLiteOk, SQLiteError, SQLiteReadOnly, SQLiteAbort,
- SQLiteBlobReadOnly, SQLiteBlobReadWrite,
- SQLiteOpenReadWrite, SQLiteOpenCreate, SQLiteOpenMemory,
- sqlite3_open_v2, sqlite3_exec, sqlite3_close_v2,
- sqlite3_blob_open, sqlite3_blob_close, sqlite3_blob_read,
- sqlite3_blob_write, sqlite3_free;
- VAR
- ExitCode : INTEGER;
- db, blob : ADDRESS;
- rc : INTEGER;
- ok : BOOLEAN;
- buf : ARRAY [0..7] OF CHAR;
- PROCEDURE ExecSQL (sql : ARRAY OF CHAR) : BOOLEAN;
- VAR
- errmsg : ADDRESS;
- good : BOOLEAN;
- BEGIN
- errmsg := NIL;
- good := sqlite3_exec(db, sql, NIL, NIL, errmsg) = SQLiteOk;
- IF errmsg # NIL THEN
- sqlite3_free(errmsg)
- END;
- RETURN good
- END ExecSQL;
- PROCEDURE CloseBlob (VAR b : ADDRESS; want : INTEGER) : BOOLEAN;
- VAR
- got : INTEGER;
- BEGIN
- IF b = NIL THEN RETURN FALSE END;
- got := sqlite3_blob_close(b);
- b := NIL;
- RETURN got = want
- END CloseBlob;
- BEGIN
- ExitCode := 1;
- db := NIL; blob := NIL; ok := FALSE;
- buf[0] := 'X'; buf[1] := 'Y';
- IF (sqlite3_open_v2(":memory:", db,
- SQLiteOpenReadWrite + SQLiteOpenCreate + SQLiteOpenMemory,
- NIL) = SQLiteOk) AND (db # NIL) THEN
- IF ExecSQL("CREATE TABLE b(id INTEGER PRIMARY KEY, data BLOB);")
- AND ExecSQL("INSERT INTO b(data) VALUES(zeroblob(4));")
- AND ExecSQL("INSERT INTO b(data) VALUES(zeroblob(4));") THEN
- ok := TRUE
- END
- END;
- (* Flags 0 = read-only; a write must fail and remain pending at close. *)
- IF ok THEN
- rc := sqlite3_blob_open(db, "main", "b", "data", 1,
- SQLiteBlobReadOnly, blob);
- ok := (rc = SQLiteOk) AND (blob # NIL)
- END;
- IF ok THEN
- ok := sqlite3_blob_write(blob, ADR(buf[0]), 1, 0) = SQLiteReadOnly
- END;
- IF NOT CloseBlob(blob, SQLiteReadOnly) THEN ok := FALSE END;
- (* Bounds checks on a read-write handle. *)
- IF ok THEN
- rc := sqlite3_blob_open(db, "main", "b", "data", 1,
- SQLiteBlobReadWrite, blob);
- ok := (rc = SQLiteOk) AND (blob # NIL)
- END;
- IF ok THEN
- ok := sqlite3_blob_read(blob, ADR(buf[0]), 2, 3) = SQLiteError
- END;
- IF ok THEN
- ok := sqlite3_blob_write(blob, ADR(buf[0]), 2, 3) = SQLiteError
- END;
- IF ok THEN
- ok := sqlite3_blob_read(blob, ADR(buf[0]), 1, -1) = SQLiteError
- END;
- IF ok THEN
- ok := sqlite3_blob_write(blob, ADR(buf[0]), 1, -1) = SQLiteError
- END;
- IF NOT CloseBlob(blob, SQLiteOk) THEN ok := FALSE END;
- (* Invalid row/table/column and a non-BLOB column. *)
- IF ok THEN
- rc := sqlite3_blob_open(db, "main", "b", "data", 99,
- SQLiteBlobReadOnly, blob);
- ok := (rc # SQLiteOk) AND (blob = NIL)
- END;
- IF ok THEN
- rc := sqlite3_blob_open(db, "main", "b", "nope", 1,
- SQLiteBlobReadOnly, blob);
- ok := (rc # SQLiteOk) AND (blob = NIL)
- END;
- IF ok THEN
- rc := sqlite3_blob_open(db, "main", "nope", "data", 1,
- SQLiteBlobReadOnly, blob);
- ok := (rc # SQLiteOk) AND (blob = NIL)
- END;
- IF ok THEN
- rc := sqlite3_blob_open(db, "main", "b", "id", 1,
- SQLiteBlobReadOnly, blob);
- ok := (rc # SQLiteOk) AND (blob = NIL)
- END;
- (* An UPDATE expires an open BLOB handle. *)
- IF ok THEN
- rc := sqlite3_blob_open(db, "main", "b", "data", 2,
- SQLiteBlobReadWrite, blob);
- ok := (rc = SQLiteOk) AND (blob # NIL)
- END;
- IF ok THEN
- ok := sqlite3_blob_read(blob, ADR(buf[0]), 1, 0) = SQLiteOk
- END;
- IF ok THEN
- ok := ExecSQL("UPDATE b SET data = zeroblob(4) WHERE id = 2;")
- END;
- IF ok THEN
- ok := sqlite3_blob_read(blob, ADR(buf[0]), 1, 0) = SQLiteAbort
- END;
- IF NOT CloseBlob(blob, SQLiteOk) THEN ok := FALSE END;
- IF db # NIL THEN
- IF sqlite3_close_v2(db) # SQLiteOk THEN ok := FALSE END
- END;
- IF ok THEN ExitCode := 42 END
- END SQLiteBlobErrors.
|