SQLite3 segmentation at prepare statement
Charles Hixson
charleshixsn at earthlink.net
Thu Sep 19 12:38:28 PDT 2013
You're right about the finalize, but changing the line to:
rc = sqlite3_prepare(db, toStringz(sql), cast(int)sql.length +
1000, &stmt, null);
results in the compile time error:
sqlitetest.d(39): Error: function etc.c.sqlite3.sqlite3_prepare
(sqlite3* db, const(char)* zSql, int nByte, sqlite3_stmt** ppStmt,
const(char*)* pzTail) is not callable using argument types (sqlite3*,
immutable(char)*, int, sqlite3_stmt***, typeof(null))
On 09/18/2013 09:29 PM, growler wrote:
> On Wednesday, 18 September 2013 at 21:31:00 UTC, Charles Hixson wrote:
>> I'm trying to use SQLite3 in D, but am getting a segmentation fault
>> when I attempt to replace the exec statement with a prepare
>> statement. What am I doing wrong?
>>
>> If the prepare statement is commented out, and the exec statement is
>> uncommented, the program runs successfully. (There's no data yet in
>> the database file.)
>>
>> The test program is:
>>
>> pragma (lib, "sqlite3");
>>
>>
>> import etc.c.sqlite3;
>> import std.exception;
>> import std.stdio;
>> import std.string;
>>
>> /** int function(void*, int, char**, char**) callback */
>> extern(C)
>> int callback (void* notUsed, int argc, char** argv, char**
>> azColName)
>> {
>> for (int i = 0; i < argc; i++)
>> { printf ("%s = %s\n", azColName[i], argv[i] ? argv[i] :
>> "null"); }
>> printf ("\n");
>> return 0;
>> }
>>
>> void main()
>> { sqlite3* db;
>> int rc;
>> char* zErrMsg = null;
>> sqlite3_stmt** stmt;
>>
>> rc = sqlite3_open (toStringz("data/sqlitetest.db"), &db);
>> if (SQLITE_OK != rc)
>> { printf ("DB create error: %s\n", sqlite3_errmsg(db) );
>> }
>>
>> string sql =
>> "create table if not exists wrds (name text primary key, id
>> int)\0";
>> rc = sqlite3_exec(db, sql.ptr, &callback, cast(void*)0,
>> &zErrMsg);
>> if (SQLITE_OK != rc)
>> { printf ("DB create table error: %s\n", sqlite3_errmsg(db) );
>> printf ("sql = <<%s>>\n", sql);
>> }
>>
>> sql = "select * from wrds\0";
>> rc = sqlite3_prepare(db, toStringz(sql),
>> cast(int)sql.length, stmt, null);
>> // if (SQLITE_OK != rc)
>> // { printf ("DB prepare statement error: %s\n",
>> sqlite3_errmsg(db) );
>> // printf ("sql = <<%s>>\n", sql);
>> // }
>> // rc = sqlite3_step(*stmt);
>> // if (SQLITE_OK != rc)
>> // { printf ("DB statement step error: %s\n",
>> sqlite3_errmsg(db) );
>> // printf ("sql = <<%s>>\n", sql);
>> // }
>> //
>> // rc = sqlite3_exec(db, sql.ptr, &callback, cast(void*)0,
>> &zErrMsg);
>> // if (SQLITE_OK != rc)
>> // { printf ("DB select error: %s\n", sqlite3_errmsg(db) );
>> // printf ("sql = <<%s>>\n", sql);
>> // }
>> //
>> rc = sqlite3_close (db);
>> enforce (rc == SQLITE_OK);
>> }
>
> Sorry I'm not a sqlite3 expert, nor do I have access to DMD at the
> moment so cannot fully test but that sqlite3_stmt** looks wrong, try
> this:
>
> change:
> ---
> sqlite3_stmt** stmt;
> ...
> rc= sqlite3_prepare(db, toStringz(sql), cast(int)sql.length, stmt, null);
> ...
> rc= sqlite3_step(*stmt);
> ---
>
> to:
> ---
> sqlite3_stmt* stmt;
> ...
> rc= sqlite3_prepare(db, toStringz(sql), cast(int)sql.length, &stmt,
> null);
> ...
> rc= sqlite3_step(stmt);
> ---
>
> I think (from ancient memory) that you also need to clean up the
> statement with something like:
>
> sqlite_finalize(stmt);
>
> but don't quote me on that :D
>
--
Charles Hixson
More information about the Digitalmars-d-learn
mailing list