1// Copyright (c) 2012-present The upper.io/db authors. All rights reserved.
2//
3// Permission is hereby granted, free of charge, to any person obtaining
4// a copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to
8// permit persons to whom the Software is furnished to do so, subject to
9// the following conditions:
10//
11// The above copyright notice and this permission notice shall be
12// included in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22package mysql // import "upper.io/db.v3/mysql"
23
24import (
25	"database/sql"
26
27	db "upper.io/db.v3"
28	"upper.io/db.v3/internal/sqladapter"
29	"upper.io/db.v3/lib/sqlbuilder"
30)
31
32const sqlDriver = `mysql`
33
34// Adapter is the public name of the adapter.
35const Adapter = sqlDriver
36
37func init() {
38	sqlbuilder.RegisterAdapter(Adapter, &sqlbuilder.AdapterFuncMap{
39		New:   New,
40		NewTx: NewTx,
41		Open:  Open,
42	})
43}
44
45// Open stablishes a new connection with the SQL server.
46func Open(settings db.ConnectionURL) (sqlbuilder.Database, error) {
47	d := newDatabase(settings)
48	if err := d.Open(settings); err != nil {
49		return nil, err
50	}
51	return d, nil
52}
53
54// NewTx wraps a regular *sql.Tx transaction and returns a new upper-db
55// transaction backed by it.
56func NewTx(sqlTx *sql.Tx) (sqlbuilder.Tx, error) {
57	d := newDatabase(nil)
58
59	// Binding with sqladapter's logic.
60	d.BaseDatabase = sqladapter.NewBaseDatabase(d)
61
62	// Binding with sqlbuilder.
63	d.SQLBuilder = sqlbuilder.WithSession(d.BaseDatabase, template)
64
65	if err := d.BaseDatabase.BindTx(d.Context(), sqlTx); err != nil {
66		return nil, err
67	}
68
69	newTx := sqladapter.NewDatabaseTx(d)
70	return &tx{DatabaseTx: newTx}, nil
71}
72
73// New wraps the given *sql.DB session and creates a new db session.
74func New(sess *sql.DB) (sqlbuilder.Database, error) {
75	d := newDatabase(nil)
76
77	// Binding with sqladapter's logic.
78	d.BaseDatabase = sqladapter.NewBaseDatabase(d)
79
80	// Binding with sqlbuilder.
81	d.SQLBuilder = sqlbuilder.WithSession(d.BaseDatabase, template)
82
83	if err := d.BaseDatabase.BindSession(sess); err != nil {
84		return nil, err
85	}
86	return d, nil
87}
88