camtool dbinit: sqlite support

Change-Id: I649a28e52df8d2689daa784dd2b1c06770e4b857
This commit is contained in:
mpl 2013-03-20 17:10:39 +01:00
parent 61f0d3c691
commit 1148a51b09
2 changed files with 74 additions and 6 deletions

View File

@ -18,6 +18,7 @@ package main
import (
"database/sql"
"errors"
"flag"
"fmt"
"os"
@ -26,6 +27,7 @@ import (
"camlistore.org/pkg/cmdmain"
"camlistore.org/pkg/index/mysql"
"camlistore.org/pkg/index/postgres"
"camlistore.org/pkg/index/sqlite"
_ "camlistore.org/third_party/github.com/bmizerany/pq"
_ "camlistore.org/third_party/github.com/ziutek/mymysql/godrv"
@ -48,8 +50,8 @@ func init() {
flags.StringVar(&cmd.user, "user", "root", "Admin user.")
flags.StringVar(&cmd.password, "password", "", "Admin password.")
flags.StringVar(&cmd.host, "host", "localhost", "host[:port]")
flags.StringVar(&cmd.dbName, "dbname", "", "Database to wipe or create.")
flags.StringVar(&cmd.dbType, "dbtype", "mysql", "Which RDMS to use; possible values: mysql, postgres.")
flags.StringVar(&cmd.dbName, "dbname", "", "Database to wipe or create. For sqlite, this is the db filename.")
flags.StringVar(&cmd.dbType, "dbtype", "mysql", "Which RDMS to use; possible values: mysql, postgres, sqlite.")
flags.BoolVar(&cmd.wipe, "wipe", false, "Wipe the database and re-create it?")
flags.BoolVar(&cmd.keep, "ignoreexists", false, "Do nothing if database already exists.")
@ -78,8 +80,15 @@ func (c *dbinitCmd) RunCommand(args []string) error {
}
if c.dbType != "mysql" && c.dbType != "postgres" {
return cmdmain.UsageError(fmt.Sprintf("--dbtype flag: got %v, want %v", c.dbType, `"mysql" or "postgres"`))
if c.dbType == "sqlite" {
if !WithSQLite {
return ErrNoSQLite
}
} else {
return cmdmain.UsageError(fmt.Sprintf("--dbtype flag: got %v, want %v", c.dbType, `"mysql" or "postgres", or "sqlite"`))
}
}
var rootdb *sql.DB
var err error
switch c.dbType {
@ -102,20 +111,31 @@ func (c *dbinitCmd) RunCommand(args []string) error {
if !c.wipe {
return cmdmain.UsageError(fmt.Sprintf("Database %q already exists, but --wipe not given. Stopping.", dbname))
}
do(rootdb, "DROP DATABASE "+dbname)
if c.dbType != "sqlite" {
do(rootdb, "DROP DATABASE "+dbname)
}
}
if c.dbType == "sqlite" {
_, err := os.Create(dbname)
if err != nil {
exitf("Error creating file %v for sqlite db: %v", dbname, err)
}
} else {
do(rootdb, "CREATE DATABASE "+dbname)
}
do(rootdb, "CREATE DATABASE "+dbname)
var db *sql.DB
switch c.dbType {
case "postgres":
conninfo := fmt.Sprintf("user=%s dbname=%s host=%s password=%s sslmode=require", c.user, dbname, c.host, c.password)
db, err = sql.Open("postgres", conninfo)
case "sqlite":
db, err = sql.Open("sqlite3", dbname)
default:
db, err = sql.Open("mymysql", dbname+"/"+c.user+"/"+c.password)
}
if err != nil {
return fmt.Errorf("Error connecting to the %s %s database: %v", dbname, c.dbType, err)
return fmt.Errorf("Connecting to the %s %s database: %v", dbname, c.dbType, err)
}
switch c.dbType {
@ -132,6 +152,11 @@ func (c *dbinitCmd) RunCommand(args []string) error {
do(db, tableSql)
}
do(db, fmt.Sprintf(`REPLACE INTO meta VALUES ('version', '%d')`, mysql.SchemaVersion()))
case "sqlite":
for _, tableSql := range sqlite.SQLCreateTables() {
do(db, tableSql)
}
do(db, fmt.Sprintf(`REPLACE INTO meta VALUES ('version', '%d')`, sqlite.SchemaVersion()))
}
return nil
}
@ -159,6 +184,11 @@ func dbExists(db *sql.DB, dbtype, dbname string) bool {
query = "SELECT datname FROM pg_database"
case "mysql":
query = "SHOW DATABASES"
case "sqlite":
// There is no point in using sql.Open because it apparently does
// not return an error when the file does not exist.
_, err := os.Stat(dbname)
return err == nil
}
rows, err := db.Query(query)
check(err)
@ -187,3 +217,14 @@ func exitf(format string, args ...interface{}) {
cmdmain.Errorf(format, args)
cmdmain.Exit(1)
}
var WithSQLite = false
var ErrNoSQLite = errors.New("the command was not built with SQLite support. Rebuild with go get/install --tags=with_sqlite " + compileHint())
func compileHint() string {
if _, err := os.Stat("/etc/apt"); err == nil {
return " (Required: apt-get install libsqlite3-dev)"
}
return ""
}

View File

@ -0,0 +1,27 @@
// +build with_sqlite
/*
Copyright 2013 The Camlistore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
_ "camlistore.org/third_party/github.com/mattn/go-sqlite3"
)
func init() {
WithSQLite = true
}