mirror of
https://github.com/dolthub/dolt.git
synced 2026-05-12 19:39:32 -05:00
Merge pull request #3994 from dolthub/taylor/use-db-tag
Support `USE` statement with tag name
This commit is contained in:
@@ -726,6 +726,22 @@ func (ddb *DoltDB) GetTags(ctx context.Context) ([]ref.DoltRef, error) {
|
||||
return ddb.GetRefsOfType(ctx, tagsRefFilter)
|
||||
}
|
||||
|
||||
// HasTag returns whether the DB has a tag with the name given
|
||||
func (ddb *DoltDB) HasTag(ctx context.Context, tagName string) (bool, error) {
|
||||
tags, err := ddb.GetRefsOfType(ctx, tagsRefFilter)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, t := range tags {
|
||||
if t.GetPath() == tagName {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
type TagWithHash struct {
|
||||
Tag *Tag
|
||||
Hash hash.Hash
|
||||
|
||||
@@ -425,6 +425,40 @@ func (p DoltDatabaseProvider) databaseForRevision(ctx *sql.Context, revDB string
|
||||
return db, init, true, nil
|
||||
}
|
||||
|
||||
isTag, err := isTag(ctx, srcDb, revSpec, p.remoteDialer)
|
||||
if err != nil {
|
||||
return nil, dsess.InitialDbState{}, false, err
|
||||
}
|
||||
|
||||
if isTag {
|
||||
// TODO: this should be an interface, not a struct
|
||||
replicaDb, ok := srcDb.(ReadReplicaDatabase)
|
||||
if ok {
|
||||
srcDb = replicaDb.Database
|
||||
}
|
||||
|
||||
srcDb, ok = srcDb.(Database)
|
||||
if !ok {
|
||||
return nil, dsess.InitialDbState{}, false, nil
|
||||
}
|
||||
|
||||
tag, err := srcDb.(Database).DbData().Ddb.ResolveTag(ctx, ref.NewTagRef(revSpec))
|
||||
if err != nil {
|
||||
return nil, dsess.InitialDbState{}, false, err
|
||||
}
|
||||
|
||||
commitHash, err := tag.Commit.HashOf()
|
||||
if err != nil {
|
||||
return nil, dsess.InitialDbState{}, false, err
|
||||
}
|
||||
|
||||
db, init, err := dbRevisionForCommit(ctx, srcDb.(Database), commitHash.String())
|
||||
if err != nil {
|
||||
return nil, dsess.InitialDbState{}, false, err
|
||||
}
|
||||
return db, init, true, nil
|
||||
}
|
||||
|
||||
if doltdb.IsValidCommitHash(revSpec) {
|
||||
// TODO: this should be an interface, not a struct
|
||||
replicaDb, ok := srcDb.(ReadReplicaDatabase)
|
||||
@@ -584,6 +618,36 @@ func isBranch(ctx context.Context, db SqlDatabase, branchName string, dialer dbf
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// isTag returns whether a tag with the given name is in scope for the database given
|
||||
func isTag(ctx context.Context, db SqlDatabase, tagName string, dialer dbfactory.GRPCDialProvider) (bool, error) {
|
||||
var ddbs []*doltdb.DoltDB
|
||||
|
||||
if rdb, ok := db.(ReadReplicaDatabase); ok {
|
||||
remoteDB, err := rdb.remote.GetRemoteDB(ctx, rdb.ddb.Format(), dialer)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
ddbs = append(ddbs, rdb.ddb, remoteDB)
|
||||
} else if ddb, ok := db.(Database); ok {
|
||||
ddbs = append(ddbs, ddb.ddb)
|
||||
} else {
|
||||
return false, fmt.Errorf("unrecognized type of database %T", db)
|
||||
}
|
||||
|
||||
for _, ddb := range ddbs {
|
||||
tagExists, err := ddb.HasTag(ctx, tagName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if tagExists {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func dbRevisionForBranch(ctx context.Context, srcDb SqlDatabase, revSpec string) (SqlDatabase, dsess.InitialDbState, error) {
|
||||
branch := ref.NewBranchRef(revSpec)
|
||||
cm, err := srcDb.DbData().Ddb.ResolveCommitRef(ctx, branch)
|
||||
|
||||
@@ -316,6 +316,24 @@ teardown() {
|
||||
server_query repo2 1 "use \`repo2/$head_hash\`" ""
|
||||
}
|
||||
|
||||
@test "remotes-sql-server: connect to tag works" {
|
||||
skiponwindows "Missing dependencies"
|
||||
|
||||
cd repo1
|
||||
dolt commit -am "cm"
|
||||
dolt push remote1 main
|
||||
head_hash=$(get_head_commit)
|
||||
|
||||
cd ../repo2
|
||||
dolt config --local --add sqlserver.global.dolt_read_replica_remote remote1
|
||||
dolt config --local --add sqlserver.global.dolt_replicate_heads main
|
||||
dolt tag v1
|
||||
start_sql_server repo2
|
||||
|
||||
server_query repo2 1 "show tables" "Tables_in_repo2\ntest"
|
||||
server_query repo2 1 "use \`repo2/v1\`" ""
|
||||
}
|
||||
|
||||
get_head_commit() {
|
||||
dolt log -n 1 | grep -m 1 commit | cut -c 13-44
|
||||
}
|
||||
|
||||
@@ -1606,6 +1606,83 @@ SQL
|
||||
[[ "$output" =~ 'read-only' ]] || false
|
||||
}
|
||||
|
||||
@test "sql: tag qualified DB name in select" {
|
||||
dolt add .; dolt commit -m 'commit tables'
|
||||
dolt checkout -b feature-branch
|
||||
|
||||
dolt sql <<SQL
|
||||
USE \`dolt_repo_$$/feature-branch\`;
|
||||
CREATE TABLE a1(x int primary key);
|
||||
insert into a1 values (1), (2), (3);
|
||||
SELECT DOLT_COMMIT('-a', '-m', 'new table');
|
||||
SQL
|
||||
|
||||
run dolt tag v1
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run dolt sql -q "select * from \`dolt_repo_$$/v1\`.a1 order by x;" -r csv
|
||||
[ "$status" -eq 0 ]
|
||||
[ "${#lines[@]}" -eq 4 ]
|
||||
}
|
||||
|
||||
@test "sql: tag qualified DB name in delete" {
|
||||
dolt add .; dolt commit -m 'commit tables'
|
||||
dolt checkout -b feature-branch
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE a1(x int primary key);
|
||||
insert into a1 values (1), (2), (3);
|
||||
SELECT DOLT_COMMIT('-a', '-m', 'new table');
|
||||
insert into a1 values (4), (5), (6);
|
||||
select DOLT_COMMIT('-a', '-m', 'more values');
|
||||
SQL
|
||||
|
||||
run dolt tag v1
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run dolt sql -q "delete from \`dolt_repo_$$/v1\`.a1;" -r csv
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ 'read-only' ]] || false
|
||||
|
||||
# same with USE syntax
|
||||
run dolt sql <<SQL
|
||||
USE \`dolt_repo_$$/v1\`;
|
||||
delete from a1;
|
||||
SQL
|
||||
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ 'read-only' ]] || false
|
||||
}
|
||||
|
||||
@test "sql: tag qualified DB name in update" {
|
||||
dolt add .; dolt commit -m 'commit tables'
|
||||
dolt checkout -b feature-branch
|
||||
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE a1(x int primary key);
|
||||
insert into a1 values (1), (2), (3);
|
||||
SELECT DOLT_COMMIT('-a', '-m', 'new table');
|
||||
insert into a1 values (4), (5), (6);
|
||||
select DOLT_COMMIT('-a', '-m', 'more values');
|
||||
SQL
|
||||
|
||||
run dolt tag v1
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run dolt sql -q "update \`dolt_repo_$$/v1\`.a1 set x = x*10" -r csv
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ 'read-only' ]] || false
|
||||
|
||||
# same with USE syntax
|
||||
run dolt sql <<SQL
|
||||
USE \`dolt_repo_$$/v1\`;
|
||||
update a1 set x = x*10;
|
||||
SQL
|
||||
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ 'read-only' ]] || false
|
||||
}
|
||||
|
||||
@test "sql: describe" {
|
||||
run dolt sql -q "describe one_pk"
|
||||
[ $status -eq 0 ]
|
||||
|
||||
Reference in New Issue
Block a user