Skip to content

Commit

Permalink
Added parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
Tevon Strand-Brown committed Mar 30, 2024
1 parent 750a618 commit 625f3f0
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 14 deletions.
1 change: 1 addition & 0 deletions backend/src/definitions/user-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const UserQuerySchema = z.object({
description: z.string().optional(),
sql: z.string().optional(),
pipeline: z.any().optional(), // TODO replace with actual pipeline schema
parameters: z.any().optional(), // TODO replace with actual parameter schema
scope: z.enum(["private", "organization"]), // TODO turn this into an enum
permissions: z.record(z.any()), // TODO update
favorited_by: z.array(z.string()),
Expand Down
8 changes: 6 additions & 2 deletions backend/src/user-queries/user-queries.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
UseInterceptors,
HttpException,
HttpStatus,
Query,
} from "@nestjs/common";
import { UserQueriesService } from "./user-queries.service";
import { OrgGuard } from "@/auth/organizations.guard";
Expand Down Expand Up @@ -67,9 +68,12 @@ export class UserQueriesController {
@Get("/:id/run")
@UseGuards(OrgGuard("query"))
@UseInterceptors(TrackingInterceptor)
async run(@Param("id") id: string): Promise<QueryResult<any>> {
async run(
@Param("id") id: string,
@Query() query: any,
): Promise<QueryResult<any>> {
try {
const results = await this.userQueriesService.run(id);
const results = await this.userQueriesService.run(id, query);
return results;
} catch (e) {
throw new HttpException(
Expand Down
30 changes: 27 additions & 3 deletions backend/src/user-queries/user-queries.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export class UserQueriesService {
}

// TODO decide on the correct return type here
async run(id: string): Promise<QueryResult<any>> {
async run(id: string, query): Promise<QueryResult<any>> {
const userQuery = await this.findOne(id);

assert(userQuery, new NotFoundException(`Query not found with id ${id}`));
Expand All @@ -142,13 +142,37 @@ export class UserQueriesService {
userQuery.sql,
`SQL statement not found for query ${userQuery.name}`,
);

const { sql, params } = parseParametersFromSQL(userQuery.sql, query);
const results = await this.postgresAdapterService.run({
databaseId: userQuery.database_id,
sql: userQuery.sql,
sql: sql,
values: params,
});

return results;
}
}
}

const parseParametersFromSQL = (
sql: string,
parameters: Record<string, any>,
): { sql: string; params: any[] } => {
const matches = sql.match(/{{(.*?)}}/g);
let paramIndex = 1;
const params: any[] = [];
console.log("Matches", matches);
if (!matches) {
return { sql, params: [] };
}
matches.forEach((match) => {
const paramName = match.replace("{{", "").replace("}}", "");
if (parameters[paramName] !== undefined) {
sql = sql.replace(match, `$${paramIndex}`);
params.push(parameters[paramName]);
paramIndex++;
}
});

return { sql, params };
};
12 changes: 7 additions & 5 deletions frontend/src/app/queries/[userQueryId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,23 @@ const Page: React.FC<UserQueryPageProps> = ({ params: { userQueryId } }) => {
isLoading: isLoadingUserQuery,
error: userQueryError,
} = useUserQuery(userQueryId);
const [parameters, setParameters] = useState<Parameter[]>([]);
const [savedParameters, setSavedParameters] = useState<Parameter[]>([]);

useEffect(() => {
setSqlQuery(userQuery?.sql || "");
}, [userQuery, setSqlQuery]);
setParameters(userQuery?.parameters || []);
}, [userQuery, setSqlQuery, setParameters]);

const {
data: results,
isLoading: isLoadingResults,
error: resultsError,
} = useUserQueryResults(userQueryId, userQuery?.sql);

const [parameters, setParameters] = useState<Parameter[]>([]);
} = useUserQueryResults(userQueryId, userQuery?.sql, savedParameters);

const handleSaveQuery = () => {
updateUserQueryTrigger({ sql: sqlQuery });
setSavedParameters(parameters);
updateUserQueryTrigger({ sql: sqlQuery, parameters: parameters });
};

const { trigger: updateUserQueryTrigger, isMutating: isUpdatingUserQuery } =
Expand Down
18 changes: 15 additions & 3 deletions frontend/src/data/use-user-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { backendCreate, backendGet, backendUpdate } from "./client";
import { CreateUserQuery, UserQuery } from "@/definitions";
import useSWRMutation from "swr/mutation";
import { useSelectedDatabase } from "@/stores";
import { Parameter } from "@/components/query/query-parameters";

export const useUserQuery = (queryId?: string) => {
const { data, error, isLoading } = useSWR<UserQuery>(
Expand Down Expand Up @@ -48,9 +49,20 @@ export const useCreateUserQuery = () => {
return { data, error, trigger, isMutating };
};

export const useUserQueryResults = (queryId: string, sql?: string) => {
const { data, error, isLoading } = useSWR<any>(sql, () => {
return backendGet(`/user-queries/${queryId}/run`);
export const useUserQueryResults = (
queryId: string,
sql?: string,
params?: Parameter[],
) => {
const reducedParams: Record<string, any> = {};
if (params) {
for (const param of params) {
reducedParams[param.name] = param.value || param.defaultValue;
}
}
const paramsString = new URLSearchParams(reducedParams).toString();
const { data, error, isLoading } = useSWR<any>(sql + paramsString, () => {
return backendGet(`/user-queries/${queryId}/run?${paramsString}`);
});

return { data, error, isLoading };
Expand Down
10 changes: 9 additions & 1 deletion frontend/src/definitions/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const TableConfigurationSchema = z.object({
primary_key: z.string().optional(),
title_property: z.string().optional(),
hidden_columns: z.array(z.string()).optional(),
ordered_columns: z.array(z.string()).optional()
ordered_columns: z.array(z.string()).optional(),
});
export type TableConfiguration = z.infer<typeof TableConfigurationSchema>;

Expand Down Expand Up @@ -60,3 +60,11 @@ export const UpdateTableSchema = TableSchema.omit({
deleted_at: true,
}).partial();
export type UpdateTable = z.infer<typeof UpdateTableSchema>;

export const UpdateTableRowSchema = z.object({
row_id: z.union([z.string(), z.number()]),
column_name: z.string(),
value: z.any(),
pk_column: z.string(),
});
export type UpdateTableRow = z.infer<typeof UpdateTableRowSchema>;
1 change: 1 addition & 0 deletions frontend/src/definitions/user-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const UserQuerySchema = z.object({
description: z.string().optional(),
sql: z.string().optional(),
pipeline: z.any().optional(), // TODO replace with actual pipeline schema
parameters: z.any().optional(), // TODO replace with actual parameter schema
scope: z.enum(["private", "organization"]), // TODO turn this into an enum
permissions: z.record(z.any()), // TODO update
favorited_by: z.array(z.string()),
Expand Down

0 comments on commit 625f3f0

Please sign in to comment.