Skip to content

Commit

Permalink
fix conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
letterbeezps committed Mar 14, 2024
2 parents fe14b77 + e6a58d6 commit 6cd0197
Show file tree
Hide file tree
Showing 23 changed files with 1,235 additions and 184 deletions.
23 changes: 13 additions & 10 deletions .github/workflows/ test.yml → .github/workflows/linux.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
name: Unit test Go code
name: Linux Build & Unit tests

on:
push:
tags:
- v*
branches:
- main
branches: [ "v2" ]
pull_request:
types: [ opened, synchronize, reopened, ready_for_review ]

jobs:
test:
strategy:
matrix:
go-version: [ 1.18.x ]
go-version: [ 1.20.x ]
os: [ ubuntu-latest ]

name: Checking
runs-on: ${{ matrix.os }}
steps:
- name: Setup Go
uses: actions/setup-go@v2
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go-version }}

- name: Check out code
uses: actions/checkout@v2
- name: run tests
run: go test ./...
uses: actions/checkout@v3

- name: Build
run: go build -v ./...

- name: Test
run: go test -v ./...
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

## Why CloverDB?

**CloverDB** has been written for being easily maintenable. As such, it trades performance with simplicity, and is not intented to be an alternative to more performant databases such as **MongoDB** or **MySQL**.
**CloverDB** has been written for being easily maintainable. As such, it trades performance with simplicity, and is not intended to be an alternative to more performant databases such as **MongoDB** or **MySQL**.
However, there are projects where running a separate database server may result overkilled, and, for simple queries, network delay may be the major performance bottleneck.
For such scenarios, **CloverDB** may be a more suitable alternative.

Expand All @@ -50,9 +50,9 @@ To store documents inside collections, you have to open a Clover database using
```go
import (
"log"
"github.com/dgraph-io/badger/v3"
"github.com/dgraph-io/badger/v4"
c "github.com/ostafen/clover"
badgerstore "github.com/ostafen/store/badger"
badgerstore "github.com/ostafen/clover/v2/store/badger"
)

...
Expand All @@ -64,9 +64,6 @@ db, _ := c.Open("clover-db")
store, _ := badgerstore.Open(badger.DefaultOptions("").WithInMemory(true)) // opens a badger in memory database
db, _ := c.OpenWithStore(store)

// or, if you don't need persistency
db, _ := c.Open("", c.InMemoryMode(true))

defer db.Close() // remember to close the db when you have done
```

Expand Down Expand Up @@ -144,7 +141,7 @@ db.FindAll(c.NewQuery("todos").Where(c.Field("completed").Eq(true)))
db.FindAll(c.NewQuery("todos").Where(c.Field("completed").IsTrue()))
```

In order to build very complex queries, we chain multiple Criteria objects by using the `And()` and `Or()` methods, each returning a new Criteria obtained by appling the corresponding logical operator.
In order to build very complex queries, we chain multiple Criteria objects by using the `And()` and `Or()` methods, each returning a new Criteria obtained by applying the corresponding logical operator.

```go
// find all completed todos belonging to users with id 5 and 8
Expand All @@ -171,7 +168,7 @@ db.FindFirst(c.NewQuery("todos").Sort(c.SortOption{"userId", -1}))

### Skip/Limit Documents

Sometimes, it can be useful to discard some documents from the output, or simply set a limit on the maximum number of results returned by a query. For this purpose, CloverDB provides the `Skip()` and `Limit()` functions, both accepting an interger $n$ as parameter.
Sometimes, it can be useful to discard some documents from the output, or simply set a limit on the maximum number of results returned by a query. For this purpose, CloverDB provides the `Skip()` and `Limit()` functions, both accepting an integer $n$ as parameter.

