24
reform путь к лучшему ORM Алексей Палажченко mc² software

Reform: путь к лучшему ORM

Embed Size (px)

Citation preview

Page 1: Reform: путь к лучшему ORM

reformпуть к лучшему ORM

Алексей Палажченко mc² software

Page 2: Reform: путь к лучшему ORM
Page 3: Reform: путь к лучшему ORM

Цели database/sqlsrc/database/sql/doc.txt

• generic database API for SQL/SQL-like, feel like Go

• common cases, portable, no quirks

• consistent but flexible type conversions

• concurrency, thread safety, built-in pool

• push complexity to drivers via optional interfaces

Page 4: Reform: путь к лучшему ORM

Интерфейс database/sql

• DB: Open, Close, Begin, Prepare, Driver

• DB, Stmt, Tx: Query, QueryRow, Exec

• Rows: Next, Scan, Err, Close

• Result: LastInsertId, RowsAffected

• NullBool, NullInt64, NullFloat64, NullString

• Scanner: Scan(src interface{}) error

Page 5: Reform: путь к лучшему ORM

INSERTresult, err := db.Exec( "INSERT INTO users (name) "+ "VALUES ($1)", "gopher" )

Page 6: Reform: путь к лучшему ORM

SELECTdefer rows.Close() for rows.Next() { var name string if e := rows.Scan(&name); e != nil { log.Fatal(e) } fmt.Println(name) } if e := rows.Err(); e != nil { log.Fatal(e) }

Page 7: Reform: путь к лучшему ORM

Интерфейс database/sql/driver

• Value: пустой интерфейс

• ValueConverter: ConvertValue(v interface{}) (Value, error)

• Valuer: Value() (Value, error)

Page 8: Reform: путь к лучшему ORM

database/sql/driver.Value• nil

• int64

• float64

• bool

• []byte (non-nil)

• string everywhere except from Rows.Next. #6497

• time.Time (боль с часовыми зонами)

Page 9: Reform: путь к лучшему ORM

Свои типыfunc (j JSONText) Value() (driver.Value, error) { if j == nil { return nil, nil }

var m json.RawMessage err := json.Unmarshal(j, &m) if err != nil { return []byte{}, err } return []byte(j), nil }

Page 10: Reform: путь к лучшему ORM

Свои типыfunc (j *JSONText) Scan(value interface{}) error { if value == nil { *j = nil return nil }

v, ok := value.([]byte) if !ok { return fmt.Errorf("error") }

*j = JSONText(append((*j)[0:0], v...)) return nil }

Page 11: Reform: путь к лучшему ORM

Драйвера• github.com/golang/go/wiki/SQLDrivers

• github.com/bradfitz/go-sql-test

Page 12: Reform: путь к лучшему ORM

Зачем ORM?

Page 13: Reform: путь к лучшему ORM

INSERTresult, err := db.Exec( "INSERT INTO users (name) "+ "VALUES ($1)", "gopher" )

Page 14: Reform: путь к лучшему ORM

SELECTdefer rows.Close() for rows.Next() { var name string if e := rows.Scan(&name); e != nil { log.Fatal(e) } fmt.Println(name) } if e := rows.Err(); e != nil { log.Fatal(e) }

Page 15: Reform: путь к лучшему ORM

ORM• Не-ORM / малые ORM (например, отображение

Scan строк в структуры)

• Большие ORM

Page 16: Reform: путь к лучшему ORM

ORM

func Save(m interface{}) error

Page 17: Reform: путь к лучшему ORM

ORM

Save(User{Name: "gopher"}) Save(&User{Name: "gopher"}) Save(nil) Save(42) Save("Batman!!")

Page 18: Reform: путь к лучшему ORM

Идея: struct для данных

type Person struct { ID int64 `sql:"id,omitempty"` Name string `sql:"name,omitempty"` }

Page 19: Reform: путь к лучшему ORM

Идея: непустые интерфейсы

type Record interface { Values() []interface{} Pointers() []interface{} PrimaryKeyPointer() interface{} SetPrimaryKey(id interface{}) Table() Table }

funс Save(record Record) error

Page 20: Reform: путь к лучшему ORM

Идея: генерация кода

• struct и код из XML

• XML из information_schema

• struct пишется, код генерируется из него

Page 21: Reform: путь к лучшему ORM

Проблемы: Go vs SQL• SQL: значения по-умолчанию

• SQL: отсутствие в запросе

• Go: zero value

Page 22: Reform: путь к лучшему ORM

person := &Person{ Name: "gopher", } if err := DB.Save(person); err != nil { log.Fatal(err) }

Page 23: Reform: путь к лучшему ORM

Что почитать• Документацию database/sql/…

• Код database/sql/…

• github.com/mc2soft/pq-types

• github.com/AlekSi/reform

Page 24: Reform: путь к лучшему ORM

• https://groups.google.com/forum/#!forum/golang-ru

• http://www.meetup.com/Golang-Moscow/

• http://4gophers.ru

• http://4gophers.ru/slack

• https://golangshow.com