Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
0
func fetch(path string) (item value.AnnotatedValue, e errors.Error) {
	bytes, er := ioutil.ReadFile(path)
	if er != nil {
		return nil, errors.NewFileDatastoreError(er, "")
	}

	doc := value.NewAnnotatedValue(value.NewValue(bytes))
	doc.SetAttachment("meta", map[string]interface{}{"id": documentPathToId(path)})
	item = doc

	return
}
Beispiel #5
0
// 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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
func (pi *primaryIndex) ScanEntries(requestId string, 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
		}
	}
}
Beispiel #8
0
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
}
Beispiel #9
0
func (pi *primaryIndex) Scan(requestId string, 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++
		}
	}
}