```go
// discard the first 10 documents from the output,
Expand Down Expand Up @@ -208,7 +205,7 @@ db.DeleteById("todos", docId)

In CloverDB, indexes support the efficient execution of queries. Without indexes, a collection must be fully scanned to select those documents matching a given query. An index is a special data structure storing the values of a specific document field (or set of fields), sorted by the value of the field itself. This means that they can be exploited to supports efficient equality matches and range-based queries.
Moreover, when documents are iterated through an index, results can be returned in sorted order without performing any additional sorting step.
Note however that using indexes is not completely for free. A part from increasing disk space, indexes require additional cpu-time during each insert and update/delete operation. Moreover, when accessing a document through an index, two disk reads must be performed, since indexes only store a reference (the document id) to the actual document. As a consequence, the speed-up is sensitive only when the specified criteria is used to access a restricted set of documents.
Note however that using indexes is not completely for free. Apart from increasing disk space, indexes require additional cpu-time during each insert and update/delete operation. Moreover, when accessing a document through an index, two disk reads must be performed, since indexes only store a reference (the document id) to the actual document. As a consequence, the speed-up is sensitive only when the specified criteria is used to access a restricted set of documents.

### Creating an index

Expand Down
37 changes: 17 additions & 20 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
"fmt"
"sync/atomic"

"github.com/gofrs/uuid/v5"
d "github.com/ostafen/clover/v2/document"
"github.com/ostafen/clover/v2/index"
"github.com/ostafen/clover/v2/internal"
"github.com/ostafen/clover/v2/query"
"github.com/ostafen/clover/v2/store"
"github.com/ostafen/clover/v2/store/bbolt"
uuid "github.com/satori/go.uuid"
)

// Collection creation errors
Expand All @@ -38,7 +38,7 @@ type DB struct {

type collectionMetadata struct {
Size int
Indexes []index.IndexInfo
Indexes []index.Info
}

// CreateCollection creates a new empty collection with the given name.
Expand Down Expand Up @@ -138,7 +138,8 @@ func (db *DB) HasCollection(name string) (bool, error) {
}

func NewObjectId() string {
return uuid.NewV4().String()
objId, _ := uuid.NewV4()
return objId.String()
}

// Insert adds the supplied documents to a collection.
Expand Down Expand Up @@ -266,11 +267,11 @@ func (db *DB) InsertOne(collectionName string, doc *d.Document) (string, error)

// Open opens a new clover database on the supplied path. If such a folder doesn't exist, it is automatically created.
func Open(dir string) (*DB, error) {
store, err := bbolt.Open(dir)
dataStore, err := bbolt.Open(dir)
if err != nil {
return nil, err
}
return OpenWithStore(store)
return OpenWithStore(dataStore)
}

// OpenWithStore opens a new clover database using the provided store.
Expand Down Expand Up @@ -321,7 +322,7 @@ func (db *DB) FindFirst(q *query.Query) (*d.Document, error) {
return doc, err
}

// ForEach runs the consumer function for each document matching the provied query.
// ForEach runs the consumer function for each document matching the provided query.
// If false is returned from the consumer function, then the iteration is stopped.
func (db *DB) ForEach(q *query.Query, consumer func(_ *d.Document) bool) error {
q, err := normalizeCriteria(q)
Expand Down Expand Up @@ -564,7 +565,7 @@ func (db *DB) Update(q *query.Query, updateMap map[string]interface{}) error {
})
}

// Update updates all the document selected by q using the provided function.
// UpdateFunc updates all the document selected by q using the provided function.
func (db *DB) UpdateFunc(q *query.Query, updateFunc func(doc *d.Document) *d.Document) error {
txn, err := db.store.Begin(true)
if err != nil {
Expand Down Expand Up @@ -680,10 +681,6 @@ func iteratePrefix(prefix []byte, tx store.Tx, itemConsumer func(item store.Item
return err
}

if err := cursor.Seek(prefix); err != nil {
return err
}

for ; cursor.Valid(); cursor.Next() {
item, err := cursor.Item()
if err != nil {
Expand All @@ -696,7 +693,7 @@ func iteratePrefix(prefix []byte, tx store.Tx, itemConsumer func(item store.Item
err = itemConsumer(item)

// do not propagate iteration stop error
if err == internal.ErrStopIteration {
if errors.Is(err, internal.ErrStopIteration) {
return nil
}

Expand All @@ -709,10 +706,10 @@ func iteratePrefix(prefix []byte, tx store.Tx, itemConsumer func(item store.Item

// CreateIndex creates an index for the specified for the specified (index, collection) pair.
func (db *DB) CreateIndex(collection, field string) error {
return db.createIndex(collection, field, index.IndexSingleField)
return db.createIndex(collection, field, index.SingleField)
}

func (db *DB) createIndex(collection, field string, indexType index.IndexType) error {
func (db *DB) createIndex(collection, field string, indexType index.Type) error {
tx, err := db.store.Begin(true)
if err != nil {
return err
Expand All @@ -731,9 +728,9 @@ func (db *DB) createIndex(collection, field string, indexType index.IndexType) e
}

if meta.Indexes == nil {
meta.Indexes = make([]index.IndexInfo, 0)
meta.Indexes = make([]index.Info, 0)
}
meta.Indexes = append(meta.Indexes, index.IndexInfo{Field: field, Type: indexType})
meta.Indexes = append(meta.Indexes, index.Info{Field: field, Type: indexType})

idx := index.CreateIndex(collection, field, indexType, tx)

Expand All @@ -753,7 +750,7 @@ func (db *DB) createIndex(collection, field string, indexType index.IndexType) e
return tx.Commit()
}

// HasIndex returns true if an idex exists for the specified (index, collection) pair.
// HasIndex returns true if an index exists for the specified (index, collection) pair.
func (db *DB) HasIndex(collection, field string) (bool, error) {
tx, err := db.store.Begin(false)
if err != nil {
Expand All @@ -776,7 +773,7 @@ func (db *DB) hasIndex(tx store.Tx, collection, field string) (bool, error) {
return false, err
}

// DropIndex deletes the idex, is such index exists for the specified (index, collection) pair.
// DropIndex deletes the index, is such index exists for the specified (index, collection) pair.
func (db *DB) DropIndex(collection, field string) error {
txn, err := db.store.Begin(true)
if err != nil {
Expand Down Expand Up @@ -818,7 +815,7 @@ func (db *DB) DropIndex(collection, field string) error {
}

// ListIndexes returns a list containing the names of all the indexes for the specified collection.
func (db *DB) ListIndexes(collection string) ([]index.IndexInfo, error) {
func (db *DB) ListIndexes(collection string) ([]index.Info, error) {
txn, err := db.store.Begin(false)
if err != nil {
return nil, err
Expand All @@ -828,7 +825,7 @@ func (db *DB) ListIndexes(collection string) ([]index.IndexInfo, error) {
return db.listIndexes(collection, txn)
}

func (db *DB) listIndexes(collection string, tx store.Tx) ([]index.IndexInfo, error) {
func (db *DB) listIndexes(collection string, tx store.Tx) ([]index.Info, error) {
meta, err := db.getCollectionMeta(collection, tx)
return meta.Indexes, err
}
Expand Down
Loading

0 comments on commit 6cd0197

Please sign in to comment.