Firebird RDBMS sql driver for Go (golang)

firebirdsql (Go firebird sql driver)

Firebird RDBMS http://firebirdsql.org SQL driver for Go

https://travis-ci.org/nakagami/firebirdsql.svg?branch=master

Requirements

  • Firebird 2.5 or higher
  • Golang 1.13 or higher

Example

package main

import (
    "fmt"
    "database/sql"
    _ "github.com/nakagami/firebirdsql"
)

func main() {
    var n int
    conn, _ := sql.Open("firebirdsql", "user:password@servername/foo/bar.fdb")
    defer conn.Close()
    conn.QueryRow("SELECT Count(*) FROM rdb$relations").Scan(&n)
    fmt.Println("Relations count=", n)

}

See also driver_test.go

package main

   import (
    "fmt"
    "github.com/nakagami/firebirdsql"
)

func main() {
    dsn := "user:password@servername/foo/bar.fdb"
    events := []string{"my_event", "order_created"}
    fbEvent, _ := firebirdsql.NewFBEvent(dsn)
    defer fbEvent.Close()
    sbr, _ := fbEvent.Subscribe(events, func(event firebirdsql.Event) { //or use SubscribeChan
        fmt.Printf("event: %s, count: %d, id: %d, remote id:%d \n", event.Name, event.Count, event.ID, event.RemoteID)
    })
    defer sbr.Unsubscribe()
    go func() {
            fbEvent.PostEvent(events[0])
            fbEvent.PostEvent(events[1])
    }()
    <- make(chan struct{}) //wait
}

See also _example

Connection string

user:password@servername[:port_number]/database_name_or_file[?params1=value1[&param2=value2]...]

General

  • user: login user
  • password: login password
  • servername: Firebird server's host name or IP address.
  • port_number: Port number. default value is 3050.
  • database_name_or_file: Database path (or alias name).

Optional

param1, param2... are

