Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
January 21, 2022 02:00 am GMT

Catch error when using SQLite in Golang

I was working on a project using Go and SQLite. For the driver part, I tried 2 libraries:

Below are examples to how to catch "primary key conflict" and "no row found" errors:

With mattn sqlite library:

import (    "database/sql"    "github.com/mattn/go-sqlite3")var (    ErrDup      = errors.New("record already exists")    ErrNoRecord = errors.New("record not found"))func wrapDBError(err error) error {    var sqliteErr sqlite3.Error    if errors.As(err, &sqliteErr) {        if errors.Is(sqliteErr.Code, sqlite3.ErrConstraint) {        return ErrDup        }    } else if errors.Is(err, sql.ErrNoRows) {        return ErrNoRecord    }    return err}

The problem is that it is using CGO, and I am using Macbook M1 for my development. I want to build a release for linux amd64, if I just use:

$ GOOS=linux GOARCH=amd64 go build -o app-linux

It will throw some errors that can't find some symbol. The library suggest to use xgo to cross build, but I still got some errors when I was doing so. Without having time to search and find the problem, I fell back to compile the linux binary with a docker image:

# I am developing on mac m1, so this can be directly builtGOOS=darwin GOARCH=arm64 go build -o build/myapp-darwin# for linux, using docker to build itdocker run --rm -v $(PWD):/myapp -w /myapp amd64/golang:bullseye go build -o build/myapp-linux -v

This works, both myapp-darwin and myapp-linux will be compiled and generated under the build folder. However, the second build with docker would take much longer time than I thought, approximately 1~2 minutes.

So I start to looking for other libraries that doesn't require CGO.

With modernc.org/sqlite library

This library doesn't need CGO, and I am able to find the way how to catch the "primary key conflict" and "no rows found" error by looking the source code:

import (    "database/sql"    "modernc.org/sqlite"    sqlite3 "modernc.org/sqlite/lib")func wrapDBError(err error) error {    if err != nil {        if errors.Is(err, sql.ErrNoRows) {            return ErrNoRecord        }        if liteErr, ok := err.(*sqlite.Error); ok {            code := liteErr.Code()            if code == sqlite3.SQLITE_CONSTRAINT_PRIMARYKEY {                return ErrDup            }        }    }    return err}

Since this lib doesn't use CGO, cross-build is easy and fast:

GOOS=darwin GOARCH=arm64 go build -o build/myapp-darwinGOOS=linux GOARCH=amd64 go build -o build/myapp-linux

It only takes seconds to finish the compilation.

Conclusion

For now I will stick to the second library which doesn't require CGO. Other than catching the errors part, there are basically no difference between those 2 libraries when writing sql (CRUD) operations.

Reference


Original Link: https://dev.to/0xbf/catch-error-when-using-sqlite-in-golang-58nn

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To