172 lines
6.0 KiB
JavaScript
172 lines
6.0 KiB
JavaScript
import { connection } from '../config/db.js'
|
||
import dotenv from 'dotenv'
|
||
dotenv.config()
|
||
|
||
export class GeneralService {
|
||
// constructor() {
|
||
// this.devhint = this.devhint.bind(this)
|
||
// }
|
||
devhint(level, location, message, extra = null) {
|
||
const isEnabled = process.env.DEVHINT === 'true'
|
||
const currentLevel = parseInt(process.env.DEVHINT_LEVEL || '1', 10)
|
||
if (!isEnabled || level > currentLevel) return
|
||
|
||
const timestamp = new Date().toISOString()
|
||
const prefix = `🧩 [DEVHINT:${location}]`
|
||
const formatted = `${prefix} → ${message} (${timestamp})`
|
||
if (extra) console.log(formatted, '\n', extra)
|
||
else console.log(formatted)
|
||
}
|
||
|
||
// ===================================================
|
||
// ✅ executeQueryConditions()
|
||
// ===================================================
|
||
async executeQueryConditions(database, baseQuery, conditions = {}) {
|
||
this.devhint(2, 'GeneralService', 'executeQueryConditions() start')
|
||
|
||
let whereClauses = []
|
||
let params = []
|
||
let idx = 1
|
||
|
||
for (const [key, value] of Object.entries(conditions)) {
|
||
if (value === undefined || value === null || value === '') continue
|
||
|
||
const match = String(value).match(/^(ILIKE|LIKE)\s+(.+)$/i)
|
||
if (match) {
|
||
const operator = match[1].toUpperCase()
|
||
const pattern = match[2].trim()
|
||
whereClauses.push(`${key} ${operator} $${idx}`)
|
||
params.push(pattern)
|
||
} else {
|
||
whereClauses.push(`${key} = $${idx}`)
|
||
params.push(value)
|
||
}
|
||
idx++
|
||
}
|
||
|
||
let finalQuery = baseQuery
|
||
if (whereClauses.length > 0) finalQuery += ' AND ' + whereClauses.join(' AND ')
|
||
const formattedSQL = finalQuery.replace(/\${database}/g, database)
|
||
|
||
this.devhint(2, 'executeQueryConditions', `📤 Executing Query`, {
|
||
database,
|
||
sql: formattedSQL,
|
||
params,
|
||
})
|
||
|
||
const result = await connection.query(formattedSQL, params)
|
||
this.devhint(2, 'executeQueryConditions', `✅ Query Success (${result.rowCount} rows)`)
|
||
return result.rows
|
||
}
|
||
|
||
// ===================================================
|
||
// ✅ executeQueryParam()
|
||
// ===================================================
|
||
// ===================================================
|
||
async executeQueryParam(database, sql, params = []) {
|
||
const formattedSQL = sql.replace(/\${database}/g, database)
|
||
|
||
this.devhint(2, 'executeQueryParam', `📤 Executing Query`, `sql = ${formattedSQL}`)
|
||
|
||
try {
|
||
const result = await connection.query(formattedSQL, params)
|
||
this.devhint(2, 'executeQueryParam', `✅ Query Success (${result.rowCount} rows)`)
|
||
return result.rows
|
||
} catch (err) {
|
||
this.devhint(2, 'executeQueryParam', `❌ Query Failed`, err.message)
|
||
console.error('SQL Error:', err)
|
||
throw err // <– ส่งต่อ error เพื่อ controller จะจับได้
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
// ===================================================
|
||
// Export สำหรับ controller หรืออื่นๆ เรียกใช้ได้ด้วย
|
||
// ===================================================
|
||
|
||
|
||
|
||
|
||
// /**
|
||
// * ✅ executeQueryParam (ของเดิม)
|
||
// * ใช้กับ SQL + database schema + params
|
||
// */
|
||
// export async function executeQueryParam(sql, database, params = []) {
|
||
// try {
|
||
// if (!database) throw new Error('Database is not defined')
|
||
|
||
// const formattedSQL = sql.replace(/\${database}/g, database)
|
||
// console.log(`[DB:${database}] → ${formattedSQL}`)
|
||
// const result = await connection.query(formattedSQL, params)
|
||
// return result.rows
|
||
// } catch (err) {
|
||
// console.error('[executeQueryParam Error]', err.message)
|
||
// throw err
|
||
// }
|
||
// }
|
||
|
||
/**
|
||
* ✅ executeQueryConditions (ใหม่)
|
||
* ใช้สร้าง WHERE อัตโนมัติจาก object เงื่อนไข
|
||
* ตัวที่ไม่มีค่า (null, undefined, '') จะไม่ถูกนำมาสร้างใน WHERE
|
||
*/
|
||
// export async function executeQueryConditions(database, baseQuery, conditions = {}) {
|
||
// try {
|
||
// if (!database) throw new Error('Database is not defined')
|
||
|
||
// let whereClauses = []
|
||
// let params = []
|
||
// let idx = 1
|
||
|
||
// for (const [key, value] of Object.entries(conditions)) {
|
||
// if (value === undefined || value === null || value === '') continue
|
||
|
||
// // ✅ ตรวจว่า value มีคำว่า LIKE หรือ ILIKE ไหม
|
||
// const match = String(value).match(/^(ILIKE|LIKE)\s+(.+)$/i)
|
||
// if (match) {
|
||
// const operator = match[1].toUpperCase()
|
||
// const pattern = match[2].trim()
|
||
// whereClauses.push(`${key} ${operator} $${idx}`)
|
||
// params.push(pattern)
|
||
// } else {
|
||
// whereClauses.push(`${key} = $${idx}`)
|
||
// params.push(value)
|
||
// }
|
||
|
||
// idx++
|
||
// }
|
||
|
||
// let finalQuery = baseQuery
|
||
// if (whereClauses.length > 0) {
|
||
// finalQuery += ' AND ' + whereClauses.join(' AND ')
|
||
// }
|
||
|
||
// const formattedSQL = finalQuery.replace(/\${database}/g, database)
|
||
// console.log(`[DB:${database}] → ${formattedSQL}`)
|
||
|
||
// const result = await connection.query(formattedSQL, params)
|
||
// return result.rows
|
||
// } catch (err) {
|
||
// console.error('[executeQueryConditions Error]', err.message)
|
||
// throw err
|
||
// }
|
||
// }
|
||
|
||
|
||
// /**
|
||
// * 🧩 devhint — Debug tracer ที่เปิดปิดได้จาก .env
|
||
// * @param {string} fileName - ชื่อไฟล์หรือโมดูล (เช่น 'usercontroller.js')
|
||
// * @param {string} message - ข้อความหรือจุดใน flow (เช่น 'onNavigate')
|
||
// * @param {object|string} [extra] - ข้อมูลเพิ่มเติม (optional)
|
||
// */
|
||
// export function devhint(fileName, message, extra = null) {
|
||
// if (process.env.DEVHINT === 'true') {
|
||
// const timestamp = new Date().toISOString()
|
||
// const prefix = `🧩 [DEVHINT:${fileName}]`
|
||
// const formatted = `${prefix} → ${message} (${timestamp})`
|
||
// if (extra) console.log(formatted, '\n', extra)
|
||
// else console.log(formatted)
|
||
// }
|
||
// }
|