mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-30 19:09:34 -06:00
case sensitivity for database and branch names
This commit is contained in:
@@ -96,10 +96,9 @@ func (p DoltDatabaseProvider) WithDbFactoryUrl(url string) DoltDatabaseProvider
|
||||
}
|
||||
|
||||
func (p DoltDatabaseProvider) Database(ctx *sql.Context, name string) (db sql.Database, err error) {
|
||||
name = strings.ToLower(name)
|
||||
var ok bool
|
||||
p.mu.RLock()
|
||||
db, ok = p.databases[name]
|
||||
db, ok = p.databases[formatDbMapKeyName(name)]
|
||||
p.mu.RUnlock()
|
||||
if ok {
|
||||
return db, nil
|
||||
@@ -116,8 +115,8 @@ func (p DoltDatabaseProvider) Database(ctx *sql.Context, name string) (db sql.Da
|
||||
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
if found, ok := p.databases[name]; !ok {
|
||||
p.databases[name] = db
|
||||
if found, ok := p.databases[formatDbMapKeyName(name)]; !ok {
|
||||
p.databases[formatDbMapKeyName(name)] = db
|
||||
return db, nil
|
||||
} else {
|
||||
return found, nil
|
||||
@@ -184,7 +183,7 @@ func (p DoltDatabaseProvider) CreateDatabase(ctx *sql.Context, name string) erro
|
||||
}
|
||||
|
||||
db := NewDatabase(name, newEnv.DbData(), opts)
|
||||
p.databases[strings.ToLower(db.Name())] = db
|
||||
p.databases[formatDbMapKeyName(db.Name())] = db
|
||||
|
||||
dbstate, err := GetInitialDBState(ctx, db)
|
||||
if err != nil {
|
||||
@@ -202,18 +201,19 @@ func (p DoltDatabaseProvider) DropDatabase(ctx *sql.Context, name string) error
|
||||
// TODO: there are still cases (not server-first) where we rename databases because the directory name would need
|
||||
// quoting if used as a database name, and that breaks here. We either need the database name to match the directory
|
||||
// name in all cases, or else keep a mapping from database name to directory on disk.
|
||||
db := p.databases[strings.ToLower(name)]
|
||||
dbKey := formatDbMapKeyName(name)
|
||||
db := p.databases[dbKey]
|
||||
|
||||
// Get the DB's directory
|
||||
exists, isDir := p.fs.Exists(db.Name())
|
||||
if !exists {
|
||||
// engine should already protect against this
|
||||
return sql.ErrDatabaseNotFound.New(name)
|
||||
return sql.ErrDatabaseNotFound.New(db.Name())
|
||||
} else if !isDir {
|
||||
return fmt.Errorf("unexpected error: %s exists but is not a directory", name)
|
||||
return fmt.Errorf("unexpected error: %s exists but is not a directory", dbKey)
|
||||
}
|
||||
|
||||
err := p.fs.Delete(name, true)
|
||||
err := p.fs.Delete(db.Name(), true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -222,21 +222,20 @@ func (p DoltDatabaseProvider) DropDatabase(ctx *sql.Context, name string) error
|
||||
|
||||
// We not only have to delete this database, but any derivative ones that we've stored as a result of USE or
|
||||
// connection strings
|
||||
derivativeNamePrefix := strings.ToLower(name) + "/"
|
||||
derivativeNamePrefix := dbKey + "/"
|
||||
for dbName := range p.databases {
|
||||
if strings.HasPrefix(strings.ToLower(dbName), derivativeNamePrefix) {
|
||||
delete(p.databases, strings.ToLower(dbName))
|
||||
if strings.HasPrefix(dbName, derivativeNamePrefix) {
|
||||
delete(p.databases, dbName)
|
||||
}
|
||||
}
|
||||
|
||||
delete(p.databases, strings.ToLower(name))
|
||||
delete(p.databases, dbKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
//TODO: databaseForRevision should call checkout on the given branch/commit, returning a non-mutable session
|
||||
// only if a non-branch revspec was indicated.
|
||||
func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revDB string) (sql.Database, dsess.InitialDbState, bool, error) {
|
||||
revDB = strings.ToLower(revDB)
|
||||
if !strings.Contains(revDB, dbRevisionDelimiter) {
|
||||
return nil, dsess.InitialDbState{}, false, nil
|
||||
}
|
||||
@@ -245,7 +244,7 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revDB string
|
||||
dbName, revSpec := parts[0], parts[1]
|
||||
|
||||
p.mu.RLock()
|
||||
candidate, ok := p.databases[dbName]
|
||||
candidate, ok := p.databases[formatDbMapKeyName(dbName)]
|
||||
p.mu.RUnlock()
|
||||
if !ok {
|
||||
return nil, dsess.InitialDbState{}, false, nil
|
||||
@@ -520,3 +519,16 @@ type staticRepoState struct {
|
||||
func (s staticRepoState) CWBHeadRef() ref.DoltRef {
|
||||
return s.branch
|
||||
}
|
||||
|
||||
// formatDbMapKeyName returns formatted string of database name and/or branch name. Database name is case-insensitive,
|
||||
// so it's stored in lower case name. Branch name is case-sensitive, so not changed.
|
||||
func formatDbMapKeyName(name string) string {
|
||||
if !strings.Contains(name, dbRevisionDelimiter) {
|
||||
return strings.ToLower(name)
|
||||
}
|
||||
|
||||
parts := strings.SplitN(name, dbRevisionDelimiter, 2)
|
||||
dbName, revSpec := parts[0], parts[1]
|
||||
|
||||
return strings.ToLower(dbName) + dbRevisionDelimiter + revSpec
|
||||
}
|
||||
|
||||
@@ -848,7 +848,7 @@ func (sess *Session) AddDB(ctx *sql.Context, dbState InitialDbState) error {
|
||||
|
||||
sessionState := &DatabaseSessionState{}
|
||||
sess.dbStates[db.Name()] = sessionState
|
||||
|
||||
sessionState.dbName = db.Name()
|
||||
// TODO: get rid of all repo state reader / writer stuff. Until we do, swap out the reader with one of our own, and
|
||||
// the writer with one that errors out
|
||||
sessionState.dbData = dbState.DbData
|
||||
|
||||
@@ -396,6 +396,36 @@ func TestCreateDatabase(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDropDatabase(t *testing.T) {
|
||||
enginetest.TestScript(t, newDoltHarness(t), queries.ScriptTest{
|
||||
Name: "Drop database engine tests for Dolt only",
|
||||
SetUpScript: []string{
|
||||
"CREATE DATABASE Test1db",
|
||||
"CREATE DATABASE TEST2db",
|
||||
},
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "DROP DATABASE TeSt2DB",
|
||||
Expected: []sql.Row{{sql.OkResult{RowsAffected: 1}}},
|
||||
},
|
||||
{
|
||||
Query: "USE test2db",
|
||||
ExpectedErr: sql.ErrDatabaseNotFound,
|
||||
},
|
||||
{
|
||||
Query: "USE TEST1DB",
|
||||
Expected: []sql.Row{},
|
||||
},
|
||||
{
|
||||
Query: "DROP DATABASE IF EXISTS test1DB",
|
||||
Expected: []sql.Row{{sql.OkResult{RowsAffected: 1}}},
|
||||
},
|
||||
{
|
||||
Query: "USE Test1db",
|
||||
ExpectedErr: sql.ErrDatabaseNotFound,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
t.Skip("Dolt doesn't yet support dropping the primary database, which these tests do")
|
||||
enginetest.TestDropDatabase(t, newDoltHarness(t))
|
||||
}
|
||||
|
||||
@@ -1131,22 +1131,25 @@ END""")
|
||||
}
|
||||
|
||||
@test "sql-server: connect to databases case insensitive" {
|
||||
skip "Database connnection strings are case sensitive and should not be"
|
||||
skiponwindows "Has dependencies that are missing on the Jenkins Windows installation."
|
||||
skip_nbf_dolt_1
|
||||
|
||||
|
||||
mkdir no_dolt && cd no_dolt
|
||||
start_sql_server
|
||||
|
||||
server_query "" 1 "create database Test1"
|
||||
|
||||
|
||||
server_query "" 1 "show databases" "Database\nTest1\ninformation_schema"
|
||||
server_query "test1" 1 "create table a(x int)"
|
||||
server_query "TEST1" 1 "insert into a values (1), (2)"
|
||||
run server_query "test1" 1 "select dolt_commit('-a', '-m', 'new table a')"
|
||||
run server_query "test1" 1 "select dolt_checkout('-b', 'newbranch')"
|
||||
server_query "TEST1/newbranch" 1 "select * from a" "x\n1\n2"
|
||||
server_query "TEST1/NEWBRANCH" 1 "select * from a" "x\n1\n2"
|
||||
multi_query "" 1 "use test1; create table a(x int);"
|
||||
multi_query "" 1 "use TEST1; insert into a values (1), (2);"
|
||||
run multi_query "" 1 "use test1; select dolt_commit('-a', '-m', 'new table a');"
|
||||
run multi_query "" 1 "use test1; select dolt_checkout('-b', 'newbranch');"
|
||||
multi_query "" 1 "use \`TEST1/newbranch\`; select * from a" "x\n1\n2"
|
||||
multi_query "" 1 "use \`test1/newbranch\`; select * from a" "x\n1\n2"
|
||||
server_query "" 1 "use \`TEST1/NEWBRANCH\`" "" "database not found: TEST1/NEWBRANCH"
|
||||
|
||||
multi_query "" 1 "create database test2; use test2; select database();" "database()\ntest2"
|
||||
multi_query "" 1 "use test2; drop database TEST2; select database();" "null"
|
||||
}
|
||||
|
||||
@test "sql-server: create and drop database with --multi-db-dir" {
|
||||
|
||||
@@ -664,7 +664,7 @@ SQL
|
||||
CREATE DATABASE test1;
|
||||
CREATE DATABASE test2;
|
||||
USE test1;
|
||||
CALL DOLT_CHECKOUT('-b', 'newbranch');
|
||||
CALL DOLT_CHECKOUT('-b', 'newBranch');
|
||||
USE \`test1/newBranch\`;
|
||||
USE test2;
|
||||
DROP DATABASE test1;
|
||||
@@ -675,16 +675,16 @@ SQL
|
||||
run dolt sql <<SQL
|
||||
CREATE DATABASE test1;
|
||||
USE test1;
|
||||
CALL DOLT_CHECKOUT('-b', 'newbranch');
|
||||
USE \`test1/newBranch\`;
|
||||
CALL DOLT_CHECKOUT('-b', 'newBranch');
|
||||
USE \`TEST1/newBranch\`;
|
||||
USE test2;
|
||||
DROP DATABASE test1;
|
||||
DROP DATABASE Test1;
|
||||
SHOW TABLES;
|
||||
USE \`test1/newBranch\`;
|
||||
SQL
|
||||
|
||||
[ $status -ne 0 ]
|
||||
[[ "$output" =~ "database not found: test1/newbranch" ]] || false
|
||||
[[ "$output" =~ "database not found: test1/newBranch" ]] || false
|
||||
|
||||
cd ../
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user