Skip to content

Commit

Permalink
Add multiple examples for dbquery (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
hluk committed Nov 3, 2023
1 parent 7c66c70 commit ac4c9cd
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 15 deletions.
18 changes: 14 additions & 4 deletions product_listings_manager/rest_api_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import logging
import os
from functools import lru_cache
from typing import Any
from typing import Annotated, Any

from fastapi import APIRouter, Depends, HTTPException, Request, status
from fastapi import APIRouter, Body, Depends, HTTPException, Request, status
from sqlalchemy import text
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
Expand All @@ -17,6 +17,7 @@
from product_listings_manager.models import get_db
from product_listings_manager.permissions import has_permission
from product_listings_manager.schemas import (
SQL_QUERY_EXAMPLES,
LoginInfo,
Message,
Permission,
Expand Down Expand Up @@ -323,17 +324,26 @@ def permissions() -> list[Permission]:
},
)
def dbquery(
query_or_queries: SqlQuery | list[SqlQuery | str] | str,
query_or_queries: Annotated[
SqlQuery | list[SqlQuery | str] | str,
Body(openapi_examples=SQL_QUERY_EXAMPLES),
],
request: Request,
db: Session = Depends(get_db),
) -> list[dict[str, Any]]:
"""
Executes given SQL queries with optionally provided parameters.
Multiple queries can be provided (pass as an array) but only the result
Multiple SQL queries can be provided (pass as an array) but only the result
(listed rows) from the last query will be returned.
User must be logged in and have permission to execute the queries.
Format for *placeholders* in the SQL queries is `:placeholder_name`.
Instead of using a `IN` SQL operator with a placeholder in a `WHERE` clause,
use format like `trees_id = ANY(:tree_ids)` where value for the placeholder
would be a list with the required values.
"""
if not query_or_queries:
raise HTTPException(
Expand Down
72 changes: 61 additions & 11 deletions product_listings_manager/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,66 @@

from pydantic import BaseModel, Field

SQL_QUERY_EXAMPLES = {
"SELECT": {
"summary": "List variant, allow_source_only for a product",
"value": {
"query": (
"SELECT variant, allow_source_only"
" FROM products WHERE label = :label LIMIT 1"
),
"params": {
"label": "RHEL-8.2.0.GA",
},
},
},
"SELECT_LIST_CHECK": {
"summary": "SELECT with ARRAY placeholders",
"value": {
"query": (
"SELECT * FROM tree_packages"
" WHERE trees_id = ANY(:tree_ids)"
" AND packages_id = ANY(:package_ids)"
),
"params": {
"tree_ids": [1, 2, 3],
"package_ids": [10, 20],
},
},
},
"INSERT": {
"summary": "Insert a new product",
"value": {
"query": (
"INSERT INTO products (id, label, version, variant, allow_source_only)"
" VALUES (nextval('products_id_seq'), :label, :version, :variant,"
" :allow_source_only)"
" RETURNING id"
),
"params": {
"label": "product1",
"version": "1.2",
"variant": "Client",
"allow_source_only": 1,
},
},
},
"DELETE": {
"summary": "Delete a product",
"value": {
"query": (
"DELETE FROM products"
" WHERE label = :label AND version = :version AND variant = :variant"
),
"params": {
"label": "product1",
"version": "1.2",
"variant": "Client",
},
},
},
}


class Message(BaseModel):
message: str
Expand All @@ -28,17 +88,7 @@ class SqlQuery(BaseModel):

model_config = {
"json_schema_extra": {
"examples": [
{
"params": {
"label": "RHEL-8.2.0.GA",
},
"query": (
"SELECT variant, allow_source_only"
" FROM products WHERE label = :label LIMIT 1"
),
},
]
"examples": [x["value"] for x in SQL_QUERY_EXAMPLES.values()]
}
}

Expand Down

0 comments on commit ac4c9cd

Please sign in to comment.