• Inital commit of sqlite support.

    From Rob Swindell@VERT to GitLab note in main/sbbs on Thu May 8 16:18:13 2025
    https://gitlab.synchro.net/main/sbbs/-/merge_requests/538#note_7208

    I would like to get @Ragnarok's input on this. e.g. Can we eliminate the 'stmt' property?

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell@VERT to GitLab note in main/sbbs on Thu May 8 16:19:02 2025
    https://gitlab.synchro.net/main/sbbs/-/merge_requests/538#note_7209

    This MR is related to issue #118

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Nigel Reed@VERT to GitLab note in main/sbbs on Thu May 8 16:33:53 2025
    https://gitlab.synchro.net/main/sbbs/-/merge_requests/538#note_7211

    I left a message on his BBS to come take a look.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Fernando Toledo@VERT to GitLab note in main/sbbs on Thu May 8 18:41:25 2025
    https://gitlab.synchro.net/main/sbbs/-/merge_requests/538#note_7216

    I don't remember exactly, I think it was because I had first used SQLite2 and understood that I should use it.
    Then, when I switched to SQLite3, it remained in the code.
    But it was just a proof of concept that ultimately worked. But I didn't continue using it for much longer.
    I'm very glad that this piece of code can be useful.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Fernando Toledo@VERT to GitLab note in main/sbbs on Thu May 8 18:54:15 2025
    https://gitlab.synchro.net/main/sbbs/-/merge_requests/538#note_7217

    I just review the code, I think that stmt is not needed... because the sql string can be passed as parameter to exec() directly.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Fernando Toledo@VERT to GitLab note in main/sbbs on Thu May 8 19:08:47 2025
    https://gitlab.synchro.net/main/sbbs/-/merge_requests/538#note_7217

    I just review the code, I think that stmt is not needed... because the sql string can be passed as parameter to exec() directly.

    I think I had put it to have both forms/options.
    The first, prepare the stmt and just call exec().
    And the second, pass the SQL string as a parameter.
    Therefore, it is redundant.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Fernando Toledo@VERT to GitLab note in main/sbbs on Thu May 8 19:18:41 2025
    https://gitlab.synchro.net/main/sbbs/-/merge_requests/538#note_7218

    I believe the SQLite documentation indicates that using direct exec is more optimal for queries that do not return results (inset/update/delete/create table/etc.)
    and using prepare/step/finalize for queries that return data using "select"

    Perhaps that was what the idea of ​​implementing both forms of use at that time was based on.

    ---
    ï¿­ Synchronet ï¿­ Vertrauen ï¿­ Home of Synchronet ï¿­ [vert/cvs/bbs].synchro.net
  • From Nigel Reed@VERT to GitLab note in main/sbbs on Thu May 8 19:34:17 2025
    https://gitlab.synchro.net/main/sbbs/-/merge_requests/538#note_7219

    So you're saying that if we want to use PREPARE then we'd be better off using db.stmt?
    I was wondering exactly how we would construct a prepare then execute.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Fernando Toledo@VERT to GitLab note in main/sbbs on Thu May 8 19:53:28 2025
    https://gitlab.synchro.net/main/sbbs/-/merge_requests/538#note_7220

    see this example (from chatgpt sorry)
    for INSERT/CREATE TABLE it-s use exec method
    and for SELECT use prepare

    Other libraries I remember, such as using MySQL for PHP, had db.exec() for queries that didn't return results, and db.query() for those that did return rows and iterate through them.


    ```c++
    #include <stdio.h>
    #include <sqlite3.h>

    int main() {
    sqlite3 *db;
    char *errMsg = 0;
    int rc;

    // Abrir (o crear) la base de datos
    rc = sqlite3_open("ejemplo.db", &db);
    if (rc) {
    fprintf(stderr, "No se puede abrir la base de datos: %s\n", sqlite3_errmsg(db));
    return 1;
    } else {
    printf("Base de datos abierta exitosamente\n");
    }

    // Crear tabla
    const char *sqlCreateTable = "CREATE TABLE IF NOT EXISTS personas (id INTEGER PRIMARY KEY, nombre TEXT);";
    rc = sqlite3_exec(db, sqlCreateTable, 0, 0, &errMsg);
    if (rc != SQLITE_OK) {
    fprintf(stderr, "Error al crear tabla: %s\n", errMsg);
    sqlite3_free(errMsg);
    }

    // Insertar datos
    const char *sqlInsert = "INSERT INTO personas (nombre) VALUES ('Juan'), ('Ana');";
    rc = sqlite3_exec(db, sqlInsert, 0, 0, &errMsg);
    if (rc != SQLITE_OK) {
    fprintf(stderr, "Error al insertar datos: %s\n", errMsg);
    sqlite3_free(errMsg);
    }

    // Consultar datos
    const char *sqlSelect = "SELECT id, nombre FROM personas;";
    sqlite3_stmt *stmt;

    rc = sqlite3_prepare_v2(db, sqlSelect, -1, &stmt, 0);
    if (rc == SQLITE_OK) {
    while (sqlite3_step(stmt) == SQLITE_ROW) {
    int id = sqlite3_column_int(stmt, 0);
    const unsigned char *nombre = sqlite3_column_text(stmt, 1);
    printf("ID: %d, Nombre: %s\n", id, nombre);
    }
    } else {
    fprintf(stderr, "Error al preparar la consulta: %s\n", sqlite3_errmsg(db));
    }

    sqlite3_finalize(stmt);
    sqlite3_close(db);
    return 0;
    }
    ```

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Nigel Reed@VERT to GitLab note in main/sbbs on Fri May 9 00:52:49 2025
    https://gitlab.synchro.net/main/sbbs/-/merge_requests/538#note_7221

    Unfortunately, your English is better than my Spanish :) I don't see how this is a prepare though.
    I would expect to see something like prepare("SELECT name,age from mytable WHERE age>?")
    and that would be followed by execute(17)
    in perl you'd construct your db connection with $dbh and then my $sth=dbh->prepare("whatever..."); and then $sth->execute(17); I believe if you just want a select you'd use do or go $dbh->do("TRUNCATE mytable");

    Maybe we need to make the js interface into the library a little better?

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Fernando Toledo@VERT to GitLab note in main/sbbs on Fri May 9 07:07:05 2025
    https://gitlab.synchro.net/main/sbbs/-/merge_requests/538#note_7222

    No, my English is pretty bad, this is a assisted translation, ha!

    Regarding the interface, it's true... Perl uses the same idea... do() for queries without results, and prepare() and execute() for queries that return rows.
    I think this would work (perhaps without needing the prepare method as a separate method).

    Could something like this work? What do you think? (from js side)

    ```javascript

    var ret; //return object array
    var row; //row object

    db = new SQLite("/tmp/base1");
    db. debug = false;
    if (!db. open())
    writeln ("i can't open it: " + db. errormsg);

    if (db. exec("create table test (a int, b text)"))
    writeln ("OK Create");
    else
    writeln("ops " + db.errormsg);

    for (i=1;i<10;i++)
    if(db.exec("insert into test values ​​(" + i + ",'hello')"))
    writeln("OK inserted ");
    else
    writeln("ops " + db.errormsg);

    writeln("querying data:");

    if (ret = db.query("select a,b from test")) {
    for (row in ret) {
    writeln (ret[row].a + " " + ret[row].b);
    }
    } else {
    writeln("ops: " + db.errormsg);
    }

    writeln("deleting data:");

    if (ret = db.exec("delete from test")) {
    writeln("OK delete");
    } else {
    writeln("ops: " + db.errormsg);
    }

    ```

    ---
    ï¿­ Synchronet ï¿­ Vertrauen ï¿­ Home of Synchronet ï¿­ [vert/cvs/bbs].synchro.net
  • From Fernando Toledo@VERT to GitLab note in main/sbbs on Fri May 9 07:07:45 2025
    https://gitlab.synchro.net/main/sbbs/-/merge_requests/538#note_7222

    No, my English is pretty bad, this is a assisted translation, ha!

    Regarding the interface, it's true... Perl uses the same idea... do() for queries without results, and prepare() and execute() for queries that return rows.
    I think this would work (perhaps without needing the prepare method as a separate method).

    Just using exec() and query()

    Could something like this work? What do you think? (from js side)

    ```javascript

    var ret; //return object array
    var row; //row object

    db = new SQLite("/tmp/base1");
    db. debug = false;
    if (!db. open())
    writeln ("i can't open it: " + db. errormsg);

    if (db. exec("create table test (a int, b text)"))
    writeln ("OK Create");
    else
    writeln("ops " + db.errormsg);

    for (i=1;i<10;i++)
    if(db.exec("insert into test values ​​(" + i + ",'hello')"))
    writeln("OK inserted ");
    else
    writeln("ops " + db.errormsg);

    writeln("querying data:");

    if (ret = db.query("select a,b from test")) {
    for (row in ret) {
    writeln (ret[row].a + " " + ret[row].b);
    }
    } else {
    writeln("ops: " + db.errormsg);
    }

    writeln("deleting data:");

    if (ret = db.exec("delete from test")) {
    writeln("OK delete");
    } else {
    writeln("ops: " + db.errormsg);
    }

    ```

    ---
    ï¿­ Synchronet ï¿­ Vertrauen ï¿­ Home of Synchronet ï¿­ [vert/cvs/bbs].synchro.net