duckdb

package module
v0.0.0-...-c46ebee Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 30, 2024 License: MIT Imports: 14 Imported by: 0

README


DuckDB logo

GORM DuckDB Driver

Report Bug


Quick Start

import (
  "github.com/alifiroozi80/duckdb"
  "gorm.io/gorm"
)

// DO NOT use 'gorm.Model' here. See 'Limitations' for more.
type Product struct {
	ID        uint `gorm:"primarykey"`
	Code      string
	Price     uint
	CreatedAt time.Time
	UpdatedAt time.Time
}

func main() {
	// duckdb extentions: .ddb, .duckdb, .db
        db, err := gorm.Open(duckdb.Open("duckdb.ddb"), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}

	// Migrate the schema
	db.AutoMigrate(&Product{})

	// Create
	db.Create(&Product{Code: "D42", Price: 100})

        // Read
	var product Product
	db.First(&product, 1)                 // find product with integer primary key
	db.First(&product, "code = ?", "D42") // find product with code D42

	// Update - update product's price to 200
	db.Model(&product).Update("Price", 200)
	// Update - update multiple fields
	db.Model(&product).Updates(Product{Price: 200, Code: "F42"}) // non-zero fields
	db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})

	// Delete - delete product
	db.Delete(&product, 1)
}

Checkout https://gorm.io for details.

Limitations

deleted_at field.

DuckDB has two index types:

  • Min-Max (Zonemap)
  • Adaptive Radix Tree In DuckDB, ART indexes are automatically created for columns with a UNIQUE or PRIMARY KEY constraint and can be defined using CREATE INDEX.

However, every technology has its pros and cons. Despite being helpful (read attached pdf), ART indexes have some limitations.

ART indexes create a secondary copy of the data in a second location – this complicates processing, particularly when combined with transactions. Certain limitations apply when it comes to modifying data stored in secondary indexes.

Due to the presence of transactions, data can only be removed from the index after the transaction that performed the delete is committed and no further transactions that refer to the old entry are still present in the index. As a result, transactions that perform deletions followed by insertions may trigger unexpected, unique constraint violations, as the deleted tuple has not yet been removed from the index. For example:

GORM will update the deleted_at column when you perform a db.Delete(). so your db.Delete() will be translate to:

UPDATE products SET deleted_at='2024-11-01 12:06:00.942' WHERE products.id = 1 AND products.deleted_at IS NULL;

And it cause an error:

Constraint Error: Duplicate key "id: 1" violates primary key constraint. If this is an unexpected constraint violation please double check with the known index limitations section in our documentation (https://duckdb.org/docs/sql/indexes).

That is why you should not use the default gorm.Model structure and manually use ID, CreatedAt and UpdatedAt.

For more info, see DuckDB documentations.


JSONB

DuckDB doesn't support JSONB schema yet, so whenever you use gorm:"type:jsonb", it will translate it to gorm:"type:json" under the hood.

Why did I add this?

Because in a couple of projects that I was contributing to, this type was being used in GORM drivers, so I added this small thing to avoid facing the below error:

Catalogue Error: Type with name jsonb does not exist!

Contributing

Any contributions you make are greatly appreciated.

See here for more details on contributing.

Roadmap

  • Support switch indexes between ART and Min-Max in the configuraion.
  • Implement TODO functions:
    • ColumnTypes
    • CreateConstraint
  • Support sequence for each field that needs auto-increment (See here).

License

The license is under the MIT License. See LICENSE for more information.

❤ Show your support

Give a ⭐️ if this project helped you!

Documentation

Index

Constants

View Source
const DriverName = "duckdb"

Variables

View Source
var ErrDuckDBNotSupported = errors.New("DuckDB are not supported this operation")

Functions

func New

func New(config Config) gorm.Dialector

func Open

func Open(dsn string) gorm.Dialector

Types

type BuildIndexOptionsInterface

type BuildIndexOptionsInterface interface {
	BuildIndexOptions([]schema.IndexOption, *gorm.Statement) []interface{}
}

type Config

type Config struct {
	DriverName string
	DSN        string
	Conn       gorm.ConnPool
}

type Dialector

type Dialector struct {
	*Config
}

func (Dialector) BindVarTo

func (dialector Dialector) BindVarTo(writer clause.Writer, stmt *gorm.Statement, v interface{})

func (Dialector) ClauseBuilders

func (dialector Dialector) ClauseBuilders() map[string]clause.ClauseBuilder

func (Dialector) DataTypeOf

func (dialector Dialector) DataTypeOf(field *schema.Field) string

func (Dialector) DefaultValueOf

func (dialector Dialector) DefaultValueOf(field *schema.Field) clause.Expression

func (Dialector) Explain

func (dialector Dialector) Explain(sql string, vars ...interface{}) string

func (Dialector) Initialize

func (dialector Dialector) Initialize(db *gorm.DB) (err error)

func (Dialector) Migrator

func (dialector Dialector) Migrator(db *gorm.DB) gorm.Migrator

func (Dialector) Name

func (dialector Dialector) Name() string

func (Dialector) QuoteTo

func (dialector Dialector) QuoteTo(writer clause.Writer, str string)

func (Dialector) RollbackTo

func (dialectopr Dialector) RollbackTo(tx *gorm.DB, name string) error

func (Dialector) SavePoint

func (dialectopr Dialector) SavePoint(tx *gorm.DB, name string) error

type Migrator

type Migrator struct {
	migrator.Migrator
}

func (Migrator) AddColumn

func (m Migrator) AddColumn(value interface{}, field string) error

func (Migrator) AlterColumn

func (m Migrator) AlterColumn(value interface{}, field string) error

func (Migrator) CreateIndex

func (m Migrator) CreateIndex(value interface{}, name string) error

func (Migrator) CreateTable

func (m Migrator) CreateTable(values ...interface{}) (err error)

func (Migrator) CreateView

func (m Migrator) CreateView(name string, option gorm.ViewOption) error

Views

func (Migrator) CurrentDatabase

func (m Migrator) CurrentDatabase() (name string)

func (Migrator) CurrentSchema

func (m Migrator) CurrentSchema(stmt *gorm.Statement, table string) (interface{}, interface{})

func (Migrator) DropColumn

func (m Migrator) DropColumn(dst interface{}, field string) error

func (Migrator) DropIndex

func (m Migrator) DropIndex(value interface{}, name string) error

func (Migrator) DropTable

func (m Migrator) DropTable(values ...interface{}) error

func (Migrator) DropView

func (m Migrator) DropView(name string) error

func (Migrator) FullDataTypeOf

func (m Migrator) FullDataTypeOf(field *schema.Field) clause.Expr

func (Migrator) GetTables

func (m Migrator) GetTables() (tableList []string, err error)

func (Migrator) GetTypeAliases

func (m Migrator) GetTypeAliases(databaseTypeName string) []string

func (Migrator) HasColumn

func (m Migrator) HasColumn(value interface{}, field string) bool

func (Migrator) HasConstraint

func (m Migrator) HasConstraint(value interface{}, name string) bool

func (Migrator) HasIndex

func (m Migrator) HasIndex(value interface{}, name string) bool

func (Migrator) HasTable

func (m Migrator) HasTable(value interface{}) bool

func (Migrator) MigrateColumn

func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnType gorm.ColumnType) error

func (Migrator) RenameColumn

func (m Migrator) RenameColumn(dst interface{}, oldName, field string) error

func (Migrator) RenameIndex

func (m Migrator) RenameIndex(dst interface{}, oldName, newName string) error

func (Migrator) RenameTable

func (m Migrator) RenameTable(oldName, newName interface{}) (err error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL