Commit 64221327 authored by Massimo Costantini's avatar Massimo Costantini
Browse files

Updated comments

parent aad76ef3
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import { v4 as uuidv4 } from "uuid";
 * Functional signature: Request -> IO -> IO String
 *
 * @param {Request} req - Incoming HTTP request
 * @returns {function(Symbol): Promise<string>} - HTML content
 * @returns {function(Symbol): Promise<string>} - HTML content (or throws on error)
 */
const IVOA_tapEndpoint = (req) => async (IO) => {
  return await readFile("Stat/tap.html")(IO);
@@ -167,7 +167,7 @@ const IVOA_syncEndpoint = (req) => async (IO) => {
 *
 * Functional signature: String -> IO -> IO String
 *
 * @param {string} message - Error message to embed in VOTable
 * @param {string} message - Error message to embed in the VOTable
 * @returns {(IO) => Promise<string>} - A CPS IO action returning an XML error document
 */
function makeSyncError(message) {
@@ -191,7 +191,7 @@ function makeSyncError(message) {
 * Functional signature: IO -> IO ()
 *
 * @param {Symbol} IO - IO token
 * @returns {Promise<void>} - Starts the server and binds all routes
 * @returns {Promise<void>} - A CPS IO action that starts the server and binds all routes
 */
const IVOA_main = () => async (IO) => {
  const port = await readRESTPort(IO);
+10 −13
Original line number Diff line number Diff line
@@ -13,8 +13,8 @@ from typing import Awaitable, Callable
from xml.dom import minidom

import asyncio
import uuid
import xml.etree.ElementTree as ET
import uuid


def ivoa_tap_endpoint(req) -> Callable[[object], Awaitable[str]]:
@@ -27,7 +27,7 @@ def ivoa_tap_endpoint(req) -> Callable[[object], Awaitable[str]]:
        req: Incoming HTTP request.

    Returns:
        A function that takes an IO token and returns an awaitable HTML string.
        Callable[[object], Awaitable[str]]: A CPS IO action that returns HTML content (or raises on error).
    """

    def inner(io):
@@ -46,7 +46,7 @@ def ivoa_availability_endpoint(req) -> Callable[[object], Awaitable[str]]:
        req: Incoming HTTP request.

    Returns:
        A function that takes an IO token and returns an awaitable XML string.
        Callable[[object], Awaitable[str]]: A CPS IO action that returns XML content (or raises on error).
    """

    def inner(io):
@@ -65,7 +65,7 @@ def ivoa_capabilities_endpoint(req) -> Callable[[object], Awaitable[str]]:
        req: Incoming HTTP request.

    Returns:
        A function that takes an IO token and returns an awaitable XML string.
        Callable[[object], Awaitable[str]]: A CPS IO action that returns XML content (or raises on error).
    """

    def inner(io):
@@ -84,7 +84,7 @@ def ivoa_tables_endpoint(req) -> Callable[[object], Awaitable[str]]:
        req: Incoming HTTP request.

    Returns:
        A function that takes an IO token and returns an awaitable XML VOTable string.
        Callable[[object], Awaitable[str]]: A CPS IO action that returns VOTable XML content or an error message.
    """

    async def inner(io):
@@ -115,7 +115,7 @@ def make_sync_error(message: str) -> Callable[[object], Awaitable[str]]:
        message: Error message to embed in the VOTable.

    Returns:
        A CPS IO action that returns the XML error document.
        Callable[[object], Awaitable[str]]: A CPS IO action returning an XML error document.
    """

    async def inner(io):
@@ -132,7 +132,6 @@ def make_sync_error(message: str) -> Callable[[object], Awaitable[str]]:
        ET.SubElement(
            resource, "INFO", {"name": "QUERY_STATUS", "value": "ERROR"}
        ).text = message

        xml_str = ET.tostring(votable, encoding="utf-8")
        return minidom.parseString(xml_str).toprettyxml(indent="  ")

@@ -149,7 +148,7 @@ def ivoa_sync_endpoint(req) -> Callable[[object], Awaitable[str]]:
        req: Incoming HTTP request.

    Returns:
        A function that takes an IO token and returns an awaitable VOTable XML string.
        Callable[[object], Awaitable[str]]: A CPS IO action that returns VOTable XML content or an error message.
    """

    async def inner(io):
@@ -179,7 +178,7 @@ def ivoa_sync_endpoint(req) -> Callable[[object], Awaitable[str]]:
        await quit_postgresql(conn)(io)

        if result["tag"] == "nothing":
            return await make_sync_error("No results")(io)
            return await make_sync_error("No results.")(io)

        fields = result["value"]["fields"]
        rows = result["value"]["rows"]
@@ -203,7 +202,6 @@ def ivoa_sync_endpoint(req) -> Callable[[object], Awaitable[str]]:
        ET.SubElement(
            table, "FIELD", {"name": "access_url", "datatype": "char", "arraysize": "*"}
        )

        data = ET.SubElement(ET.SubElement(table, "DATA"), "TABLEDATA")

        for row in rows:
@@ -224,7 +222,6 @@ def ivoa_sync_endpoint(req) -> Callable[[object], Awaitable[str]]:
            ET.SubElement(tr, "TD").text = access_url

        await quit_redis(redis)(io)

        xml_str = ET.tostring(votable, encoding="utf-8")
        return minidom.parseString(xml_str).toprettyxml(indent="  ")

@@ -238,7 +235,7 @@ def ivoa_main() -> Callable[[object], Awaitable[None]]:
    Functional signature: IO -> IO ()

    Returns:
        A CPS IO action that takes the IO token and starts the IVOA server.
        Callable[[object], Awaitable[None]]: A CPS IO action that starts the server and binds all routes.
    """

    async def inner(io):
@@ -266,7 +263,7 @@ def main_expression() -> Callable[[object], Awaitable[None]]:
    Functional signature: () -> IO ()

    Returns:
        A CPS IO action that launches the main TAP and DataLink server logic.
        Callable[[object], Awaitable[None]]: A CPS IO action that launches the main TAP and DataLink server logic.
    """
    return ivoa_main()

+9 −9
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ export const IO = Symbol("IO");
/**
 * Applies an implicit CPS IO continuation to the IO token.
 *
 * Functional signature: ((Symbol) -> a) -> a)
 * Functional signature: ((Symbol) -> a) -> a
 *
 * @param {function(Symbol): any} f - A CPS function expecting an IO token
 * @returns {*} - The result of applying the function to the "IO world"
@@ -37,7 +37,7 @@ export function createIO(f) {
/**
 * Alias for createIO which semantically marks a point where an effect is executed.
 *
 * Functional signature: ((Symbol) -> a) -> a)
 * Functional signature: ((Symbol) -> IO a) -> IO a
 *
 * @param {function(Symbol): any} f - A CPS function
 * @returns {*} - The result of the function performing IO operations
@@ -49,10 +49,10 @@ export function performIO(f) {
/**
 * Prints a string to the console.
 *
 * Functional signature: String -> IO -> IO)
 * Functional signature: String -> IO -> IO ()
 *
 * @param {string} x - Text to print
 * @returns {function(Symbol): Promise<Symbol>} - A CPS IO action that prints a string to the console
 * @returns {function(Symbol): Promise<Symbol>} - A CPS IO action that prints a string and returns the IO token
 */
export const putStr = (x) => async (IO) => {
  console.log(x);
@@ -62,10 +62,10 @@ export const putStr = (x) => async (IO) => {
/**
 * Reads the contents of a file as UTF-8.
 *
 * Functional signature: String -> IO -> IO String)
 * Functional signature: String -> IO -> IO String
 *
 * @param {string} path - Path to the file
 * @returns {function(Symbol): Promise<string>} - A CPS IO action that reads the contents of a file as a UTF-8 string
 * @returns {function(Symbol): Promise<string>} - A CPS IO action that reads the file content and returns it as a string
 */
export const readFile = (path) => async (IO) => {
  return await fs.readFile(path, "utf-8");
@@ -74,7 +74,7 @@ export const readFile = (path) => async (IO) => {
/**
 * Represents the absence of a value.
 *
 * Functional signature: Maybe a)
 * Functional signature: Maybe a
 *
 * @const
 * @type {{tag: "nothing"}}
@@ -82,9 +82,9 @@ export const readFile = (path) => async (IO) => {
export const nothing = { tag: "nothing" };

/**
 * Wraps a value into a 'just' tagged union
 * Wraps a value into a 'just' tagged union.
 *
 * Functional signature: a -> Maybe a)
 * Functional signature: a -> Maybe a
 *
 * @param {*} value - The value to wrap
 * @returns {{tag: "just", value: *}} - A tagged value
+6 −7
Original line number Diff line number Diff line
@@ -5,8 +5,7 @@
# - pip install aiofiles

import aiofiles

from typing import Callable, Awaitable, Any
from typing import Any, Awaitable, Callable


class InternalError(Exception):
@@ -38,7 +37,7 @@ def create_io(f: Callable[[object], Any]) -> Any:
        f: A CPS function expecting the IO token.

    Returns:
        The result of applying the function to the IO world.
        Any: The result of applying the function to the IO world.
    """
    return f(IO)

@@ -53,7 +52,7 @@ def perform_io(f: Callable[[object], Awaitable[Any]]) -> Awaitable[Any]:
        f: A CPS function.

    Returns:
        The result of the function performing IO operations.
        Awaitable[Any]: The result of the function performing IO operations.
    """
    return create_io(lambda w: f(w))

@@ -68,7 +67,7 @@ def put_str(x: str) -> Callable[[object], Awaitable[object]]:
        x: Text to print.

    Returns:
        A CPS IO action that prints the string.
        Callable[[object], Awaitable[object]]: A CPS IO action that prints the string and returns the IO token.
    """

    async def inner(io: object) -> object:
@@ -88,7 +87,7 @@ def read_file(path: str) -> Callable[[object], Awaitable[str]]:
        path: Path to the file.

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

    async def inner(io: object) -> str:
@@ -111,6 +110,6 @@ def just(value: Any) -> dict:
        value: The value to wrap.

    Returns:
        A tagged value {'tag': 'just', 'value': *}.
        dict: A tagged value {'tag': 'just', 'value': *}.
    """
    return {"tag": "just", "value": value}
+5 −7
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@ import { putStr } from "./IO.js";
import { just, nothing } from "./IO.js";

import pkg from "pg";

import config from "../Conf/PostgreSQL.json" with { type: "json" };

const { Client } = pkg;
@@ -21,12 +20,11 @@ const { Client } = pkg;
/**
 * Connects to the PostgreSQL server using parameters from the config file.
 *
 * Functional signature: () -> IO PGConn)
 * Functional signature: () -> IO -> IO PGConn
 *
 * @returns {function(Symbol): Promise<PGConn>} - A CPS IO action that returns a connected PostgreSQL connection
 * @throws {InternalError} - If the connection fails
 */

export function connPostgreSQL() {
  return async (IO) => {
    const conn = new Client(config);
@@ -43,7 +41,7 @@ export function connPostgreSQL() {
/**
 * Executes an SQL query with parameters, returning no result.
 *
 * Functional signature: PGConn -> String -> List String -> IO ())
 * Functional signature: PGConn -> String -> [String] -> IO -> IO ()
 *
 * @param {PGConn} conn - A connected PostgreSQL client
 * @param {string} sql - The SQL statement
@@ -66,12 +64,12 @@ export function execQuery(conn, sql, params) {
/**
 * Executes an SQL query and returns both field metadata and row data.
 *
 * Functional signature: PGConn -> String -> List String -> IO (Maybe { fields, rows}))
 * Functional signature: PGConn -> String -> [String] -> IO -> IO (Maybe { fields, rows })
 *
 * @param {PGConn} conn - A connected PostgreSQL client
 * @param {string} sql - The SQL query
 * @param {Array<string>} params - A list of parameters to bind
 * @returns {function(Symbol): Promise<{ tag: "just", value: { fields, rows } } | { tag: "nothing" }>} - A CPS IO action that returns query result wrapped in a Maybe
 * @returns {function(Symbol): Promise<{ tag: "just", value: { fields: Array, rows: Array } } | { tag: "nothing" }>} - A CPS IO action that returns query result wrapped in a Maybe
 * @throws {InternalError} - If the query fails
 */
export function fetchQueryResult(conn, sql, params) {
@@ -99,7 +97,7 @@ export function fetchQueryResult(conn, sql, params) {
/**
 * Closes the PostgreSQL connection.
 *
 * Functional signature: PGConn -> IO ())
 * Functional signature: PGConn -> IO -> IO ()
 *
 * @param {PGConn} conn - A connected PostgreSQL client
 * @returns {function(Symbol): Promise<Symbol>} - A CPS IO action that closes the PostgreSQL connection
Loading