goplus / llgo

A Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python
Apache License 2.0
365 stars 26 forks source link

Feature Request: implemnts some methods to build a basic sqlite3 project #889

Open cpunion opened 3 days ago

cpunion commented 3 days ago

I just want to compile a demo base on https://github.com/mattn/go-sqlite3 that used cgo, all cgo compiling problems are solved in (https://github.com/goplus/llgo/pull/881), but there's some methods not implemented.

Methods required by https://github.com/mattn/go-sqlite3 :

reflect.Copy
reflect.Indirect
reflect.Value.Convert
reflect.Value.OverflowFloat
reflect.Value.OverflowInt
reflect.Value.OverflowUint
runtime.Stack
sync.(*Mutex).lockSlow
sync.(*Mutex).unlockSlow
sync.(*RWMutex).RLocker
time.LoadLocation
time.Time.In

And some other methods needed:

runtime.FuncForPC
runtime.(*Func).Name

I would be very grateful if someone could implement these.

Sqlite3 demo:

package main

import (
    "database/sql"
    "database/sql/driver"
    "encoding/json"
    "fmt"
    "log"
    "os"

    _ "github.com/mattn/go-sqlite3"
)

type Tag struct {
    Name    string `json:"name"`
    Country string `json:"country"`
}

func (t *Tag) Scan(value interface{}) error {
    return json.Unmarshal([]byte(value.(string)), t)
}

func (t *Tag) Value() (driver.Value, error) {
    b, err := json.Marshal(t)
    return string(b), err
}

func main() {
    os.Remove("./foo.db")

    db, err := sql.Open("sqlite3", "./foo.db")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    _, err = db.Exec(`create table foo (tag jsonb)`)
    if err != nil {
        log.Fatal(err)
    }

    stmt, err := db.Prepare("insert into foo(tag) values(?)")
    if err != nil {
        log.Fatal(err)
    }
    defer stmt.Close()
    _, err = stmt.Exec(`{"name": "mattn", "country": "japan"}`)
    if err != nil {
        log.Fatal(err)
    }
    _, err = stmt.Exec(`{"name": "michael", "country": "usa"}`)
    if err != nil {
        log.Fatal(err)
    }

    var country string
    err = db.QueryRow("select tag->>'country' from foo where tag->>'name' = 'mattn'").Scan(&country)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(country)

    var tag Tag
    err = db.QueryRow("select tag from foo where tag->>'name' = 'mattn'").Scan(&tag)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(tag.Name)

    tag.Country = "日本"
    _, err = db.Exec(`update foo set tag = ? where tag->>'name' == 'mattn'`, &tag)
    if err != nil {
        log.Fatal(err)
    }

    err = db.QueryRow("select tag->>'country' from foo where tag->>'name' = 'mattn'").Scan(&country)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(country)
}