Name Description Default Note
auth_plugin_name Authentication plugin name. Srp Srp256/Srp/Legacy_Auth are available.
column_name_to_lower Force column name to lower false For "github.com/jmoiron/sqlx"
role Role name    
tzname Time Zone name For Firebird 4.0+  
wire_crypt Enable wire data encryption or not. true For Firebird 3.0+
charset Firebird Charecter Set    
Comments
  • error handling/messages Problem

    error handling/messages Problem

    Hello, I tried the following (should return something like : Artithmetic Overflow or Division / 0)

    package main import ( "database/sql" "fmt" "log" _ "github.com/nakagami/firebirdsql" ) func main() { var n int conn, err := sql.Open("firebirdsql", "sysdba:[email protected]/wetten") if err != nil { log.Fatal(err) } defer conn.Close() err = conn.QueryRow("SELECT 5 / 0 FROM rdb$database").Scan(&n) if err != nil { log.Fatal(err) } fmt.Println("Result=", n) }

    And I get: 2017/06/15 23:05:51 sql: no rows in result set This is correct, but why I'm not getting the real error message?

    On Server Side (log from firebirdsql) I get Thu Jun 15 23:05:09 2017 INET/Inet_error: read errno = 104

    if I change the query to err = conn.QueryRow("SELECT 5 / 2 FROM rdb$database").Scan(&n) (this produces no error, of course) anything is ok and on server side there is not INET/Inet_error anymore

    How can I get (possible) runtime Errors?

    If i change from QueryRow to Query and loop over row.next then I never get an error If i use Transactions then on commit (or rollback) I get opcode=0

    What I'm doing wrong?

  • driver is 4X time slower compared to C++ and Perl on windows 10 platform, Firebird 2.5

    driver is 4X time slower compared to C++ and Perl on windows 10 platform, Firebird 2.5

    I performed some tests and found out that fetching rows is very slow compared to using C++ or even Perl. The problem is at the wireprotocol.go module - seems that every Write or Read from the socket goes through a operating system syscall creating huge overhead as there are many small (4 bytes) read operations. I am not familiar with tcp in go and the Firebird protocol, but is it possible to improve the way of communicating with the server ?
    In my specific test fetching ~2000 rows that takes 50-70ms in C++ (using IBPP driver) or Perl , took 230-240ms in Go. Even when I limit to 40 records there is a huge penalty in Go.

    if there is such a penalty in the tcp then all the internet staff etc would be very slow, but I did not found complains about slow communication, so maybe there is a way around this problem ?

  • Result truncated on row with VARCHAR field using max length and non UTF8 charset

    Result truncated on row with VARCHAR field using max length and non UTF8 charset

    example table contains 10 rows the NAME field is VARCHAR 30 with WIN1250 charset second row has 30 characters in the NAME field with one non ASCII char

    ` rows, errQ := db.Query("select ID, NAME from TABLE") if errQ != nil { t.Fatal(errQ) }

    defer rows.Close()
    var id, name string
    for rows.Next() {
    	errScan := rows.Scan(&id, &name)
    	if errScan != nil {
    		t.Fatal(errScan)
    	}
    	t.Log(id, name)
    }
    

    `

    returns only first row, rest is droped no error is returned

  • Creating or connecting to databases with non-UTF8 character sets

    Creating or connecting to databases with non-UTF8 character sets

    It's not always desired to create databases or to connect to databases with character set UTF8, which is what is currently hard-coded. I would be happy to submit a patch, but the DSN format would need to be extended. The DSN used by the postgresql library lib/pq appears to use space-separated key=value pairs. My go-fb library uses semicolon-separated key=value pairs. I don't mind what schema is used as long as it's extensible. Your library, your call...

  • Interbase 2007 Connection

    Interbase 2007 Connection

    Hi

    Please, when I try to connect to a remote Interbase 2007 using the example in README.md, I get no errors, but always return count = 0. If I use fmt.Println(conn.Ping()), I get this error: opAccept() protocol error

    I know that this driver is not specificaly for Interbase, but Firebird and Interbase are usualy interchangable. And if i use this driver https://github.com/rowland/go-fb it's work, but the driver does not currently conform to database/sql/driver interfaces.

    Thanks in advance

    PS: I use ubuntu 14.04 x64 with packages: firebird-dev firebird2.5-classic-common firebird2.5-common firebird2.5-common-doc firebird2.5-server-common

  • Blobs returning incorrectly

    Blobs returning incorrectly

    I'm actually unsure if this is a problem on my end or the packages.

    When getting a blob via a query and trying to save it as a file, the file won't open. Printing the data as plain text shows that all characters are strangely encoded.

    var mapa []byte qRow := conn.QueryRow("select A_PICTURE from A_TABLE where ID = 1") qRow.Scan(&mapa) err := ioutil.WriteFile("picture.png", mapa, 0644) if err != nil { log.Fatal(err) }

    If I do this for a plain something.txt file, it works perfectly. Anything more complex than that results in a broken file.

    The original intent behind this is to get a .sxc file from the database and parse it. File won't open. Tried using a .png file just to test it out with the same end result.

    Not sure if this is an issue with the package or my method of saving the file doesn't work with the file types I'm working with. If it's on my end, apologies for submitting this.

  • Not properly work after transaction

    Not properly work after transaction

    `package main

    import ( "database/sql" "log"

    _ "github.com/nakagami/firebirdsql"
    

    )

    func main() {

    conn, err := sql.Open("firebirdsql", "SYSDBA:[email protected]/d:/Temp/TestDatabases/TEST.FDB")
    defer conn.Close()
    
    if err != nil {
        log.Fatal(err)
    }
    
    // контроль связи с БД
    err = conn.Ping()
    if err != nil {
        log.Fatal(err)
    }
    
    tx, err := conn.Begin()
    
    if err != nil {
        log.Fatal(err)
    }
    
    err = tx.Commit()
    
    if err != nil {
        log.Fatal(err)
    }
    
    const query = `CREATE TABLE SensorLog(SN INTEGER NOT NULL);`
    
    _, err = conn.Exec(query)
    
    if err != nil {
        log.Fatal(err)
    }
    

    }`

  • Error with Firebird 4.0

    Error with Firebird 4.0

    I'm trying to use this with firebird 4.0 and am getting an error. It seems the error is happening when I'm trying to do con.Ping() right after doing an sql.Open().

    panic: runtime error: slice bounds out of range [:2] with capacity 0
    
    goroutine 1 [running]:
    github.com/nakagami/firebirdsql.(*wireProtocol)._parse_connect_response(0x40003be120, {0x40003ba06b, 0x6}, {0x40003ba072, 0xb}, 0x40003ba072?, 0xb?, 0x0?)
            /home/ubuntu/go/pkg/mod/github.com/nakagami/[email protected]/wireprotocol.go:508 +0x98c
    github.com/nakagami/firebirdsql.newFirebirdsqlConn(0x40003a2050)
            /home/ubuntu/go/pkg/mod/github.com/nakagami/[email protected]/connection.go:150 +0x28c
    github.com/nakagami/firebirdsql.(*firebirdsqlDriver).Open(0x88?, {0x4000394050?, 0x1000?})
            /home/ubuntu/go/pkg/mod/github.com/nakagami/[email protected]/driver.go:39 +0x50
    database/sql.dsnConnector.Connect(...)
            /snap/go/9854/src/database/sql/sql.go:761
    database/sql.(*DB).conn(0x40003a0680, {0xaefcd8, 0x40000d4048}, 0x1)
            /snap/go/9854/src/database/sql/sql.go:1395 +0x8ec
    database/sql.(*DB).PingContext(0x9828d5?, {0xaefcd8, 0x40000d4048})
            /snap/go/9854/src/database/sql/sql.go:853 +0x78
    database/sql.(*DB).Ping(...)
            /snap/go/9854/src/database/sql/sql.go:875
    github.com/krixano/ponixserver/src/db.NewConn({0x97c0de?, 0x28?})
            /home/ubuntu/server/src/db/db.go:50 +0x52c
    github.com/krixano/ponixserver/src/migration.Migrate({0x97c0de, 0x6}, {0x400035fda8?, 0x279654?, 0x0?})
            /home/ubuntu/server/src/migration/migration.go:116 +0x40
    github.com/krixano/ponixserver/src/migration.init.0.func1(0x40003a6000?, {0x4000390230?, 0x1?, 0x1?})
            /home/ubuntu/server/src/migration/migration.go:49 +0x2f8
    github.com/spf13/cobra.(*Command).execute(0x40003a6000, {0x40003901f0, 0x1, 0x1})
            /home/ubuntu/go/pkg/mod/github.com/spf13/[email protected]/command.go:860 +0x4c4
    github.com/spf13/cobra.(*Command).ExecuteC(0x1284a60)
            /home/ubuntu/go/pkg/mod/github.com/spf13/[email protected]/command.go:974 +0x360
    github.com/spf13/cobra.(*Command).Execute(...)
            /home/ubuntu/go/pkg/mod/github.com/spf13/[email protected]/command.go:902
    main.main()
            /home/ubuntu/server/src/main.go:21 +0x2c
    
  • Procedure exception doesn't work

    Procedure exception doesn't work

    Hi! I have the following firebird procedure code create or alter procedure MY_SPCOUNTRY_EDIT ( CID_IN integer, CNAME R_NAME, CFULLNAME R_FULLNAME, USERID integer) returns ( CID integer) as begin if (condition) then begin exception exc_ur_common 'Error_text'; end other code

    end next call row, err = db.Query("select cid from my_spcountry_edit(?,?,?,?)", cid, name, fullName, user)

    I expect err that err contains 'Error_text' from firebird procedure, but err = nil How to get exeption text from firebird procedure?

  • Pooling

    Pooling

    • Implement requirements for the database/sql pooling functionality.
    • Driver now reconnects automaticly when the database is ready again.
    • Returning concrete errors from wireprotocol for better error handling.
  • Selecting blobs always returns nil

    Selecting blobs always returns nil

    rows, _ := conn.Query("SELECT BLOB_FIELD FROM MY_TABLE")
    for rows.Next() {
        var blob sql.RawBytes
        rows.Scan(&blob)
        println(blob)
    }
    

    This outputs: [0/0]0x0

    Am I doing it wrong?

    Firebird 2.5.2 on Windows.

  • cannot read chinese db path

    cannot read chinese db path

    It will return db.Ping failed:I/O error during "CreateFile (open)" operation for file "D:\病例.G_B", when is use chinese db path like D:\病例.g_b.

    dbFilePath := "D:\\病例.g_b"
    conn, err := sql.Open("firebirdsql", fmt.Sprintf("sysdba:masterkey@localhost:3050/%s?charset=GB2312", dbFilePath))
    if err != nil {
    standard.XWarning(fmt.Sprintf("sql.Open failed:%v", err))
    return
    }
    defer conn.Close()
    
  • huge latency on read operations when database is being updated

    huge latency on read operations when database is being updated

    In case table is updated with different connection, read operations with do not return results for long time. I've run similar test with fdb in python on same database and got good latency as expected (<1s for same settings). Also same test in go gives decent latency on sqlite3 database, therefore all statements are correct. Please comment on this bug and possible workaraunds.

    I've tested this with local database created with isql-fb with command CREATE DATABASE '/opt/firebird/database.fdb' USER 'SYSDBA' PASSWORD 'changeit';. Database contains a single table created with command create table numbers (i int not null primary key);

    Here is code for measuring latency in go.

    package main
    
    import (
    	"database/sql"
    	"fmt"
    	"log"
    	"sync"
    	"time"
    
    	_ "github.com/nakagami/firebirdsql"
    )
    
    const (
    	host     = "localhost"
    	database = "/opt/firebird/database.fdb"
    	user     = "SYSDBA"
    	password = "changeit"
    
    	benchLenghtSeconds = 10.0
    	msgCount           = 10
    	readInterval       = 1
    )
    
    var (
    	writeDB    *sql.DB
    	readDB     *sql.DB
    	clearDB    *sql.DB
    	writeTimes = make(map[int]time.Time)
    	readTimes  = make(map[int]time.Time)
    )
    
    func read(wg *sync.WaitGroup) {
    	defer wg.Done()
    
    	lastRead := -1
    
    	for lastRead < msgCount-1 {
    		fmt.Println("read loop start")
    
    		rows, err := readDB.Query("SELECT i from numbers WHERE i>?", lastRead)
    		if err != nil {
    			log.Fatal(err)
    		}
    
    		fmt.Println("query done")
    
    		timestamp := time.Now()
    
    		for rows.Next() {
    			fmt.Println(`in "next" loop`)
    			var i int
    			if err := rows.Scan(&i); err != nil {
    				log.Fatal(err)
    			}
    
    			readTimes[i] = timestamp
    			fmt.Println("read ", i)
    			lastRead = i
    		}
    		fmt.Println(`after "next" loop`)
    
    		rows.Close()
    
    		time.Sleep(readInterval * time.Second)
    	}
    }
    
    func write(wg *sync.WaitGroup) {
    	defer wg.Done()
    
    	stmt, err := writeDB.Prepare("INSERT INTO numbers (i) VALUES (?);")
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	defer stmt.Close()
    
    	for i := 0; i < msgCount; i++ {
    		_, err := stmt.Exec(i)
    		if err != nil {
    			log.Fatal(err)
    		}
    
    		writeTimes[i] = time.Now()
    		fmt.Println("wrote ", i)
    
    		time.Sleep(time.Duration(benchLenghtSeconds/msgCount) * time.Second)
    	}
    }
    
    func clearNumbers() {
    	if _, err := clearDB.Exec("DELETE FROM numbers;"); err != nil {
    		log.Fatal(err)
    	}
    }
    
    func main() {
    	var err error
    
    	writeDB, err = sql.Open("firebirdsql", fmt.Sprintf("%s:%s@%s/%s", user, password, host, database))
    	if err != nil {
    		log.Fatal(err)
    	}
    	defer writeDB.Close()
    
    	readDB, err = sql.Open("firebirdsql", fmt.Sprintf("%s:%s@%s/%s", user, password, host, database))
    	if err != nil {
    		log.Fatal(err)
    	}
    	defer writeDB.Close()
    
    	clearDB, err = sql.Open("firebirdsql", fmt.Sprintf("%s:%s@%s/%s", user, password, host, database))
    	if err != nil {
    		log.Fatal(err)
    	}
    	defer writeDB.Close()
    
    	clearNumbers()
    
    	wg := sync.WaitGroup{}
    	wg.Add(2)
    	go read(&wg)
    	go write(&wg)
    	wg.Wait()
    
    	mean := 0.0
    	for i, t := range writeTimes {
    		mean += readTimes[i].Sub(t).Seconds()
    	}
    	mean /= msgCount
    
    	fmt.Printf("mean latency: %v s\n", mean)
    
    	clearNumbers()
    }
    
    

    Output:

    read loop start
    wrote  0
    query done
    after "next" loop
    wrote  1
    read loop start
    query done
    after "next" loop
    wrote  2
    read loop start
    query done
    after "next" loop
    wrote  3
    read loop start
    query done
    after "next" loop
    wrote  4
    read loop start
    query done
    after "next" loop
    wrote  5
    read loop start
    query done
    after "next" loop
    wrote  6
    read loop start
    query done
    after "next" loop
    wrote  7
    read loop start
    query done
    after "next" loop
    wrote  8
    read loop start
    query done
    after "next" loop
    wrote  9
    read loop start
    query done
    after "next" loop
    read loop start
    query done
    in "next" loop
    read  0
    in "next" loop
    read  1
    in "next" loop
    read  2
    in "next" loop
    read  3
    in "next" loop
    read  4
    in "next" loop
    read  5
    in "next" loop
    read  6
    in "next" loop
    read  7
    in "next" loop
    read  8
    in "next" loop
    read  9
    after "next" loop
    mean latency: 5.5446701527 s
    

    fdb test

    import fdb
    from timeit import default_timer
    import asyncio
    
    HOST = 'localhost'
    DATABAASE = '/opt/firebird/database.fdb'
    USER = 'SYSDBA'
    PASSWORD='changeit'
    
    BENCH_LENGTH_SECONDS = 10.0
    MSG_COUNT=10
    READ_INTERVAL = 1
    
    con_write = fdb.connect(
        host=HOST, database=DATABAASE,
        user=USER, password=PASSWORD
      )
    
    con_read = fdb.connect(
        host=HOST, database=DATABAASE,
        user=USER, password=PASSWORD
      )
    
    con_cleanup = fdb.connect(
        host=HOST, database=DATABAASE,
        user=USER, password=PASSWORD
      )
      
    write_cur = con_write.cursor()
    read_cur = con_read.cursor()
    cleanup_cur = con_cleanup.cursor()
    
    write_times = {}
    read_times = {}
    
    async def write():
      for i in range(MSG_COUNT):
        write_cur.execute("INSERT INTO numbers (i) VALUES (?);",(i,))
        con_write.commit()
        
        write_times[i]=default_timer()
        
        await asyncio.sleep(BENCH_LENGTH_SECONDS/MSG_COUNT)
      
    async def read():
      last_read = -1
      while last_read<MSG_COUNT-1:
        res = read_cur.execute("SELECT i from numbers WHERE i>?;",(last_read,)).fetchall()
        timestamp = default_timer()
        
        for row in res:
          read_times[row[0]]=timestamp
          last_read = row[0]
    
        await asyncio.sleep(READ_INTERVAL)
    
    
    async def main():
        f1 = loop.create_task(write())
        f2 = loop.create_task(read())
        await asyncio.wait([f1, f2])
    
    # cleanup
    cleanup_cur.execute('DELETE FROM numbers;')
    con_cleanup.commit()
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()
    
    # cleanup
    cleanup_cur.execute('DELETE FROM numbers;')
    con_cleanup.commit()
    
    # count latency
    
    diff = 0.0
    for i,t in write_times.items():
      diff+=read_times[i]-t
    
    diff/=MSG_COUNT
    
    print(f'mean latency: {diff*1000} ms')
    
    

    output:

    mean latency: 1.1342148995026946 ms
    
  • go-critic check output

    go-critic check output

    Result of source code check by go-critick

    ./consts.go:198:2: commentFormatting: put a space between // and comment text ./consts.go:441:1: commentFormatting: put a space between // and comment text ./decfloat.go:132:3: dupBranchBody: both branches in if statement has same body ./decfloat.go:206:3: dupBranchBody: both branches in if statement has same body ./decfloat.go:57:2: ifElseChain: rewrite if-else to switch statement ./decfloat.go:130:2: ifElseChain: rewrite if-else to switch statement ./decfloat.go:205:2: ifElseChain: rewrite if-else to switch statement ./dsn.go:48:2: commentFormatting: put a space between // and comment text ./event.go:19:1: commentFormatting: put a space between // and comment text ./event.go:90:9: unslice: could simplify e.subscribers[:] to e.subscribers ./eventmanager.go:40:25: commentFormatting: put a space between // and comment text ./eventmanager.go:44:25: commentFormatting: put a space between // and comment text ./srp.go:183:2: ifElseChain: rewrite if-else to switch statement ./wireprotocol.go:44:2: commentFormatting: put a space between // and comment text ./wireprotocol.go:729:4: commentFormatting: put a space between // and comment text ./wireprotocol.go:1341:2: commentFormatting: put a space between // and comment text ./wireprotocol.go:486:9: elseif: can replace 'else {if cond {}}' with 'else if cond {}' ./wireprotocol.go:224:2: ifElseChain: rewrite if-else to switch statement ./wireprotocol.go:420:4: ifElseChain: rewrite if-else to switch statement ./wireprotocol.go:578:3: ifElseChain: rewrite if-else to switch statement ./xsqlvar.go:260:2: assignOp: replace m = m % 60 with m %= 60 ./xsqlvar.go:261:2: assignOp: replace s = s % 60 with s %= 60 ./xsqlvar.go:323:3: ifElseChain: rewrite if-else to switch statement ./xsqlvar.go:332:3: ifElseChain: rewrite if-else to switch statement ./xsqlvar.go:341:3: ifElseChain: rewrite if-else to switch statement ./driver_test.go:58:3: assignOp: replace retorno = retorno + "/" with retorno += "/" ./driver_test.go:61:2: assignOp: replace retorno = retorno + TempFileName(file) with retorno += TempFileName(file) ./driver_test.go:599:2: commentFormatting: put a space between // and comment text ./driver_test.go:605:2: commentFormatting: put a space between // and comment text ./driver_test.go:612:2: commentFormatting: put a space between // and comment text ./driver_test.go:748:2: commentFormatting: put a space between // and comment text

  • return query linux

    return query linux

    I'm in a strange situation. I made an integration with firebird (which I don't have access to configure it) where I look for the viq query information and insert it in another database. When run via windows it works normally. When I run via linux (compiled on linux OS) it doesn't work. I receive the following feedback:" sql: no rows in result set" The interesting thing is that this integration is for two clients where one is working perfectly and the other is having this difficulty. Has anyone ever experienced this? I believe it's something in the firebird configuration more, as I don't have access I have to make sure which configuration is missing.

  • No output on complex Firebird queries in golang

    No output on complex Firebird queries in golang

    I am currently working on a project to getting me started with golang / Firebird SQL and programming in general.

    My Firebird SQL query works perfectly when run against the database:

    | NAME | DELIVERY_DATE | LIST | |---------------------------|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 | 2021-06-19 19:00:00 | MEGAITEM groß STK:1 | SMALLITEM STK:1 | DELTAITEM klein STK:1| | | NAME1 | 2021-06-19 12:00:00 | ITEM STK:1 | | NAME2 | 2021-06-26 12:00:00 | ITEM STK:1 | | NAME3 | 2021-06-18 17:00:00 | DELTATIEM STK:1

    However, when I run it in my code, I get an empty array as an answer. The small Firebird query in the comments works fine. It returns three columns and the struct is filled up as expected.

    Command line output:

    2021/07/03 14:18:30 &{0xc000162000 0x55a4c0 0xc000106540 <nil> <nil> {{0 0} 0 0 0 0} false <nil> []}
    2021/07/03 14:18:30 []
    

    Golang Code

    package main
    
    import (
    	"database/sql"
    	"html/template"
    	"log"
    	"net/http"
    
    	_ "github.com/nakagami/firebirdsql"
    )
    
    type SqlTableContent struct {
    	UID  string
    	DATE string
    	NAME string
    }
    
    func main() {
    
    	log.Println("Server started on: http://localhost:8080")
    	http.HandleFunc("/", Mainquery)
    	http.ListenAndServe(":8080", nil)
    
    }
    
    func dbConn() (db *sql.DB) {
    	db, err := sql.Open("firebirdsql", `SYSDBA:masterkey@localhost/C:\DATA.FDB`)
    	if err != nil {
    		panic(err.Error())
    	}
    	return db
    }
    
    var tmpl = template.Must(template.ParseGlob("form/*"))
    
    func Mainquery(w http.ResponseWriter, r *http.Request) {
    	w.Header().Set("Content-Type", "text/html")
    
    	db := dbConn()
    	query := `with data as ( select article_name || ' STK:' || cast(quantity as integer) as quantity  , PREORDER_ID as PID from preorder_item )  SELECT PREORDER.NAME ,PREORDER.DELIVERY_DATE  ,LIST(DATA.QUANTITY, ' | ') FROM PREORDER INNER JOIN DATA ON PREORDER.ID = DATA.PID GROUP by PREORDER.NAME  ,PREORDER.DELIVERY_DATE`
    
    	//	selDB, err := db.Query("SELECT SALE_ID, DELIVERY_DATE, NAME FROM PREORDER") This works
    	selDB, err := db.Query(query)
    	if err != nil {
    		panic(err.Error())
    	}
    
    	log.Println(selDB)
    	var queryContent SqlTableContent
    	var SqlTableContentArray []SqlTableContent
    	for selDB.Next() {
    
    		var id string
    		var date string
    		var name string
    
    		err = selDB.Scan(&id, &date, &name)
    		if err != nil {
    			panic(err.Error())
    		}
    		queryContent.UID = id
    		queryContent.DATE = date
    		queryContent.NAME = name
    
    		SqlTableContentArray = append(SqlTableContentArray, queryContent)
    
    	}
    	tmpl.ExecuteTemplate(w, "Show", SqlTableContentArray)
    	log.Println(SqlTableContentArray)
    	defer db.Close()
    }
    
  • cyrillic connection path

    cyrillic connection path

    Hi, if i have directory with cyrillic symbols, do i have opportunities work with date base inside that directory? when i want connect to the database i get error - I/O error during "CreateFile (open)" operation for file "D:\ДИРЕКТОРИЯ\test.FDB" Error while trying to open file

    ДИРЕКТОРИЯ - this is a cyrillic directory if i check it - _, err := os.Stat(path); os.IsNotExist(err) i do not have any errors. Also i connect to my database with any SQL client and do not have any errors

