This PostgreSQL function successfully returns JSON; however, the function name is associated with the result:
CREATE OR REPLACE FUNCTION public.find_classes(
search_text character varying,
current_page integer DEFAULT 1,
page_size integer DEFAULT 10,
sort_by character varying DEFAULT 'name'::character varying,
direction character varying DEFAULT 'ASC'::character varying
)
RETURNS json AS
$$
WITH classes_found AS (
SELECT
classes._id AS id, classes.name, classes.description, classes.active
FROM classes
WHERE search_text IS NULL OR search_text = '' OR LOWER(classes.name) LIKE LOWER(search_text) || '%'
ORDER BY
CASE
WHEN direction = 'ASC' THEN
CASE
WHEN sort_by = 'name' THEN classes.name
WHEN sort_by = 'active' THEN classes.active::varchar
END
END ASC,
CASE
WHEN direction = 'DESC' THEN
CASE
WHEN sort_by = 'name' THEN classes.name
WHEN sort_by = 'active' THEN classes.active::varchar
END
END DESC
)
SELECT json_build_object(
'totalItems',(SELECT COUNT(*) FROM classes_found),
'currentPage', current_page,
'pageSize', page_size,
'classes', COALESCE((SELECT json_agg(l.*) FROM (SELECT classes_found.* FROM classes_found LIMIT page_size OFFSET ((current_page - 1) * page_size)) l ), '[]')
) AS results;
$$ LANGUAGE SQL;
As far as both pgAdmin and node-postgres go, the data returned looks like one row with a JSON column named "find_classes".
If it has to have a name, I want it to be "results" so I can handle it on on the calling side in a more modular way.
In the SELECT at the bottom, "AS results" didn't help. I also tried writing it in plpgsql but that didn't give me any finer-grained control over this.
Here's the code that calls the PostgreSQL function...
import pg from 'pg'
const pgNativePool = new pg.native.Pool({
max: 10, // default
connectionString: <string> import.meta.env.VITE_DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
})
type QueryResponse = (sql: string, params?: Array<number|string|boolean|StudioLocation>) => Promise<pg.QueryResult<any>>
const query: QueryResponse = (sql: string, params?: Array<number|string|boolean>) => pgNativePool.query(sql, params)
type FindLocationsResponse = (searchText: string | null, currentPage: number | null, pageSize: number | null, sortBy: string | null, direction: string | null) => Promise<{ body: ClassSearchResults }>
const find: FindLocationsResponse = async (searchText, currentPage, pageSize, sortBy, direction) => {
const sql = `SELECT * FROM find_classes(search_text:=$1, current_page:=$2, page_size:=$3, sort_by:=$4, direction:=$5);`
const { rows } = await query(sql, [searchText, currentPage, pageSize, sortBy, direction])
return { body: <ClassSearchResults> rows[0].find_classes }
}
Any idea how to change the column name returned?
