From f0e3e556cfe88cea2bba799b053f0c48437d5b36 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Wed, 8 May 2024 10:43:10 +0800 Subject: [PATCH] demo: sqlite --- _demo/llama2-c/run.go | 16 ----- _demo/sqlite/sqlite.go | 59 ++++++++++++++++ c/c.go | 5 ++ x/sqlite/sqlite.go | 152 ++++++++++++++++++++++++++--------------- 4 files changed, 161 insertions(+), 71 deletions(-) create mode 100644 _demo/sqlite/sqlite.go diff --git a/_demo/llama2-c/run.go b/_demo/llama2-c/run.go index fe131aaf..af6acb90 100644 --- a/_demo/llama2-c/run.go +++ b/_demo/llama2-c/run.go @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package main import ( diff --git a/_demo/sqlite/sqlite.go b/_demo/sqlite/sqlite.go new file mode 100644 index 00000000..bf353160 --- /dev/null +++ b/_demo/sqlite/sqlite.go @@ -0,0 +1,59 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/x/sqlite" +) + +func main() { + db, err := sqlite.OpenV2(c.Str(":memory:"), sqlite.OpenReadWrite|sqlite.OpenMemory, nil) + check(err) + + err = db.Exec(c.Str("CREATE TABLE foo (id INT, name TEXT)"), nil, nil, nil) + check(err) + + stmt, err := db.PrepareV3("INSERT INTO foo VALUES (?, ?)", 0, nil) + check(err) + + stmt.BindInt(1, 100) + stmt.BindText(2, c.Str("Hello World"), sqlite.Static, nil) + + err = stmt.Step() + checkDone(err) + + stmt.Reset() + stmt.BindInt(1, 200) + stmt.BindText(2, c.Str("This is llgo"), sqlite.Static, nil) + + err = stmt.Step() + checkDone(err) + + stmt.Close() + + stmt, err = db.PrepareV3("SELECT * FROM foo", 0, nil) + check(err) + + 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) + + stmt.Close() + db.Close() +} + +func check(err sqlite.Errno) { + if err != sqlite.OK { + c.Printf(c.Str("==> Error: (%d) %s\n"), err, err.Errstr()) + c.Exit(1) + } +} + +func checkDone(err sqlite.Errno) { + if err != sqlite.Done { + check(err) + } +} diff --git a/c/c.go b/c/c.go index b8064409..59e09f47 100644 --- a/c/c.go +++ b/c/c.go @@ -71,6 +71,11 @@ func GoStringData(string) *Char // ----------------------------------------------------------------------------- +//go:linkname Exit C.exit +func Exit(Int) + +// ----------------------------------------------------------------------------- + //go:linkname Rand C.rand func Rand() Int diff --git a/x/sqlite/sqlite.go b/x/sqlite/sqlite.go index ca83c105..4e16c840 100644 --- a/x/sqlite/sqlite.go +++ b/x/sqlite/sqlite.go @@ -32,46 +32,6 @@ const ( LLGoPackage = "noinit,link" ) -// ----------------------------------------------------------------------------- - -type Errno Int - -const ( - OK Errno = 0 // Successful result - Error Errno = 1 // Generic error - ErrInternal Errno = 2 // Internal logic error in SQLite - ErrPerm Errno = 3 // Access permission denied - ErrAbort Errno = 4 // Callback routine requested an abort - ErrBusy Errno = 5 // The database file is locked - ErrLocked Errno = 6 // A table in the database is locked - ErrNomem Errno = 7 // A malloc() failed - ErrReadOnly Errno = 8 // Attempt to write a readonly database - ErrInterrupt Errno = 9 // Operation terminated by sqlite3_interrupt() - ErrIo Errno = 10 // Some kind of disk I/O error occurred - ErrCorrupt Errno = 11 // The database disk image is malformed - ErrNotfound Errno = 12 // Unknown opcode in sqlite3_file_control() - ErrFull Errno = 13 // Insertion failed because database is full - ErrCantopen Errno = 14 // Unable to open the database file - ErrProtocol Errno = 15 // Database lock protocol error - _ErrEmpty Errno = 16 // Internal use only - ErrSchema Errno = 17 // The database schema changed - ErrToobig Errno = 18 // String or BLOB exceeds size limit - ErrConstraint Errno = 19 // Abort due to constraint violation - ErrMismatch Errno = 20 // Data type mismatch - ErrMisuse Errno = 21 // Library used incorrectly - ErrNolfs Errno = 22 // Uses OS features not supported on host - ErrAuth Errno = 23 // Authorization denied - _ErrFormat Errno = 24 // Not used - ErrRange Errno = 25 // 2nd parameter to sqlite3_bind out of range - ErrNotadb Errno = 26 // File opened that is not a database file - ErrNotice Errno = 27 // Notifications from sqlite3_log() - ErrWarning Errno = 28 // Warnings from sqlite3_log() - ErrRow Errno = 100 // sqlite3_step() has another row ready - ErrDone Errno = 101 // sqlite3_step() has finished executing -) - -// ----------------------------------------------------------------------------- - // llgo:type C type Sqlite3 struct { } @@ -82,6 +42,58 @@ type Stmt struct { // ----------------------------------------------------------------------------- +type Errno Int + +const ( + OK Errno = 0 // Successful result + + Error Errno = 1 // Generic error + ErrInternal Errno = 2 // Internal logic error in SQLite + ErrPerm Errno = 3 // Access permission denied + ErrAbort Errno = 4 // Callback routine requested an abort + ErrBusy Errno = 5 // The database file is locked + ErrLocked Errno = 6 // A table in the database is locked + ErrNomem Errno = 7 // A malloc() failed + ErrReadOnly Errno = 8 // Attempt to write a readonly database + ErrInterrupt Errno = 9 // Operation terminated by sqlite3_interrupt() + ErrIo Errno = 10 // Some kind of disk I/O error occurred + ErrCorrupt Errno = 11 // The database disk image is malformed + ErrNotfound Errno = 12 // Unknown opcode in sqlite3_file_control() + ErrFull Errno = 13 // Insertion failed because database is full + ErrCantopen Errno = 14 // Unable to open the database file + ErrProtocol Errno = 15 // Database lock protocol error + _ErrEmpty Errno = 16 // Internal use only + ErrSchema Errno = 17 // The database schema changed + ErrToobig Errno = 18 // String or BLOB exceeds size limit + ErrConstraint Errno = 19 // Abort due to constraint violation + ErrMismatch Errno = 20 // Data type mismatch + ErrMisuse Errno = 21 // Library used incorrectly + ErrNolfs Errno = 22 // Uses OS features not supported on host + ErrAuth Errno = 23 // Authorization denied + _ErrFormat Errno = 24 // Not used + ErrRange Errno = 25 // 2nd parameter to sqlite3_bind out of range + ErrNotadb Errno = 26 // File opened that is not a database file + ErrNotice Errno = 27 // Notifications from sqlite3_log() + ErrWarning Errno = 28 // Warnings from sqlite3_log() + + HasRow Errno = 100 // sqlite3_step() has another row ready + Done Errno = 101 // sqlite3_step() has finished executing +) + +// llgo:link (Errno).Errstr C.sqlite3_errstr +func (err Errno) Errstr() *Char { return nil } + +// llgo:link (*Sqlite3).Errmsg C.sqlite3_errmsg +func (db *Sqlite3) Errmsg() *Char { return nil } + +// llgo:link (*Sqlite3).Errcode C.sqlite3_errcode +func (db *Sqlite3) Errcode() Errno { return 0 } + +// llgo:link (*Sqlite3).ExtendedErrcode C.sqlite3_extended_errcode +func (db *Sqlite3) ExtendedErrcode() Errno { return 0 } + +// ----------------------------------------------------------------------------- + //go:linkname doOpen C.sqlite3_open func doOpen(filename *Char, ppDb **Sqlite3) Errno @@ -134,12 +146,12 @@ func OpenV2(filename *Char, flags OpenFlags, zVfs *Char) (db *Sqlite3, err Errno // Closing A Database Connection // // llgo:link (*Sqlite3).Close C.sqlite3_close -func (*Sqlite3) Close() Errno { return 0 } +func (db *Sqlite3) Close() Errno { return 0 } // Closing A Database Connection // // llgo:link (*Sqlite3).CloseV2 C.sqlite3_close_v2 -func (*Sqlite3) CloseV2() Errno { return 0 } +func (db *Sqlite3) CloseV2() Errno { return 0 } // ----------------------------------------------------------------------------- @@ -168,22 +180,27 @@ const ( ) // Compiling An SQL Statement -// tail: Pointer to unused portion of zSql -func (db *Sqlite3) Prepare(sql string) (stmt *Stmt, tail *Char, err Errno) { - err = db.doPrepare(c.GoStringData(sql), c.Int(len(sql)), &stmt, &tail) +// tail: Pointer to unused portion of sql +func (db *Sqlite3) Prepare(sql string, tail **Char) (stmt *Stmt, err Errno) { + err = db.doPrepare(c.GoStringData(sql), c.Int(len(sql)), &stmt, tail) return } -func (db *Sqlite3) PrepareV2(sql string) (stmt *Stmt, tail *Char, err Errno) { - err = db.doPrepareV2(c.GoStringData(sql), c.Int(len(sql)), &stmt, &tail) +func (db *Sqlite3) PrepareV2(sql string, tail **Char) (stmt *Stmt, err Errno) { + err = db.doPrepareV2(c.GoStringData(sql), c.Int(len(sql)), &stmt, tail) return } -func (db *Sqlite3) PrepareV3(sql string, flags PrepareFlags) (stmt *Stmt, tail *Char, err Errno) { - err = db.doPrepareV3(c.GoStringData(sql), c.Int(len(sql)), flags, &stmt, &tail) +func (db *Sqlite3) PrepareV3(sql string, flags PrepareFlags, tail **Char) (stmt *Stmt, err Errno) { + err = db.doPrepareV3(c.GoStringData(sql), c.Int(len(sql)), flags, &stmt, tail) return } +// Destroy A Prepared Statement Object +// +// llgo:link (*Stmt).Close C.sqlite3_finalize +func (stmt *Stmt) Close() Errno { return 0 } + // ----------------------------------------------------------------------------- // llgo:link (*Stmt).BindInt C.sqlite3_bind_int @@ -192,15 +209,23 @@ func (*Stmt) BindInt(idx Int, val Int) Errno { return 0 } // llgo:link (*Stmt).BindInt64 C.sqlite3_bind_int64 func (*Stmt) BindInt64(idx Int, val int64) Errno { return 0 } -// llgo:link (*Stmt).doBindText C.sqlite3_bind_text -func (*Stmt) doBindText(Int, *Char, Int, func(Pointer)) Errno { return 0 } +const ( + Static Int = 0 // val is a static string + Transient Int = -1 // val is a transient (temporary) string +) -func (stmt *Stmt) BindText(idx Int, val string, xDel func(Pointer)) Errno { - return stmt.doBindText(idx, c.GoStringData(val), c.Int(len(val)), xDel) -} +// llgo:link (*Stmt).BindText C.sqlite3_bind_text +func (*Stmt) BindText(idx Int, val *Char, lenOrKind Int, destructor func(Pointer)) Errno { return 0 } // ----------------------------------------------------------------------------- +// Reset A Prepared Statement Object +// +// llgo:link (*Stmt).Reset C.sqlite3_reset +func (stmt *Stmt) Reset() Errno { + return 0 +} + // Evaluate An SQL Statement // // llgo:link (*Stmt).Step C.sqlite3_step @@ -208,12 +233,29 @@ func (*Stmt) Step() Errno { return 0 } // ----------------------------------------------------------------------------- +// llgo:link (*Stmt).ColumnCount C.sqlite3_column_count +func (stmt *Stmt) ColumnCount() Int { return 0 } + +// llgo:link (*Stmt).ColumnName C.sqlite3_column_name +func (stmt *Stmt) ColumnName(idx Int) *Char { return nil } + +// llgo:link (*Stmt).ColumnInt C.sqlite3_column_int +func (stmt *Stmt) ColumnInt(idx Int) Int { return 0 } + +// llgo:link (*Stmt).ColumnInt64 C.sqlite3_column_int64 +func (stmt *Stmt) ColumnInt64(idx Int) int64 { return 0 } + +// llgo:link (*Stmt).ColumnText C.sqlite3_column_text +func (stmt *Stmt) ColumnText(idx Int) *Char { return nil } + +// ----------------------------------------------------------------------------- + // One-Step Query Execution Interface // // llgo:link (*Sqlite3).Exec C.sqlite3_exec func (*Sqlite3) Exec( sql *Char, callback func(arg Pointer, resultCols Int, colVals, colNames **Char) Int, - arg Pointer, errmsg *Char) Errno { + arg Pointer, errmsg **Char) Errno { return 0 }