File size: 1,806 Bytes
123c60b 9853b20 123c60b 9853b20 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | import { createServerClient, isSupabaseConfigured } from './supabase/server'
import { Pool } from 'pg'
const LOCAL_DB_URL = process.env.LOCAL_DATABASE_URL
let pool: Pool | null = null
if (LOCAL_DB_URL) {
pool = new Pool({ connectionString: LOCAL_DB_URL })
}
async function upsertLocal(table: string, row: Record<string, any>) {
if (!pool) return
const cols = Object.keys(row)
if (!cols.includes('id')) {
throw new Error(`Row for ${table} missing id`)
}
const colList = cols.map((c) => `"${c}"`).join(',')
const vals = Object.values(row)
const placeholders = cols.map((_, i) => `$${i + 1}`).join(',')
const updates = cols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(',')
const query = `INSERT INTO ${table} (${colList}) VALUES(${placeholders}) ON CONFLICT (id) DO UPDATE SET ${updates}`
await pool.query(query, vals)
}
export async function syncSupabaseToLocal() {
if (!pool) {
throw new Error('LOCAL_DATABASE_URL required for pull sync')
}
if (!isSupabaseConfigured() || !process.env.SUPABASE_SERVICE_ROLE_KEY) {
console.error('Missing Supabase service credentials for pull sync; skipping pull')
return { synced: 0 }
}
const supabase = await createServerClient({ service: true })
let synced = 0
const pull = async (table: string) => {
const { data, error } = await supabase.from(table).select('*')
if (error) throw error
for (const row of data || []) {
await upsertLocal(table, row as any)
synced++
}
}
await pull('rooms')
await pull('codes')
await pull('room_messages')
return { synced }
}
if (require.main === module) {
syncSupabaseToLocal().then((r) => {
console.log('Pull sync result', r)
process.exit(0)
}).catch((e) => {
console.error('Pull sync failed', e)
process.exit(1)
})
}
|