All Projects → si3nloong → sqlike

si3nloong / sqlike

Licence: MIT license
Golang Sequel ORM that supports Enum, JSON, Spatial, and many more

Programming Languages

go
31211 projects - #10 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to sqlike

spatial-microsim-book
Code, data and prose of the book: Spatial Microsimulation with R
Stars: ✭ 98 (+444.44%)
Mutual labels:  spatial
FastGWR
Fast Geographically Weighted Regression (FastGWR)
Stars: ✭ 26 (+44.44%)
Mutual labels:  spatial
NHibernate.Spatial
NHibernate.Spatial is a library of spatial extensions for NHibernate, and allows you to connect NHibernate to a spatially enabled database and manipulate geometries in Linq or HQL using NetTopologySuite, providing you with a fully integrated GIS programming experience.
Stars: ✭ 38 (+111.11%)
Mutual labels:  spatial
flask-authz
Use Casbin in Flask, Casbin is a powerful and efficient open-source access control library.
Stars: ✭ 100 (+455.56%)
Mutual labels:  casbin
geosapi
R interface to GeoServer REST API
Stars: ✭ 26 (+44.44%)
Mutual labels:  spatial
jaeger-node
Out of the box distributed tracing for Node.js applications.
Stars: ✭ 66 (+266.67%)
Mutual labels:  opentracing
sequel-batches
Sequel extension for querying large datasets in batches
Stars: ✭ 16 (-11.11%)
Mutual labels:  sequel
sqlalchemy-adapter
SQLAlchemy Adapter for PyCasbin
Stars: ✭ 53 (+194.44%)
Mutual labels:  casbin
casbin-pg-adapter
A go-pg adapter for casbin
Stars: ✭ 23 (+27.78%)
Mutual labels:  casbin
java-jaxrs
OpenTracing Java JAX-RS instrumentation
Stars: ✭ 37 (+105.56%)
Mutual labels:  opentracing
basemaps
A lightweight package for accessing basemaps from open sources in R 🗺️
Stars: ✭ 39 (+116.67%)
Mutual labels:  spatial
CopyAsMarkdownForSequelProBundle
Copy selected rows as Markdown. It's so easy to paste in GitHub issue.
Stars: ✭ 23 (+27.78%)
Mutual labels:  sequel
geoflow
R engine to orchestrate and run (meta)data workflows
Stars: ✭ 28 (+55.56%)
Mutual labels:  spatial
uuid
A decentralized favorites and bookmarks based on Git hosting
Stars: ✭ 70 (+288.89%)
Mutual labels:  uuid
uuids
UUID library for Nim
Stars: ✭ 28 (+55.56%)
Mutual labels:  uuid
Intro to spatial analysis
Intro to spatial analysis in R
Stars: ✭ 28 (+55.56%)
Mutual labels:  spatial
colossal-squuid
Library for generating sequential UUIDs, or SQUUIDs
Stars: ✭ 52 (+188.89%)
Mutual labels:  uuid
sqlx-adapter
Asynchronous casbin adapter for mysql, postgres, sqlite based on sqlx-rs
Stars: ✭ 27 (+50%)
Mutual labels:  casbin
scala-akka
OpenTracing instrumentation for Scala Akka
Stars: ✭ 16 (-11.11%)
Mutual labels:  opentracing
sabre
sabre: Spatial Association Between REgionalizations
Stars: ✭ 34 (+88.89%)
Mutual labels:  spatial

sqlike

Build Release Go Report Go Coverage LICENSE FOSSA Status

A Golang SQL ORM which anti-toxic query and focus on the latest features.

🔨 Installation

go get github.com/si3nloong/sqlike

Fully compatible with native library database/sql, which mean you are allow to use driver.Valuer and sql.Scanner.

📻 Legacy Support

SQLike did support mysql 5.7 as well. For better compatibility, we suggest you to use at least mysql 8.0.

🪣 Minimum Requirements

  • mysql 8.0 and above
  • golang 1.15 and above

Why another ORM?

  • We don't really care about legacy support, we want latest feature that mysql and golang offer us
  • We want to get rid from toxic query (also known as slow query)

What do we provide apart from native package (database/sql)?

  • Support ENUM and SET
  • Support UUID (^8.0)
  • Support JSON
  • Support descending index (^8.0)
  • Support multi-valued index (^8.0.17)
  • Support Spatial with package orb, such as Point, LineString
  • Support generated column of stored column and virtual column
  • Extra custom type such as Date, Key, Boolean
  • Support struct on Find, FindOne, InsertOne, Insert, ModifyOne, DeleteOne, Delete, DestroyOne and Paginate apis
  • Support Transactions
  • Support cursor based pagination
  • Support advance and complex query statement
  • Support civil.Date, civil.Time and time.Location
  • Support language.Tag and currency.Unit
  • Support authorization plugin Casbin
  • Support tracing plugin OpenTracing
  • Developer friendly, (query is highly similar to native sql query)
  • Support sqldump for backup purpose (experiment)

⚠️ Limitation

