/gomodel

A lightweight, fast, orm-like library helps interactive with database

Primary LanguageGoMIT LicenseMIT

gomodel wercker status GoDoc

gomodel provide another method to interact with database.
Instead of reflection, use bitset represent fields of CRUD, sql/stmt cache and generate model code for you, high performance.

Install

$ go get github.com/cosiner/gomodel
$ cd /path/of/gomodel/cmd/gomodel
$ go install # it will install the gomodel binary file to your $GOPATH/bin
$ gomodel -cp # copy model.tmpl to default path $HOME/.config/go/model.tmpl
              # or just put it to your model package, gomodel will search it first 
$ # if need customed template, just copy model.tmpl to your models directory

The gomodel cmd tool and SQL convertion for structures.

There is a detailed example User-Follow.

User

var (
    ErrDuplicateUserName = httperrs.Conflict.NewS("user name already exists")
    ErrNoUser            = httperrs.NotFound.NewS("user not found")
)

type User struct {
    Id   int64
    Name string
    Age  int

    Followings int
    Followers  int
}

func (u *User) Add() error {
    u.Followings = 0
    u.Followers = 0

    id, err := DB.Insert(u, userFieldsExcpId, gomodel.RES_ID)
    err = dberrs.DuplicateKeyError(err, UserNameCol, ErrDuplicateUserName)
    if err == nil {
        u.Id = id
    }

    return err
}

func DeleteUserById(id int64) error {
    c, err := DB.ArgsDelete(userInstance, USER_ID, id)

    return dberrs.NoAffects(c, err, ErrNoUser)
}

func (u *User) Update() error {
    c, err := DB.Update(u, USER_NAME|USER_AGE, USER_ID)

    return dberrs.NoAffects(c, err, ErrNoUser)
}

func (u *User) ById() error {
    err := DB.One(u, userFieldsExcpId, USER_ID)

    return dberrs.NoRows(err, ErrNoUser)
}

func UsersByAge(age, start, count int) ([]User, error) {
    users := userStore{
        Fields: userFieldsAll,
    }

    err := DB.ArgsLimit(&users, userInstance, userFieldsAll, USER_AGE, age, start, count)
    return users.Values, dberrs.NoRows(err, ErrNoUser)
}

func AllUsersByAge(age int) ([]User, error) {
    users := userStore{
        Fields: userFieldsAll,
    }

    err := DB.ArgsAll(&users, userInstance, userFieldsAll, USER_AGE, age)
    return users.Values, dberrs.NoRows(err, ErrNoUser)
}

Follow

var (
    ErrFollowed  = httperrs.Conflict.NewS("already followed")
    ErrNonFollow = httperrs.NotFound.NewS("non follow")
)

type Follow struct {
    UserId       int64 `table:"user_follow"`
    FollowUserId int64
}


//gomodel insertUserFollowSQL = [
//  INSERT INTO Follow(UserId, FollowUserId)
//      SELECT ?, ? FROM DUAL
//      WHERE EXISTS(SELECT Id FROM User WHERE Id=?)
//]
func (f *Follow) Add() error {
    return f.txDo(DB, func(tx gomodel.Tx, f *Follow) error {
        c, err := tx.UpdateById(insertUserFollowSQL, gomodel.FieldVals(f, followFieldsAll, f.FollowUserId)...)

        err = dberrs.NoAffects(c, err, ErrNoUser)
        err = dberrs.DuplicateKeyError(err, dberrs.PRIMARY_KEY, ErrFollowed)

        return f.updateFollowInfo(tx, err, 1)
    })
}

func (f *Follow) Delete() error {
    return f.txDo(DB, func(tx gomodel.Tx, f *Follow) error {
        c, err := tx.Delete(f, followFieldsAll)
        err = dberrs.NoAffects(c, err, ErrNonFollow)

        return f.updateFollowInfo(tx, err, -1)
    })
}

func (f *Follow) updateFollowInfo(tx gomodel.Tx, err error, c int) error {
    if err == nil {
        _, err = tx.ArgsIncrBy(userInstance, USER_FOLLOWINGS, USER_ID, c, f.UserId)
        if err == nil {
            _, err = tx.ArgsIncrBy(userInstance, USER_FOLLOWERS, USER_ID, c, f.FollowUserId)
        }
    }
    return err
}

LICENSE

MIT.