Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
reform: путь к лучшему ORM
Search
Alexey Palazhchenko
May 14, 2016
Programming
2
600
reform: путь к лучшему ORM
Alexey Palazhchenko
May 14, 2016
Tweet
Share
More Decks by Alexey Palazhchenko
See All by Alexey Palazhchenko
Песнь Хорьков и Гоферов
aleksi
0
300
Fuzzy generics
aleksi
0
110
On Ferrets and Gophers
aleksi
0
210
How to Go Wrong with Concurrency
aleksi
2
710
Adding context to existing code
aleksi
1
110
Зачем и как написать свой database/sql драйвер
aleksi
1
130
Cooking gRPC
aleksi
1
780
Profiling and Optimizing Go Programs
aleksi
1
1.7k
Go: начало
aleksi
0
92
Other Decks in Programming
See All in Programming
Nurturing OpenJDK distribution: Eclipse Temurin Success History and plan
ivargrimstad
0
1k
Figma Dev Modeで変わる!Flutterの開発体験
watanave
0
150
Make Impossible States Impossibleを 意識してReactのPropsを設計しよう
ikumatadokoro
0
240
CSC509 Lecture 09
javiergs
PRO
0
140
Micro Frontends Unmasked Opportunities, Challenges, Alternatives
manfredsteyer
PRO
0
110
[Do iOS '24] Ship your app on a Friday...and enjoy your weekend!
polpielladev
0
110
タクシーアプリ『GO』のリアルタイムデータ分析基盤における機械学習サービスの活用
mot_techtalk
5
1.5k
Kaigi on Rails 2024 〜運営の裏側〜
krpk1900
1
250
Functional Event Sourcing using Sekiban
tomohisa
0
100
CSC509 Lecture 12
javiergs
PRO
0
160
Amazon Bedrock Agentsを用いてアプリ開発してみた!
har1101
0
340
CSC509 Lecture 13
javiergs
PRO
0
110
Featured
See All Featured
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
25
1.8k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
A better future with KSS
kneath
238
17k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
GraphQLとの向き合い方2022年版
quramy
43
13k
The Cost Of JavaScript in 2023
addyosmani
45
6.8k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
47
2.1k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Building Your Own Lightsaber
phodgson
103
6.1k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
720
Transcript
reform путь к лучшему ORM Алексей Палажченко mc² software
None
Цели database/sql src/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
Интерфейс 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
INSERT result, err := db.Exec( "INSERT INTO users (name) "+
"VALUES ($1)", "gopher" )
SELECT defer 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) }
Интерфейс database/sql/driver • Value: пустой интерфейс • ValueConverter: ConvertValue(v interface{})
(Value, error) • Valuer: Value() (Value, error)
database/sql/driver.Value • nil • int64 • float64 • bool •
[]byte (non-nil) • string everywhere except from Rows.Next. #6497 • time.Time (боль с часовыми зонами)
Свои типы 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 }
Свои типы 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 }
Драйвера • github.com/golang/go/wiki/SQLDrivers • github.com/bradfitz/go-sql-test
Зачем ORM?
INSERT result, err := db.Exec( "INSERT INTO users (name) "+
"VALUES ($1)", "gopher" )
SELECT defer 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) }
ORM • Не-ORM / малые ORM (например, отображение Scan строк
в структуры) • Большие ORM
ORM func Save(m interface{}) error
ORM Save(User{Name: "gopher"}) Save(&User{Name: "gopher"}) Save(nil) Save(42) Save("Batman!!")
Идея: struct для данных type Person struct { ID int64
`sql:"id,omitempty"` Name string `sql:"name,omitempty"` }
Идея: непустые интерфейсы type Record interface { Values() []interface{} Pointers()
[]interface{} PrimaryKeyPointer() interface{} SetPrimaryKey(id interface{}) Table() Table } funс Save(record Record) error
Идея: генерация кода • struct и код из XML •
XML из information_schema • struct пишется, код генерируется из него
Проблемы: Go vs SQL • SQL: значения по-умолчанию • SQL:
отсутствие в запросе • Go: zero value
person := &Person{ Name: "gopher", } if err := DB.Save(person);
err != nil { log.Fatal(err) }
Что почитать • Документацию database/sql/… • Код database/sql/… • github.com/mc2soft/pq-types
• github.com/AlekSi/reform
• https://groups.google.com/forum/#!forum/golang-ru • http://www.meetup.com/Golang-Moscow/ • http://4gophers.ru • http://4gophers.ru/slack • https://golangshow.com