# Orm
Connects schemadriver
with dsn
,
loads schema
info for generating ORM
struct and codes.
# Usage
# Annotation
+zz:orm:[schema][:options...]
# Exact Arguments
# schema
Specify database schema
to loads.
- Use
,
to separate multi value.
Example: +zz:orm:my_database,my_database2
# Optional Arguments
# filename
Generate target filepath, default: ./zzgen.orm.go
.
Example: +zz:orm:schema:filename=./models/
# driver
Specify schemadriver
.
This driver
is not sql.Driver
,
but it is the interface for plugin loading different kind of database schema.
External extension interface could be loaded from .so
.
default: mysql
.
Example: +zz:orm:schema:driver=sqlite
# type
Specify type mapping from database type to golang type,
format as: ${database DATA_TYPE}=${Golang type}
Example: +zz:orm:schema:type=varchar=MyString
- Use
,
to join multi types.
Example: +zz:orm:schema:type=varchar=MyString,varchar(255)=string,int unsign=uint
The priority of type matching would be controlled by schemadriver
implement.
- Use
*
to specifyNullable
type.
Example: +zz:orm:schema:type=*varchar=sql.NullString,*json=*json.RawMessage
# table
Specify database tables to generates from, default: *
for all tables.
- Use
,
to join multi tables.
Example: +zz:orm:schema:table=user,car,order
# password
Generally, developer would use orm
to generate code in local develop environment,
And database in this case mostly were installed and exported as default connection.
So schemadriver
should provide a default dsn
template for default database connection.
For example: mysql
use root:${pwd}@tcp(localhost:3306)/
.
Users could provide password
only and
complete all configuration to access the schema source database.
We suggest to use this plugin as example:
read -s pwd && gozz run -p "orm:password=${pwd}" ./
# dsn
You could also provide full dsn
url to access.
If you have letter :
in argument,
you should use \
to argument escape.
Example:
read -s pwd && gozz run -p "orm:dsn=dev_user\:${pwd}@tcp(192.168.1.2\:3306)/" ./
# Examples
Example Project (opens new window) Example SQL (opens new window)
package orm01
// +zz:orm:{{ .Name }}
type employees struct{}
Execute gozz run -p "orm:password=***" ./
, and it generates file zzgen.orm.go
and template file.
// Code generated by gozz:orm github.com/go-zing/gozz. DO NOT EDIT.
package orm01
import (
"context"
"database/sql"
"encoding/json"
"time"
)
var (
_ = (*context.Context)(nil)
_ = (*json.RawMessage)(nil)
_ = (*time.Time)(nil)
_ = (*sql.NullString)(nil)
)
var tables = []interface{}{
CurrentDeptEmp{},
Departments{},
DeptEmp{},
DeptEmpLatestDate{},
DeptManager{},
Employees{},
Salaries{},
Titles{},
}
// employees.current_dept_emp
// VIEW
const TableCurrentDeptEmp = "current_dept_emp"
type CurrentDeptEmp struct {
// emp_no : int
EmpNo int
// dept_no : char(4)
DeptNo string
// from_date : NULLABLE date
FromDate interface{}
// to_date : NULLABLE date
ToDate interface{}
}
func (CurrentDeptEmp) TableName() string { return TableCurrentDeptEmp }
func (m *CurrentDeptEmp) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["dept_no"] = &m.DeptNo
dst["from_date"] = &m.FromDate
dst["to_date"] = &m.ToDate
}
type SliceCurrentDeptEmp []CurrentDeptEmp
func (s *SliceCurrentDeptEmp) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, CurrentDeptEmp{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.departments
const TableDepartments = "departments"
type Departments struct {
// dept_no : char(4)
DeptNo string
// dept_name : varchar(40)
DeptName string
}
func (Departments) TableName() string { return TableDepartments }
func (m *Departments) FieldMapping(dst map[string]interface{}) {
dst["dept_no"] = &m.DeptNo
dst["dept_name"] = &m.DeptName
}
type SliceDepartments []Departments
func (s *SliceDepartments) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, Departments{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.dept_emp
const TableDeptEmp = "dept_emp"
type DeptEmp struct {
// emp_no : int
EmpNo int
// dept_no : char(4)
DeptNo string
// from_date : date
FromDate interface{}
// to_date : date
ToDate interface{}
}
func (DeptEmp) TableName() string { return TableDeptEmp }
func (m *DeptEmp) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["dept_no"] = &m.DeptNo
dst["from_date"] = &m.FromDate
dst["to_date"] = &m.ToDate
}
type SliceDeptEmp []DeptEmp
func (s *SliceDeptEmp) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, DeptEmp{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.dept_emp_latest_date
// VIEW
const TableDeptEmpLatestDate = "dept_emp_latest_date"
type DeptEmpLatestDate struct {
// emp_no : int
EmpNo int
// from_date : NULLABLE date
FromDate interface{}
// to_date : NULLABLE date
ToDate interface{}
}
func (DeptEmpLatestDate) TableName() string { return TableDeptEmpLatestDate }
func (m *DeptEmpLatestDate) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["from_date"] = &m.FromDate
dst["to_date"] = &m.ToDate
}
type SliceDeptEmpLatestDate []DeptEmpLatestDate
func (s *SliceDeptEmpLatestDate) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, DeptEmpLatestDate{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.dept_manager
const TableDeptManager = "dept_manager"
type DeptManager struct {
// emp_no : int
EmpNo int
// dept_no : char(4)
DeptNo string
// from_date : date
FromDate interface{}
// to_date : date
ToDate interface{}
}
func (DeptManager) TableName() string { return TableDeptManager }
func (m *DeptManager) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["dept_no"] = &m.DeptNo
dst["from_date"] = &m.FromDate
dst["to_date"] = &m.ToDate
}
type SliceDeptManager []DeptManager
func (s *SliceDeptManager) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, DeptManager{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.employees
const TableEmployees = "employees"
type Employees struct {
// emp_no : int
EmpNo int
// birth_date : date
BirthDate interface{}
// first_name : varchar(14)
FirstName string
// last_name : varchar(16)
LastName string
// gender : enum('M','F')
Gender string
}
func (Employees) TableName() string { return TableEmployees }
func (m *Employees) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["birth_date"] = &m.BirthDate
dst["first_name"] = &m.FirstName
dst["last_name"] = &m.LastName
dst["gender"] = &m.Gender
}
type SliceEmployees []Employees
func (s *SliceEmployees) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, Employees{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.salaries
const TableSalaries = "salaries"
type Salaries struct {
// emp_no : int
EmpNo int
// salary : int
Salary int
// from_date : date
FromDate interface{}
// to_date : date
ToDate interface{}
}
func (Salaries) TableName() string { return TableSalaries }
func (m *Salaries) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["salary"] = &m.Salary
dst["from_date"] = &m.FromDate
dst["to_date"] = &m.ToDate
}
type SliceSalaries []Salaries
func (s *SliceSalaries) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, Salaries{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}
// employees.titles
const TableTitles = "titles"
type Titles struct {
// emp_no : int
EmpNo int
// title : varchar(50)
Title string
// from_date : date
FromDate interface{}
// to_date : NULLABLE date
ToDate interface{}
}
func (Titles) TableName() string { return TableTitles }
func (m *Titles) FieldMapping(dst map[string]interface{}) {
dst["emp_no"] = &m.EmpNo
dst["title"] = &m.Title
dst["from_date"] = &m.FromDate
dst["to_date"] = &m.ToDate
}
type SliceTitles []Titles
func (s *SliceTitles) Iterate(f func(interface{}, bool) bool) {
for i := 0; ; i++ {
if c := i >= len(*s); !c {
if !f(&(*s)[i], c) {
return
}
} else if n := append(*s, Titles{}); f(&n[i], c) {
*s = n
} else {
*s = n[:i]
return
}
}
}