func (b *keyspace) Count() (int64, errors.Error) { dirEntries, er := ioutil.ReadDir(b.path()) if er != nil { return 0, errors.NewFileDatastoreError(er, "") } return int64(len(dirEntries)), nil }
func (s *store) loadNamespaces() (e errors.Error) { dirEntries, er := ioutil.ReadDir(s.path) if er != nil { return errors.NewFileDatastoreError(er, "") } s.namespaces = make(map[string]*namespace, len(dirEntries)) s.namespaceNames = make([]string, 0, len(dirEntries)) var p *namespace for _, dirEntry := range dirEntries { if dirEntry.IsDir() { s.namespaceNames = append(s.namespaceNames, dirEntry.Name()) diru := strings.ToUpper(dirEntry.Name()) if _, ok := s.namespaces[diru]; ok { return errors.NewFileDuplicateNamespaceError(nil, dirEntry.Name()) } p, e = newNamespace(s, dirEntry.Name()) if e != nil { return } s.namespaces[diru] = p } } return }
func (p *namespace) loadKeyspaces() (e errors.Error) { dirEntries, er := ioutil.ReadDir(p.path()) if er != nil { return errors.NewFileDatastoreError(er, "") } p.keyspaces = make(map[string]*keyspace, len(dirEntries)) p.keyspaceNames = make([]string, 0, len(dirEntries)) var b *keyspace for _, dirEntry := range dirEntries { if dirEntry.IsDir() { diru := strings.ToUpper(dirEntry.Name()) if _, ok := p.keyspaces[diru]; ok { return errors.NewFileDuplicateKeyspaceError(nil, dirEntry.Name()) } b, e = newKeyspace(p, dirEntry.Name()) if e != nil { return } p.keyspaces[diru] = b p.keyspaceNames = append(p.keyspaceNames, b.Name()) } } return }
// NewStore creates a new file-based store for the given filepath. func NewDatastore(path string) (s datastore.Datastore, e errors.Error) { path, er := filepath.Abs(path) if er != nil { return nil, errors.NewFileDatastoreError(er, "") } fs := &store{path: path} e = fs.loadNamespaces() if e != nil { return } s = fs return }
func fetch(path string) (item value.AnnotatedValue, e errors.Error) { bytes, er := ioutil.ReadFile(path) if er != nil { if os.IsNotExist(er) { // file doesn't exist should simply return nil, nil return } return nil, errors.NewFileDatastoreError(er, "") } doc := value.NewAnnotatedValue(value.NewValue(bytes)) doc.SetAttachment("meta", map[string]interface{}{"id": documentPathToId(path)}) item = doc return }
// newKeyspace creates a new keyspace. func newKeyspace(p *namespace, dir string) (b *keyspace, e errors.Error) { b = new(keyspace) b.namespace = p b.name = dir fi, er := os.Stat(b.path()) if er != nil { return nil, errors.NewFileDatastoreError(er, "") } if !fi.IsDir() { return nil, errors.NewFileKeyspaceNotDirError(nil, "Keyspace path "+dir) } b.fi = newFileIndexer(b) b.fi.CreatePrimaryIndex("#primary", nil) return }
func (pi *primaryIndex) ScanEntries(limit int64, cons datastore.ScanConsistency, vector timestamp.Vector, conn *datastore.IndexConnection) { defer close(conn.EntryChannel()) dirEntries, er := ioutil.ReadDir(pi.keyspace.path()) if er != nil { conn.Error(errors.NewFileDatastoreError(er, "")) return } for i, dirEntry := range dirEntries { if limit > 0 && int64(i) > limit { break } if !dirEntry.IsDir() { entry := datastore.IndexEntry{PrimaryKey: documentPathToId(dirEntry.Name())} conn.EntryChannel() <- &entry } } }
func (b *keyspace) Delete(deletes []string) ([]string, errors.Error) { var fileError []string var deleted []string for _, key := range deletes { filename := filepath.Join(b.path(), key+".json") if err := os.Remove(filename); err != nil { if !os.IsNotExist(err) { fileError = append(fileError, err.Error()) } } else { deleted = append(deleted, key) } } if len(fileError) > 0 { errLine := fmt.Sprintf("Delete failed on some keys %v", fileError) return deleted, errors.NewFileDatastoreError(nil, errLine) } return deleted, nil }
func (pi *primaryIndex) Scan(span *datastore.Span, distinct bool, limit int64, cons datastore.ScanConsistency, vector timestamp.Vector, conn *datastore.IndexConnection) { defer close(conn.EntryChannel()) // For primary indexes, bounds must always be strings, so we // can just enforce that directly low, high := "", "" // Ensure that lower bound is a string, if any if len(span.Range.Low) > 0 { a := span.Range.Low[0].Actual() switch a := a.(type) { case string: low = a default: conn.Error(errors.NewFileDatastoreError(nil, fmt.Sprintf("Invalid lower bound %v of type %T.", a, a))) return } } // Ensure that upper bound is a string, if any if len(span.Range.High) > 0 { a := span.Range.High[0].Actual() switch a := a.(type) { case string: high = a default: conn.Error(errors.NewFileDatastoreError(nil, fmt.Sprintf("Invalid upper bound %v of type %T.", a, a))) return } } dirEntries, er := ioutil.ReadDir(pi.keyspace.path()) if er != nil { conn.Error(errors.NewFileDatastoreError(er, "")) return } var n int64 = 0 for _, dirEntry := range dirEntries { fmt.Printf("Dir entry being scanned %v", dirEntry.Name()) if limit > 0 && n > limit { break } id := documentPathToId(dirEntry.Name()) if low != "" && (id < low || (id == low && (span.Range.Inclusion&datastore.LOW == 0))) { continue } low = "" if high != "" && (id > high || (id == high && (span.Range.Inclusion&datastore.HIGH == 0))) { break } if !dirEntry.IsDir() { entry := datastore.IndexEntry{PrimaryKey: id} conn.EntryChannel() <- &entry n++ } } }