Skip to content

Commit

Permalink
Fetch and show users
Browse files Browse the repository at this point in the history
  • Loading branch information
chvp committed Aug 28, 2023
1 parent c6d4d01 commit cc1c4e0
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 69 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')
11 changes: 8 additions & 3 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,8 +8,12 @@ interface Options {

export default {
install: (app: App, options: Options) => {
const client = new SqliteClient(options.file)
client.executeMutation('test', 'CREATE TABLE IF NOT EXISTS test (a, b, c);')
app.provide('db', client)
const client = new SqliteClient(options.file, [
'CREATE TABLE IF NOT EXISTS users (id INT PRIMARY KEY, name VARCHAR, permission VARCHAR);'
])
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
39 changes: 36 additions & 3 deletions src/views/AppRootView.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<script setup lang="ts">
import { RouterView, useRouter } from 'vue-router'
import { watchEffect } from 'vue'
import { watchEffect, ref, inject } from 'vue'
import { useAuthStore } from '@/stores/auth'
import type UserDao from '@/db/user_dao'
const router = useRouter()
const authStore = useAuthStore()
const { users }: { users: UserDao } = inject('db')!
const drawer = ref(false)
const loading = ref(false)
watchEffect(() => {
if (!authStore.loggedIn) {
Expand All @@ -15,9 +20,37 @@ watchEffect(() => {
function logout() {
authStore.logout()
}
async function loadData() {
loading.value = true
await users.refresh()
loading.value = false
}
</script>

<template>
<v-btn @click="logout">Logout</v-btn>
<router-view />
<v-app-bar color="primary">
<template #prepend>
<v-app-bar-nav-icon @click.stop="drawer = !drawer" />
</template>
<v-toolbar-title class="font-weight-medium">Accentor</v-toolbar-title>
<template #append>
<v-btn :disabled="loading" variant="text" icon @click="loadData">
<v-icon>mdi-refresh {{ loading ? 'mdi-spin' : '' }}</v-icon>
</v-btn>
<v-btn variant="text" icon @click="logout">
<v-icon>mdi-logout-variant</v-icon>
</v-btn>
</template>
</v-app-bar>
<v-navigation-drawer v-model="drawer">
<v-list>
<v-list-item prepend-icon="mdi-home" title="Home" :to="{ name: 'home' }" exact />
</v-list>
</v-navigation-drawer>
<v-main>
<v-container>
<router-view />
</v-container>
</v-main>
</template>
48 changes: 6 additions & 42 deletions src/views/HomeView.vue
Original file line number Diff line number Diff line change
@@ -1,47 +1,11 @@
<script setup lang="ts">
import { inject, ref } from 'vue'
import type SqliteClient from '../db-client'
const dbClient: SqliteClient = inject('db')!
const minA = ref(0)
const minB = ref(0)
const minC = ref(0)
const values = dbClient.executeSelect(
['test'],
'SELECT * FROM test WHERE a >= ? AND b >= ? AND c >= ? ORDER BY a ASC LIMIT ?;',
minA,
minB,
minC,
10
)
async function deleteAll() {
await dbClient.executeMutation('test', 'DELETE FROM test;')
}
function randInt(max: number): number {
return Math.round(Math.random() * max)
}
async function insertNew() {
await dbClient.executeMutation(
'test',
'INSERT INTO test VALUES (?, ?, ?);',
randInt(100),
randInt(50),
randInt(10)
)
}
import { inject } from 'vue'
import type UserDao from '@/db/user_dao'
const { users }: { users: UserDao } = inject('db')!
const values = users.getAll()
</script>

<template>
<div>
<div>Table contents: {{ values }}</div>
<div>
<v-text-field v-model.number="minA" type="number" />
<v-text-field v-model.number="minB" type="number" />
<v-text-field v-model.number="minC" type="number" />
<v-btn @click="deleteAll">Delete all</v-btn>
<v-btn @click="insertNew">Insert new</v-btn>
</div>
</div>
<p>Home</p>
<div>Table contents: {{ values }}</div>
</template>

0 comments on commit cc1c4e0

Please sign in to comment.