chore: import codes
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* Posts Module - Database
|
||||
* Creates zen_posts and zen_posts_category tables.
|
||||
*/
|
||||
|
||||
import { query } from '@hykocx/zen/database';
|
||||
import { getPostsConfig } from './config.js';
|
||||
|
||||
async function tableExists(tableName) {
|
||||
const result = await query(
|
||||
`SELECT EXISTS (
|
||||
SELECT FROM information_schema.tables
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = $1
|
||||
)`,
|
||||
[tableName]
|
||||
);
|
||||
return result.rows[0].exists;
|
||||
}
|
||||
|
||||
async function createPostsCategoryTable() {
|
||||
const tableName = 'zen_posts_category';
|
||||
const exists = await tableExists(tableName);
|
||||
|
||||
if (exists) {
|
||||
console.log(`- Table already exists: ${tableName}`);
|
||||
return { created: false, tableName };
|
||||
}
|
||||
|
||||
await query(`
|
||||
CREATE TABLE zen_posts_category (
|
||||
id SERIAL PRIMARY KEY,
|
||||
post_type VARCHAR(100) NOT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`);
|
||||
|
||||
await query(`CREATE INDEX idx_zen_posts_category_post_type ON zen_posts_category(post_type)`);
|
||||
await query(`CREATE INDEX idx_zen_posts_category_is_active ON zen_posts_category(is_active)`);
|
||||
|
||||
console.log(`✓ Created table: ${tableName}`);
|
||||
return { created: true, tableName };
|
||||
}
|
||||
|
||||
async function createPostsTable() {
|
||||
const tableName = 'zen_posts';
|
||||
const exists = await tableExists(tableName);
|
||||
|
||||
if (exists) {
|
||||
console.log(`- Table already exists: ${tableName}`);
|
||||
return { created: false, tableName };
|
||||
}
|
||||
|
||||
await query(`
|
||||
CREATE TABLE zen_posts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
post_type VARCHAR(100) NOT NULL,
|
||||
slug VARCHAR(500) NOT NULL,
|
||||
data JSONB NOT NULL DEFAULT '{}',
|
||||
category_id INTEGER REFERENCES zen_posts_category(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(post_type, slug)
|
||||
)
|
||||
`);
|
||||
|
||||
await query(`CREATE INDEX idx_zen_posts_post_type ON zen_posts(post_type)`);
|
||||
await query(`CREATE INDEX idx_zen_posts_post_type_slug ON zen_posts(post_type, slug)`);
|
||||
await query(`CREATE INDEX idx_zen_posts_category_id ON zen_posts(category_id)`);
|
||||
await query(`CREATE INDEX idx_zen_posts_data_gin ON zen_posts USING GIN (data)`);
|
||||
|
||||
console.log(`✓ Created table: ${tableName}`);
|
||||
return { created: true, tableName };
|
||||
}
|
||||
|
||||
async function createPostsRelationsTable() {
|
||||
const tableName = 'zen_posts_relations';
|
||||
const exists = await tableExists(tableName);
|
||||
|
||||
if (exists) {
|
||||
console.log(`- Table already exists: ${tableName}`);
|
||||
return { created: false, tableName };
|
||||
}
|
||||
|
||||
await query(`
|
||||
CREATE TABLE zen_posts_relations (
|
||||
id SERIAL PRIMARY KEY,
|
||||
post_id INTEGER NOT NULL REFERENCES zen_posts(id) ON DELETE CASCADE,
|
||||
field_name VARCHAR(100) NOT NULL,
|
||||
related_post_id INTEGER NOT NULL REFERENCES zen_posts(id) ON DELETE CASCADE,
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
UNIQUE(post_id, field_name, related_post_id)
|
||||
)
|
||||
`);
|
||||
|
||||
await query(`CREATE INDEX idx_zen_posts_relations_post_id ON zen_posts_relations(post_id)`);
|
||||
await query(`CREATE INDEX idx_zen_posts_relations_related ON zen_posts_relations(related_post_id)`);
|
||||
|
||||
console.log(`✓ Created table: ${tableName}`);
|
||||
return { created: true, tableName };
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all posts-related tables.
|
||||
* zen_posts_category is only created if at least one type uses the 'category' field.
|
||||
* zen_posts_relations is only created if at least one type uses the 'relation' field.
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export async function createTables() {
|
||||
const created = [];
|
||||
const skipped = [];
|
||||
|
||||
const config = getPostsConfig();
|
||||
const needsRelations = Object.values(config.types).some(t => t.hasRelations);
|
||||
|
||||
// zen_posts_category must always be created before zen_posts
|
||||
// because zen_posts has a FK reference to it
|
||||
console.log('\n--- Posts Categories ---');
|
||||
const catResult = await createPostsCategoryTable();
|
||||
if (catResult.created) created.push(catResult.tableName);
|
||||
else skipped.push(catResult.tableName);
|
||||
|
||||
console.log('\n--- Posts ---');
|
||||
const postResult = await createPostsTable();
|
||||
if (postResult.created) created.push(postResult.tableName);
|
||||
else skipped.push(postResult.tableName);
|
||||
|
||||
if (needsRelations) {
|
||||
console.log('\n--- Posts Relations ---');
|
||||
const relResult = await createPostsRelationsTable();
|
||||
if (relResult.created) created.push(relResult.tableName);
|
||||
else skipped.push(relResult.tableName);
|
||||
}
|
||||
|
||||
return { created, skipped };
|
||||
}
|
||||
Reference in New Issue
Block a user