Skip to content

Commit 49a7ce3

Browse files
author
c9845
committed
Heavy rewrite of existing basic functionality, remove older func to create configs, clean up old code.
1 parent e4255eb commit 49a7ce3

File tree

5 files changed

+274
-302
lines changed

5 files changed

+274
-302
lines changed

sqldb-mariadb.go

+13
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,16 @@ func (cfg *Config) IsMariaDB() bool {
2828
func IsMariaDB() bool {
2929
return config.IsMariaDB()
3030
}
31+
32+
// IsMySQLOrMariaDB returns if the database is a MySQL or MariaDB. This is useful
33+
// since MariaDB is a fork of MySQL and most things are compatible; this way you
34+
// don't need to check IsMySQL() and IsMariaDB().
35+
func (cfg *Config) IsMySQLOrMariaDB() bool {
36+
return cfg.Type == DBTypeMySQL || cfg.Type == DBTypeMariaDB
37+
}
38+
39+
// IsMySQLOrMariaDB returns if the database is a MySQL or MariaDB for the package
40+
// level config.
41+
func IsMySQLOrMariaDB() bool {
42+
return config.IsMySQLOrMariaDB()
43+
}

sqldb-sqlite-mattn.go

+16-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
//!modernc causes this file to be included by default if no -tags are provided to
2-
//go build or go run. AKA, default to using mattn if no build tag is provided.
1+
//go:build !modernc
32

4-
//mattn requires CGO. modernc does not which allows for easier cross compiled builds.
3+
/*
4+
This file handles the [github.com/mattn/go-sqlite3] SQLite library.
55
6-
//go:build !modernc
6+
This library is the default SQLite library if no build tags are provided. Note the
7+
"go:build !modernc" line.
8+
9+
This library requires CGO, and therefore requires a bit more work to get cross-
10+
compiling to work properly.
11+
*/
712

813
package sqldb
914

@@ -12,9 +17,14 @@ import (
1217
)
1318

1419
const (
15-
sqliteLibrary = "github.com/mattn/go-sqlite3"
20+
//sqliteLibrary is used in logging.
21+
sqliteLibrary = "github.com/mattn/go-sqlite3"
22+
23+
//sqliteDriverName is used in Connect() when calling [database/sql.Open].
1624
sqliteDriverName = "sqlite3"
1725
)
1826

19-
// Placeholder so that this variable is defined for this SQLite library.
27+
// Placeholder so that this variable is defined for this SQLite library. The mattn
28+
// library defines some default PRAGMAs already so we do not need to define them here.
29+
// However, we need this variable defined since it is checked for in Connect().
2030
var sqliteDefaultPragmas = []string{}

sqldb-sqlite-modernc.go

+20-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,35 @@
11
//go:build modernc
22

3+
/*
4+
This file handles the [modernc.org/sqlite] SQLite library.
5+
6+
This library is not the default since it doesn't use the SQLite source C code and
7+
isn't as widely used.
8+
9+
However, this library is straight golang and does not require CGO which makes cross-
10+
compiling much easier.
11+
*/
12+
313
package sqldb
414

515
import (
616
_ "modernc.org/sqlite"
717
)
818

919
const (
10-
sqliteLibrary = "modernc.org/sqlite"
20+
//sqliteLibrary is used in logging.
21+
sqliteLibrary = "modernc.org/sqlite"
22+
23+
//sqliteDriverName is used in Connect() when calling [database/sql.Open].
1124
sqliteDriverName = "sqlite"
1225
)
1326

27+
// The [github.com/mattn/go-sqlite3] library sets some PRAGMAs by default. The
28+
// [modernc.org/sqlite]library does not define any default PRAGMAs. However, to
29+
// make switching between the two database libraries/drivers easier, we define
30+
// some PRAGMAs here to make using a SQLite database more consistent.
31+
//
32+
// https://github.com/mattn/go-sqlite3/blob/ae2a61f847e10e6dd771ecd4e1c55e0421cdc7f9/sqlite3.go#L1086
1433
var sqliteDefaultPragmas = []string{
15-
//The mattn/go-sqlite3 sets this value by default. Use this for modernc/sqlite as
16-
//well.
17-
//https://github.com/mattn/go-sqlite3/blob/ae2a61f847e10e6dd771ecd4e1c55e0421cdc7f9/sqlite3.go#L1086
1834
"PRAGMA busy_timeout = 5000",
1935
}

sqldb-sqlite.go

+46-72
Original file line numberDiff line numberDiff line change
@@ -7,73 +7,51 @@ import (
77
"github.com/jmoiron/sqlx"
88
)
99

10-
// defaults
1110
const (
12-
//Possible libraries. Used in comparisons, such as when building connection string
13-
//pragmas.
11+
//Possible SQLite libraries. These are used in comparisons, such as when building
12+
//the connection string PRAGMAs.
1413
sqliteLibraryMattn = "github.com/mattn/go-sqlite3"
1514
sqliteLibraryModernc = "modernc.org/sqlite"
1615

17-
//InMemoryFilePathRacy is the "path" to provide for the SQLite file when you want
18-
//to use an in-memory database instead of a filesystem file database. This is racy
19-
//because each "Connect" call to :memory: will open a brand new database.
16+
//InMemoryFilePathRacy is the path to provide for SQLitePath when you want to use
17+
//an in-memory database instead of a file on disk. This is racy because each call
18+
//to Connect() will open a brand new database. If you only call Connect() once
19+
//then this is safe to use.
2020
//
2121
//This is good for running tests since then each test runs with a separate
2222
//in-memory db.
2323
InMemoryFilePathRacy = ":memory:"
2424

25-
//InMemoryFilePathRaceSafe is the "path" to provide for the SQLite file when you
26-
//want to use an in-memory database between multiple "Connect" calls. This is race
27-
//safe since multiple calls of "Connect" will connect to the same in-memory db,
28-
//although connecting more than once to the same db would be very odd.
25+
//InMemoryFilePathRaceSafe is the path to provide for SQLitePath when you want to
26+
//use an in-memory database instead of a file on disk. This is race safe since
27+
//multiple calls of Connect() will connect to the same in-memory database,
28+
//although connecting more than once to the same database would be very odd.
2929
InMemoryFilePathRaceSafe = "file::memory:?cache=shared"
3030
)
3131

32-
// NewSQLiteConfig returns a config for connecting to a SQLite database.
33-
func NewSQLiteConfig(pathToFile string) (cfg *Config) {
34-
//The returned error can be ignored since it only returns if a bad db type is
35-
//provided but we are providing a known-good db type.
36-
cfg, _ = NewConfig(DBTypeSQLite)
37-
38-
cfg.SQLitePath = pathToFile
39-
cfg.SQLitePragmas = sqliteDefaultPragmas
40-
cfg.UseDefaultTranslateFuncs()
41-
42-
return
43-
}
44-
45-
// DefaultSQLiteConfig initializes the globally accessible package level config with
46-
// some defaults set.
47-
func DefaultSQLiteConfig(pathToFile string) {
48-
cfg := NewSQLiteConfig(pathToFile)
49-
config = *cfg
50-
}
51-
52-
// IsSQLite returns true if the database is a SQLite database. This is easier
53-
// than checking for equality against the Type field in the config.
54-
func (cfg *Config) IsSQLite() bool {
55-
return cfg.Type == DBTypeSQLite
32+
// IsSQLite returns true if the database is a SQLite database.
33+
func (c *Config) IsSQLite() bool {
34+
return c.Type == DBTypeSQLite
5635
}
5736

58-
// IsSQLite returns true if the database is a SQLite database. This is easier
59-
// than checking for equality against the Type field in the config.
37+
// IsSQLite returns true if the database is a SQLite database.
6038
func IsSQLite() bool {
61-
return config.IsSQLite()
39+
return cfg.IsSQLite()
6240
}
6341

64-
// GetSQLiteVersion returns the version of SQLite that is embedded into the app. This
65-
// works by creating a temporary in-memory SQLite database to run a query against. We
66-
// don't use the config or an already established connection because we may want to
67-
// get the SQLiter version before a database is connected to!
42+
// GetSQLiteVersion returns the version of SQLite that is embedded into your app.
43+
// This works by creating a temporary in-memory SQLite database to run a query
44+
// against.
45+
//
46+
// A separate database connection is established because you might want to get the
47+
// SQLite version before you call Connect(). This also just keeps things separate
48+
// from your own connection.
6849
func GetSQLiteVersion() (version string, err error) {
6950
//Get driver name based on SQLite library in use.
70-
driver, err := getDriver(DBTypeSQLite)
71-
if err != nil {
72-
return
73-
}
51+
driver := getDriver(DBTypeSQLite)
7452

7553
//Connect.
76-
conn, err := sqlx.Open(driver, ":memory:")
54+
conn, err := sqlx.Open(driver, InMemoryFilePathRacy)
7755
if err != nil {
7856
return
7957
}
@@ -89,66 +67,62 @@ func GetSQLiteVersion() (version string, err error) {
8967
}
9068

9169
// GetSQLiteLibrary returns the SQLite library that was used to build the binary. The
92-
// library is set at build/run with -tags {mattn || modernc}.
70+
// library is set at build/run with go build tags.
9371
func GetSQLiteLibrary() string {
9472
return sqliteLibrary
9573
}
9674

97-
// SQLitePragmasAsString builds the string of pragmas that should be appended to the
98-
// filename when connecting to a SQLite database. This is needed to set pragmas reliably
99-
// since pragmas must be set upon initially connecting to the database. The difficulty
100-
// in setting pragmas is that each SQLite library (mattn vs modernc) has a slighly
101-
// different format for setting pragmas. This takes the list of pragmas in SQLite query
102-
// format (PRAGMA busy_timeout = 5000) and translates them to the correct format for
103-
// the SQLite library in use.
104-
func (cfg *Config) SQLitePragmasAsString() (filenamePragmaString string) {
75+
// pragmsQueriesToString takes SQLite PRAGMAs in query format and retuns them in the
76+
// format needed to be appended to a SQLite database filepath per the in-use SQLite
77+
// driver.
78+
//
79+
// SQLite PRAGMAs need to be set upon initially connecting to the database. The
80+
// PRAGMAs are added to the database file's path as query parameter (?...&...).
81+
// However, the format of these appended query parameters differs between SQLite
82+
// libraries. This translates PRAGMA statements into the format required by the
83+
// library the binary is built with.
84+
//
85+
// "PRAGMA busy_timeout = 5000" becomes "_pragma=busy_timeout=5000" when using the
86+
// modernc library.
87+
func pragmsQueriesToString(pragmas []string) (filenamePragmaString string) {
10588
v := url.Values{}
10689

107-
for _, p := range cfg.SQLitePragmas {
90+
for _, p := range pragmas {
10891
//Sanitize, to make replace/stripping of "PRAGMA" keyword easier.
10992
p = strings.ToLower(p)
11093

11194
//Strip out the PRAGMA keyword.
112-
p = strings.Replace(p, "pragma", "", 1)
95+
p = strings.TrimPrefix(p, "pragma")
11396

114-
//Build filename pragma as expected by SQLite library is use.
97+
//Build pragma as expected by library in use.
11598
switch GetSQLiteLibrary() {
11699
case sqliteLibraryMattn:
117-
//ex: _busy_timeout=5000
100+
//Library's format: _busy_timeout=5000
118101
key, value, found := strings.Cut(p, "=")
119102
if !found {
120103
continue
121104
}
122105

123-
//trim
124106
key = strings.TrimSpace(key)
125107
value = strings.TrimSpace(value)
126108

127-
//add
128109
key = "_" + key
129110
v.Add(key, value)
111+
130112
case sqliteLibraryModernc:
131-
//ex: _pragma=busy_timeout=5000
113+
//Library's format: _pragma=busy_timeout=5000
132114
key := "_pragma"
133115
value := p
134116

135-
//trim
136117
value = strings.TrimSpace(value)
137118
value = strings.Replace(value, " ", "", -1)
138119

139-
//add
140120
v.Add(key, value)
121+
141122
default:
142-
//this can never happen since we hardcode the supported sqlite libraries.
123+
//This can never happen since we hardcode the supported SQLite libraries.
143124
}
144125
}
145126

146127
return "?" + v.Encode()
147128
}
148-
149-
// GetDefaultSQLitePragmas returns the default PRAGMAs this package defines for use with
150-
// either SQLite library. This can be helpful for debugging. We don't just export the
151-
// sqliteDefaultPragmas slice so that it cannot be modified.
152-
func GetDefaultSQLitePragmas() []string {
153-
return sqliteDefaultPragmas
154-
}

0 commit comments

Comments
 (0)