Commit 9b6d7662 authored by Massimo Costantini's avatar Massimo Costantini
Browse files

Unified structure

parent 20ab7ad1
Loading
Loading
Loading
Loading
+9 −9
Original line number Original line Diff line number Diff line
@@ -51,9 +51,9 @@ const IVOA_capabilitiesEndpoint = staticEndpoint("Stat/capabilities.xml");
 */
 */
const IVOA_tablesEndpoint = (req) => async (IO) => {
const IVOA_tablesEndpoint = (req) => async (IO) => {
  const query = await readFile("Query/tables.sql")(IO);
  const query = await readFile("Query/tables.sql")(IO);
  const conn = await connPostgreSQL()(IO);
  const pg = await connPostgreSQL()(IO);
  const result = await fetchQueryResult(conn, query, [])(IO);
  const result = await fetchQueryResult(pg, query, [])(IO);
  await quitPostgreSQL(conn)(IO);
  await quitPostgreSQL(pg)(IO);


  if (result.tag === "nothing") {
  if (result.tag === "nothing") {
    return '<?xml version="1.0" encoding="UTF-8"?><error>No tables found</error>';
    return '<?xml version="1.0" encoding="UTF-8"?><error>No tables found</error>';
@@ -96,9 +96,9 @@ const IVOA_syncEndpoint = (req) => async (IO) => {
  }
  }


  // Execute the SQL query
  // Execute the SQL query
  const conn = await connPostgreSQL()(IO);
  const pg = await connPostgreSQL()(IO);
  const result = await fetchQueryResult(conn, query, [])(IO);
  const result = await fetchQueryResult(pg, query, [])(IO);
  await quitPostgreSQL(conn)(IO);
  await quitPostgreSQL(pg)(IO);


  if (!result || result.tag === "nothing" || !result.value) {
  if (!result || result.tag === "nothing" || !result.value) {
    return makeSyncError("No results");
    return makeSyncError("No results");
@@ -314,9 +314,9 @@ export const datalinkTransitsEndpoint = (req) => async (IO) => {


  // SQL query to fetch transits for a given source_id
  // SQL query to fetch transits for a given source_id
  const sql = await readFile("Query/transits.sql")(IO);
  const sql = await readFile("Query/transits.sql")(IO);
  const conn = await connPostgreSQL()(IO);
  const pg = await connPostgreSQL()(IO);
  const result = await fetchQueryResult(conn, sql, [sourceId])(IO);
  const result = await fetchQueryResult(pg, sql, [sourceId])(IO);
  await quitPostgreSQL(conn)(IO);
  await quitPostgreSQL(pg)(IO);


  if (result.tag === "nothing") {
  if (result.tag === "nothing") {
    return makeDatalinkError(`No transits found for source_id ${sourceId}`);
    return makeDatalinkError(`No transits found for source_id ${sourceId}`);
+9 −9
Original line number Original line Diff line number Diff line
@@ -67,9 +67,9 @@ def ivoa_tables_endpoint(req) -> Callable[[object], Awaitable[str]]:


    async def inner(io):
    async def inner(io):
        query = await read_file("Query/tables.sql")(io)
        query = await read_file("Query/tables.sql")(io)
        conn = await conn_postgresql()(io)
        pg = await conn_postgresql()(io)
        result = await fetch_query_result(conn, query, [])(io)
        result = await fetch_query_result(pg, query, [])(io)
        await quit_postgresql(conn)(io)
        await quit_postgresql(pg)(io)


        if result["tag"] == "nothing":
        if result["tag"] == "nothing":
            return (
            return (
@@ -120,9 +120,9 @@ def ivoa_sync_endpoint(req) -> Callable[[object], Awaitable[str]]:
            )
            )


        # Execute the SQL query
        # Execute the SQL query
        conn = await conn_postgresql()(io)
        pg = await conn_postgresql()(io)
        result = await fetch_query_result(conn, query, [])(io)
        result = await fetch_query_result(pg, query, [])(io)
        await quit_postgresql(conn)(io)
        await quit_postgresql(pg)(io)


        if result["tag"] == "nothing":
        if result["tag"] == "nothing":
            return make_sync_error("No results")
            return make_sync_error("No results")
@@ -343,9 +343,9 @@ def ivoa_transits_endpoint(req) -> Callable[[object], Awaitable[str]]:


        # SQL query to fetch transits for a given source_id
        # SQL query to fetch transits for a given source_id
        query = await read_file("Query/transits.sql")(io)
        query = await read_file("Query/transits.sql")(io)
        conn = await conn_postgresql()(io)
        pg = await conn_postgresql()(io)
        result_query = await fetch_query_result(conn, query, [int(source_id)])(io)
        result_query = await fetch_query_result(pg, query, [int(source_id)])(io)
        await quit_postgresql(conn)(io)
        await quit_postgresql(pg)(io)


        if result_query["tag"] == "nothing":
        if result_query["tag"] == "nothing":
            return make_datalink_error(f"No transits found for source_id {source_id}")
            return make_datalink_error(f"No transits found for source_id {source_id}")
+4 −4
Original line number Original line Diff line number Diff line
@@ -33,19 +33,19 @@ export const IO = Symbol("IO");
 * Functional signature: ((Symbol) -> a) -> a
 * Functional signature: ((Symbol) -> a) -> a
 *
 *
 * @param {function(Symbol): any} f - A CPS function expecting an IO token
 * @param {function(Symbol): any} f - A CPS function expecting an IO token
 * @returns {*} - The result of applying the function to the "IO world"
 * @returns {*} - The result of applying the function to the IO world
 */
 */
export function createIO(f) {
export function createIO(f) {
  return f(IO);
  return f(IO);
}
}


/**
/**
 * Alias for createIO which semantically marks a point where an effect is executed.
 * Semantically marks a point where an effectful IO computation is performed.
 *
 *
 * Functional signature: ((Symbol) -> IO a) -> IO a
 * Functional signature: ((IO) -> IO a) -> IO a
 *
 *
 * @param {function(Symbol): any} f - A CPS function
 * @param {function(Symbol): any} f - A CPS function
 * @returns {*} - The result of the function performing IO operations
 * @returns {*} - A CPS IO action that performs the given effectful computation
 */
 */
export function performIO(f) {
export function performIO(f) {
  return createIO((w) => f(w));
  return createIO((w) => f(w));
+12 −4
Original line number Original line Diff line number Diff line
@@ -15,7 +15,7 @@ class InternalError(Exception):
    Functional signature: String -> InternalError
    Functional signature: String -> InternalError


    Args:
    Args:
        message (str): The error message to associate with the exception.
        message (str): The error message.
    """
    """


    def __init__(self, message: str):
    def __init__(self, message: str):
@@ -26,9 +26,12 @@ class InternalError(Exception):
        return f"InternalError: {self.message}"
        return f"InternalError: {self.message}"




# Token representing the 'IO world' in an implicit continuation-passing style.
# Functional signature: Symbol
IO = object()
IO = object()
"""
Token representing the 'IO world' in an implicit continuation-passing style.

Functional signature: Symbol
"""




def create_io(f: Callable[[object], Any]) -> Any:
def create_io(f: Callable[[object], Any]) -> Any:
@@ -91,7 +94,7 @@ def read_file(path: str) -> Callable[[object], Awaitable[str]]:
        path: Path to the file.
        path: Path to the file.


    Returns:
    Returns:
        Callable[[object], Awaitable[str]]: A CPS IO action that reads the file contents and returns them as a string.
        Callable[[object], Awaitable[str]]: A CPS IO action that reads the file content and returns it as a string.
    """
    """


    async def inner(io: object) -> str:
    async def inner(io: object) -> str:
@@ -102,6 +105,11 @@ def read_file(path: str) -> Callable[[object], Awaitable[str]]:




nothing = {"tag": "nothing"}
nothing = {"tag": "nothing"}
"""
Represents the absence of a value.

Functional signature: Maybe a
"""




def just(value: Any) -> dict:
def just(value: Any) -> dict:
+3 −26
Original line number Original line Diff line number Diff line
@@ -14,7 +14,7 @@ import config from "../Conf/PostgreSQL.json" with { type: "json" };
const { Client } = pkg;
const { Client } = pkg;


/**
/**
 * @typedef {import("pg").Client} PGConn - A PostgreSQL connection in the CPS model
 * @typedef {object} PGConn - A PostgreSQL connection in the CPS model
 */
 */


/**
/**
@@ -22,7 +22,7 @@ const { Client } = pkg;
 *
 *
 * Functional signature: () -> IO -> IO PGConn
 * Functional signature: () -> IO -> IO PGConn
 *
 *
 * @returns {function(Symbol): Promise<PGConn>} - A CPS IO action that returns a connected PostgreSQL connection
 * @returns {function(Symbol): Promise<PGConn>} - A CPS IO action that returns a PostgreSQL connection
 * @throws {InternalError} - If the connection fails
 * @throws {InternalError} - If the connection fails
 */
 */
export function connPostgreSQL() {
export function connPostgreSQL() {
@@ -38,29 +38,6 @@ export function connPostgreSQL() {
  };
  };
}
}


/**
 * Executes an SQL query with parameters, returning no result.
 *
 * Functional signature: PGConn -> String -> [String] -> IO -> IO ()
 *
 * @param {PGConn} conn - A connected PostgreSQL client
 * @param {string} sql - The SQL statement
 * @param {Array<string>} params - A list of parameters to bind
 * @returns {function(Symbol): Promise<Symbol>} - A CPS IO action that executes an SQL query without returning any result
 * @throws {InternalError} - If the query execution fails
 */
export function execQuery(conn, sql, params) {
  return async (IO) => {
    try {
      await conn.query(sql, params);
      await putStr("Query executed")(IO);
      return IO;
    } catch (err) {
      throw new InternalError("Execution failed: " + err.message);
    }
  };
}

/**
/**
 * Executes an SQL query and returns both field metadata and row data.
 * Executes an SQL query and returns both field metadata and row data.
 *
 *
@@ -100,7 +77,7 @@ export function fetchQueryResult(conn, sql, params) {
 * Functional signature: PGConn -> IO -> IO ()
 * Functional signature: PGConn -> IO -> IO ()
 *
 *
 * @param {PGConn} conn - A connected PostgreSQL client
 * @param {PGConn} conn - A connected PostgreSQL client
 * @returns {function(Symbol): Promise<Symbol>} - A CPS IO action that closes the PostgreSQL connection
 * @returns {function(Symbol): Promise<Symbol>} - A CPS IO action that closes the PostgreSQL connection and returns the IO token
 */
 */
export function quitPostgreSQL(conn) {
export function quitPostgreSQL(conn) {
  return async (IO) => {
  return async (IO) => {
Loading