Qmgo - The Go driver for MongoDB. It‘s based on official mongo-go-driver but easier to use like Mgo.

Qmgo English | 简体中文 Qmgo is a Go driver for MongoDB . It is based on MongoDB official driver, but easier to use like mgo (such as the chain call). Qmg

Dec 28, 2022
Go driver for PostgreSQL over SSH. This driver can connect to postgres on a server via SSH using the local ssh-agent, password, or private-key.

pqssh Go driver for PostgreSQL over SSH. This driver can connect to postgres on a server via SSH using the local ssh-agent, password, or private-key.

Nov 6, 2022
Mirror of Apache Calcite - Avatica Go SQL Driver

Apache Avatica/Phoenix SQL Driver Apache Calcite's Avatica Go is a Go database/sql driver for the Avatica server. Avatica is a sub-project of Apache C

Nov 3, 2022
Microsoft ActiveX Object DataBase driver for go that using exp/sql

go-adodb Microsoft ADODB driver conforming to the built-in database/sql interface Installation This package can be installed with the go get command:

Dec 30, 2022
Microsoft SQL server driver written in go language

A pure Go MSSQL driver for Go's database/sql package Install Requires Go 1.8 or above. Install with go get github.com/denisenkom/go-mssqldb . Connecti

Dec 26, 2022
Oracle driver for Go using database/sql

