mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
add database/orm/reform example
This commit is contained in:
parent
eacbcea653
commit
acf058b006
|
@ -153,6 +153,8 @@ Prior to this version the `iris.Context` was the only one dependency that has be
|
||||||
| [http.ResponseWriter](https://golang.org/pkg/net/http/#ResponseWriter) | `ctx.ResponseWriter()` |
|
| [http.ResponseWriter](https://golang.org/pkg/net/http/#ResponseWriter) | `ctx.ResponseWriter()` |
|
||||||
| [http.Header](https://golang.org/pkg/net/http/#Header) | `ctx.Request().Header` |
|
| [http.Header](https://golang.org/pkg/net/http/#Header) | `ctx.Request().Header` |
|
||||||
| [time.Time](https://golang.org/pkg/time/#Time) | `time.Now()` |
|
| [time.Time](https://golang.org/pkg/time/#Time) | `time.Now()` |
|
||||||
|
| [golog.Logger](https://pkg.go.dev/github.com/kataras/golog) | Iris Logger |
|
||||||
|
| [net.IP](https://golang.org/pkg/net/#IP) | `net.ParseIP(ctx.RemoteAddr())` |
|
||||||
| `string`, | |
|
| `string`, | |
|
||||||
| `int, int8, int16, int32, int64`, | |
|
| `int, int8, int16, int32, int64`, | |
|
||||||
| `uint, uint8, uint16, uint32, uint64`, | |
|
| `uint, uint8, uint16, uint32, uint64`, | |
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
* [MongoDB](database/mongodb)
|
* [MongoDB](database/mongodb)
|
||||||
* [Xorm](database/orm/xorm/main.go)
|
* [Xorm](database/orm/xorm/main.go)
|
||||||
* [Gorm](database/orm/gorm/main.go)
|
* [Gorm](database/orm/gorm/main.go)
|
||||||
|
* [Reform](database/orm/reform/main.go)
|
||||||
* HTTP Server
|
* HTTP Server
|
||||||
* [HOST:PORT](http-server/listen-addr/main.go)
|
* [HOST:PORT](http-server/listen-addr/main.go)
|
||||||
* [Public Test Domain](http-server/listen-addr-public/main.go)
|
* [Public Test Domain](http-server/listen-addr-public/main.go)
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"myapp/models"
|
||||||
|
|
||||||
|
"github.com/kataras/golog"
|
||||||
|
"gopkg.in/reform.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PersonController is the model.Person's web controller.
|
||||||
|
type PersonController struct {
|
||||||
|
DB *reform.DB
|
||||||
|
|
||||||
|
// Logger and IP fields are automatically binded by the framework.
|
||||||
|
Logger *golog.Logger // binds to the application's logger.
|
||||||
|
IP net.IP // binds to the client's IP.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get handles
|
||||||
|
// GET /persons
|
||||||
|
func (c *PersonController) Get() ([]reform.Struct, error) {
|
||||||
|
return c.DB.SelectAllFrom(models.PersonTable, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBy handles
|
||||||
|
// GET /persons/{ID}
|
||||||
|
func (c *PersonController) GetBy(id int32) (reform.Record, error) {
|
||||||
|
return c.DB.FindByPrimaryKeyFrom(models.PersonTable, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post handles
|
||||||
|
// POST /persons with JSON request body of model.Person.
|
||||||
|
func (c *PersonController) Post(p *models.Person) int {
|
||||||
|
p.CreatedAt = time.Now()
|
||||||
|
|
||||||
|
if err := c.DB.Save(p); err != nil {
|
||||||
|
c.Logger.Errorf("[%s] create person: %v", c.IP.String(), err)
|
||||||
|
return 500 // iris.StatusInternalServerError
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Logger.Debugf("[%s] create person [%s] succeed", c.IP.String(), p.Name)
|
||||||
|
|
||||||
|
return 201 // iris.StatusCreated
|
||||||
|
}
|
11
_examples/database/orm/reform/go.mod
Normal file
11
_examples/database/orm/reform/go.mod
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
module myapp
|
||||||
|
|
||||||
|
go 1.14
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/kataras/iris/v12 v12.1.8
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.0
|
||||||
|
gopkg.in/reform.v1 v1.4.0
|
||||||
|
)
|
||||||
|
|
||||||
|
replace github.com/kataras/iris/v12 => ../../../../
|
50
_examples/database/orm/reform/main.go
Normal file
50
_examples/database/orm/reform/main.go
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
$ go get gopkg.in/reform.v1/reform
|
||||||
|
$ go generate ./models
|
||||||
|
$ go run .
|
||||||
|
|
||||||
|
Read more at: https://github.com/go-reform/reform
|
||||||
|
*/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
|
||||||
|
"myapp/controllers"
|
||||||
|
|
||||||
|
"github.com/kataras/iris/v12"
|
||||||
|
"github.com/kataras/iris/v12/mvc"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
"gopkg.in/reform.v1"
|
||||||
|
"gopkg.in/reform.v1/dialects/sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := iris.New()
|
||||||
|
app.Logger().SetLevel("debug")
|
||||||
|
|
||||||
|
sqlDB, err := sql.Open("sqlite3", "./myapp.db")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer sqlDB.Close()
|
||||||
|
sqlStmt := `
|
||||||
|
drop table people;
|
||||||
|
create table people (id integer not null primary key, name text, email text, created_at datetime not null, updated_at datetime null);
|
||||||
|
delete from people;
|
||||||
|
`
|
||||||
|
_, err = sqlDB.Exec(sqlStmt)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
db := reform.NewDB(sqlDB, sqlite3.Dialect, reform.NewPrintfLogger(app.Logger().Debugf))
|
||||||
|
|
||||||
|
mvcApp := mvc.New(app.Party("/persons"))
|
||||||
|
mvcApp.Register(db)
|
||||||
|
mvcApp.Handle(new(controllers.PersonController))
|
||||||
|
|
||||||
|
app.Listen(":8080")
|
||||||
|
}
|
13
_examples/database/orm/reform/models/person.go
Normal file
13
_examples/database/orm/reform/models/person.go
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
//go:generate reform
|
||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
//reform:people
|
||||||
|
type Person struct {
|
||||||
|
ID int32 `reform:"id,pk" json:"id"`
|
||||||
|
Name string `reform:"name" json:"name"`
|
||||||
|
Email *string `reform:"email" json:"email"`
|
||||||
|
CreatedAt time.Time `reform:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt *time.Time `reform:"updated_at" json:"updated_at"`
|
||||||
|
}
|
136
_examples/database/orm/reform/models/person_reform.go
Normal file
136
_examples/database/orm/reform/models/person_reform.go
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
// Code generated by gopkg.in/reform.v1. DO NOT EDIT.
|
||||||
|
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"gopkg.in/reform.v1"
|
||||||
|
"gopkg.in/reform.v1/parse"
|
||||||
|
)
|
||||||
|
|
||||||
|
type personTableType struct {
|
||||||
|
s parse.StructInfo
|
||||||
|
z []interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schema returns a schema name in SQL database ("").
|
||||||
|
func (v *personTableType) Schema() string {
|
||||||
|
return v.s.SQLSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns a view or table name in SQL database ("people").
|
||||||
|
func (v *personTableType) Name() string {
|
||||||
|
return v.s.SQLName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Columns returns a new slice of column names for that view or table in SQL database.
|
||||||
|
func (v *personTableType) Columns() []string {
|
||||||
|
return []string{"id", "name", "email", "created_at", "updated_at"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStruct makes a new struct for that view or table.
|
||||||
|
func (v *personTableType) NewStruct() reform.Struct {
|
||||||
|
return new(Person)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRecord makes a new record for that table.
|
||||||
|
func (v *personTableType) NewRecord() reform.Record {
|
||||||
|
return new(Person)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PKColumnIndex returns an index of primary key column for that table in SQL database.
|
||||||
|
func (v *personTableType) PKColumnIndex() uint {
|
||||||
|
return uint(v.s.PKFieldIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PersonTable represents people view or table in SQL database.
|
||||||
|
var PersonTable = &personTableType{
|
||||||
|
s: parse.StructInfo{Type: "Person", SQLSchema: "", SQLName: "people", Fields: []parse.FieldInfo{{Name: "ID", Type: "int32", Column: "id"}, {Name: "Name", Type: "string", Column: "name"}, {Name: "Email", Type: "*string", Column: "email"}, {Name: "CreatedAt", Type: "time.Time", Column: "created_at"}, {Name: "UpdatedAt", Type: "*time.Time", Column: "updated_at"}}, PKFieldIndex: 0},
|
||||||
|
z: new(Person).Values(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a string representation of this struct or record.
|
||||||
|
func (s Person) String() string {
|
||||||
|
res := make([]string, 5)
|
||||||
|
res[0] = "ID: " + reform.Inspect(s.ID, true)
|
||||||
|
res[1] = "Name: " + reform.Inspect(s.Name, true)
|
||||||
|
res[2] = "Email: " + reform.Inspect(s.Email, true)
|
||||||
|
res[3] = "CreatedAt: " + reform.Inspect(s.CreatedAt, true)
|
||||||
|
res[4] = "UpdatedAt: " + reform.Inspect(s.UpdatedAt, true)
|
||||||
|
return strings.Join(res, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values returns a slice of struct or record field values.
|
||||||
|
// Returned interface{} values are never untyped nils.
|
||||||
|
func (s *Person) Values() []interface{} {
|
||||||
|
return []interface{}{
|
||||||
|
s.ID,
|
||||||
|
s.Name,
|
||||||
|
s.Email,
|
||||||
|
s.CreatedAt,
|
||||||
|
s.UpdatedAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pointers returns a slice of pointers to struct or record fields.
|
||||||
|
// Returned interface{} values are never untyped nils.
|
||||||
|
func (s *Person) Pointers() []interface{} {
|
||||||
|
return []interface{}{
|
||||||
|
&s.ID,
|
||||||
|
&s.Name,
|
||||||
|
&s.Email,
|
||||||
|
&s.CreatedAt,
|
||||||
|
&s.UpdatedAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// View returns View object for that struct.
|
||||||
|
func (s *Person) View() reform.View {
|
||||||
|
return PersonTable
|
||||||
|
}
|
||||||
|
|
||||||
|
// Table returns Table object for that record.
|
||||||
|
func (s *Person) Table() reform.Table {
|
||||||
|
return PersonTable
|
||||||
|
}
|
||||||
|
|
||||||
|
// PKValue returns a value of primary key for that record.
|
||||||
|
// Returned interface{} value is never untyped nil.
|
||||||
|
func (s *Person) PKValue() interface{} {
|
||||||
|
return s.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
// PKPointer returns a pointer to primary key field for that record.
|
||||||
|
// Returned interface{} value is never untyped nil.
|
||||||
|
func (s *Person) PKPointer() interface{} {
|
||||||
|
return &s.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasPK returns true if record has non-zero primary key set, false otherwise.
|
||||||
|
func (s *Person) HasPK() bool {
|
||||||
|
return s.ID != PersonTable.z[PersonTable.s.PKFieldIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPK sets record primary key.
|
||||||
|
func (s *Person) SetPK(pk interface{}) {
|
||||||
|
if i64, ok := pk.(int64); ok {
|
||||||
|
s.ID = int32(i64)
|
||||||
|
} else {
|
||||||
|
s.ID = pk.(int32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check interfaces
|
||||||
|
var (
|
||||||
|
_ reform.View = PersonTable
|
||||||
|
_ reform.Struct = (*Person)(nil)
|
||||||
|
_ reform.Table = PersonTable
|
||||||
|
_ reform.Record = (*Person)(nil)
|
||||||
|
_ fmt.Stringer = (*Person)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
parse.AssertUpToDate(&PersonTable.s, new(Person))
|
||||||
|
}
|
58
_examples/database/orm/reform/postman_collection.json
Normal file
58
_examples/database/orm/reform/postman_collection.json
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
{
|
||||||
|
"info": {
|
||||||
|
"_postman_id": "6b66000d-9c04-4d0a-b55c-8a493bf59015",
|
||||||
|
"name": "iris-reform-example",
|
||||||
|
"description": "Example API calls for iris reform example.",
|
||||||
|
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
||||||
|
},
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "http://localhost:8080/persons",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\r\n \"name\": \"John\",\r\n \"email\": \"example@example.com\"\r\n}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://localhost:8080/persons",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"localhost"
|
||||||
|
],
|
||||||
|
"port": "8080",
|
||||||
|
"path": [
|
||||||
|
"persons"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "http://localhost:8080/persons",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "http://localhost:8080/persons",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"localhost"
|
||||||
|
],
|
||||||
|
"port": "8080",
|
||||||
|
"path": [
|
||||||
|
"persons"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"protocolProfileBehavior": {}
|
||||||
|
}
|
|
@ -3,12 +3,15 @@ package hero
|
||||||
import (
|
import (
|
||||||
stdContext "context"
|
stdContext "context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kataras/iris/v12/context"
|
"github.com/kataras/iris/v12/context"
|
||||||
"github.com/kataras/iris/v12/sessions"
|
"github.com/kataras/iris/v12/sessions"
|
||||||
|
|
||||||
|
"github.com/kataras/golog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Default is the default container value which can be used for dependencies share.
|
// Default is the default container value which can be used for dependencies share.
|
||||||
|
@ -57,6 +60,10 @@ var BuiltinDependencies = []*Dependency{
|
||||||
|
|
||||||
return session
|
return session
|
||||||
}).Explicitly(),
|
}).Explicitly(),
|
||||||
|
// application's logger.
|
||||||
|
NewDependency(func(ctx *context.Context) *golog.Logger {
|
||||||
|
return ctx.Application().Logger()
|
||||||
|
}).Explicitly(),
|
||||||
// time.Time to time.Now dependency.
|
// time.Time to time.Now dependency.
|
||||||
NewDependency(func(ctx *context.Context) time.Time {
|
NewDependency(func(ctx *context.Context) time.Time {
|
||||||
return time.Now()
|
return time.Now()
|
||||||
|
@ -73,6 +80,10 @@ var BuiltinDependencies = []*Dependency{
|
||||||
NewDependency(func(ctx *context.Context) http.Header {
|
NewDependency(func(ctx *context.Context) http.Header {
|
||||||
return ctx.Request().Header
|
return ctx.Request().Header
|
||||||
}).Explicitly(),
|
}).Explicitly(),
|
||||||
|
// Client IP.
|
||||||
|
NewDependency(func(ctx *context.Context) net.IP {
|
||||||
|
return net.ParseIP(ctx.RemoteAddr())
|
||||||
|
}).Explicitly(),
|
||||||
// payload and param bindings are dynamically allocated and declared at the end of the `binding` source file.
|
// payload and param bindings are dynamically allocated and declared at the end of the `binding` source file.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package hero
|
package hero
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/kataras/iris/v12/context"
|
"github.com/kataras/iris/v12/context"
|
||||||
|
@ -41,9 +42,12 @@ func isFunc(kindable interface{ Kind() reflect.Kind }) bool {
|
||||||
return kindable.Kind() == reflect.Func
|
return kindable.Kind() == reflect.Func
|
||||||
}
|
}
|
||||||
|
|
||||||
var inputTyp = reflect.TypeOf((*Input)(nil))
|
var (
|
||||||
|
inputTyp = reflect.TypeOf((*Input)(nil))
|
||||||
|
errTyp = reflect.TypeOf((*error)(nil)).Elem()
|
||||||
|
|
||||||
var errTyp = reflect.TypeOf((*error)(nil)).Elem()
|
ipTyp = reflect.TypeOf(net.IP{})
|
||||||
|
)
|
||||||
|
|
||||||
// isError returns true if "typ" is type of `error`.
|
// isError returns true if "typ" is type of `error`.
|
||||||
func isError(typ reflect.Type) bool {
|
func isError(typ reflect.Type) bool {
|
||||||
|
@ -221,6 +225,10 @@ func isZero(v reflect.Value) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v.Type() == ipTyp {
|
||||||
|
return len(v.Interface().(net.IP)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
zero := reflect.Zero(v.Type())
|
zero := reflect.Zero(v.Type())
|
||||||
return v.Interface() == zero.Interface()
|
return v.Interface() == zero.Interface()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user