Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
Add support for multiple sort values in Dexie
Browse files Browse the repository at this point in the history
  • Loading branch information
albrow committed May 29, 2020
1 parent 78a34bd commit b59dbac
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 18 deletions.
8 changes: 4 additions & 4 deletions db/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ type Database interface {
}

type Options struct {
DriverName string
DataSourceName string
MaxOrders int
MaxMiniHeaders int
DriverName string `json:"driverName"`
DataSourceName string `json:"dataSourceName"`
MaxOrders int `json:"maxOrders"`
MaxMiniHeaders int `json:"maxMiniHeaders"`
}

func parseOptions(opts *Options) *Options {
Expand Down
3 changes: 3 additions & 0 deletions db/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2216,6 +2216,9 @@ func TestParseContractAddressesAndTokenIdsFromAssetData(t *testing.T) {
func newTestDB(t *testing.T, ctx context.Context) *DB {
db, err := New(ctx, TestOptions())
require.NoError(t, err)
count, err := db.CountOrders(nil)
require.NoError(t, err)
require.Equal(t, count, 0, "there should be no orders stored in a brand new database")
return db
}

Expand Down
3 changes: 3 additions & 0 deletions db/dexie_implementation.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ func defaultOptions() *Options {
// New creates a new connection to the database. The connection will be automatically closed
// when the given context is canceled.
func New(ctx context.Context, opts *Options) (database *DB, err error) {
if opts != nil && opts.DriverName != "dexie" {
return nil, fmt.Errorf(`unexpected driver name for js/wasm: %q (only "dexie" is supported)`, opts.DriverName)
}
defer func() {
if r := recover(); r != nil {
err = recoverError(r)
Expand Down
58 changes: 44 additions & 14 deletions packages/test-wasm/src/database/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Dexie, { Transaction } from 'dexie';

export interface Options {
name: string;
dataSourceName: string;
maxOrders: number;
maxMiniHeaders: number;
}
Expand Down Expand Up @@ -102,7 +102,7 @@ export class Database {
private orders: Dexie.Table<Order, string>;

constructor(opts: Options) {
this.db = new Dexie(opts.name);
this.db = new Dexie(opts.dataSourceName);
this.maxOrders = opts.maxOrders;
this.maxMiniHeaders = opts.maxMiniHeaders;

Expand Down Expand Up @@ -323,19 +323,49 @@ export class Database {
query.sort.length === 0
) {
return col.toArray();
} else if (query.sort.length === 1) {
// TODO(albrow): As an optimization we can skip calling `sortBy`
// if the results of the query would already be sorted in
// "natural order" based on the filters.
if (query.sort[0].direction === SortDirection.Desc) {
col = col.reverse();
} else {
if (
(query.offset !== null && query.offset !== undefined && query.offset !== 0) ||
(query.limit !== null && query.limit !== undefined && query.limit !== 0)
) {
if (
query.filters === null ||
query.filters === undefined ||
(query.filters.length === 1 && query.filters[0].field === 'hash')
) {
// This is okay.
} else {
// TODO(albrow): Technically this is allowed if and only if
// there is exactly one filter, exactly one sort, and the sort
// field is equal to the filter field.
throw new Error('sorting by arbitrary fields with limit and offset is not supported by Dexie.js');
}
}
return col.sortBy(query.sort[0].field);
}

// TODO(albrow): Dexie.js can't sort by more than one field. Looks like
// we have no choice but to manually sort here. This will not be fast or
// efficient.
throw new Error('sorting by multiple fields is not yet implemented');
// Note(albrow): Dexie.js can't sort by more than one field. Looks like
// we have no choice but to manually sort here. This is not fast or
// efficient.
return (await col.toArray()).sort((a: Order, b: Order) => {
for (const s of query.sort!) {
switch (s.direction) {
case SortDirection.Asc:
if (a[s.field] < b[s.field]) {
return -1;
} else if (a[s.field] > b[s.field]) {
return 1;
}
break;
case SortDirection.Desc:
if (a[s.field] > b[s.field]) {
return -1;
} else if (a[s.field] < b[s.field]) {
return 1;
}
break;
}
}
return 0;
});
}
}
}

0 comments on commit b59dbac

Please sign in to comment.