datapeek 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/dev.js CHANGED
@@ -191,12 +191,63 @@ tableRoutes.get("/:schema/:table/data", async (req, res) => {
191
191
  const sortColumn = req.query.sortColumn;
192
192
  const sortDirection = req.query.sortDirection || "asc";
193
193
  const offset = (page - 1) * pageSize;
194
+ const filters = {};
195
+ Object.keys(req.query).forEach((key) => {
196
+ const match = key.match(/^filter\[(.+)\]$/);
197
+ if (match && req.query[key] && String(req.query[key]).trim()) {
198
+ filters[match[1]] = String(req.query[key]).trim();
199
+ }
200
+ });
201
+ console.log("Received filters from query:", filters);
202
+ console.log("All query params:", req.query);
194
203
  const pool = getConnection();
195
204
  if (!pool || !pool.connected) {
196
205
  return res.status(400).json({ error: "Not connected to database" });
197
206
  }
198
- const countQuery = `SELECT COUNT(*) as total FROM [${schema}].[${table}]`;
199
- const countResult = await executeQuery(countQuery);
207
+ const filterColumns = [];
208
+ if (Object.keys(filters).length > 0) {
209
+ try {
210
+ const columnNames = Object.keys(filters);
211
+ const placeholders = columnNames.map((_, i) => `@col${i}`).join(", ");
212
+ const validateQuery = `
213
+ SELECT COLUMN_NAME
214
+ FROM INFORMATION_SCHEMA.COLUMNS
215
+ WHERE TABLE_SCHEMA = @schema AND TABLE_NAME = @table AND COLUMN_NAME IN (${placeholders})
216
+ `;
217
+ const validateParams = [
218
+ { name: "schema", value: schema, type: sql.NVarChar },
219
+ { name: "table", value: table, type: sql.NVarChar },
220
+ ...columnNames.map((col, i) => ({ name: `col${i}`, value: col, type: sql.NVarChar }))
221
+ ];
222
+ const validateResult = await executeQuery(validateQuery, validateParams);
223
+ filterColumns.push(...validateResult.map((r) => r.COLUMN_NAME));
224
+ console.log("Validated filter columns:", filterColumns, "from filters:", filters);
225
+ } catch (e) {
226
+ console.error("Error validating filter columns:", e);
227
+ console.error("Filters that failed validation:", filters);
228
+ }
229
+ }
230
+ let whereClause = "";
231
+ const filterParams = [];
232
+ if (filterColumns.length > 0) {
233
+ const validFilters = filterColumns.filter((col) => {
234
+ const filterValue = filters[col];
235
+ return filterValue && filterValue.trim() !== "";
236
+ });
237
+ if (validFilters.length > 0) {
238
+ const whereConditions = validFilters.map((col, index) => {
239
+ const filterValue = filters[col];
240
+ filterParams.push({ name: `filter${index}`, value: `%${filterValue.trim()}%`, type: sql.NVarChar });
241
+ return `[${col}] LIKE @filter${index}`;
242
+ });
243
+ whereClause = `WHERE ${whereConditions.join(" AND ")}`;
244
+ console.log("Applying WHERE clause:", whereClause);
245
+ console.log("Filter params:", filterParams);
246
+ console.log("Valid filters:", validFilters);
247
+ }
248
+ }
249
+ const countQuery = `SELECT COUNT(*) as total FROM [${schema}].[${table}]${whereClause ? " " + whereClause : ""}`;
250
+ const countResult = await executeQuery(countQuery, filterParams.length > 0 ? filterParams : []);
200
251
  const total = countResult[0]?.total || 0;
201
252
  let orderByColumn = sortColumn || "";
202
253
  let orderByDirection = sortDirection?.toUpperCase() === "DESC" ? "DESC" : "ASC";
@@ -240,24 +291,26 @@ tableRoutes.get("/:schema/:table/data", async (req, res) => {
240
291
  let data;
241
292
  let generatedQuery = "";
242
293
  if (orderByColumn) {
243
- generatedQuery = `SELECT * FROM [${schema}].[${table}]
294
+ generatedQuery = `SELECT * FROM [${schema}].[${table}]${whereClause ? "\n" + whereClause : ""}
244
295
  ORDER BY [${orderByColumn}] ${orderByDirection}
245
296
  OFFSET ${offset} ROWS
246
297
  FETCH NEXT ${pageSize} ROWS ONLY`;
247
298
  const dataQuery = `
248
299
  SELECT * FROM [${schema}].[${table}]
300
+ ${whereClause}
249
301
  ORDER BY [${orderByColumn}] ${orderByDirection}
250
302
  OFFSET @offset ROWS
251
303
  FETCH NEXT @pageSize ROWS ONLY
252
304
  `;
253
305
  data = await executeQuery(dataQuery, [
254
306
  { name: "offset", value: offset, type: sql.Int },
255
- { name: "pageSize", value: pageSize, type: sql.Int }
307
+ { name: "pageSize", value: pageSize, type: sql.Int },
308
+ ...filterParams
256
309
  ]);
257
310
  } else {
258
311
  generatedQuery = `SELECT * FROM (
259
312
  SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) as rn
260
- FROM [${schema}].[${table}]
313
+ FROM [${schema}].[${table}]${whereClause ? "\n " + whereClause : ""}
261
314
  ) t
262
315
  WHERE rn > ${offset} AND rn <= ${offset + pageSize}
263
316
  ORDER BY rn`;
@@ -265,13 +318,15 @@ ORDER BY rn`;
265
318
  SELECT * FROM (
266
319
  SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) as rn
267
320
  FROM [${schema}].[${table}]
321
+ ${whereClause}
268
322
  ) t
269
323
  WHERE rn > @offset AND rn <= @offset + @pageSize
270
324
  ORDER BY rn
271
325
  `;
272
326
  data = await executeQuery(dataQuery, [
273
327
  { name: "offset", value: offset, type: sql.Int },
274
- { name: "pageSize", value: pageSize, type: sql.Int }
328
+ { name: "pageSize", value: pageSize, type: sql.Int },
329
+ ...filterParams
275
330
  ]);
276
331
  data = data.map((row) => {
277
332
  const { rn, ...rest } = row;
package/dist/cli/index.js CHANGED
@@ -194,12 +194,63 @@ tableRoutes.get("/:schema/:table/data", async (req, res) => {
194
194
  const sortColumn = req.query.sortColumn;
195
195
  const sortDirection = req.query.sortDirection || "asc";
196
196
  const offset = (page - 1) * pageSize;
197
+ const filters = {};
198
+ Object.keys(req.query).forEach((key) => {
199
+ const match = key.match(/^filter\[(.+)\]$/);
200
+ if (match && req.query[key] && String(req.query[key]).trim()) {
201
+ filters[match[1]] = String(req.query[key]).trim();
202
+ }
203
+ });
204
+ console.log("Received filters from query:", filters);
205
+ console.log("All query params:", req.query);
197
206
  const pool = getConnection();
198
207
  if (!pool || !pool.connected) {
199
208
  return res.status(400).json({ error: "Not connected to database" });
200
209
  }
201
- const countQuery = `SELECT COUNT(*) as total FROM [${schema}].[${table}]`;
202
- const countResult = await executeQuery(countQuery);
210
+ const filterColumns = [];
211
+ if (Object.keys(filters).length > 0) {
212
+ try {
213
+ const columnNames = Object.keys(filters);
214
+ const placeholders = columnNames.map((_, i) => `@col${i}`).join(", ");
215
+ const validateQuery = `
216
+ SELECT COLUMN_NAME
217
+ FROM INFORMATION_SCHEMA.COLUMNS
218
+ WHERE TABLE_SCHEMA = @schema AND TABLE_NAME = @table AND COLUMN_NAME IN (${placeholders})
219
+ `;
220
+ const validateParams = [
221
+ { name: "schema", value: schema, type: sql.NVarChar },
222
+ { name: "table", value: table, type: sql.NVarChar },
223
+ ...columnNames.map((col, i) => ({ name: `col${i}`, value: col, type: sql.NVarChar }))
224
+ ];
225
+ const validateResult = await executeQuery(validateQuery, validateParams);
226
+ filterColumns.push(...validateResult.map((r) => r.COLUMN_NAME));
227
+ console.log("Validated filter columns:", filterColumns, "from filters:", filters);
228
+ } catch (e) {
229
+ console.error("Error validating filter columns:", e);
230
+ console.error("Filters that failed validation:", filters);
231
+ }
232
+ }
233
+ let whereClause = "";
234
+ const filterParams = [];
235
+ if (filterColumns.length > 0) {
236
+ const validFilters = filterColumns.filter((col) => {
237
+ const filterValue = filters[col];
238
+ return filterValue && filterValue.trim() !== "";
239
+ });
240
+ if (validFilters.length > 0) {
241
+ const whereConditions = validFilters.map((col, index) => {
242
+ const filterValue = filters[col];
243
+ filterParams.push({ name: `filter${index}`, value: `%${filterValue.trim()}%`, type: sql.NVarChar });
244
+ return `[${col}] LIKE @filter${index}`;
245
+ });
246
+ whereClause = `WHERE ${whereConditions.join(" AND ")}`;
247
+ console.log("Applying WHERE clause:", whereClause);
248
+ console.log("Filter params:", filterParams);
249
+ console.log("Valid filters:", validFilters);
250
+ }
251
+ }
252
+ const countQuery = `SELECT COUNT(*) as total FROM [${schema}].[${table}]${whereClause ? " " + whereClause : ""}`;
253
+ const countResult = await executeQuery(countQuery, filterParams.length > 0 ? filterParams : []);
203
254
  const total = countResult[0]?.total || 0;
204
255
  let orderByColumn = sortColumn || "";
205
256
  let orderByDirection = sortDirection?.toUpperCase() === "DESC" ? "DESC" : "ASC";
@@ -243,24 +294,26 @@ tableRoutes.get("/:schema/:table/data", async (req, res) => {
243
294
  let data;
244
295
  let generatedQuery = "";
245
296
  if (orderByColumn) {
246
- generatedQuery = `SELECT * FROM [${schema}].[${table}]
297
+ generatedQuery = `SELECT * FROM [${schema}].[${table}]${whereClause ? "\n" + whereClause : ""}
247
298
  ORDER BY [${orderByColumn}] ${orderByDirection}
248
299
  OFFSET ${offset} ROWS
249
300
  FETCH NEXT ${pageSize} ROWS ONLY`;
250
301
  const dataQuery = `
251
302
  SELECT * FROM [${schema}].[${table}]
303
+ ${whereClause}
252
304
  ORDER BY [${orderByColumn}] ${orderByDirection}
253
305
  OFFSET @offset ROWS
254
306
  FETCH NEXT @pageSize ROWS ONLY
255
307
  `;
256
308
  data = await executeQuery(dataQuery, [
257
309
  { name: "offset", value: offset, type: sql.Int },
258
- { name: "pageSize", value: pageSize, type: sql.Int }
310
+ { name: "pageSize", value: pageSize, type: sql.Int },
311
+ ...filterParams
259
312
  ]);
260
313
  } else {
261
314
  generatedQuery = `SELECT * FROM (
262
315
  SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) as rn
263
- FROM [${schema}].[${table}]
316
+ FROM [${schema}].[${table}]${whereClause ? "\n " + whereClause : ""}
264
317
  ) t
265
318
  WHERE rn > ${offset} AND rn <= ${offset + pageSize}
266
319
  ORDER BY rn`;
@@ -268,13 +321,15 @@ ORDER BY rn`;
268
321
  SELECT * FROM (
269
322
  SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) as rn
270
323
  FROM [${schema}].[${table}]
324
+ ${whereClause}
271
325
  ) t
272
326
  WHERE rn > @offset AND rn <= @offset + @pageSize
273
327
  ORDER BY rn
274
328
  `;
275
329
  data = await executeQuery(dataQuery, [
276
330
  { name: "offset", value: offset, type: sql.Int },
277
- { name: "pageSize", value: pageSize, type: sql.Int }
331
+ { name: "pageSize", value: pageSize, type: sql.Int },
332
+ ...filterParams
278
333
  ]);
279
334
  data = data.map((row) => {
280
335
  const { rn, ...rest } = row;