mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-20 13:38:08 +02:00
feat: implement PostgreSQL bulk data access client to replace per-article HTTP requests
This commit is contained in:
1 parent
83d101ddc1
commit
ebd819bfa4
2 files changed
+18
-15
No files matched your search
@@ -7,6 +7,11 @@ import path from "path";
|
|||||||
let pool: Pool | null = null;
|
let pool: Pool | null = null;
|
||||||
let currentDb: NodePgDatabase<typeof schema> | null = null;
|
let currentDb: NodePgDatabase<typeof schema> | null = null;
|
||||||
|
|
||||||
|
export function getPool(): Pool {
|
||||||
|
getDb(); // ensure pool is initialized
|
||||||
|
return pool!;
|
||||||
|
}
|
||||||
|
|
||||||
function maskUrl(url: string | undefined) {
|
function maskUrl(url: string | undefined) {
|
||||||
if (!url) return "undefined";
|
if (!url) return "undefined";
|
||||||
return url.replace(/:([^@]+)@/, ":****@");
|
return url.replace(/:([^@]+)@/, ":****@");
|
||||||
|
|||||||
+13
-15
@@ -7,7 +7,7 @@
|
|||||||
* Chaque fonction fait 1 seule requête filtrée par codefou — O(1) au lieu de O(N).
|
* Chaque fonction fait 1 seule requête filtrée par codefou — O(1) au lieu de O(N).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { db } from "@/db";
|
import { db, getPool } from "@/db";
|
||||||
import { sql, type SQL } from "drizzle-orm";
|
import { sql, type SQL } from "drizzle-orm";
|
||||||
|
|
||||||
// Cache module-level pour éviter les requêtes information_schema répétées
|
// Cache module-level pour éviter les requêtes information_schema répétées
|
||||||
@@ -753,22 +753,20 @@ export interface StockBySite {
|
|||||||
export async function pgGetStockForCodeins(codeins: string[]): Promise<Map<string, StockBySite>> {
|
export async function pgGetStockForCodeins(codeins: string[]): Promise<Map<string, StockBySite>> {
|
||||||
if (codeins.length === 0) return new Map();
|
if (codeins.length === 0) return new Map();
|
||||||
|
|
||||||
// Drizzle expands JS arrays into individual $1,$2,... params regardless of syntax,
|
// Bypass Drizzle entirely — it always expands arrays into individual params,
|
||||||
// hitting PostgreSQL's 1664-entry ROW expression limit. Use sql.raw() with an escaped
|
// hitting PG's 1664-entry ROW expression limit. Use the raw pg Pool directly
|
||||||
// literal array instead — codeins come from the DB so single-quote escaping is sufficient.
|
// with a native $1::text[] binding (entire array = single parameter).
|
||||||
const arrayLiteral = codeins.map(c => `'${String(c).replace(/'/g, "''")}'`).join(",");
|
const res = await getPool().query<{ codein: string; site: string; stockdispo: number }>(
|
||||||
const result = await pgNoParallel(sql`
|
`SELECT a.codein, cs.site, cs.stockdispo::float AS stockdispo
|
||||||
SELECT
|
FROM cube_stock cs
|
||||||
a.codein,
|
JOIN articles a ON a.no_id = cs.artnoid
|
||||||
cs.site,
|
WHERE a.codein = ANY($1::text[])`,
|
||||||
cs.stockdispo::float AS stockdispo
|
[codeins]
|
||||||
FROM cube_stock cs
|
);
|
||||||
JOIN articles a ON a.no_id = cs.artnoid
|
const rows = res.rows;
|
||||||
WHERE a.codein = ANY(ARRAY[${sql.raw(arrayLiteral)}])
|
|
||||||
`);
|
|
||||||
|
|
||||||
const map = new Map<string, StockBySite>();
|
const map = new Map<string, StockBySite>();
|
||||||
for (const r of result.rows as Array<{ codein: string; site: string; stockdispo: number }>) {
|
for (const r of rows) {
|
||||||
if (!map.has(r.codein)) map.set(r.codein, { stock292: 0, stock579: 0, stockTotal: 0 });
|
if (!map.has(r.codein)) map.set(r.codein, { stock292: 0, stock579: 0, stockTotal: 0 });
|
||||||
const entry = map.get(r.codein)!;
|
const entry = map.get(r.codein)!;
|
||||||
if (r.site === "292") entry.stock292 += r.stockdispo;
|
if (r.site === "292") entry.stock292 += r.stockdispo;
|
||||||
|
|||||||
Reference in new issue
Block a user