Skip to content

Commit

Permalink
Fix directory structure (#16)
Browse files Browse the repository at this point in the history
* add a v2 directory and get everything working

* fix some strange bug in the generated workspace file

* also have to fix the staticcheck test
  • Loading branch information
arjenderijke authored Jan 25, 2024
1 parent f731612 commit e543a7e
Show file tree
Hide file tree
Showing 33 changed files with 4,537 additions and 10 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ jobs:
uses: dominikh/[email protected]
with:
version: "2023.1.6"
working-directory: "v2"

- name: Build
run: go build -v ./...
run: go build -v ./v2

- name: Test
run: go test -v -test.short ./...
run: go test -v -short ./v2
4 changes: 2 additions & 2 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
cache: false

- name: Build
run: go build -v ./...
run: go build -v ./v2

- name: Test
run: go test -v -test.short ./...
run: go test -v -short ./v2
5 changes: 2 additions & 3 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ jobs:
run: choco install golang

- name: Build
run: go build -v ./...
run: go build -v ./v2

- name: Test
# For some reason, the command is different than on linux/macos
run: go test -short -v ./...
run: go test -short -v ./v2


4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ To install the `monetdb` package to your `$GOPATH`, simply use
the `go` tool. Make sure you have [Git](http://git-scm.com/downloads) installed.

```bash
$ go get github.com/MonetDB/MonetDB-Go
$ go get github.com/MonetDB/MonetDB-Go@v2.0.1
```

## Usage
Expand All @@ -22,7 +22,7 @@ Once you import it, you can use the standard Go database API to access MonetDB.
```go
import (
"database/sql"
_ "github.com/MonetDB/MonetDB-Go/src"
_ "github.com/MonetDB/MonetDB-Go/v2"
)
```

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/MonetDB/MonetDB-Go

go 1.16
go 1.18
3 changes: 3 additions & 0 deletions go.work
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
go 1.21

use ./v2
4 changes: 4 additions & 0 deletions implementation.MD
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ The [go sql library](https://pkg.go.dev/database/sql) and the [go sql driver lib

The previous version, v1.1.0, implemented the Go v1.7 library interfaces. The latest version, v2.0.0, implements the latest database interfaces (go 1.21.5). This provides more functionality, specifically the column types and supporting the context interface.

### Go module major version

It turns out that the go module system has a specific way of implementing a new major version of a module. This is explained in [this](https://go.dev/blog/v2-go-modules#TOC_4.) blog post. This means the the published version v2.0.0 is completely unusable. Unfortunately, when you fix the repository as suggested, the old version of the module becomes completely unusable. There is no obvious fix for this, so for now we accept this. This means that the code in this repository only works for major version v2. We also needed to upgrade the required go version to 1.18, because we needed the go workspace functionality in order to be able to run tests for the v2 version

### Mapi

[Mapi](https://www.monetdb.org/documentation-Jun2023/user-guide/client-interfaces/libraries-drivers/mapi-library/) is the API that provides the communication protocol with the MonetDB database. To understand the details of the mapi protocol implementation in this library, check the documentation in the [PHP](https://github.com/MonetDB/MonetDB-PHP/tree/master/protocol_doc) driver.
Expand Down
147 changes: 147 additions & 0 deletions v2/conn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package monetdb

import (
"context"
"database/sql"
"database/sql/driver"
"fmt"
"time"

"github.com/MonetDB/MonetDB-Go/v2/mapi"
)

type Conn struct {
mapi *mapi.MapiConn
timezone *time.Location
}

func newConn(name string) (*Conn, error) {
conn := &Conn{
mapi: nil,
}

// For now we do not change the timezone, because this might certain users.
// conn.timezone = time.Local
m, err := mapi.NewMapi(name)
if err != nil {
return conn, err
}
errConn := m.Connect()
if errConn != nil {
return conn, errConn
}

conn.mapi = m
m.SetSizeHeader(true)
conn.setServerTimezone()
return conn, nil
}

func (c *Conn) setServerTimezone() error {
tz, err := time.LoadLocation(c.timezone.String())
if err != nil {
return err
}
if tz.String() != c.timezone.String() {
return err
}
_, offset := time.Now().Zone()

hours := int(offset / 3600)
remaining := offset - 3600 * hours
minutes := int(remaining / 60)
// Go does not have an absolute value function for int
if minutes < 0 {
minutes = -1 * minutes
}
query := fmt.Sprintf("SET TIME ZONE INTERVAL '%+03d:%02d' HOUR TO MINUTE;", hours, minutes)
err = executeStmt(c, query)
return err
}

func (c *Conn) Prepare(query string) (driver.Stmt, error) {
return newStmt(c, query, true), nil
}

func (c *Conn) Close() error {
// TODO: close prepared statements
c.mapi.Disconnect()
c.mapi = nil
return nil
}

func (c *Conn) begin(readonly bool, isolation driver.IsolationLevel) (driver.Tx, error) {
t := newTx(c)
var query string
if readonly {
// The monetdb documentation mentions this options, but it is not supported
query = "START TRANSACTION READ ONLY"
} else {
switch isolation {
case driver.IsolationLevel(sql.LevelDefault):
query = "START TRANSACTION"
case driver.IsolationLevel(sql.LevelReadUncommitted):
query = "START TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"
case driver.IsolationLevel(sql.LevelReadCommitted):
query = "START TRANSACTION ISOLATION LEVEL READ COMMITTED"
case driver.IsolationLevel(sql.LevelRepeatableRead):
query = "START TRANSACTION ISOLATION LEVEL REPEATABLE READ"
case driver.IsolationLevel(sql.LevelSerializable):
query = "START TRANSACTION ISOLATION LEVEL SERIALIZABLE"
default:
err := fmt.Errorf("monetdb: unsupported transaction level")
t.err = err
return t, t.err
}
}

err := executeStmt(c, query)

if err != nil {
t.err = err
}

return t, t.err
}

// Deprecated: Use BeginTx instead
func (c *Conn) Begin() (driver.Tx, error) {
return c.begin(false, driver.IsolationLevel(sql.LevelDefault))
}

func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
tx, err := c.begin(opts.ReadOnly, opts.Isolation)
return tx, err
}

func (c *Conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
stmt := newStmt(c, query, false)
res, err := stmt.ExecContext(ctx, args)
defer stmt.Close()

return res, err
}

func (c *Conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
// QueryContext may return ErrSkip.
// QueryContext must honor the context timeout and return when the context is canceled.
stmt := newStmt(c, query, false)
res, err := stmt.QueryContext(ctx, args)
defer stmt.Close()

return res, err
}

func (c *Conn) PrepareContext(ctx context.Context, query string) (Stmt, error) {
stmt := newStmt(c, query, true)
return *stmt, nil
}

func (c *Conn) CheckNamedValue(arg *driver.NamedValue) error {
_, err := mapi.ConvertToMonet(arg.Value)
return err
}
Loading

0 comments on commit e543a7e

Please sign in to comment.