Our main objective is anti toxic query, that why some functionality we doesn't offer out of box

  • offset based pagination (but you may achieve this by using Limit and Offset)
  • eager loading (we want to avoid magic function, you should handle this by your own using goroutines)
  • join (eg. left join, outer join, inner join), join clause is consider as toxic query, you should alway find your record using primary key
  • left wildcard search using Like is not allow (but you may use expr.Raw to bypass it)
  • bidirectional sorting is not allow (except mysql 8.0 and above)
  • currently only support mysql driver (postgres and sqlite yet to implement)

General APIs

package main

import (
    "time"
    "github.com/si3nloong/sqlike/sqlike/actions"
    "github.com/si3nloong/sqlike/sqlike"
    "github.com/si3nloong/sqlike/sqlike/options"
    "github.com/si3nloong/sqlike/sql/expr"
    "github.com/google/uuid"
    "context"

    _ "github.com/go-sql-driver/mysql"
)

// UserStatus :
type UserStatus string

const (
    UserStatusActive  UserStatus = "ACTIVE"
    UserStatusSuspend UserStatus = "SUSPEND"
)

type User struct {
    ID        uuid.UUID  `sqlike:",primary_key"`
    ICNo      string     `sqlike:",generated_column"` // generated column generated by virtual column `Detail.ICNo`
    Name      string     `sqlike:",size=200,charset=latin1"` // you can set the data type length and charset with struct tag
    Email     string     `sqlike:",unique"` // set to unique
    Address   string     `sqlike:",longtext"` // `longtext` is an alias of long text data type in mysql
    Detail    struct {
        ICNo    string `sqlike:",virtual_column=ICNo"` // virtual column
        PhoneNo string
        Age     uint
    }
    Status    UserStatus `sqlike:",enum=ACTIVE|SUSPEND"` // enum data type
    CreatedAt time.Time
    UpdatedAt time.Time
}

func newUser() (user User) {
    now := time.Now()
    user.ID = uuid.New()
    user.CreatedAt = now
    user.UpdatedAt = now
    return
}

func main() {
    ctx := context.Background()
    client := sqlike.MustConnect(
        ctx,
        "mysql",
        options.Connect().
        SetUsername("root").
        SetPassword("").
        SetHost("localhost").
        SetPort("3306"),
    )

    client.SetPrimaryKey("ID") // Change default primary key name
    version := client.Version() // Display driver version
    dbs, _ := client.ListDatabases(ctx) // List databases

    userTable := client.Database("sqlike").Table("User")

    // Drop Table
    userTable.Drop(ctx)

    // Migrate Table
    userTable.Migrate(ctx, User{})

    // Truncate Table
    userTable.Truncate(ctx)

    // Insert one record
    {
        user := newUser()
        if _, err := userTable.InsertOne(ctx, &user); err != nil {
            panic(err)
        }
    }

    // Insert multiple record
    {
        users := [...]User{
            newUser(),
            newUser(),
            newUser(),
        }
        if _, err := userTable.Insert(ctx, &users); err != nil {
            panic(err)
        }
    }

    // Find one record
    {
        user := User{}
        err := userTable.FindOne(ctx, nil).Decode(&user)
        if err != nil {
            // `sqlike.ErrNoRows` is an alias of `sql.ErrNoRows`
            if err != sqlike.ErrNoRows {  // or you may check with sql.ErrNoRows
                panic(err)
            }
            // record not exist
        }
    }

    // Find multiple records
    {
        users := make([]User, 0)
        result, err := userTable.Find(
            ctx,
            actions.Find().
                Where(
                    expr.Equal("ID", result.ID),
                ).
                OrderBy(
                    expr.Desc("UpdatedAt"),
                ),
        )
        if err != nil {
            panic(err)
        }
        // map into the struct of slice
        if err:= result.All(&users); err != nil {
            panic(err)
        }
    }

    // Update one record with all fields of struct
    {
        user.Name = `🤖 Hello World!`
        if err := userTable.ModifyOne(ctx, &user); err != nil {
            panic(err)
        }
    }

    // Update one record with selected fields
    {
        userTable.UpdateOne(
            ctx,
            actions.UpdateOne().
                Where(
                    expr.Equal("ID", 100),
                ).Set(
                    expr.ColumnValue("Name", "SianLoong"),
                    expr.ColumnValue("Email", "[email protected]"),
                ),
            options.UpdateOne().SetDebug(true), // debug the query
        )
    }

    {
        limit := uint(10)
        pg, err := userTable.Paginate(
            ctx,
            actions.Paginate().
                OrderBy(
                    expr.Desc("CreatedAt"),
                ).
                Limit(limit + 1),
             options.Paginate().SetDebug(true),
        )
        if err != nil {
            panic(err)
        }

        for {
            var users []User
            if err := pg.All(&users); err != nil {
                panic(err)
            }
            length := uint(len(users))
            if length == 0 {
                break
            }
            cursor := users[length-1].ID
            if err := pg.NextCursor(ctx, cursor); err != nil {
                if err == sqlike.ErrInvalidCursor {
                    break
                }
                panic(err)
            }
            if length <= limit {
                break
            }
        }

    }
}

Inspired by gorm, mongodb-go-driver and sqlx.

🎉 Big Thanks To

Thanks to these awesome companies for their support of Open Source developers

GitHub NPM

📄 License

MIT

Copyright (c) 2019-present, SianLoong Lee

FOSSA Status

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].