gorm-sample

module
v0.0.0-...-aa3d205 Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2024 License: GPL-3.0

README

GORM sample


GitHub Workflow Status (with event)

Introduction

Golang doesn't have many ORMs and one the famous one is GORM. Here we want to demonstrate some of its features using a very simple application.

Also, using GORM's AutoMigrate feature is not suitable for production because you cannot find out what is going to be changed on each commit. Atlas can help you with this.

Atlas works based on its configuration defined in atlas.hcl. You can apply migrations with

atlas migrate apply --env local

and see the differences with

atlas migrate diff --env local

GORM

Here is the official GORM package:

The followings are GORM drivers for popular databases:

In the following code we create connection using GORM and have zap as our logger:

import (
 "gorm.io/gorm"
 "gorm.io/driver/postgres"
 "moul.io/zapgorm2"
)

func main() {
 logger, err := zap.NewDevelopment()
 if err != nil {
  logger = zap.NewNop()
 }

 db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
  Logger: zapgorm2.New(logger),
 })
}
type User struct {
 ID uint
 FirstName string

 CreatedAt time.Time
 DeletedAt time.Time
}


db.Where("name = ?", "parham").Last()
db.Where("name = ?", "parham").First()
db.Where("name = ?", "parham").Find()
  • User (structure): plural snake-case as table name
  • ID (field): primary-key by default, please pay attention
  • FirstName (field): snake-case as column name

Hooks as methods on model.

JSON with SQL

You can also create custom JSON based data-types with the following example:

// JSONMap defiend JSON data type, need to implements driver.Valuer, sql.Scanner interface
type JSONMap map[string]interface{}

// Value return json value, implement driver.Valuer interface
func (m JSONMap) Value() (driver.Value, error) {
  if m == nil {
    return nil, nil
  }
  ba, err := m.MarshalJSON()
  return string(ba), err
}

// Scan scan value into Jsonb, implements sql.Scanner interface
func (m *JSONMap) Scan(val interface{}) error {
  var ba []byte
  switch v := val.(type) {
  case []byte:
    ba = v
  case string:
    ba = []byte(v)
  default:
    return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", val))
  }
  t := map[string]interface{}{}
  err := json.Unmarshal(ba, &t)
  *m = JSONMap(t)
  return err
}

// MarshalJSON to output non base64 encoded []byte
func (m JSONMap) MarshalJSON() ([]byte, error) {
  if m == nil {
    return []byte("null"), nil
  }
  t := (map[string]interface{})(m)
  return json.Marshal(t)
}

// UnmarshalJSON to deserialize []byte
func (m *JSONMap) UnmarshalJSON(b []byte) error {
  t := map[string]interface{}{}
  err := json.Unmarshal(b, &t)
  *m = JSONMap(t)
  return err
}

// GormDataType gorm common data type
func (m JSONMap) GormDataType() string {
  return "jsonmap"
}

// GormDBDataType gorm db data type
func (JSONMap) GormDBDataType(db *gorm.DB, field *schema.Field) string {
  switch db.Dialector.Name() {
  case "sqlite":
    return "JSON"
  case "mysql":
    return "JSON"
  case "postgres":
    return "JSONB"
  }
  return ""
}

Directories

Path Synopsis
cmd
cli
internal

Jump to

Keyboard shortcuts

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