12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- package abstract_sql
- import (
- "context"
- "database/sql"
- "encoding/base64"
- "fmt"
- "strings"
- "github.com/chrislusf/seaweedfs/weed/filer"
- "github.com/chrislusf/seaweedfs/weed/util/log"
- "github.com/chrislusf/seaweedfs/weed/util"
- )
- func (store *AbstractSqlStore) KvPut(ctx context.Context, key []byte, value []byte) (err error) {
- dirStr, dirHash, name := genDirAndName(key)
- res, err := store.getTxOrDB(ctx).ExecContext(ctx, store.SqlInsert, dirHash, name, dirStr, value)
- if err != nil {
- if !strings.Contains(strings.ToLower(err.Error()), "duplicate") {
- return fmt.Errorf("kv insert: %s", err)
- }
- }
- // now the insert failed possibly due to duplication constraints
- log.Debugf("kv insert falls back to update: %s", err)
- res, err = store.getTxOrDB(ctx).ExecContext(ctx, store.SqlUpdate, value, dirHash, name, dirStr)
- if err != nil {
- return fmt.Errorf("kv upsert: %s", err)
- }
- _, err = res.RowsAffected()
- if err != nil {
- return fmt.Errorf("kv upsert no rows affected: %s", err)
- }
- return nil
- }
- func (store *AbstractSqlStore) KvGet(ctx context.Context, key []byte) (value []byte, err error) {
- dirStr, dirHash, name := genDirAndName(key)
- row := store.getTxOrDB(ctx).QueryRowContext(ctx, store.SqlFind, dirHash, name, dirStr)
- err = row.Scan(&value)
- if err == sql.ErrNoRows {
- return nil, filer.ErrKvNotFound
- }
- if err != nil {
- return nil, fmt.Errorf("kv get: %v", err)
- }
- return
- }
- func (store *AbstractSqlStore) KvDelete(ctx context.Context, key []byte) (err error) {
- dirStr, dirHash, name := genDirAndName(key)
- res, err := store.getTxOrDB(ctx).ExecContext(ctx, store.SqlDelete, dirHash, name, dirStr)
- if err != nil {
- return fmt.Errorf("kv delete: %s", err)
- }
- _, err = res.RowsAffected()
- if err != nil {
- return fmt.Errorf("kv delete no rows affected: %s", err)
- }
- return nil
- }
- func genDirAndName(key []byte) (dirStr string, dirHash int64, name string) {
- for len(key) < 8 {
- key = append(key, 0)
- }
- dirHash = int64(util.BytesToUint64(key[:8]))
- dirStr = base64.StdEncoding.EncodeToString(key[:8])
- name = base64.StdEncoding.EncodeToString(key[8:])
- return
- }
|