diff --git a/internal/llgen/llgenf.go b/internal/llgen/llgenf.go index e7f54dce..7459be55 100644 --- a/internal/llgen/llgenf.go +++ b/internal/llgen/llgenf.go @@ -103,8 +103,6 @@ func SmartDoFile(inFile string, pkgPath ...string) { fname := autgenFile if inCompilerDir(absDir) { fname = "out.ll" - } else if inSqlite(absDir) { - fname = "sqlite.ll" } outFile := dir + fname @@ -129,7 +127,3 @@ func genZip(dir string, outFile, inFile string) { func inCompilerDir(dir string) bool { return strings.Contains(dir, "/llgo/cl/") } - -func inSqlite(dir string) bool { - return strings.HasSuffix(dir, "/llgo/x/sqlite") -} diff --git a/x/sqlite/README.md b/x/sqlite/README.md new file mode 100644 index 00000000..f6e86dc2 --- /dev/null +++ b/x/sqlite/README.md @@ -0,0 +1,35 @@ +LLGo wrapper of sqlite +===== +[![Build Status](https://github.com/goplus/sqlite/actions/workflows/go.yml/badge.svg)](https://github.com/goplus/sqlite/actions/workflows/go.yml) +[![GitHub release](https://img.shields.io/github/v/tag/goplus/sqlite.svg?label=release)](https://github.com/goplus/sqlite/releases) +[![GoDoc](https://pkg.go.dev/badge/github.com/goplus/sqlite.svg)](https://pkg.go.dev/github.com/goplus/sqlite) +[![Compiler](https://img.shields.io/badge/compiler-llgo-darkgreen.svg)](https://github.com/goplus/llgo) +[![Language](https://img.shields.io/badge/language-Go+-blue.svg)](https://github.com/goplus/gop) + +## How to install + +```sh +git clone https://github.com/goplus/sqlite.git +cd sqlite +git submodule init +git submodule update +mkdir build.dir +cd build.dir +../sqlite/configure --enable-shared +sudo make install +``` + +## Demos + +The `_demo` directory contains our demos (it start with `_` to prevent the `go` command from compiling it): + +* [sqlitedemo](_demo/sqlitedemo/demo.go): a basic sqlite demo + +### How to run demos + +To run the demos in directory `_demo`: + +```sh +cd # eg. cd _demo/sqlitedemo +llgo run . +``` diff --git a/x/sqlite/_demo/sqlitedemo/demo.go b/x/sqlite/_demo/sqlitedemo/demo.go new file mode 100644 index 00000000..9dc4dc0f --- /dev/null +++ b/x/sqlite/_demo/sqlitedemo/demo.go @@ -0,0 +1,61 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/x/sqlite" +) + +func main() { + c.Remove(c.Str("test.db")) + + db, err := sqlite.Open(c.Str("test.db")) + check(err, db, "sqlite: Open") + + err = db.Exec(c.Str("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)"), nil, nil, nil) + check(err, db, "sqlite: Exec CREATE TABLE") + + stmt, err := db.PrepareV3("INSERT INTO users (id, name) VALUES (?, ?)", 0, nil) + check(err, db, "sqlite: PrepareV3 INSERT") + + stmt.BindInt(1, 100) + stmt.BindText(2, c.Str("Hello World"), -1, nil) + + err = stmt.Step() + checkDone(err, db, "sqlite: Step INSERT 1") + + stmt.Reset() + stmt.BindInt(1, 200) + stmt.BindText(2, c.Str("This is llgo"), -1, nil) + + err = stmt.Step() + checkDone(err, db, "sqlite: Step INSERT 2") + + stmt.Close() + + stmt, err = db.PrepareV3("SELECT * FROM users", 0, nil) + check(err, db, "sqlite: PrepareV3 SELECT") + + for { + if err = stmt.Step(); err != sqlite.HasRow { + break + } + c.Printf(c.Str("==> id=%d, name=%s\n"), stmt.ColumnInt(0), stmt.ColumnText(1)) + } + checkDone(err, db, "sqlite: Step done") + + stmt.Close() + db.Close() +} + +func check(err sqlite.Errno, db *sqlite.Sqlite3, at string) { + if err != sqlite.OK { + c.Printf(c.Str("==> %s Error: (%d) %s\n"), c.AllocaCStr(at), err, db.Errmsg()) + c.Exit(1) + } +} + +func checkDone(err sqlite.Errno, db *sqlite.Sqlite3, at string) { + if err != sqlite.Done { + check(err, db, at) + } +} diff --git a/x/sqlite/llgo.cfg b/x/sqlite/llgo.cfg deleted file mode 100644 index 3b457a74..00000000 --- a/x/sqlite/llgo.cfg +++ /dev/null @@ -1,12 +0,0 @@ -{ - "cl": [ - "mkdir build.dir", - "cd build.dir", - "../sqlite/configure", - "make", - "clang -emit-llvm -S -o ../llgo_autogen.ll -c sqlite3.c", - "cd ..", - "llgen .", - "rm llgo_autogen.lla; zip llgo_autogen.lla llgo_autogen.ll sqlite.ll", - ] -} diff --git a/x/sqlite/llgo_autogen.lla b/x/sqlite/llgo_autogen.lla index 6aa88aa4..64a7e929 100644 Binary files a/x/sqlite/llgo_autogen.lla and b/x/sqlite/llgo_autogen.lla differ diff --git a/x/sqlite/sqlite.go b/x/sqlite/sqlite.go index 275d8379..133a5b8f 100644 --- a/x/sqlite/sqlite.go +++ b/x/sqlite/sqlite.go @@ -29,15 +29,17 @@ type ( ) const ( - LLGoPackage = "link" + LLGoPackage = "link: sqlite3" ) // llgo:type C type Sqlite3 struct { + Unused [8]byte } // llgo:type C type Stmt struct { + Unused [8]byte } // ----------------------------------------------------------------------------- diff --git a/x/sqlite/sqlite.ll b/x/sqlite/sqlite.ll deleted file mode 100644 index d4bdb25a..00000000 --- a/x/sqlite/sqlite.ll +++ /dev/null @@ -1,99 +0,0 @@ -; ModuleID = 'github.com/goplus/llgo/x/sqlite' -source_filename = "github.com/goplus/llgo/x/sqlite" - -%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } - -@"github.com/goplus/llgo/x/sqlite.init$guard" = global ptr null - -define ptr @"(*github.com/goplus/llgo/x/sqlite.Errno).Errstr"(ptr %0) { -_llgo_0: - %1 = load i32, ptr %0, align 4 - %2 = call ptr @sqlite3_errstr(i32 %1) - ret ptr %2 -} - -define { ptr, i32 } @"github.com/goplus/llgo/x/sqlite.Open"(ptr %0) { -_llgo_0: - %1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) - %2 = call i32 @sqlite3_open(ptr %0, ptr %1) - %3 = load ptr, ptr %1, align 8 - %mrv = insertvalue { ptr, i32 } poison, ptr %3, 0 - %mrv1 = insertvalue { ptr, i32 } %mrv, i32 %2, 1 - ret { ptr, i32 } %mrv1 -} - -define { ptr, i32 } @"github.com/goplus/llgo/x/sqlite.OpenV2"(ptr %0, i32 %1, ptr %2) { -_llgo_0: - %3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) - %4 = call i32 @sqlite3_open_v2(ptr %0, ptr %3, i32 %1, ptr %2) - %5 = load ptr, ptr %3, align 8 - %mrv = insertvalue { ptr, i32 } poison, ptr %5, 0 - %mrv1 = insertvalue { ptr, i32 } %mrv, i32 %4, 1 - ret { ptr, i32 } %mrv1 -} - -define { ptr, i32 } @"(*github.com/goplus/llgo/x/sqlite.Sqlite3).Prepare"(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1, ptr %2) { -_llgo_0: - %3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) - %4 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %1, 0 - %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %1, 1 - %6 = trunc i64 %5 to i32 - %7 = call i32 @sqlite3_prepare(ptr %0, ptr %4, i32 %6, ptr %3, ptr %2) - %8 = load ptr, ptr %3, align 8 - %mrv = insertvalue { ptr, i32 } poison, ptr %8, 0 - %mrv1 = insertvalue { ptr, i32 } %mrv, i32 %7, 1 - ret { ptr, i32 } %mrv1 -} - -define { ptr, i32 } @"(*github.com/goplus/llgo/x/sqlite.Sqlite3).PrepareV2"(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1, ptr %2) { -_llgo_0: - %3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) - %4 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %1, 0 - %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %1, 1 - %6 = trunc i64 %5 to i32 - %7 = call i32 @sqlite3_prepare_v2(ptr %0, ptr %4, i32 %6, ptr %3, ptr %2) - %8 = load ptr, ptr %3, align 8 - %mrv = insertvalue { ptr, i32 } poison, ptr %8, 0 - %mrv1 = insertvalue { ptr, i32 } %mrv, i32 %7, 1 - ret { ptr, i32 } %mrv1 -} - -define { ptr, i32 } @"(*github.com/goplus/llgo/x/sqlite.Sqlite3).PrepareV3"(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1, i32 %2, ptr %3) { -_llgo_0: - %4 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) - %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %1, 0 - %6 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %1, 1 - %7 = trunc i64 %6 to i32 - %8 = call i32 @sqlite3_prepare_v3(ptr %0, ptr %5, i32 %7, i32 %2, ptr %4, ptr %3) - %9 = load ptr, ptr %4, align 8 - %mrv = insertvalue { ptr, i32 } poison, ptr %9, 0 - %mrv1 = insertvalue { ptr, i32 } %mrv, i32 %8, 1 - ret { ptr, i32 } %mrv1 -} - -define void @"github.com/goplus/llgo/x/sqlite.init"() { -_llgo_0: - %0 = load i1, ptr @"github.com/goplus/llgo/x/sqlite.init$guard", align 1 - br i1 %0, label %_llgo_2, label %_llgo_1 - -_llgo_1: ; preds = %_llgo_0 - store i1 true, ptr @"github.com/goplus/llgo/x/sqlite.init$guard", align 1 - br label %_llgo_2 - -_llgo_2: ; preds = %_llgo_1, %_llgo_0 - ret void -} - -declare ptr @sqlite3_errstr(i32) - -declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) - -declare i32 @sqlite3_open(ptr, ptr) - -declare i32 @sqlite3_open_v2(ptr, ptr, i32, ptr) - -declare i32 @sqlite3_prepare(ptr, ptr, i32, ptr, ptr) - -declare i32 @sqlite3_prepare_v2(ptr, ptr, i32, ptr, ptr) - -declare i32 @sqlite3_prepare_v3(ptr, ptr, i32, i32, ptr, ptr)