From ba65c95d22f92b36577b06f5df49d2ac12cf8a05 Mon Sep 17 00:00:00 2001 From: Martin Nilsson <mani@lysator.liu.se> Date: Thu, 6 Sep 2001 20:52:55 +0200 Subject: [PATCH] Autodoc Rev: lib/modules/Sql.pmod/Sql.pike:1.51 Rev: lib/modules/Sql.pmod/postgres.pike:1.14 Rev: lib/modules/Sql.pmod/postgres_result.pike:1.5 --- lib/modules/Sql.pmod/Sql.pike | 165 ++++++++-------- lib/modules/Sql.pmod/postgres.pike | 231 +++++++++++++++++++++- lib/modules/Sql.pmod/postgres_result.pike | 3 + 3 files changed, 310 insertions(+), 89 deletions(-) diff --git a/lib/modules/Sql.pmod/Sql.pike b/lib/modules/Sql.pmod/Sql.pike index bcb43e917b..0c066407e8 100644 --- a/lib/modules/Sql.pmod/Sql.pike +++ b/lib/modules/Sql.pmod/Sql.pike @@ -1,5 +1,5 @@ /* - * $Id: Sql.pike,v 1.50 2001/08/24 12:39:15 grubba Exp $ + * $Id: Sql.pike,v 1.51 2001/09/06 18:52:55 nilsson Exp $ * * Implements the generic parts of the SQL-interface * @@ -8,17 +8,7 @@ #pike __REAL_VERSION__ -//. -//. File: sql.pike -//. RCSID: $Id: Sql.pike,v 1.50 2001/08/24 12:39:15 grubba Exp $ -//. Author: Henrik Grubbstr�m (grubba@roxen.com) -//. -//. Synopsis: Implements the generic parts of the SQL-interface. -//. -//. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -//. -//. Implements those functions that need not be present in all SQL-modules. -//. +//! Implements those functions that need not be present in all SQL-modules. #define throw_error(X) throw(({ (X), backtrace() })) @@ -85,26 +75,33 @@ function(int:string) encode_datetime; function(string:int) decode_datetime; -//! Create a new generic SQL object. +//! Create a new generic SQL object. //! //! @param host -//! object - Use this object to access the SQL-database. -//! string - Connect to the server specified. -//! The string should be on the format: -//! @tt{dbtype://[user[:password]@@]hostname[:port][/database]@} -//! Use the dbtype protocol to connect to the database server -//! on the specified host. -//! If the hostname is @tt{""@}, access through a UNIX-domain -//! socket or similar. -//! zero - Access through a UNIX-domain socket or similar. +//! @mixed +//! @type object +//! Use this object to access the SQL-database. +//! @type string +//! Connect to the server specified. +//! The string should be on the format: +//! @tt{dbtype://[user[:password]@@]hostname[:port][/database]@} +//! Use the dbtype protocol to connect to the database server +//! on the specified host. +//! If the hostname is @tt{""@}, access through a UNIX-domain +//! socket or similar. +//! @type int(0..0) +//! Access through a UNIX-domain socket or similar. +//! @endmixed //! //! @param database //! Select this database. //! //! @param user //! User name to access the database as. +//! //! @param password //! Password to access the database. +//! //! @note //! In versions of Pike prior to 7.2 it was possible to leave out the //! dbtype, but that has been deprecated, since it never worked well. @@ -248,8 +245,7 @@ static private array(mapping(string:mixed)) res_obj_to_array(object res_obj) return 0; } -//! - error -//! Return last error message. +//! Return last error message. int|string error() { if (functionp (master_sql->error)) @@ -257,18 +253,17 @@ int|string error() return "Unknown error"; } -//! - select_db -//! Select database to access. +//! Select database to access. void select_db(string db) { master_sql->select_db(db); } -//! - compile_query -//! Compiles the query (if possible). Otherwise returns it as is. -//! The resulting object can be used multiple times in query() and -//! big_query(). -//! > q +//! Compiles the query (if possible). Otherwise returns it as is. +//! The resulting object can be used multiple times in query() and +//! big_query(). +//! +//! @param q //! SQL-query to compile. string|object compile_query(string q) { @@ -278,8 +273,7 @@ string|object compile_query(string q) return(q); } -//! - handle_extraargs -//! Handle sprintf-based quoted arguments +//! Handle sprintf-based quoted arguments private array(string|mapping(string|int:mixed)) handle_extraargs(string query, array(mixed) extraargs) { array(mixed) args=allocate(sizeof(extraargs)); mixed s; @@ -302,26 +296,35 @@ private array(string|mapping(string|int:mixed)) handle_extraargs(string query, a return ({sprintf(query,@args), b}); } -//. - query -//. Send an SQL query to the underlying SQL-server. The result is returned -//. as an array of mappings indexed on the name of the columns. -//. Returns 0 if the query didn't return any result (e.g. INSERT or similar). -//. > q -//. Query to send to the SQL-server. This can either be a string with the -//. query, or a previously compiled query (see compile_query()). -//. > extraargs -//. This parameter, if specified, can be in two forms: -//. 1) a mapping containing bindings of variables used in the query. -//. A variable is identified by a colon (:) followed by a name or number. -//. Each index in the mapping corresponds to one such variable, and the -//. value for that index is substituted (quoted) into the query wherever -//. the variable is used. -//. (i.e. query("select foo from bar where gazonk=:baz", -//. ([":baz":"value"])) ) -//. Binary values (BLOBs) may need to be placed in multisets. -//. 2) arguments as you would use in sprintf. They are automatically -//. quoted. -//. (i.e. query("select foo from bar where gazonk=%s","value") ) +//! Send an SQL query to the underlying SQL-server. The result is returned +//! as an array of mappings indexed on the name of the columns. +//! Returns 0 if the query didn't return any result (e.g. INSERT or similar). +//! +//! @param q +//! Query to send to the SQL-server. This can either be a string with the +//! query, or a previously compiled query (see compile_query()). +//! @param extraargs +//! This parameter, if specified, can be in two forms: +//! +//! @ol +//! @item +//! A mapping containing bindings of variables used in the query. +//! A variable is identified by a colon (:) followed by a name or number. +//! Each index in the mapping corresponds to one such variable, and the +//! value for that index is substituted (quoted) into the query wherever +//! the variable is used. +//! +//! @code{ query("select foo from bar where gazonk=:baz", +//! ([":baz":"value"])) ) @} +//! +//! Binary values (BLOBs) may need to be placed in multisets. +//! +//! @item +//! Arguments as you would use in sprintf. They are automatically +//! quoted. +//! +//! @code{ query("select foo from bar where gazonk=%s","value") ) @} +//! @endol array(mapping(string:mixed)) query(object|string q, mixed ... extraargs) { @@ -347,12 +350,11 @@ array(mapping(string:mixed)) query(object|string q, } } -//! - big_query -//! Send an SQL query to the underlying SQL-server. The result is returned -//! as a Sql.sql_result object. This allows for having results larger than -//! the available memory, and returning some more info about the result. -//! Returns 0 if the query didn't return any result (e.g. INSERT or similar). -//! For the other arguments, they are the same as the query() function. +//! Send an SQL query to the underlying SQL-server. The result is returned +//! as a Sql.sql_result object. This allows for having results larger than +//! the available memory, and returning some more info about the result. +//! Returns 0 if the query didn't return any result (e.g. INSERT or similar). +//! For the other arguments, they are the same as the query() function. int|object big_query(object|string q, mixed ... extraargs) { object|array(mapping) pre_res; @@ -380,26 +382,25 @@ int|object big_query(object|string q, mixed ... extraargs) return(pre_res && Sql.sql_result(pre_res)); } -//! - create_db -//! Create a new database. -//! > db +//! Create a new database. +//! +//! @param db //! Name of database to create. void create_db(string db) { master_sql->create_db(db); } -//! - drop_db -//! Drop database -//! > db +//! Drop database +//! +//! @param db //! Name of database to drop. void drop_db(string db) { master_sql->drop_db(db); } -//! - shutdown -//! Shutdown a database server. +//! Shutdown a database server. void shutdown() { if (functionp(master_sql->shutdown)) { @@ -409,8 +410,7 @@ void shutdown() } } -//! - reload -//! Reload the tables. +//! Reload the tables. void reload() { if (functionp(master_sql->reload)) { @@ -420,8 +420,7 @@ void reload() } } -//! - server_info -//! Return info about the current SQL-server. +//! Return info about the current SQL-server. string server_info() { if (functionp(master_sql->server_info)) { @@ -430,8 +429,7 @@ string server_info() return("Unknown SQL-server"); } -//! - host_info -//! Return info about the connection to the SQL-server. +//! Return info about the connection to the SQL-server. string host_info() { if (functionp(master_sql->host_info)) { @@ -440,9 +438,9 @@ string host_info() return("Unknown connection to host"); } -//! - list_dbs -//! List available databases on this SQL-server. -//! > wild +//! List available databases on this SQL-server. +//! +//! @param wild //! Optional wildcard to match against. array(string) list_dbs(string|void wild) { @@ -467,9 +465,9 @@ array(string) list_dbs(string|void wild) return(res); } -//! - list_tables -//! List tables available in the current database. -//! > wild +//! List tables available in the current database. +//! +//! @param wild //! Optional wildcard to match against. array(string) list_tables(string|void wild) { @@ -494,11 +492,12 @@ array(string) list_tables(string|void wild) return(res); } -//! - list_fields -//! List fields available in the specified table -//! > table +//! List fields available in the specified table +//! +//! @param table //! Table to list the fields of. -//! > wild +//! +//! @param wild //! Optional wildcard to match against. array(mapping(string:mixed)) list_fields(string table, string|void wild) { diff --git a/lib/modules/Sql.pmod/postgres.pike b/lib/modules/Sql.pmod/postgres.pike index b0091bffbb..c4fe74eaec 100644 --- a/lib/modules/Sql.pmod/postgres.pike +++ b/lib/modules/Sql.pmod/postgres.pike @@ -2,10 +2,52 @@ * This is part of the Postgres module for Pike. * (C) 1997 Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it> * - * $Id: postgres.pike,v 1.13 2001/09/06 14:43:27 nilsson Exp $ + * $Id: postgres.pike,v 1.14 2001/09/06 18:52:55 nilsson Exp $ * */ +//! This is an interface to the Postgres (Postgres95, pgsql) database server. +//! This module may or may not be availible on your Pike, depending +//! whether the appropriate include and library files +//! could be found at compile-time. Note that you @b{do not@} +//! need to have a Postgres server running on your host to use this module: +//! you can connect to the database over a TCP/IP socket. +//! +//! @note +//! Also note that @b{this module uses blocking I/O@} I/O to connect to the server. +//! Postgres is quite slow, and so you might want to consider this +//! particular aspect. It is (at least should be) thread-safe, and so it can be used +//! in a multithread environment. +//! +//! The behavior of the Postgres C API also depends on certain environment variables +//! defined in the environment of the pike interpreter. +//! +//! @string +//! @value "PGHOST" +//! Sets the name of the default host to connect to. It defaults +//! to "localhost" +//! @value "PGOPTIONS" +//! Sets some extra flags for the frontend-backend connection. +//! DO NOT SET unless you're sure of what you're doing. +//! @value "PGPORT" +//! Sets the default port to connect to, otherwise it will use +//! compile-time defaults (that is: the time you compiled the postgres +//! library, not the Pike driver). +//! @value "PGTTY" +//! Sets the file to be used for Postgres frontend debugging. +//! Do not use, unless you're sure of what you're doing. +//! @value "PGDATABASE" +//! Sets the default database to connect to. +//! @value "PGREALM" +//! Sets the default realm for Kerberos authentication. I never used +//! this, so I can't help you. +//! @endstring +//! +//! Refer to the Postgres documentation for further details. +//! +//! @seealso +//! Sql.Sql, Postgres.postgres, Sql.postgres_result + #pike __REAL_VERSION__ #if constant(Postgres.postgres) @@ -15,6 +57,49 @@ inherit Postgres.postgres: mo; private static mixed callout; +//! @decl void select_db(string dbname) +//! +//! This function allows you to connect to a database. Due to restrictions +//! of the Postgres frontend-backend protocol, you always have to be connected +//! to a database, so in fact this function just allows you to connect +//! to a different database on the same server. +//! +//! @note +//! This function @b{can@} raise exceptions if something goes wrong (backend process +//! not running, not enough permissions..) +//! +//! @seealso +//! create + +//! @decl string error() +//! +//! This function returns the textual description of the last server-related +//! error. Returns 0 if no error has occurred yet. It is not cleared upon +//! reading (can be invoked multiple times, will return the same result +//! until a new error occurs). +//! +//! @seealso +//! big_query + +//! @decl string host_info() +//! +//! This function returns a string describing what host are we talking to, +//! and how (TCP/IP or UNIX sockets). + +//! @decl void reset() +//! +//! This function resets the connection to the backend. Can be used for +//! a variety of reasons, for example to detect the status of a connection. +//! +//! @note +//! This function is Postgres-specific, and thus it is not availible +//! through the generic SQL-interface. + +//! @decl string version +//! +//! Should you need to report a bug to the author, please submit along with +//! the report the driver version number, as returned by this call. + private static string glob_to_regexp (string glob) { if (!glob||!sizeof(glob)) return 0; @@ -27,6 +112,41 @@ static private int mkbool(string s) { return 1; } +//! @decl void create() +//! @decl void create(string host, void|string database, void|string user, void|string password) +//! +//! With no arguments, this function initializes (reinitializes if a connection +//! had been previously set up) a connection to the Postgres backend. +//! Since Postgres requires a database to be selected, it will try +//! to connect to the default database. The connection may fail however for a +//! variety of reasons, in this case the most likely of all is because +//! you don't have enough authority to connect to that database. +//! So use of this particular syntax is discouraged. +//! +//! The host argument can have the syntax "hostname" or "hostname:portname". +//! This allows to specify the TCP/IP port to connect to. If it is 0 or "", it +//! will try to connect to localhost, default port. +//! +//! The database argument specifies the database to connect to. If 0 or "", it +//! will try to connect to the specified database. +//! +//! The username and password arguments are silently ignored, since the Postgres +//! C API doesn't allow to connect to the server as any user different than the +//! user running the interface. +//! +//! @note +//! You need to have a database selected before using the sql-object, +//! otherwise you'll get exceptions when you try to query it. +//! Also notice that this function @b{can@} raise exceptions if the db +//! server doesn't respond, if the database doesn't exist or is not accessible +//! by you. +//! +//! You don't need bothering about syncronizing the connection to the database: +//! it is automatically closed (and the database is sync-ed) when the +//! object is destroyed. +//! +//! @seealso +//! Postgres.postgres, Sql.Sql, postgres->select_db void create(void|string host, void|string database, void|string user, void|string pass) { string real_host=host, real_db=database; @@ -44,6 +164,44 @@ static void poll (int delay) big_query(""); } +//! @decl void set_notify_callback() +//! @decl void set_notify_callback(function f) +//! @decl void set_notify_callback(function f, int|float poll_delay) +//! +//! With Postgres you can associate events and notifications to tables. +//! This function allows you to detect and handle such events. +//! +//! With no arguments, resets and removes any callback you might have +//! put previously, and any polling cycle. +//! +//! With one argument, sets the notification callback (there can be only +//! one for each sqlobject). +//! +//! With two arguments, sets a notification callback and sets a polling +//! cycle. +//! +//! The polling cycle is necessary because of the way notifications are +//! delivered, that is piggyback with a query result. This means that +//! if you don't do any query, you'll receive no notification. The polling +//! cycle starts a call_out cycle which will do an empty query when +//! the specified interval expires, so that pending notifications +//! may be delivered. +//! +//! The callback function must return no value, and takes a string argument, +//! which will be the name of the table on which the notification event +//! has occured. In future versions, support for user-specified arguments +//! will be added. +//! +//! @note +//! The polling cycle can be run only if your process is in "event-driven mode" +//! (that is, if 'main' has returned a negative number). +//! +//! This function is Postgres-specific, and thus it is not availible +//! through the generic SQL-interface. +//! +//! @fixme +//! An integer can be passed as first argument, but it's effect is +//! not documented. void set_notify_callback(int|function f, int|float|void poll_delay) { if (callout) { remove_call_out(callout); @@ -63,24 +221,40 @@ string quote(string s) return replace(s, ({ "\\", "'", "\0" }), ({ "\\\\", "''", "\\0" }) ); } +//! This function creates a new database with the given name (assuming we +//! have enough permissions to do this). +//! +//! @seealso +//! drop_db void create_db(string db) { big_query(sprintf("CREATE DATABASE %s",db)); } +//! This function destroys a database and all the data it contains (assuming +//! we have enough permissions to do so). +//! +//! @seealso +//! create_db void drop_db(string db) { big_query(sprintf("DROP database %s",db)); } +//! This function returns a string describing the server we are talking +//! to. It has the form "servername/serverversion" (like the HTTP protocol +//! description) and is most useful in conjunction with the generic SQL-server +//! module. string server_info () { - return "Postgres/unknown"; + return "Postgres/unknown"; } -array(string) list_dbs (void|string wild) { +//! Lists all the databases availible on the server. +//! If glob is specified, lists only those databases matching it. +array(string) list_dbs (void|string glob) { array name,ret=({}); object res= big_query( "SELECT datname from pg_database"+ - ((wild&&sizeof(wild))? " WHERE datname ~ '"+glob_to_regexp(wild)+"'" : "") + ((glob&&sizeof(glob))? " WHERE datname ~ '"+glob_to_regexp(glob)+"'" : "") ); while (name=res->fetch_row()) { ret += ({name[0]}); @@ -88,7 +262,11 @@ array(string) list_dbs (void|string wild) { return sort(ret); } -array(string) list_tables (void|string wild) { +//! Returns an array containing the names of all the tables in the currently +//! selected database. +//! If a glob is specified, it will return only those tables +//! whose name matches it. +array(string) list_tables (void|string glob) { array name,ret=({}); object res; res=big_query( @@ -96,7 +274,7 @@ array(string) list_tables (void|string wild) { "WHERE ( relkind = 'r' OR relkind = 'i' OR relkind = 'S') " "AND relname !~ '^pg_' " "AND usesysid = relowner " + - ((wild && sizeof(wild)) ? "AND relname ~ '"+glob_to_regexp(wild)+"' " : "") + + ((glob && sizeof(glob)) ? "AND relname ~ '"+glob_to_regexp(glob)+"' " : "") + "ORDER BY relname" ); while (name=res->fetch_row()) { @@ -105,6 +283,32 @@ array(string) list_tables (void|string wild) { return ret; } +//! Returns a mapping, indexed on the column name, of mappings describing the +//! attributes of a table of the current database. +//! If a glob is specified, will return descriptions only of the columns matching +//! it. +//! +//! The current fields are: +//! +//! @mapping +//! @member int "has_rules" +//! +//! @member int "is_shared" +//! +//! @member string "expires" +//! A string representing an internal date. +//! +//! @member string "owner" +//! It's the textual representation of a Postgres uid. +//! +//! @member string "length" +//! +//! @member string "text" +//! A textual description of the internal (to the server) type-name +//! +//! @member mixed "default" +//! @endmapping +//! array(mapping(string:mixed)) list_fields (string table, void|string wild) { array row, ret=({}); object res=big_query( @@ -127,6 +331,21 @@ array(mapping(string:mixed)) list_fields (string table, void|string wild) { return ret; } +//! This is the only provided interface which allows you to query the +//! database. If you wish to use the simpler "query" function, you need to +//! use the Sql.sql generic sql-object. +//! +//! It returns a postgres_result object (which conforms to the Sql.sql_result +//! standard interface for accessing data). I recommend using query() for +//! simpler queries (because it is easier to handle, but stores all the result +//! in memory), and big_query for queries you expect to return huge amounts +//! of data (it's harder to handle, but fectches results on demand). +//! +//! @note +//! This function @b{can@} raise exceptions. +//! +//! @seealso +//! Sql.Sql, Sql.sql_result int|object big_query(object|string q, mapping(string|int:mixed)|void bindings) { if (!bindings) diff --git a/lib/modules/Sql.pmod/postgres_result.pike b/lib/modules/Sql.pmod/postgres_result.pike index aacafedb48..3bf39875ea 100644 --- a/lib/modules/Sql.pmod/postgres_result.pike +++ b/lib/modules/Sql.pmod/postgres_result.pike @@ -1,5 +1,8 @@ #pike __REAL_VERSION__ +//! Sql.postgres_result contains the result of a Postgres-query. +//! See @[Sql.postgres] for a description of this program's functions. + #if constant(Postgres.postgres_result) inherit Postgres.postgres_result; #else /* !constant(Postgres.postgres_result) */ -- GitLab