Skip to content

Commit

Permalink
feat: add tracks data type (#564)
Browse files Browse the repository at this point in the history
* feat: add track data type

* Add e2e CRUD tests for tracks

---------

Co-authored-by: Gregor MacLennan <gmaclennan@digital-democracy.org>
  • Loading branch information
EvanHahn and gmaclennan authored Apr 17, 2024
1 parent 114da4a commit bfd0a3c
Show file tree
Hide file tree
Showing 9 changed files with 252 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,27 @@ CREATE TABLE `role` (
`links` text NOT NULL,
`deleted` integer NOT NULL,
`roleId` text NOT NULL,
`fromIndex` real NOT NULL,
`fromIndex` integer NOT NULL,
`forks` text NOT NULL
);
--> statement-breakpoint
CREATE TABLE `track_backlink` (
`versionId` text PRIMARY KEY NOT NULL
);
--> statement-breakpoint
CREATE TABLE `track` (
`docId` text PRIMARY KEY NOT NULL,
`versionId` text NOT NULL,
`schemaName` text NOT NULL,
`createdAt` text NOT NULL,
`createdBy` text NOT NULL,
`updatedAt` text NOT NULL,
`links` text NOT NULL,
`deleted` integer NOT NULL,
`locations` text NOT NULL,
`refs` text NOT NULL,
`attachments` text NOT NULL,
`tags` text NOT NULL,
`forks` text NOT NULL
);
--> statement-breakpoint
Expand Down
120 changes: 118 additions & 2 deletions drizzle/project/meta/0000_snapshot.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"version": "5",
"dialect": "sqlite",
"id": "f68815a6-4e7a-4ca7-9882-6f31bb34b716",
"id": "6f1659f1-038f-4705-8059-b075a5a2c82d",
"prevId": "00000000-0000-0000-0000-000000000000",
"tables": {
"coreOwnership_backlink": {
Expand Down Expand Up @@ -863,7 +863,123 @@
},
"fromIndex": {
"name": "fromIndex",
"type": "real",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"forks": {
"name": "forks",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"track_backlink": {
"name": "track_backlink",
"columns": {
"versionId": {
"name": "versionId",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"track": {
"name": "track",
"columns": {
"docId": {
"name": "docId",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"versionId": {
"name": "versionId",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"schemaName": {
"name": "schemaName",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdBy": {
"name": "createdBy",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"updatedAt": {
"name": "updatedAt",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"links": {
"name": "links",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"deleted": {
"name": "deleted",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"locations": {
"name": "locations",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"refs": {
"name": "refs",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"attachments": {
"name": "attachments",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"tags": {
"name": "tags",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
Expand Down
4 changes: 2 additions & 2 deletions drizzle/project/meta/_journal.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
{
"idx": 0,
"version": "5",
"when": 1707965473123,
"tag": "0000_supreme_forgotten_one",
"when": 1713301821225,
"tag": "0000_burly_network",
"breakpoints": true
}
]
Expand Down
2 changes: 1 addition & 1 deletion src/datastore/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { createMap } from '../utils.js'
*/

const NAMESPACE_SCHEMAS = /** @type {const} */ ({
data: ['observation'],
data: ['observation', 'track'],
config: [
'translation',
'preset',
Expand Down
10 changes: 10 additions & 0 deletions src/mapeo-project.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
deviceInfoTable,
fieldTable,
observationTable,
trackTable,
presetTable,
roleTable,
iconTable,
Expand Down Expand Up @@ -149,6 +150,7 @@ export class MapeoProject extends TypedEmitter {
const indexWriter = new IndexWriter({
tables: [
observationTable,
trackTable,
presetTable,
fieldTable,
coreOwnershipTable,
Expand Down Expand Up @@ -200,6 +202,11 @@ export class MapeoProject extends TypedEmitter {
table: observationTable,
db,
}),
track: new DataType({
dataStore: this.#dataStores.data,
table: trackTable,
db,
}),
preset: new DataType({
dataStore: this.#dataStores.config,
table: presetTable,
Expand Down Expand Up @@ -433,6 +440,9 @@ export class MapeoProject extends TypedEmitter {
get observation() {
return this.#dataTypes.observation
}
get track() {
return this.#dataTypes.track
}
get preset() {
return this.#dataTypes.preset
}
Expand Down
2 changes: 2 additions & 0 deletions src/schema/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const observationTable = sqliteTable(
'observation',
toColumns(schemas.observation)
)
export const trackTable = sqliteTable('track', toColumns(schemas.track))
export const presetTable = sqliteTable('preset', toColumns(schemas.preset))
export const fieldTable = sqliteTable('field', toColumns(schemas.field))
export const coreOwnershipTable = sqliteTable(
Expand All @@ -29,6 +30,7 @@ export const iconTable = sqliteTable('icon', toColumns(schemas.icon))

export const translationBacklinkTable = backlinkTable(translationTable)
export const observationBacklinkTable = backlinkTable(observationTable)
export const trackBacklinkTable = backlinkTable(trackTable)
export const presetBacklinkTable = backlinkTable(presetTable)
export const fieldBacklinkTable = backlinkTable(fieldTable)
export const coreOwnershipBacklinkTable = backlinkTable(coreOwnershipTable)
Expand Down
56 changes: 49 additions & 7 deletions test-e2e/project-crud.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@
import { test } from 'brittle'
import { randomBytes } from 'crypto'
import { valueOf } from '../src/utils.js'
import { createManager, sortById, removeUndefinedFields } from './utils.js'
import {
createManager,
sortById,
removeUndefinedFields,
randomBool,
randomDate,
randomNum,
} from './utils.js'
import { round } from './utils.js'
import { generate } from '@mapeo/mock-data'
import { setTimeout as delay } from 'timers/promises'
Expand Down Expand Up @@ -32,6 +39,13 @@ const fixtures = [
tagKey: 'foo',
label: 'my label',
},
{
schemaName: 'track',
refs: [],
tags: {},
attachments: [],
locations: Array.from({ length: 10 }, trackPositionFixture),
},
]

/**
Expand Down Expand Up @@ -59,6 +73,13 @@ function getUpdateFixture(value) {
...value,
label: randomBytes(10).toString('hex'),
}
case 'track':
return {
...value,
tags: {
foo: 'bar',
},
}
default:
return { ...value }
}
Expand All @@ -80,10 +101,12 @@ test('CRUD operations', async (t) => {
project[schemaName].on('updated-docs', (docs) => updates.push(...docs))
let i = 0
while (i++ < CREATE_COUNT) {
const value = valueOf(generate(schemaName)[0])
const mocked =
// TODO: add tracks to @mapeo/mock-data
schemaName === 'track' ? value : valueOf(generate(schemaName)[0])
writePromises.push(
// @ts-ignore
project[schemaName].create(value)
project[schemaName].create(mocked)
)
}
const written = await Promise.all(writePromises)
Expand Down Expand Up @@ -129,10 +152,12 @@ test('CRUD operations', async (t) => {
const project = await manager.getProject(projectId)
const writePromises = []
for (let i = 0; i < CREATE_COUNT; i++) {
const value = valueOf(generate(schemaName)[0])
const mocked =
// TODO: add tracks to @mapeo/mock-data
schemaName === 'track' ? value : valueOf(generate(schemaName)[0])
writePromises.push(
// @ts-ignore
project[schemaName].create(value)
project[schemaName].create(mocked)
)
}
const written = await Promise.all(writePromises)
Expand Down Expand Up @@ -236,10 +261,12 @@ test('CRUD operations', async (t) => {
const writePromises = []
let i = 0
while (i++ < CREATE_COUNT) {
const value = valueOf(generate(schemaName)[0])
const mocked =
// TODO: add tracks to @mapeo/mock-data
schemaName === 'track' ? value : valueOf(generate(schemaName)[0])
writePromises.push(
// @ts-ignore
project[schemaName].create(value)
project[schemaName].create(mocked)
)
}
const written = await Promise.all(writePromises)
Expand Down Expand Up @@ -292,3 +319,18 @@ test('CRUD operations', async (t) => {
})
}
})

function trackPositionFixture() {
return {
timestamp: randomDate().toISOString(),
mocked: randomBool(),
coords: {
latitude: randomNum({ min: -90, max: 90, precision: 6 }),
longitude: randomNum({ min: -180, max: 180, precision: 6 }),
altitude: randomNum({ min: 0, max: 5000 }),
accuracy: randomNum({ min: 0, max: 100, precision: 2 }),
heading: randomNum({ min: 0, max: 360, precision: 6 }),
speed: randomNum({ min: 0, max: 100, precision: 2 }),
},
}
}
17 changes: 17 additions & 0 deletions test-e2e/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -361,3 +361,20 @@ export function sortById(docs) {
export function removeUndefinedFields(object) {
return JSON.parse(JSON.stringify(object))
}

export function randomDate() {
return new Date(randomNum({ min: 0, max: Date.now() }))
}

export function randomBool() {
return Math.random() >= 0.5
}

/**
* @param {{ min?: number, max?: number, precision?: number }} [options]
*/
export function randomNum({ min = 0, max = 1, precision } = {}) {
const num = Math.random() * (max - min) + min
if (typeof precision === 'undefined') return num
return round(num, precision)
}
Loading

0 comments on commit bfd0a3c

Please sign in to comment.