Skip to content

Commit

Permalink
Extract user manipulation to a DAO
Browse files Browse the repository at this point in the history
  • Loading branch information
chvp committed Aug 28, 2023
1 parent cd45cbf commit 3c527c0
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 50 deletions.
25 changes: 11 additions & 14 deletions src/api.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { createApiClient } from '@accentor/api-client-js'
import type { App } from 'vue'

export default {
install: (app: App) => {
let url: string
if (import.meta.env.VITE_APP_API_URL != undefined) {
url = import.meta.env.VITE_APP_API_URL
} else if (import.meta.env.PROD) {
url = '/api'
} else {
url = 'http://localhost:3000/api'
}
app.provide('apiBaseUrl', url)
app.provide('api', createApiClient(url))
}
let url: string
if (import.meta.env.VITE_APP_API_URL != undefined) {
url = import.meta.env.VITE_APP_API_URL
} else if (import.meta.env.PROD) {
url = '/api'
} else {
url = 'http://localhost:3000/api'
}

export const baseURL = url

export default createApiClient(url)
34 changes: 32 additions & 2 deletions src/db-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,41 @@ export default class SqliteClient {

listenersForTable: Map<string, Ref<number>> = new Map()

constructor(dbFile: string) {
constructor(dbFile: string, migrations: string[]) {
const DbWorker: any = Comlink.wrap(
new Worker(new URL('./db-worker.ts', import.meta.url), { type: 'module' })
)
this.sqliteWorker = new DbWorker().then((worker: any) => worker.init(dbFile).then(() => worker))
this.sqliteWorker = new DbWorker().then((worker: any) =>
worker.init(dbFile).then(async () => {
await worker.executeSqlNoResult(
'CREATE TABLE IF NOT EXISTS migrations (text VARCHAR PRIMARY KEY);'
)
for (const m of migrations) {
const migrationResult = await this.executeRawSelect(
worker,
'SELECT * FROM migrations WHERE text = ?;',
m
)
if (migrationResult.length == 0) {
await worker.executeSqlNoResult(m)
await worker.executeSqlNoResult('INSERT INTO migrations VALUES (?)', m)
}
}
return worker
})
)
}

executeRawSelect(worker: any, statement: String, ...bindParameters: any[]): Promise<any[]> {
return new Promise((resolve) => {
worker.executeSql(
statement,
bindParameters.map(unref),
Comlink.proxy((resultRows: any[]) => {
resolve(resultRows)
})
)
})
}

getRefsForTables(tables: string[]): Ref<number>[] {
Expand Down
41 changes: 41 additions & 0 deletions src/db/user_dao.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type SqliteClient from '@/db-client'
import api from '@/api'
import { useAuthStore } from '@/stores/auth'
import type { UnwrapNestedRefs } from 'vue'

export default class UserDao {
client: SqliteClient
authStore: UnwrapNestedRefs<{ secret: string | null; deviceId: string | null }>

constructor(client: SqliteClient) {
this.client = client
this.authStore = useAuthStore()
}

async refresh() {
let done = false
const generator = api.users.index({
secret: this.authStore.secret!,
device_id: this.authStore.deviceId!
})
while (!done) {
const obj = await generator.next()
for (const row of obj.value) {
await this.client.executeMutation(
'users',
'INSERT INTO users VALUES (?, ?, ?) ON CONFLICT(id) DO UPDATE SET name=?, permission=?;',
row.id,
row.name,
row.permission,
row.name,
row.permission
)
}
done = obj.done!
}
}

getAll() {
return this.client.executeSelect(['users'], 'SELECT * FROM users;')
}
}
2 changes: 0 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { aliases, mdi } from 'vuetify/iconsets/mdi'
import App from './App.vue'
import router from './router'
import sqlitePlugin from './sqlite'
import api from './api'

const app = createApp(App)

Expand Down Expand Up @@ -50,6 +49,5 @@ app.use(
app.use(createPinia())
app.use(router)
app.use(sqlitePlugin, { file: '/accentor.sqlite3' })
app.use(api)

app.mount('#app')
12 changes: 7 additions & 5 deletions src/sqlite.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import SqliteClient from './db-client'
import UserDao from './db/user_dao'
import type { App } from 'vue'

interface Options {
Expand All @@ -7,11 +8,12 @@ interface Options {

export default {
install: (app: App, options: Options) => {
const client = new SqliteClient(options.file)
client.executeMutation(
'users',
const client = new SqliteClient(options.file, [
'CREATE TABLE IF NOT EXISTS users (id INT PRIMARY KEY, name VARCHAR, permission VARCHAR);'
)
app.provide('db', client)
])
const daos = {
users: new UserDao(client)
}
app.provide('db', daos)
}
}
5 changes: 2 additions & 3 deletions src/stores/auth.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { defineStore } from 'pinia'
import { useStorage } from '@vueuse/core'
import { computed, inject, type Ref } from 'vue'
import type { AuthTokenModule } from '@accentor/api-client-js'
import { computed, type Ref } from 'vue'
import api from '@/api'
import { useBaseStore } from './base'

export const useAuthStore = defineStore('auth', () => {
const baseStore = useBaseStore()
const api: { auth_tokens: AuthTokenModule } = inject('api')!

const secret: Ref<string | null> = useStorage('auth_secret', null)
const deviceId: Ref<string | null> = useStorage('auth_device_id', null)
Expand Down
24 changes: 3 additions & 21 deletions src/views/AppRootView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
import { RouterView, useRouter } from 'vue-router'
import { watchEffect, ref, inject } from 'vue'
import { useAuthStore } from '@/stores/auth'
import type { UserModule } from '@accentor/api-client-js'
import type SqliteClient from '../db-client'
import type UserDao from '@/db/user_dao'
const router = useRouter()
const authStore = useAuthStore()
const api: { users: UserModule } = inject('api')!
const client: SqliteClient = inject('db')!
const { users }: { users: UserDao } = inject('db')!
const drawer = ref(false)
const loading = ref(false)
Expand All @@ -25,23 +23,7 @@ function logout() {
async function loadData() {
loading.value = true
let done = false
const generator = api.users.index({ secret: authStore.secret!, device_id: authStore.deviceId! })
while (!done) {
const obj = await generator.next()
for (let row of obj.value) {
await client.executeMutation(
'users',
'INSERT INTO users VALUES (?, ?, ?) ON CONFLICT(id) DO UPDATE SET name=?, permission=?;',
row.id,
row.name,
row.permission,
row.name,
row.permission
)
}
done = obj.done!
}
await users.refresh()
loading.value = false
}
</script>
Expand Down
6 changes: 3 additions & 3 deletions src/views/HomeView.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script setup lang="ts">
import { inject } from 'vue'
import type SqliteClient from '../db-client'
const dbClient: SqliteClient = inject('db')!
const values = dbClient.executeSelect(['users'], 'SELECT * FROM users;')
import type UserDao from '@/db/user_dao'
const { users }: { users: UserDao } = inject('db')!
const values = users.getAll()
</script>

<template>
Expand Down

0 comments on commit 3c527c0

Please sign in to comment.