SQLiteUtils.mod 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. IMPLEMENTATION MODULE SQLiteUtils ;
  2. FROM SYSTEM IMPORT ADDRESS, ADR;
  3. FROM SQLite IMPORT DbHandle, StmtHandle, ContextHandle, ValueHandle,
  4. BackupHandle,
  5. SQLiteOk, SQLiteDone, SQLiteBusy, SQLiteLocked,
  6. sqlite3_libversion, sqlite3_errmsg, sqlite3_errstr,
  7. sqlite3_open, sqlite3_close, sqlite3_errcode,
  8. sqlite3_exec, sqlite3_free,
  9. sqlite3_bind_text, sqlite3_bind_blob,
  10. sqlite3_value_text, sqlite3_result_text,
  11. sqlite3_backup_init, sqlite3_backup_step, sqlite3_backup_finish;
  12. FROM libc IMPORT strlen, strncpy;
  13. PROCEDURE CStrToM2 (src: ADDRESS; VAR dst: ARRAY OF CHAR);
  14. VAR n: CARDINAL;
  15. BEGIN
  16. IF HIGH(dst) < 0 THEN RETURN END;
  17. IF src = NIL THEN dst[0] := 0C; RETURN END;
  18. n := VAL(CARDINAL, strlen(src));
  19. IF n > HIGH(dst) THEN n := HIGH(dst) END;
  20. strncpy(ADR(dst), src, n);
  21. IF n <= HIGH(dst) THEN dst[n] := 0C END
  22. END CStrToM2;
  23. PROCEDURE ErrMsg (db: DbHandle; VAR buf: ARRAY OF CHAR);
  24. BEGIN
  25. CStrToM2(sqlite3_errmsg(db), buf)
  26. END ErrMsg;
  27. PROCEDURE ErrStr (code: INTEGER; VAR buf: ARRAY OF CHAR);
  28. BEGIN
  29. CStrToM2(sqlite3_errstr(code), buf)
  30. END ErrStr;
  31. PROCEDURE LibVersionStr (VAR buf: ARRAY OF CHAR);
  32. BEGIN
  33. CStrToM2(sqlite3_libversion(), buf)
  34. END LibVersionStr;
  35. PROCEDURE StaticDestr () : ADDRESS;
  36. BEGIN
  37. RETURN VAL(ADDRESS, 0)
  38. END StaticDestr;
  39. PROCEDURE TransientDestr () : ADDRESS;
  40. BEGIN
  41. RETURN VAL(ADDRESS, -1)
  42. END TransientDestr;
  43. PROCEDURE BindTextCopy (stmt: StmtHandle; idx: INTEGER;
  44. v: ARRAY OF CHAR) : INTEGER;
  45. BEGIN
  46. RETURN sqlite3_bind_text(stmt, idx, v, -1, TransientDestr())
  47. END BindTextCopy;
  48. PROCEDURE BindBlobCopy (stmt: StmtHandle; idx: INTEGER;
  49. data: ADDRESS; n: INTEGER) : INTEGER;
  50. BEGIN
  51. RETURN sqlite3_bind_blob(stmt, idx, data, n, TransientDestr())
  52. END BindBlobCopy;
  53. PROCEDURE ValueText (v: ValueHandle; VAR buf: ARRAY OF CHAR);
  54. BEGIN
  55. CStrToM2(sqlite3_value_text(v), buf)
  56. END ValueText;
  57. PROCEDURE ResultTextCopy (ctx: ContextHandle; str: ARRAY OF CHAR);
  58. BEGIN
  59. sqlite3_result_text(ctx, str, -1, TransientDestr())
  60. END ResultTextCopy;
  61. PROCEDURE BackupToFile (srcDb: DbHandle;
  62. filename: ARRAY OF CHAR) : INTEGER;
  63. VAR dst: DbHandle; bk: BackupHandle; rc, rc2, tries: INTEGER;
  64. BEGIN
  65. rc := sqlite3_open(filename, dst);
  66. IF rc # SQLiteOk THEN RETURN rc END;
  67. bk := sqlite3_backup_init(dst, "main", srcDb, "main");
  68. IF bk = NIL THEN
  69. rc := sqlite3_errcode(dst);
  70. rc2 := sqlite3_close(dst);
  71. RETURN rc
  72. END;
  73. tries := 0;
  74. LOOP
  75. rc := sqlite3_backup_step(bk, 50);
  76. IF (rc # SQLiteOk) AND (rc # SQLiteBusy)
  77. AND (rc # SQLiteLocked) THEN EXIT END;
  78. INC(tries);
  79. IF tries > 100000 THEN rc := SQLiteBusy; EXIT END
  80. END;
  81. IF rc = SQLiteDone THEN rc := SQLiteOk END;
  82. rc2 := sqlite3_backup_finish(bk);
  83. IF rc = SQLiteOk THEN rc := rc2 END;
  84. rc2 := sqlite3_close(dst);
  85. RETURN rc
  86. END BackupToFile;
  87. PROCEDURE ExecSimple (db: DbHandle; sql: ARRAY OF CHAR) : INTEGER;
  88. BEGIN
  89. RETURN sqlite3_exec(db, sql, NIL, NIL, NIL)
  90. END ExecSimple;
  91. PROCEDURE ExecWithErr (db: DbHandle; sql: ARRAY OF CHAR;
  92. VAR buf: ARRAY OF CHAR) : INTEGER;
  93. VAR rc: INTEGER; msg: ADDRESS;
  94. BEGIN
  95. msg := NIL;
  96. rc := sqlite3_exec(db, sql, NIL, NIL, ADR(msg));
  97. IF msg # NIL THEN
  98. CStrToM2(msg, buf);
  99. sqlite3_free(msg)
  100. ELSIF HIGH(buf) >= 0 THEN
  101. buf[0] := 0C
  102. END;
  103. RETURN rc
  104. END ExecWithErr;
  105. END SQLiteUtils.