mirror of
https://github.com/johndoe6345789/snippet-pastebin.git
synced 2026-04-24 13:34:55 +00:00
Phase 1: Extract db-mapper helper to reduce duplication in db.ts
Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
43
src/lib/db-mapper.ts
Normal file
43
src/lib/db-mapper.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Database row-to-object mapping utilities
|
||||
* Handles conversion of SQL query results to typed objects
|
||||
*/
|
||||
|
||||
/**
|
||||
* Maps a SQL query result row to a typed object
|
||||
* Handles special conversions for boolean and JSON fields
|
||||
*/
|
||||
export function mapRowToObject<T>(row: any[], columns: string[]): T {
|
||||
const obj: any = {}
|
||||
|
||||
columns.forEach((col, idx) => {
|
||||
const value = row[idx]
|
||||
|
||||
// Convert integer boolean fields to actual booleans
|
||||
if (col === 'hasPreview' || col === 'isDefault') {
|
||||
obj[col] = value === 1
|
||||
}
|
||||
// Parse JSON string fields
|
||||
else if (col === 'inputParameters') {
|
||||
obj[col] = value ? JSON.parse(value as string) : undefined
|
||||
}
|
||||
// All other fields pass through as-is
|
||||
else {
|
||||
obj[col] = value
|
||||
}
|
||||
})
|
||||
|
||||
return obj as T
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps multiple SQL result rows to an array of typed objects
|
||||
*/
|
||||
export function mapRowsToObjects<T>(results: any[]): T[] {
|
||||
if (results.length === 0) return []
|
||||
|
||||
const columns = results[0].columns
|
||||
const values = results[0].values
|
||||
|
||||
return values.map(row => mapRowToObject<T>(row, columns))
|
||||
}
|
||||
105
src/lib/db.ts
105
src/lib/db.ts
@@ -1,6 +1,7 @@
|
||||
import initSqlJs, { Database } from 'sql.js'
|
||||
import type { Snippet, SnippetTemplate } from './types'
|
||||
import { getStorageConfig, FlaskStorageAdapter, loadStorageConfig } from './storage'
|
||||
import { mapRowToObject, mapRowsToObjects } from './db-mapper'
|
||||
|
||||
let dbInstance: Database | null = null
|
||||
let sqlInstance: any = null
|
||||
@@ -304,27 +305,9 @@ export async function getAllSnippets(): Promise<Snippet[]> {
|
||||
}
|
||||
|
||||
const db = await initDB()
|
||||
|
||||
const results = db.exec('SELECT * FROM snippets ORDER BY updatedAt DESC')
|
||||
|
||||
if (results.length === 0) return []
|
||||
|
||||
const columns = results[0].columns
|
||||
const values = results[0].values
|
||||
|
||||
return values.map(row => {
|
||||
const snippet: any = {}
|
||||
columns.forEach((col, idx) => {
|
||||
if (col === 'hasPreview') {
|
||||
snippet[col] = row[idx] === 1
|
||||
} else if (col === 'inputParameters') {
|
||||
snippet[col] = row[idx] ? JSON.parse(row[idx] as string) : undefined
|
||||
} else {
|
||||
snippet[col] = row[idx]
|
||||
}
|
||||
})
|
||||
return snippet as Snippet
|
||||
})
|
||||
return mapRowsToObjects<Snippet>(results)
|
||||
}
|
||||
|
||||
export async function getSnippet(id: string): Promise<Snippet | null> {
|
||||
@@ -334,7 +317,6 @@ export async function getSnippet(id: string): Promise<Snippet | null> {
|
||||
}
|
||||
|
||||
const db = await initDB()
|
||||
|
||||
const results = db.exec('SELECT * FROM snippets WHERE id = ?', [id])
|
||||
|
||||
if (results.length === 0 || results[0].values.length === 0) return null
|
||||
@@ -342,18 +324,7 @@ export async function getSnippet(id: string): Promise<Snippet | null> {
|
||||
const columns = results[0].columns
|
||||
const row = results[0].values[0]
|
||||
|
||||
const snippet: any = {}
|
||||
columns.forEach((col, idx) => {
|
||||
if (col === 'hasPreview') {
|
||||
snippet[col] = row[idx] === 1
|
||||
} else if (col === 'inputParameters') {
|
||||
snippet[col] = row[idx] ? JSON.parse(row[idx] as string) : undefined
|
||||
} else {
|
||||
snippet[col] = row[idx]
|
||||
}
|
||||
})
|
||||
|
||||
return snippet as Snippet
|
||||
return mapRowToObject<Snippet>(row, columns)
|
||||
}
|
||||
|
||||
export async function createSnippet(snippet: Snippet): Promise<void> {
|
||||
@@ -431,27 +402,9 @@ export async function deleteSnippet(id: string): Promise<void> {
|
||||
|
||||
export async function getAllTemplates(): Promise<SnippetTemplate[]> {
|
||||
const db = await initDB()
|
||||
|
||||
const results = db.exec('SELECT * FROM snippet_templates')
|
||||
|
||||
if (results.length === 0) return []
|
||||
|
||||
const columns = results[0].columns
|
||||
const values = results[0].values
|
||||
|
||||
return values.map(row => {
|
||||
const template: any = {}
|
||||
columns.forEach((col, idx) => {
|
||||
if (col === 'hasPreview') {
|
||||
template[col] = row[idx] === 1
|
||||
} else if (col === 'inputParameters') {
|
||||
template[col] = row[idx] ? JSON.parse(row[idx] as string) : undefined
|
||||
} else {
|
||||
template[col] = row[idx]
|
||||
}
|
||||
})
|
||||
return template as SnippetTemplate
|
||||
})
|
||||
return mapRowsToObjects<SnippetTemplate>(results)
|
||||
}
|
||||
|
||||
export async function createTemplate(template: SnippetTemplate): Promise<void> {
|
||||
@@ -957,25 +910,9 @@ export async function getAllNamespaces(): Promise<import('./types').Namespace[]>
|
||||
}
|
||||
|
||||
const db = await initDB()
|
||||
|
||||
const results = db.exec('SELECT * FROM namespaces ORDER BY isDefault DESC, name ASC')
|
||||
|
||||
if (results.length === 0) return []
|
||||
|
||||
const columns = results[0].columns
|
||||
const values = results[0].values
|
||||
|
||||
return values.map(row => {
|
||||
const namespace: any = {}
|
||||
columns.forEach((col, idx) => {
|
||||
if (col === 'isDefault') {
|
||||
namespace[col] = row[idx] === 1
|
||||
} else {
|
||||
namespace[col] = row[idx]
|
||||
}
|
||||
})
|
||||
return namespace
|
||||
})
|
||||
return mapRowsToObjects<import('./types').Namespace>(results)
|
||||
}
|
||||
|
||||
export async function createNamespace(name: string): Promise<import('./types').Namespace> {
|
||||
@@ -1057,32 +994,13 @@ export async function ensureDefaultNamespace(): Promise<void> {
|
||||
|
||||
export async function getSnippetsByNamespace(namespaceId: string): Promise<Snippet[]> {
|
||||
const db = await initDB()
|
||||
|
||||
const results = db.exec('SELECT * FROM snippets WHERE namespaceId = ? OR (namespaceId IS NULL AND ? = (SELECT id FROM namespaces WHERE isDefault = 1)) ORDER BY updatedAt DESC', [namespaceId, namespaceId])
|
||||
|
||||
if (results.length === 0) return []
|
||||
|
||||
const columns = results[0].columns
|
||||
const values = results[0].values
|
||||
|
||||
return values.map(row => {
|
||||
const snippet: any = {}
|
||||
columns.forEach((col, idx) => {
|
||||
if (col === 'hasPreview') {
|
||||
snippet[col] = row[idx] === 1
|
||||
} else if (col === 'inputParameters') {
|
||||
snippet[col] = row[idx] ? JSON.parse(row[idx] as string) : undefined
|
||||
} else {
|
||||
snippet[col] = row[idx]
|
||||
}
|
||||
})
|
||||
return snippet as Snippet
|
||||
})
|
||||
return mapRowsToObjects<Snippet>(results)
|
||||
}
|
||||
|
||||
export async function getNamespaceById(id: string): Promise<import('./types').Namespace | null> {
|
||||
const db = await initDB()
|
||||
|
||||
const results = db.exec('SELECT * FROM namespaces WHERE id = ?', [id])
|
||||
|
||||
if (results.length === 0 || results[0].values.length === 0) return null
|
||||
@@ -1090,16 +1008,7 @@ export async function getNamespaceById(id: string): Promise<import('./types').Na
|
||||
const columns = results[0].columns
|
||||
const row = results[0].values[0]
|
||||
|
||||
const namespace: any = {}
|
||||
columns.forEach((col, idx) => {
|
||||
if (col === 'isDefault') {
|
||||
namespace[col] = row[idx] === 1
|
||||
} else {
|
||||
namespace[col] = row[idx]
|
||||
}
|
||||
})
|
||||
|
||||
return namespace
|
||||
return mapRowToObject<import('./types').Namespace>(row, columns)
|
||||
}
|
||||
|
||||
export async function moveSnippetToNamespace(snippetId: string, targetNamespaceId: string): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user