// Open opens or creates an HBase storage with given dsn, format should be 'zk1,zk2,zk3|tsoaddr:port/tblName'. // If tsoAddr is not provided, it will use a local oracle instead. func (d Driver) Open(dsn string) (kv.Storage, error) { mc.mu.Lock() defer mc.mu.Unlock() if store, ok := mc.cache[dsn]; ok { // TODO: check the cache store has the same engine with this Driver. return store, nil } zks, oracleAddr, tableName, err := parseDSN(dsn) if err != nil { return nil, errors.Trace(err) } // create buffered HBase connections, HBaseClient is goroutine-safe, so // it's OK to redistribute to transactions. conns := make([]hbase.HBaseClient, 0, hbaseConnPoolSize) for i := 0; i < hbaseConnPoolSize; i++ { c, err := hbase.NewClient(zks, "/hbase") if err != nil { return nil, errors.Trace(err) } conns = append(conns, c) } c := conns[0] if !c.TableExists(tableName) { // Create new hbase table for store. t := hbase.NewTableDesciptor(hbase.NewTableNameWithDefaultNS(tableName)) cf := hbase.NewColumnFamilyDescriptor(hbaseColFamily) cf.AddStrAddr("THEMIS_ENABLE", "true") t.AddColumnDesc(cf) //TODO: specify split? if err := c.CreateTable(t, nil); err != nil { return nil, errors.Trace(err) } } var ora oracle.Oracle if len(oracleAddr) == 0 { ora = oracles.NewLocalOracle() } else { ora = oracles.NewRemoteOracle(oracleAddr) } s := &hbaseStore{ dsn: dsn, storeName: tableName, oracle: ora, conns: conns, } mc.cache[dsn] = s return s, nil }
// Open opens or creates an HBase storage with given path. // // The format of path should be 'hbase://zk1,zk2,zk3/table[?tso=local|zk]'. // If tso is not provided, it will use a local oracle instead. (for test only) func (d Driver) Open(path string) (kv.Storage, error) { mc.mu.Lock() defer mc.mu.Unlock() zks, tso, tableName, err := parsePath(path) if err != nil { return nil, errors.Trace(err) } if tso != tsoTypeLocal && tso != tsoTypeZK { return nil, errors.Trace(ErrInvalidDSN) } uuid := fmt.Sprintf("hbase-%v-%v", zks, tableName) if tso == tsoTypeLocal { log.Warnf("hbase: store(%s) is using local oracle(for test only)", uuid) } if store, ok := mc.cache[uuid]; ok { return store, nil } // create buffered HBase connections, HBaseClient is goroutine-safe, so // it's OK to redistribute to transactions. conns := make([]hbase.HBaseClient, 0, hbaseConnPoolSize) for i := 0; i < hbaseConnPoolSize; i++ { var c hbase.HBaseClient c, err = hbase.NewClient(strings.Split(zks, ","), "/hbase") if err != nil { return nil, errors.Trace(err) } conns = append(conns, c) } c := conns[0] var b bool b, err = c.TableExists(tableName) if err != nil { return nil, errors.Trace(err) } if !b { // Create new hbase table for store. t := hbase.NewTableDesciptor(tableName) cf := hbase.NewColumnFamilyDescriptor(hbaseColFamily) cf.AddAttr("THEMIS_ENABLE", "true") t.AddColumnDesc(cf) //TODO: specify split? if err := c.CreateTable(t, nil); err != nil { return nil, errors.Trace(err) } } var ora oracle.Oracle switch tso { case tsoTypeLocal: ora = oracles.NewLocalOracle() case tsoTypeZK: ora = oracles.NewRemoteOracle(zks, tsoZKPath) } s := &hbaseStore{ uuid: uuid, storeName: tableName, oracle: ora, conns: conns, } mc.cache[uuid] = s return s, nil }