// Five Example: Dual SQLite — NO #pragma BEGINDUMP // // Two databases open simultaneously — transfer data between them. // All Go calls via IMPORT — zero boilerplate. IMPORT "database/sql" IMPORT _ "modernc.org/sqlite" PROCEDURE Main() LOCAL dbSource, dbTarget, aSrc, aTgt LOCAL aRows, i, nCount ? "=== Dual SQLite Demo ===" ? dbSource := sql.Open("sqlite", "source.db") dbTarget := sql.Open("sqlite", "target.db") // Setup source dbSource:Exec("DROP TABLE IF EXISTS products") dbSource:Exec("CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price REAL, stock INTEGER)") dbSource:Exec("INSERT INTO products VALUES (1, 'Keyboard', 89.99, 150)") dbSource:Exec("INSERT INTO products VALUES (2, 'Mouse', 29.99, 300)") dbSource:Exec("INSERT INTO products VALUES (3, 'Monitor', 499.99, 45)") dbSource:Exec("INSERT INTO products VALUES (4, 'Headset', 79.99, 200)") dbSource:Exec("INSERT INTO products VALUES (5, 'Webcam', 59.99, 120)") ? "Source: 5 products created" // Setup target dbTarget:Exec("DROP TABLE IF EXISTS inventory") dbTarget:Exec("CREATE TABLE inventory (product_id INTEGER, name TEXT, price REAL, status TEXT)") ? "Target: inventory table ready" ? // Source -> Target transfer (stock > 100) aRows := SqlScan(dbSource, "SELECT * FROM products WHERE stock > 100") ? "Transferring", Len(aRows), "products with stock > 100..." nCount := 0 FOR i := 1 TO Len(aRows) dbTarget:Exec("INSERT INTO inventory VALUES (" + ; Str(aRows[i]["id"]) + ", " + ; "'" + aRows[i]["name"] + "', " + ; Str(aRows[i]["price"]) + ", " + ; "'" + IIF(aRows[i]["stock"] > 200, "high", "normal") + "')") nCount++ NEXT ? Str(nCount, 3), "records transferred" ? // Verify target ? "=== Target Inventory ===" aRows := SqlScan(dbTarget, "SELECT * FROM inventory ORDER BY price DESC") ? PadR("ID", 4), PadR("Name", 15), PadR("Price", 10), "Status" ? Replicate("-", 45) FOR i := 1 TO Len(aRows) ? PadR(aRows[i]["product_id"], 4), ; PadR(aRows[i]["name"], 15), ; PadR(Str(aRows[i]["price"], 8, 2), 10), ; aRows[i]["status"] NEXT ? // Cross-database summary ? "=== Cross-DB Summary ===" aSrc := SqlScan(dbSource, "SELECT COUNT(*) as cnt, SUM(price) as total FROM products") aTgt := SqlScan(dbTarget, "SELECT COUNT(*) as cnt, SUM(price) as total FROM inventory") ? "Source:", aSrc[1]["cnt"], "products, total", aSrc[1]["total"] ? "Target:", aTgt[1]["cnt"], "items, total", aTgt[1]["total"] dbSource:Close() dbTarget:Close() ? ? "Both databases closed. Done." RETURN // SqlScan — pure PRG function using Go's sql.Rows directly // No #pragma BEGINDUMP needed! FUNCTION SqlScan(db, cSQL) LOCAL rows, cols, aResult, aRow, i, nCols aResult := {} rows := db:Query(cSQL) IF rows == NIL RETURN aResult ENDIF cols := rows:Columns() nCols := Len(cols) DO WHILE rows:Next() aRow := {=>} FOR i := 1 TO nCols aRow[cols[i]] := rows:Column(i) NEXT AAdd(aResult, aRow) ENDDO rows:Close() RETURN aResult