go-oci8 Description Golang Oracle database driver conforming to the Go database/sql interface Installation Install Oracle full client or Instant Clien

Dec 30, 2022
sqlite3 driver for go using database/sql

go-sqlite3 Latest stable version is v1.14 or later not v2. NOTE: The increase to v2 was an accident. There were no major changes or features. Descript

Jan 8, 2023
Go Sql Server database driver.

gofreetds Go FreeTDS wrapper. Native Sql Server database driver. Features: can be used as database/sql driver handles calling stored procedures handle

Dec 16, 2022
Pure Go Postgres driver for database/sql

pq - A pure Go postgres driver for Go's database/sql package Install go get github.com/lib/pq Features SSL Handles bad connections for database/sql S

Jan 2, 2023
Attach hooks to any database/sql driver

sqlhooks Attach hooks to any database/sql driver. The purpose of sqlhooks is to provide a way to instrument your sql statements, making really easy to

Dec 14, 2022
Lightweight Golang driver for ArangoDB

Arangolite Arangolite is a lightweight ArangoDB driver for Go. It focuses on pure AQL querying. See AranGO for a more ORM-like experience. IMPORTANT:

Sep 26, 2022
Golang driver for ClickHouse

ClickHouse Golang SQL database driver for Yandex ClickHouse Key features Uses native ClickHouse tcp client-server protocol Compatibility with database

