// Copyright 2018 PingCAP, Inc. // // 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, // See the License for the specific language governing permissions and // limitations under the License. package store import ( "net/url" "strings" "github.com/pingcap/errors" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/util" log "github.com/sirupsen/logrus" ) var stores = make(map[string]kv.Driver) // Register registers a kv storage with unique name and its associated Driver. func Register(name string, driver kv.Driver) error { name = strings.ToLower(name) if _, ok := stores[name]; ok { return errors.Errorf("%s is already registered", name) } stores[name] = driver return nil } // New creates a kv Storage with path. // // The path must be a URL format 'engine://path?params' like the one for // session.Open() but with the dbname cut off. // Examples: // goleveldb://relative/path // boltdb:///absolute/path // // The engine should be registered before creating storage. func New(path string) (kv.Storage, error) { return newStoreWithRetry(path, util.DefaultMaxRetries) } func newStoreWithRetry(path string, maxRetries int) (kv.Storage, error) { storeURL, err := url.Parse(path) if err != nil { return nil, errors.Trace(err) } name := strings.ToLower(storeURL.Scheme) d, ok := stores[name] if !ok { return nil, errors.Errorf("invalid uri format, storage %s is not registered", name) } var s kv.Storage err = util.RunWithRetry(maxRetries, util.RetryInterval, func() (bool, error) { log.Infof("new store") s, err = d.Open(path) return kv.IsRetryableError(err), err }) return s, errors.Trace(err) }