-
Notifications
You must be signed in to change notification settings - Fork 32
Expand file tree
/
Copy pathemulator_util.go
More file actions
94 lines (88 loc) · 3.3 KB
/
emulator_util.go
File metadata and controls
94 lines (88 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright 2025 Google LLC All Rights Reserved.
//
// 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 spannerdriver
import (
"context"
"fmt"
"cloud.google.com/go/spanner"
database "cloud.google.com/go/spanner/admin/database/apiv1"
"cloud.google.com/go/spanner/admin/database/apiv1/databasepb"
instance "cloud.google.com/go/spanner/admin/instance/apiv1"
"cloud.google.com/go/spanner/admin/instance/apiv1/instancepb"
"google.golang.org/api/option"
"google.golang.org/grpc/codes"
)
func autoConfigEmulator(ctx context.Context, host, project, instance, database string, dialect databasepb.DatabaseDialect, opts []option.ClientOption) error {
if err := createInstance(project, instance, opts); err != nil {
if spanner.ErrCode(err) != codes.AlreadyExists {
return err
}
}
if err := createDatabase(project, instance, database, dialect, opts); err != nil {
if spanner.ErrCode(err) != codes.AlreadyExists {
return err
}
}
return nil
}
func createInstance(projectId, instanceId string, opts []option.ClientOption) error {
ctx := context.Background()
instanceAdmin, err := instance.NewInstanceAdminClient(ctx, opts...)
if err != nil {
return err
}
defer func() { _ = instanceAdmin.Close() }()
op, err := instanceAdmin.CreateInstance(ctx, &instancepb.CreateInstanceRequest{
Parent: fmt.Sprintf("projects/%s", projectId),
InstanceId: instanceId,
Instance: &instancepb.Instance{
Config: fmt.Sprintf("projects/%s/instanceConfigs/%s", projectId, "emulator-config"),
DisplayName: instanceId,
NodeCount: 1,
},
})
if err != nil {
return fmt.Errorf("could not create instance %s: %w", fmt.Sprintf("projects/%s/instances/%s", projectId, instanceId), err)
}
// Wait for the instance creation to finish.
if _, err := op.Wait(ctx); err != nil {
return fmt.Errorf("waiting for instance creation to finish failed: %v", err)
}
return nil
}
func createDatabase(projectId, instanceId, databaseId string, dialect databasepb.DatabaseDialect, opts []option.ClientOption) error {
ctx := context.Background()
databaseAdminClient, err := database.NewDatabaseAdminClient(ctx, opts...)
if err != nil {
return err
}
defer func() { _ = databaseAdminClient.Close() }()
createStatement := fmt.Sprintf("CREATE DATABASE `%s`", databaseId)
if dialect == databasepb.DatabaseDialect_POSTGRESQL {
createStatement = fmt.Sprintf(`CREATE DATABASE "%s"`, databaseId)
}
opDB, err := databaseAdminClient.CreateDatabase(ctx, &databasepb.CreateDatabaseRequest{
Parent: fmt.Sprintf("projects/%s/instances/%s", projectId, instanceId),
CreateStatement: createStatement,
DatabaseDialect: dialect,
})
if err != nil {
return err
}
// Wait for the database creation to finish.
if _, err := opDB.Wait(ctx); err != nil {
return fmt.Errorf("waiting for database creation to finish failed: %v", err)
}
return nil
}