Jan 8, 2023
Golang MySQL driver

Install go get github.com/vczyh/go-mysql-driver Usage import _ "github.com/vczyh

Jan 27, 2022
GO DRiver for ORacle DB

Go DRiver for ORacle godror is a package which is a database/sql/driver.Driver for connecting to Oracle DB, using Anthony Tuininga's excellent OCI wra

Jan 5, 2023
PostgreSQL driver and toolkit for Go

pgx - PostgreSQL Driver and Toolkit pgx is a pure Go driver and toolkit for PostgreSQL. pgx aims to be low-level, fast, and performant, while also ena

Jan 4, 2023
Go language driver for RethinkDB
Go language driver for RethinkDB

RethinkDB-go - RethinkDB Driver for Go Go driver for RethinkDB Current version: v6.2.1 (RethinkDB v2.4) Please note that this version of the driver on

Dec 24, 2022
goriak - Go language driver for Riak KV
goriak - Go language driver for Riak KV

goriak Current version: v3.2.1. Riak KV version: 2.0 or higher, the latest version of Riak KV is always recommended. What is goriak? goriak is a wrapp

Nov 22, 2022
Mongo Go Models (mgm) is a fast and simple MongoDB ODM for Go (based on official Mongo Go Driver)
Mongo Go Models (mgm) is a fast and simple MongoDB ODM for Go (based on official Mongo Go Driver)

Mongo Go Models Important Note: We changed package name from github.com/Kamva/mgm/v3(uppercase Kamva) to github.com/kamva/mgm/v3(lowercase kamva) in v

Jan 2, 2023
The MongoDB driver for Go

The MongoDB driver for Go This fork has had a few improvements by ourselves as well as several PR's merged from the original mgo repo that are current

Jan 8, 2023