рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЧреЛрд▓рдВрдЧ рдЪрд▓рд╛рдиреЗ рд╡рд╛рд▓реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рд╕рд░рд▓ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рддреЗ рд╕рдордп, рдпреЗ рд╕рдорд╕реНрдпрд╛рдПрдВ рдЖрдорддреМрд░ рдкрд░ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрддреА рд╣реИрдВред рдЬреИрд╕реЗ-рдЬреИрд╕реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдврд╝рддрд╛ рд╣реИ, рд╡реИрд╕реЗ-рд╡реИрд╕реЗ рд╕рдорд╕реНрдпрд╛ рдЖрддреА рд╣реИред рдЙрдирдореЗрдВ рд╕реЗ рд╕рдмрд╕реЗ рд╕рд╛рдордпрд┐рдХ:
- рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреА рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдХрдо рд╣реЛ рд░рд╣реА рд╣реИ
- рдбрд┐рдмрдЧ рдореЛрдб рдХреНрд╡реЗрд░реА рд▓реЙрдЧрд┐рдВрдЧ
- рдкреНрд░рддрд┐рдХреГрддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ
рд▓реЗрдЦ github.com/adverax/echo/database/sql рдкреИрдХреЗрдЬ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред рдЗрд╕ рдкреИрдХреЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╢рдмреНрджрд╛рд░реНрде рдорд╛рдирдХ рдбреЗрдЯрд╛рдмреЗрд╕ / sql рдкреИрдХреЗрдЬ рдХреЗ рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рдХрд░реАрдм рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдХрд┐рд╕реА рдХреЛ рднреА рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рд╣реЛрдЧреАред
рдХреНрд╖реЗрддреНрд░
рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рдмрдбрд╝реЗ рд╕рд┐рд╕реНрдЯрдо рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдХ рдХреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХреЗ рд╕реНрдкрд╖реНрдЯ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд╕рд╛рде рд╢рд┐рдерд┐рд▓ рд░реВрдк рд╕реЗ рдЬреБрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдкреНрд░рдХрд╛рд╢рдХ / рдЧреНрд░рд╛рд╣рдХ рдбрд┐рдЬрд╛рдЗрди рдкреИрдЯрд░реНрди рд╡реНрдпрд╛рдкрдХ рд░реВрдк рд╕реЗ рдкреНрд░рдЪрд▓рд┐рдд рд╣реИрдВред рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдПрдХ рдирдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред
package main import "database/sql" type User struct { Id int64 Name string Language string } type Manager struct { DB *sql.DB OnSignup func(db *sql.DB, user *User) error } func (m *Manager) Signup(user *User) (id int64, err error) { id, err = m.insert(user) if err != nil { return } user.Id = id err = m.OnSignup(m.DB, user) return } func (m *Manager) insert(user *User) (int64, error) { res, err := m.DB.Exec("INSERT ...") if err != nil { return 0, err } id, err := res.LastInsertId() if err != nil { return 0, err } return id, err } func main() { manager := &Manager{
рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рдореБрдЦреНрдп рд░реВрдк рд╕реЗ OnSignup рдШрдЯрдирд╛ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВред рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣реИрдВрдбрд▓рд░ рдХреЛ рдПрдХрд▓ рдлрд╝рдВрдХреНрд╢рди (рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреАрд╡рди рдореЗрдВ, рд╕рдм рдХреБрдЫ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ) рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдШрдЯрдирд╛ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдореЗрдВ, рд╣рдо рдкрд╣рд▓реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдХрдареЛрд░рддрд╛ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдЖрдорддреМрд░ рдкрд░ рджреВрд░рдЧрд╛рдореА рдкрд░рд┐рдгрд╛рдо рд╣реЛрддреЗ рд╣реИрдВред
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЕрдм рд╣рдо рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдФрд░ рд╕рдлрд▓ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрдВрдЬреАрдХрд░рдг рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЕрдкрдиреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдЦрд╛рддреЗ рдореЗрдВ рдПрдХ рд╕рдВрджреЗрд╢ рднреЗрдЬрддреЗ рд╣реИрдВред рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рд╕рдВрджреЗрд╢ рдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрдВрдЬреАрдХрд░рдг рдХреЗ рд╕рдорд╛рди рд▓реЗрдирджреЗрди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
type Manager struct { DB *sql.DB OnSignup func(tx *sql.Tx, user *User) error } func (m *Manager) Signup(user *User) error { tx, err := m.DB.Begin() if err != nil { return err } defer tx.Rollback() id, err := m.insert(user) if err != nil { return err } user.Id = id err = m.OnSignup(tx, id) if err != nil { return err } return tx.Commit() } func main() { manager := &Manager{
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЙрджрд╛рд╣рд░рдг рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рдШрдЯрдирд╛ рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдпрд╣ рд╕рдорд╛рдзрд╛рди рд╕рд╛рдл тАЛтАЛрдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреНрд╡реЗрд░реА рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд╕рдВрджрд░реНрдн рдХрд╛ рдЬреНрдЮрд╛рди рд╣реИред рдПрдХ рдЬреЗрдиреЗрд░рд┐рдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдФрд░ рдЯреНрд░рд╛рдВрдЬреЗрдХреНрд╢рди рдЗрдВрдЯрд░рдлрд╝реЗрд╕ - рд╕реНрдХреЛрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдХреНрд▓реАрдирд░ рд╕рдорд╛рдзрд╛рди рд╣реЛрдЧрд╛
import "github.com/adverax/echo/database/sql" type Manager struct { DB sql.DB OnSignup func(scope sql.Scope, user *User) error } func (m *Manager) Signup(user *User) error { tx, err := m.DB.Begin() if err != nil { return err } defer tx.Rollback() id, err := m.insert(user) if err != nil { return err } err = m.OnSignup(tx, id) if err != nil { return err } return tx.Commit() } func main() { manager := &Manager{
рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдиреЗрд╕реНрдЯреЗрдб рд▓реЗрдирджреЗрди рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рд╣реИрдВрдбрд▓рд░, рдмрджрд▓реЗ рдореЗрдВ, рд▓реЗрдирджреЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ DBMS SAVEPOINT рддрдВрддреНрд░ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВред
рдбреЗрдЯрд╛рдмреЗрд╕ рдФрд░ рд╕рдВрджрд░реНрдн
рд╕рд╛рдорд╛рдиреНрдп рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдХрдиреЗрдХреНрд╢рди рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдмрдВрдзрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рд┐рдВрдХ рд░рдЦрддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рдзрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░реЛрдВ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдХреЛрдб рдкрдардиреАрдпрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЗрд╕рд╕реЗ рдмрдЪрдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд▓реЗрдирджреЗрди рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рд╕рдВрджрд░реНрдн рдореЗрдВ рд▓реЗрди-рджреЗрди (рдЧреБрдВрдЬрд╛рдЗрд╢) рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдХ рдбрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реБрдВрджрд░ рд╕рдорд╛рдзрд╛рди рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╕рдВрджрд░реНрдн рдХреЛ рдПрдВрдб-рдЯреВ-рдПрдВрдб рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдлрд┐рд░ рд╣рдо рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рдФрд░ рд╕рд░рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
import ( "context" "github.com/adverax/echo/database/sql" ) type Manager struct { sql.Repository OnSignup func(ctx context.Context, user *User) error } func (m *Manager) Signup(ctx context.Context, user *User) error { return m.Transaction( ctx, func(ctx context.Context, scope sql.Scope) error { id, err := m.insert(user) if err != nil { return err } user.Id = id return m.OnSignup(ctx, user) }, ) } type Messenger struct { sql.Repository } func(messenger *Messenger) onSignupUser(ctx context.Context, user *User) error { _, err := messenger.Scope(ctx).Exec("INSERT ...") return err } func main() { db := ... messenger := &Messenger{ Repository: sql.NewRepository(db), } manager := &Manager{ Repository: sql.NewRepository(db), OnSignup: messenger.onSignup, } err := manager.Signup(&User{...}) if err != nil { panic(err) } }
рдпрд╣ рдЙрджрд╛рд╣рд░рдг рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рд╣рдордиреЗ рдкреНрд░рдмрдВрдзрдХреЛрдВ рдХреЗ рдкреВрд░реНрдг рдЕрд▓рдЧрд╛рд╡ рдХреЛ рдмрдирд╛рдП рд░рдЦрд╛ рд╣реИ, рдХреЛрдб рдХреА рдкрдардиреАрдпрддрд╛ рдХреЛ рдмрдврд╝рд╛рдпрд╛ рд╣реИ, рдФрд░ рдПрдХ рд╣реА рджрд╛рдпрд░реЗ рдореЗрдВ рдЕрдкрдиреЗ рд╕рдВрдпреБрдХреНрдд рдХрд╛рд░реНрдп рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рд╣реИред
рдкреНрд░рддрд┐рдХреГрддрд┐ рд╕рдорд░реНрдерди
рдкреБрд╕реНрддрдХрд╛рд▓рдп рдкреНрд░рддрд┐рдХреГрддрд┐ рдХреЗ рдЙрдкрдпреЛрдЧ рдХрд╛ рднреА рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред Exec рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рднреА рдЕрдиреБрд░реЛрдз рдорд╛рд╕реНрдЯрд░ рдХреЛ рднреЗрдЬреЗ рдЬрд╛рддреЗ рд╣реИрдВред рджрд╛рд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд░реВрдк рд╕реЗ рдЪрдпрдирд┐рдд рджрд╛рд╕ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкреНрд░рддрд┐рдХреГрддрд┐ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ рдХрдИ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ:
func work() { dsc := &sql.DSC{ Driver: "mysql", DSN: []*sql.DSN{ { Host: "127.0.0.1", Database: "echo", Username: "root", Password: "password", }, { Host: "192.168.44.01", Database: "echo", Username: "root", Password: "password", }, }, } db := dsc.Open(nil) defer db.Close() ... }
рдпрджрд┐ рдЖрдк рдбреЗрдЯрд╛рдмреЗрд╕ рдЦреЛрд▓рддреЗ рд╕рдордп рдПрдХрд▓ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдмрд┐рдирд╛ рдЕрддрд┐рд░рд┐рдХреНрдд рдУрд╡рд░рд╣реЗрдб рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдореЛрдб рдореЗрдВ рдЦреЛрд▓рд╛ рдЬрд╛рдПрдЧрд╛ред
рдореИрдЯреНрд░рд┐рдХреНрд╕
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдореИрдЯреНрд░рд┐рдХреНрд╕ рд╕рд╕реНрддреЗ рд╣реИрдВ, рдФрд░ рд▓реЙрдЧ рдорд╣рдВрдЧреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛ред
рдХреНрд╡реЗрд░реА рд░реВрдкрд░реЗрдЦрд╛ рдФрд░ рд▓реЙрдЧрд┐рдВрдЧ
рдбреАрдмрдЧрд┐рдВрдЧ рдХреЗ рджреМрд░рд╛рди рдбреЗрдЯрд╛рдмреЗрд╕ рдХреНрд╡реЗрд░реА рд▓реЙрдЧ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╡рд╢реНрдпрдХ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореИрдВрдиреЗ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рд╢реВрдиреНрдп рдУрд╡рд░рд╣реЗрдб рдХреЗ рд╕рд╛рде рдЙрдЪреНрдЪ-рдЧреБрдгрд╡рддреНрддрд╛ рд╡рд╛рд▓реЗ рд▓реЙрдЧрд┐рдВрдЧ рддрдВрддреНрд░ рдХреЛ рдирд╣реАрдВ рджреЗрдЦрд╛ рд╣реИред рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рд▓рдкреЗрдЯрдХрд░ рдЖрдкрдХреЛ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдкреНрд░реЛрдлрд╛рдЗрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдПрдХреНрдЯрд┐рд╡реЗрдЯрд░ рдкрд╛рд╕ рдХрд░реЗрдВ:
func openDatabase(dsc sql.DSC, debug bool) (sql.DB, error){ if debug { return dsc.Open(sql.OpenWithProfiler(nil, "", nil)) } return dsc.Open(nil) } func main() { dsc := ... db, err := openDatabase(dsc, true) if err != nil { panic(err) } defer db.Close() ... }
рдирд┐рд╖реНрдХрд░реНрд╖
рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╡рд┐рд╡рд░рдг рдХреЛ рдЫрд┐рдкрд╛рддреЗ рд╣реБрдП рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдкреИрдХреЗрдЬ рдЖрдкрдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХреА рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рдмрдврд╝рддреА рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдЗрд╕реЗ рд╢рд┐рдерд┐рд▓ рд░реВрдк рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рдФрд░ рдкрд╛рд░рджрд░реНрд╢реА рдЫреЛрдбрд╝рдХрд░, рдХреЛрдб рдХреА рдЧреБрдгрд╡рддреНрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред