private/{dbutil,tagsql}: pass ctx to database opening
Database opening usually dial and hence we should pass ctx to them. Change-Id: Iaa2875981570d83e65be3710f841cf30349f807b
This commit is contained in:
parent
e3985799a1
commit
caefde6b32
@ -37,7 +37,7 @@ func OpenUnique(ctx context.Context, connStr string, schemaPrefix string) (db *d
|
|||||||
|
|
||||||
schemaName := schemaPrefix + "-" + CreateRandomTestingSchemaName(8)
|
schemaName := schemaPrefix + "-" + CreateRandomTestingSchemaName(8)
|
||||||
|
|
||||||
masterDB, err := tagsql.Open("cockroach", connStr)
|
masterDB, err := tagsql.Open(ctx, "cockroach", connStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(err)
|
return nil, errs.Wrap(err)
|
||||||
}
|
}
|
||||||
@ -65,12 +65,12 @@ func OpenUnique(ctx context.Context, connStr string, schemaPrefix string) (db *d
|
|||||||
return nil, errs.Combine(err, cleanup(masterDB))
|
return nil, errs.Combine(err, cleanup(masterDB))
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlDB, err := tagsql.Open("cockroach", modifiedConnStr)
|
sqlDB, err := tagsql.Open(ctx, "cockroach", modifiedConnStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Combine(errs.Wrap(err), cleanup(masterDB))
|
return nil, errs.Combine(errs.Wrap(err), cleanup(masterDB))
|
||||||
}
|
}
|
||||||
|
|
||||||
dbutil.Configure(sqlDB, "tmp_cockroach", mon)
|
dbutil.Configure(ctx, sqlDB, "tmp_cockroach", mon)
|
||||||
return &dbutil.TempDatabase{
|
return &dbutil.TempDatabase{
|
||||||
DB: sqlDB,
|
DB: sqlDB,
|
||||||
ConnStr: modifiedConnStr,
|
ConnStr: modifiedConnStr,
|
||||||
|
@ -37,7 +37,7 @@ func TestTempCockroachDB(t *testing.T) {
|
|||||||
connStrCopy := testDB.ConnStr
|
connStrCopy := testDB.ConnStr
|
||||||
|
|
||||||
// assert new test db exists and can be connected to again
|
// assert new test db exists and can be connected to again
|
||||||
otherConn, err := tagsql.Open(driverCopy, connStrCopy)
|
otherConn, err := tagsql.Open(ctx, driverCopy, connStrCopy)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer ctx.Check(otherConn.Close)
|
defer ctx.Check(otherConn.Close)
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ func TestTempCockroachDB(t *testing.T) {
|
|||||||
|
|
||||||
// make a new connection back to the master connstr just to check that the our temp db
|
// make a new connection back to the master connstr just to check that the our temp db
|
||||||
// really was dropped
|
// really was dropped
|
||||||
plainDBConn, err := tagsql.Open("cockroach", connstr)
|
plainDBConn, err := tagsql.Open(ctx, "cockroach", connstr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer ctx.Check(plainDBConn.Close)
|
defer ctx.Check(plainDBConn.Close)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
package dbutil
|
package dbutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"flag"
|
"flag"
|
||||||
"time"
|
"time"
|
||||||
@ -26,7 +27,7 @@ type ConfigurableDB interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Configure Sets Connection Boundaries and adds db_stats monitoring to monkit.
|
// Configure Sets Connection Boundaries and adds db_stats monitoring to monkit.
|
||||||
func Configure(db ConfigurableDB, dbName string, mon *monkit.Scope) {
|
func Configure(ctx context.Context, db ConfigurableDB, dbName string, mon *monkit.Scope) {
|
||||||
if *maxIdleConns >= 0 {
|
if *maxIdleConns >= 0 {
|
||||||
db.SetMaxIdleConns(*maxIdleConns)
|
db.SetMaxIdleConns(*maxIdleConns)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ func OpenUnique(ctx context.Context, connstr string, schemaPrefix string) (*dbut
|
|||||||
schemaName := schemaPrefix + "-" + CreateRandomTestingSchemaName(8)
|
schemaName := schemaPrefix + "-" + CreateRandomTestingSchemaName(8)
|
||||||
connStrWithSchema := ConnstrWithSchema(connstr, schemaName)
|
connStrWithSchema := ConnstrWithSchema(connstr, schemaName)
|
||||||
|
|
||||||
db, err := tagsql.Open("pgx", connStrWithSchema)
|
db, err := tagsql.Open(ctx, "pgx", connStrWithSchema)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// check that connection actually worked before trying CreateSchema, to make
|
// check that connection actually worked before trying CreateSchema, to make
|
||||||
// troubleshooting (lots) easier
|
// troubleshooting (lots) easier
|
||||||
@ -61,7 +61,7 @@ func OpenUnique(ctx context.Context, connstr string, schemaPrefix string) (*dbut
|
|||||||
return DropSchema(ctx, cleanupDB, schemaName)
|
return DropSchema(ctx, cleanupDB, schemaName)
|
||||||
}
|
}
|
||||||
|
|
||||||
dbutil.Configure(db, "tmp_postgres", mon)
|
dbutil.Configure(ctx, db, "tmp_postgres", mon)
|
||||||
return &dbutil.TempDatabase{
|
return &dbutil.TempDatabase{
|
||||||
DB: db,
|
DB: db,
|
||||||
ConnStr: connStrWithSchema,
|
ConnStr: connStrWithSchema,
|
||||||
|
@ -26,7 +26,7 @@ func TestTempPostgresDB(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// assert new test db exists and can be connected to again
|
// assert new test db exists and can be connected to again
|
||||||
otherConn, err := tagsql.Open(testDB.Driver, testDB.ConnStr)
|
otherConn, err := tagsql.Open(ctx, testDB.Driver, testDB.ConnStr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer ctx.Check(otherConn.Close)
|
defer ctx.Check(otherConn.Close)
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import (
|
|||||||
|
|
||||||
// LoadSchemaFromSQL inserts script into connstr and loads schema.
|
// LoadSchemaFromSQL inserts script into connstr and loads schema.
|
||||||
func LoadSchemaFromSQL(ctx context.Context, script string) (_ *dbschema.Schema, err error) {
|
func LoadSchemaFromSQL(ctx context.Context, script string) (_ *dbschema.Schema, err error) {
|
||||||
db, err := tagsql.Open("sqlite3", ":memory:")
|
db, err := tagsql.Open(ctx, "sqlite3", ":memory:")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(err)
|
return nil, errs.Wrap(err)
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ func LoadSchemaFromSQL(ctx context.Context, script string) (_ *dbschema.Schema,
|
|||||||
|
|
||||||
// LoadSnapshotFromSQL inserts script into connstr and loads schema.
|
// LoadSnapshotFromSQL inserts script into connstr and loads schema.
|
||||||
func LoadSnapshotFromSQL(ctx context.Context, script string) (_ *dbschema.Snapshot, err error) {
|
func LoadSnapshotFromSQL(ctx context.Context, script string) (_ *dbschema.Snapshot, err error) {
|
||||||
db, err := tagsql.Open("sqlite3", ":memory:")
|
db, err := tagsql.Open(ctx, "sqlite3", ":memory:")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(err)
|
return nil, errs.Wrap(err)
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,9 @@ func TestMigrateTablesToDatabase(t *testing.T) {
|
|||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
srcDB := newMemDB(t)
|
srcDB := openMemDB(ctx, t)
|
||||||
defer ctx.Check(srcDB.Close)
|
defer ctx.Check(srcDB.Close)
|
||||||
destDB := newMemDB(t)
|
destDB := openMemDB(ctx, t)
|
||||||
defer ctx.Check(srcDB.Close)
|
defer ctx.Check(srcDB.Close)
|
||||||
|
|
||||||
query := `
|
query := `
|
||||||
@ -53,7 +53,7 @@ func TestKeepTables(t *testing.T) {
|
|||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
db := newMemDB(t)
|
db := openMemDB(ctx, t)
|
||||||
defer ctx.Check(db.Close)
|
defer ctx.Check(db.Close)
|
||||||
|
|
||||||
table1SQL := `
|
table1SQL := `
|
||||||
@ -90,8 +90,8 @@ func execSQL(ctx context.Context, t *testing.T, db tagsql.DB, query string, args
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMemDB(t *testing.T) tagsql.DB {
|
func openMemDB(ctx context.Context, t *testing.T) tagsql.DB {
|
||||||
db, err := tagsql.Open("sqlite3", ":memory:")
|
db, err := tagsql.Open(ctx, "sqlite3", ":memory:")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return db
|
return db
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ func TestQuery(t *testing.T) {
|
|||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
db, err := tagsql.Open("sqlite3", ":memory:")
|
db, err := tagsql.Open(ctx, "sqlite3", ":memory:")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
defer ctx.Check(db.Close)
|
defer ctx.Check(db.Close)
|
||||||
|
@ -23,7 +23,7 @@ func TestCreate_Sqlite(t *testing.T) {
|
|||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
db, err := tagsql.Open("sqlite3", ":memory:")
|
db, err := tagsql.Open(ctx, "sqlite3", ":memory:")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -25,24 +25,24 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestBasicMigrationSqliteNoRebind(t *testing.T) {
|
func TestBasicMigrationSqliteNoRebind(t *testing.T) {
|
||||||
db, err := tagsql.Open("sqlite3", ":memory:")
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer func() { assert.NoError(t, db.Close()) }()
|
|
||||||
|
|
||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
|
db, err := tagsql.Open(ctx, "sqlite3", ":memory:")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer func() { assert.NoError(t, db.Close()) }()
|
||||||
|
|
||||||
basicMigration(ctx, t, db, db)
|
basicMigration(ctx, t, db, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBasicMigrationSqlite(t *testing.T) {
|
func TestBasicMigrationSqlite(t *testing.T) {
|
||||||
db, err := tagsql.Open("sqlite3", ":memory:")
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer func() { assert.NoError(t, db.Close()) }()
|
|
||||||
|
|
||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
|
db, err := tagsql.Open(ctx, "sqlite3", ":memory:")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer func() { assert.NoError(t, db.Close()) }()
|
||||||
|
|
||||||
basicMigration(ctx, t, db, &sqliteDB{DB: db})
|
basicMigration(ctx, t, db, &sqliteDB{DB: db})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,27 +137,30 @@ func basicMigration(ctx *testcontext.Context, t *testing.T, db tagsql.DB, testDB
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMultipleMigrationSqlite(t *testing.T) {
|
func TestMultipleMigrationSqlite(t *testing.T) {
|
||||||
db, err := tagsql.Open("sqlite3", ":memory:")
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer func() { assert.NoError(t, db.Close()) }()
|
|
||||||
|
|
||||||
multipleMigration(t, db, &sqliteDB{DB: db})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMultipleMigrationPostgres(t *testing.T) {
|
|
||||||
connstr := pgtest.PickPostgres(t)
|
|
||||||
|
|
||||||
db, err := tagsql.Open("pgx", connstr)
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer func() { assert.NoError(t, db.Close()) }()
|
|
||||||
|
|
||||||
multipleMigration(t, db, &postgresDB{DB: db})
|
|
||||||
}
|
|
||||||
|
|
||||||
func multipleMigration(t *testing.T, db tagsql.DB, testDB tagsql.DB) {
|
|
||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
|
db, err := tagsql.Open(ctx, "sqlite3", ":memory:")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer func() { assert.NoError(t, db.Close()) }()
|
||||||
|
|
||||||
|
multipleMigration(ctx, t, db, &sqliteDB{DB: db})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMultipleMigrationPostgres(t *testing.T) {
|
||||||
|
ctx := testcontext.New(t)
|
||||||
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
|
connstr := pgtest.PickPostgres(t)
|
||||||
|
|
||||||
|
db, err := tagsql.Open(ctx, "pgx", connstr)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer func() { assert.NoError(t, db.Close()) }()
|
||||||
|
|
||||||
|
multipleMigration(ctx, t, db, &postgresDB{DB: db})
|
||||||
|
}
|
||||||
|
|
||||||
|
func multipleMigration(ctx context.Context, t *testing.T, db tagsql.DB, testDB tagsql.DB) {
|
||||||
dbName := strings.ToLower(`versions_` + t.Name())
|
dbName := strings.ToLower(`versions_` + t.Name())
|
||||||
defer func() { assert.NoError(t, dropTables(ctx, db, dbName)) }()
|
defer func() { assert.NoError(t, dropTables(ctx, db, dbName)) }()
|
||||||
|
|
||||||
@ -213,27 +216,30 @@ func multipleMigration(t *testing.T, db tagsql.DB, testDB tagsql.DB) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFailedMigrationSqlite(t *testing.T) {
|
func TestFailedMigrationSqlite(t *testing.T) {
|
||||||
db, err := tagsql.Open("sqlite3", ":memory:")
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer func() { assert.NoError(t, db.Close()) }()
|
|
||||||
|
|
||||||
failedMigration(t, db, &sqliteDB{DB: db})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFailedMigrationPostgres(t *testing.T) {
|
|
||||||
connstr := pgtest.PickPostgres(t)
|
|
||||||
|
|
||||||
db, err := tagsql.Open("pgx", connstr)
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer func() { assert.NoError(t, db.Close()) }()
|
|
||||||
|
|
||||||
failedMigration(t, db, &postgresDB{DB: db})
|
|
||||||
}
|
|
||||||
|
|
||||||
func failedMigration(t *testing.T, db tagsql.DB, testDB tagsql.DB) {
|
|
||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
|
db, err := tagsql.Open(ctx, "sqlite3", ":memory:")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer func() { assert.NoError(t, db.Close()) }()
|
||||||
|
|
||||||
|
failedMigration(ctx, t, db, &sqliteDB{DB: db})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFailedMigrationPostgres(t *testing.T) {
|
||||||
|
ctx := testcontext.New(t)
|
||||||
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
|
connstr := pgtest.PickPostgres(t)
|
||||||
|
|
||||||
|
db, err := tagsql.Open(ctx, "pgx", connstr)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer func() { assert.NoError(t, db.Close()) }()
|
||||||
|
|
||||||
|
failedMigration(ctx, t, db, &postgresDB{DB: db})
|
||||||
|
}
|
||||||
|
|
||||||
|
func failedMigration(ctx context.Context, t *testing.T, db tagsql.DB, testDB tagsql.DB) {
|
||||||
dbName := strings.ToLower(`versions_` + t.Name())
|
dbName := strings.ToLower(`versions_` + t.Name())
|
||||||
defer func() { assert.NoError(t, dropTables(ctx, db, dbName)) }()
|
defer func() { assert.NoError(t, dropTables(ctx, db, dbName)) }()
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Open opens *sql.DB and wraps the implementation with tagging.
|
// Open opens *sql.DB and wraps the implementation with tagging.
|
||||||
func Open(driverName, dataSourceName string) (DB, error) {
|
func Open(ctx context.Context, driverName, dataSourceName string) (DB, error) {
|
||||||
db, err := sql.Open(driverName, dataSourceName)
|
db, err := sql.Open(driverName, dataSourceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -24,7 +24,7 @@ func run(t *testing.T, fn func(*testcontext.Context, *testing.T, tagsql.DB, tags
|
|||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
db, err := tagsql.Open("sqlite3", ":memory:")
|
db, err := tagsql.Open(ctx, "sqlite3", ":memory:")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ func Open(ctx context.Context, log *zap.Logger, databaseURL string, opts Options
|
|||||||
}
|
}
|
||||||
log.Debug("Connected to:", zap.String("db source", source))
|
log.Debug("Connected to:", zap.String("db source", source))
|
||||||
|
|
||||||
dbutil.Configure(dbxDB.DB, "satellitedb", mon)
|
dbutil.Configure(ctx, dbxDB.DB, "satellitedb", mon)
|
||||||
|
|
||||||
core := &satelliteDB{
|
core := &satelliteDB{
|
||||||
DB: dbxDB,
|
DB: dbxDB,
|
||||||
|
@ -37,12 +37,12 @@ type Client struct {
|
|||||||
func Open(ctx context.Context, dbURL string) (*Client, error) {
|
func Open(ctx context.Context, dbURL string) (*Client, error) {
|
||||||
dbURL = pgutil.CheckApplicationName(dbURL)
|
dbURL = pgutil.CheckApplicationName(dbURL)
|
||||||
|
|
||||||
db, err := tagsql.Open("cockroach", dbURL)
|
db, err := tagsql.Open(ctx, "cockroach", dbURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dbutil.Configure(db, "cockroachkv", mon)
|
dbutil.Configure(ctx, db, "cockroachkv", mon)
|
||||||
|
|
||||||
return NewWith(db, dbURL), nil
|
return NewWith(db, dbURL), nil
|
||||||
}
|
}
|
||||||
|
@ -34,12 +34,12 @@ type Client struct {
|
|||||||
func Open(ctx context.Context, dbURL string) (*Client, error) {
|
func Open(ctx context.Context, dbURL string) (*Client, error) {
|
||||||
dbURL = pgutil.CheckApplicationName(dbURL)
|
dbURL = pgutil.CheckApplicationName(dbURL)
|
||||||
|
|
||||||
db, err := tagsql.Open("pgx", dbURL)
|
db, err := tagsql.Open(ctx, "pgx", dbURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dbutil.Configure(db, "postgreskv", mon)
|
dbutil.Configure(ctx, db, "postgreskv", mon)
|
||||||
return NewWith(db, dbURL), nil
|
return NewWith(db, dbURL), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +318,7 @@ func (db *DB) openDatabase(ctx context.Context, dbName string) error {
|
|||||||
return ErrDatabase.Wrap(err)
|
return ErrDatabase.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlDB, err := tagsql.Open(driver, "file:"+path+"?_journal=WAL&_busy_timeout=10000")
|
sqlDB, err := tagsql.Open(ctx, driver, "file:"+path+"?_journal=WAL&_busy_timeout=10000")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrDatabase.Wrap(err)
|
return ErrDatabase.Wrap(err)
|
||||||
}
|
}
|
||||||
@ -326,7 +326,7 @@ func (db *DB) openDatabase(ctx context.Context, dbName string) error {
|
|||||||
mDB := db.SQLDBs[dbName]
|
mDB := db.SQLDBs[dbName]
|
||||||
mDB.Configure(sqlDB)
|
mDB.Configure(sqlDB)
|
||||||
|
|
||||||
dbutil.Configure(sqlDB, dbName, mon)
|
dbutil.Configure(ctx, sqlDB, dbName, mon)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user