mirror of
https://github.com/appy-one/acebase.git
synced 2026-05-26 14:12:15 -06:00
203 lines
No EOL
6.6 KiB
JavaScript
203 lines
No EOL
6.6 KiB
JavaScript
/// <reference types="@types/jasmine" />
|
|
const { createTempDB } = require("./tempdb");
|
|
const { AceBase, ID } = require("..");
|
|
|
|
// TODO: MANY MORE index options to spec
|
|
|
|
describe('index', () => {
|
|
/** @type {AceBase} */
|
|
let db, removeDB;
|
|
|
|
beforeAll(async () => {
|
|
({ db, removeDB } = await createTempDB());
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await removeDB();
|
|
});
|
|
|
|
it('can be on the root', async () => {
|
|
// Created for issue https://github.com/appy-one/acebase/issues/67
|
|
const index = await db.indexes.create('', 'some_property');
|
|
expect(index.fileName).not.toContain('[undefined]');
|
|
});
|
|
|
|
});
|
|
|
|
describe('string index', () => {
|
|
/** @type {AceBase} */
|
|
let db, removeDB;
|
|
|
|
beforeAll(async () => {
|
|
({ db, removeDB } = await createTempDB());
|
|
|
|
// Insert sample data from meteorites json
|
|
const m = require('./dataset/meteorites.json');
|
|
const meteorites = {};
|
|
m.forEach(m => {
|
|
const id = ID.generate();
|
|
meteorites[id] = {
|
|
name: m.name,
|
|
mass: typeof m.mass !== 'undefined' ? parseFloat(m.mass) : null,
|
|
class: m.recclass,
|
|
location: m.geolocation && m.geolocation.coordinates ? {
|
|
lat: m.geolocation.coordinates[1],
|
|
long: m.geolocation.coordinates[0]
|
|
} : null,
|
|
meta: {
|
|
id: m.id,
|
|
date: m.year ? new Date(m.year) : null
|
|
}
|
|
};
|
|
});
|
|
await db.ref('meteorites').set(meteorites);
|
|
}, 30000);
|
|
|
|
it('key can contain slashes', async () => {
|
|
// Created for issue https://github.com/appy-one/acebase/issues/67
|
|
try {
|
|
const index = await db.indexes.create('meteorites', 'meta/id', { include: ['meta/date'] });
|
|
}
|
|
catch (err) {
|
|
fail('index key must be allowed to contain slashes');
|
|
}
|
|
|
|
// Try querying the subkey index:
|
|
const results = await db.query('meteorites')
|
|
.filter('meta/id', 'in', ['53829','463','4922']) // Sołtmany, Alessandria, Bahjoi
|
|
.sort('meta/id')
|
|
.get();
|
|
|
|
expect(results.length).toBe(3);
|
|
|
|
const meteorites = results.getValues();
|
|
// This fails occasionally, has to be investigated:
|
|
expect(meteorites[0].name).toBe('Alessandria');
|
|
expect(meteorites[1].name).toBe('Bahjoi');
|
|
expect(meteorites[2].name).toBe('Sołtmany');
|
|
|
|
// Try adding a meteorite, index should update ok
|
|
await db.ref('meteorites').push({
|
|
name: 'BigRock',
|
|
class: 'Unknown',
|
|
meta: {
|
|
id: 'bigrock',
|
|
date: new Date()
|
|
}
|
|
});
|
|
|
|
// Query BigRock
|
|
const snaps = await db.query('meteorites')
|
|
.filter('meta/id', '==', 'bigrock')
|
|
.get();
|
|
expect(snaps.length).toBe(1);
|
|
|
|
}, 60000);
|
|
|
|
it('path can start with wildcard', async () => {
|
|
// Created for issue https://github.com/appy-one/acebase/issues/86
|
|
|
|
await db.indexes.create("*/media", "timestamp");
|
|
|
|
const postSnapshots = await db.query("*/media")
|
|
.take(100)
|
|
.sort("timestamp", false)
|
|
.get();
|
|
|
|
}, 60000);
|
|
|
|
|
|
it('without included columns', async () => {
|
|
// Build
|
|
await db.indexes.create('meteorites', 'name');
|
|
|
|
// Query with '=='
|
|
let stats = [], hints = [];
|
|
let snaps = await db.ref('meteorites').query()
|
|
.filter('name', '==', 'Louisville')
|
|
.on('stats', ev => stats.push(ev))
|
|
.on('hints', ev => hints.push(ev))
|
|
.get({ });
|
|
|
|
expect(snaps.length).toEqual(1);
|
|
// Check triggered events
|
|
expect(hints.length).toEqual(0); // No hints because the query should have used the index
|
|
expect(stats.length).toEqual(1); // 1 stats event for the used index
|
|
expect(stats[0].type === 'index_query');
|
|
expect(stats[0].source).toEqual('/meteorites/*/name');
|
|
expect(stats[0].stats.result).toEqual(snaps.length);
|
|
// Check query performance. NOTE: with all other tests running at the same time (in the same 1 thread), this could possibly fail!
|
|
expect(stats[0].stats.duration).toBeLessThan(100);
|
|
|
|
// Query with 'like'
|
|
stats = [], hints = [];
|
|
snaps = await db.ref('meteorites').query()
|
|
.filter('name', 'like', 'L*')
|
|
.on('stats', ev => stats.push(ev))
|
|
.on('hints', ev => hints.push(ev))
|
|
.get();
|
|
|
|
expect(snaps.length).toEqual(48);
|
|
expect(stats.length).toEqual(1);
|
|
expect(stats[0].stats.result).toEqual(snaps.length);
|
|
|
|
// Query with '!like'
|
|
stats = [], hints = [];
|
|
snaps = await db.ref('meteorites').query()
|
|
.filter('name', '!like', 'L*')
|
|
.filter('name', '!=', 'BigRock') // Might have been added by other test above
|
|
.on('stats', ev => stats.push(ev))
|
|
.on('hints', ev => hints.push(ev))
|
|
.get();
|
|
|
|
expect(snaps.length).toEqual(952);
|
|
expect(stats.length).toEqual(1);
|
|
expect([952, 953].includes(stats[0].stats.result)).toBeTrue(); // stats[0] will contain index stats for first filter which might have "BigRock" in the results (which are filtered out by 2nd filter)
|
|
}, 60000);
|
|
|
|
afterAll(async () => {
|
|
await removeDB();
|
|
});
|
|
});
|
|
|
|
describe('Date index', () => {
|
|
/** @type {AceBase} */
|
|
let db, removeDB;
|
|
|
|
beforeAll(async () => {
|
|
({ db, removeDB } = await createTempDB({ config: (options) => { options.logLevel = 'warn' }}));
|
|
});
|
|
|
|
it('is built properly', async () => {
|
|
// Created for issue https://github.com/appy-one/acebase/issues/114
|
|
|
|
console.log('[indexing issue #114] Generating large dates collection...');
|
|
|
|
// Generate 10K dates
|
|
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
const collection = {};
|
|
for (let i = 0; i < 10000; i++) {
|
|
collection[ID.generate()] = { date: new Date(i * MS_PER_DAY) };
|
|
}
|
|
await db.ref('dates').set(collection);
|
|
|
|
console.log('[indexing issue #114] Creating index..');
|
|
|
|
// Create index
|
|
await db.indexes.create('dates', 'date');
|
|
|
|
console.log('[indexing issue #114] Success!');
|
|
|
|
// Test index by querying it
|
|
console.log('[indexing issue #117] Checking index');
|
|
|
|
const count = await db.query('dates').filter('date', '<', new Date(MS_PER_DAY * 100)).count();
|
|
expect(count).toBe(100);
|
|
|
|
console.log('[indexing issue #117] Check ok!');
|
|
}, 60e3);
|
|
|
|
afterAll(async () => {
|
|
await removeDB();
|
|
});
|
|
}); |