90 lines
1.6 KiB
Go
90 lines
1.6 KiB
Go
|
package sqlite
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"net/url"
|
||
|
"path/filepath"
|
||
|
"runtime"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
const connectionScheme = `file`
|
||
|
|
||
|
// ConnectionURL implements a SQLite connection struct.
|
||
|
type ConnectionURL struct {
|
||
|
Database string
|
||
|
Options map[string]string
|
||
|
}
|
||
|
|
||
|
func (c ConnectionURL) String() (s string) {
|
||
|
vv := url.Values{}
|
||
|
|
||
|
if c.Database == "" {
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
// Did the user provided a full database path?
|
||
|
if !strings.HasPrefix(c.Database, "/") {
|
||
|
c.Database, _ = filepath.Abs(c.Database)
|
||
|
if runtime.GOOS == "windows" {
|
||
|
// Closes https://github.com/upper/db/issues/60
|
||
|
c.Database = "/" + strings.Replace(c.Database, `\`, `/`, -1)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Do we have any options?
|
||
|
if c.Options == nil {
|
||
|
c.Options = map[string]string{}
|
||
|
}
|
||
|
|
||
|
if _, ok := c.Options["_busy_timeout"]; !ok {
|
||
|
c.Options["_busy_timeout"] = "10000"
|
||
|
}
|
||
|
|
||
|
// Converting options into URL values.
|
||
|
for k, v := range c.Options {
|
||
|
vv.Set(k, v)
|
||
|
}
|
||
|
|
||
|
// Building URL.
|
||
|
u := url.URL{
|
||
|
Scheme: connectionScheme,
|
||
|
Path: c.Database,
|
||
|
RawQuery: vv.Encode(),
|
||
|
}
|
||
|
|
||
|
return u.String()
|
||
|
}
|
||
|
|
||
|
// ParseURL parses s into a ConnectionURL struct.
|
||
|
func ParseURL(s string) (conn ConnectionURL, err error) {
|
||
|
var u *url.URL
|
||
|
|
||
|
if !strings.HasPrefix(s, connectionScheme+"://") {
|
||
|
return conn, fmt.Errorf(`Expecting file:// connection scheme.`)
|
||
|
}
|
||
|
|
||
|
if u, err = url.Parse(s); err != nil {
|
||
|
return conn, err
|
||
|
}
|
||
|
|
||
|
conn.Database = u.Host + u.Path
|
||
|
conn.Options = map[string]string{}
|
||
|
|
||
|
var vv url.Values
|
||
|
|
||
|
if vv, err = url.ParseQuery(u.RawQuery); err != nil {
|
||
|
return conn, err
|
||
|
}
|
||
|
|
||
|
for k := range vv {
|
||
|
conn.Options[k] = vv.Get(k)
|
||
|
}
|
||
|
|
||
|
if _, ok := conn.Options["cache"]; !ok {
|
||
|
conn.Options["cache"] = "shared"
|
||
|
}
|
||
|
|
||
|
return conn, err
|
||
|
}
|