pike.git / lib / modules / Sql.pmod / pgsql.pike

version» Context lines:

pike.git/lib/modules/Sql.pmod/pgsql.pike:5:   //! This is an interface to the PostgreSQL database   //! server. This module is independent of any external libraries.   //! Note that you @b{do not@} need to have a   //! PostgreSQL server running on your host to use this module: you can   //! connect to the database over a TCP/IP socket.   //!   //! This module replaces the functionality of the older @[Sql.postgres]   //! and @[Postgres.postgres] modules.   //!   //! This module supports the following features: - //! - //! - PostgreSQL network protocol version 3, authentication methods + //! @ul + //! @item + //! PostgreSQL network protocol version 3, authentication methods   //! currently supported are: cleartext and MD5 (recommended). - //! - //! - Streaming queries which do not buffer the whole resultset in memory. - //! - //! - Automatic binary transfers to and from the database for most common + //! @item + //! Streaming queries which do not buffer the whole resultset in memory. + //! @item + //! Automatic binary transfers to and from the database for most common   //! datatypes (amongst others: integer, text and bytea types). - //! - //! - SQL-injection protection by allowing just one statement per query + //! @item + //! SQL-injection protection by allowing just one statement per query   //! and ignoring anything after the first (unquoted) semicolon in the query. - //! - //! - COPY support for streaming up- and download. - //! - //! - Accurate error messages. - //! - //! - Automatic precompilation of complex queries (session cache). - //! - //! - Multiple simultaneous queries on the same database connection. - //! - //! - Cancelling of long running queries by force or by timeout. - //! - //! - Event driven NOTIFY. - //! - //! - SSL encrypted connections (optional or forced). - //! + //! @item + //! COPY support for streaming up- and download. + //! @item + //! Accurate error messages. + //! @item + //! Automatic precompilation of complex queries (session cache). + //! @item + //! Multiple simultaneous queries on the same database connection. + //! @item + //! Cancelling of long running queries by force or by timeout. + //! @item + //! Event driven NOTIFY. + //! @item + //! SSL encrypted connections (optional or forced). + //! @endul   //! Check the PostgreSQL documentation for further details.   //!   //! @note   //! Multiple simultaneous queries on the same database connection is a   //! feature that none of the other database drivers for Pike support.   //! So, although it's efficient, its use will make switching database drivers   //! difficult.   //!   //! @seealso - //! @[Sql.Sql], @[Sql.postgres] + //! @[Sql.Sql], @[Sql.postgres], @url{http://www.postgresql.org/docs/@}      #pike __REAL_VERSION__      #include "pgsql.h"      #define ERROR(X ...) predef::error(X)      int _nextportal;   int _closesent;   int _fetchlimit=FETCHLIMIT;
pike.git/lib/modules/Sql.pmod/pgsql.pike:137:   #define CTIDOID 1247   #define UUIDOID 2950      #define PG_PROTOCOL(m,n) (((m)<<16)|(n))      //! @decl void create()   //! @decl void create(string host, void|string database, void|string user,@   //! void|string password, void|mapping(string:mixed) options)   //!   //! With no arguments, this function initialises (reinitialises if a - //! connection had been previously set up) a connection to the + //! connection has been set up previously) a connection to the   //! PostgreSQL backend. Since PostgreSQL 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 + //! connection may fail however, for a variety of reasons; in this case + //! the most likely reason is because you don't have enough privileges   //! to connect to that database. So use of this particular syntax is   //! discouraged.   //! - //! The host argument can have the syntax @expr{"hostname"@} or - //! @expr{"hostname:portname"@}. This allows to specify the TCP/IP - //! port to connect to. If it is @expr{0@} or @expr{""@}, it will try - //! to connect to localhost, default port. + //! @param host + //! Should either contain @expr{"hostname"@} or + //! @expr{"hostname:portname"@}. This allows you to specify the TCP/IP + //! port to connect to. If the parameter is @expr{0@} or @expr{""@}, + //! it will try to connect to localhost, default port.   //! - //! The database argument specifies the database to connect to. If - //! @expr{0@} or @expr{""@}, it will try to connect to the specified - //! database. + //! @param database + //! Specifies the database to connect to. Not specifying this is + //! only supported if the PostgreSQL backend has a default database + //! configured. If you do not want to connect to any live database, + //! you can use @ref{template1@}.   //! - //! The options argument currently supports at least the following: - //! @string - //! @value "use_ssl" + //! @param options + //! Currently supports at least the following: + //! @mapping + //! @member int "use_ssl"   //! If the database supports and allows SSL connections, the session   //! will be SSL encrypted, if not, the connection will fallback   //! to plain unencrypted - //! @value "force_ssl" + //! @member int "force_ssl"   //! If the database supports and allows SSL connections, the session   //! will be SSL encrypted, if not, the connection will abort - //! @value "cache_autoprepared_statements" + //! @member int "cache_autoprepared_statements"   //! If set to zero, it disables the automatic statement prepare and   //! cache logic; caching prepared statements can be problematic   //! when stored procedures and tables are redefined which leave stale   //! references in the already cached prepared statements - //! @value "client_encoding" + //! @member string "client_encoding"   //! Character encoding for the client side, it defaults to using   //! the default encoding specified by the database, e.g.: "SQL_ASCII" - //! @value "standard_conforming_strings" + //! @member string "standard_conforming_strings"   //! When on, backslashes in strings must not be escaped any longer,   //! @[quote()] automatically adjusts quoting strategy accordingly - //! @value "escape_string_warning" + //! @member string "escape_string_warning"   //! When on, a warning is issued if a backslash (\) appears in an   //! ordinary string literal and @[standard_conforming_strings] is off,   //! defaults to on - //! @endstring + //! @endmapping   //! For the numerous other options please check the PostgreSQL manual.   //!   //! @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.   //!   //! @seealso - //! @[Postgres.postgres], @[Sql.Sql], @[postgres->select_db] + //! @[Postgres.postgres], @[Sql.Sql], @[select_db()], + //! @url{http://search.postgresql.org/search?u=%2Fdocs%2F&q=client+connection+defaults@}   protected void create(void|string _host, void|string _database,    void|string _user, void|string _pass, void|mapping(string:mixed) _options) {    pass = _pass; _pass = "CENSORED";    if(pass)    String.secure(pass);    user = _user; database = _database; host = _host || PGSQL_DEFAULT_HOST;    options = _options || ([]);    if(has_value(host,":") && sscanf(_host,"%s:%d",host,port)!=2)    ERROR("Error in parsing the hostname argument\n");    if(!port)    port = PGSQL_DEFAULT_PORT;    _querymutex=Thread.Mutex();    _stealmutex=Thread.Mutex();    reconnect();   }    - //! This function returns the textual description of the last + //! @returns + //! The textual description of the last   //! server-related error. Returns @expr{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).   //!   //! During the execution of a statement, this function accumulates all   //! non-error messages (notices, warnings, etc.). If a statement does not   //! generate any errors, this function will return all collected messages   //! from the last statement.   //! -  + //! @note   //! The string returned is not newline-terminated.   //! - //! To clear the error, pass 1 as argument. + //! @param clear + //! To clear the error, set it to @expr{1@}.   //!   //! @seealso - //! @[big_query] + //! @[big_query()]   string error(void|int clear) {    string s=lastmessage*"\n";    if(clear)    lastmessage=({});    warningscollected=0;    return sizeof(s) && s;   }      //! This function returns a string describing what host are we talking to,   //! and how (TCP/IP or UNIX sockets).   //!   //! @seealso - //! @[server_info] + //! @[server_info()]   string host_info() {    return sprintf("fd:%d TCP/IP %s:%d PID %d",    _c?_c.query_fd():-1,host,port,backendpid);   }      final private object getsocket(void|int nossl) {    object lcon = Stdio.File();    if(!lcon.connect(host,port))    return UNDEFINED;   
pike.git/lib/modules/Sql.pmod/pgsql.pike:279:    if(options->force_ssl)    ERROR("Encryption library missing, cannot establish connection to %s:%d\n",    host,port);   #endif    fcon=.pgsql_util.PGconn(lcon,this);    return fcon;   }      //! Cancels the currently running query.   //! + //! @seealso + //! @[reload()], @[resync()] + //! + //! @note   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface. - //! - //! @seealso - //! @[reload], @[resync] +    void cancelquery() {    if(qstate==inquery) {    qstate=cancelpending;    object lcon;    PD("CancelRequest\n");    if(!(lcon=getsocket(1)))    ERROR("Cancel connect failed\n");    lcon.write(({_c.plugint32(16),_c.plugint32(PG_PROTOCOL(1234,5678)),    _c.plugint32(backendpid),cancelsecret}));    lcon.close();    }   }      //! Changes the connection charset.   //! - //! @[charset] is a PostgreSQL charset name. + //! @param charset + //! A PostgreSQL charset name.   //!   //! @seealso - //! @[get_charset], @[create] + //! @[get_charset()], @[create()], + //! @url{http://search.postgresql.org/search?u=%2Fdocs%2F&q=character+sets@}   void set_charset(string charset)   {   #if 0    // FIXME Do we want to support the "unicode" setting? (see mysql.pike)   #endif    big_query("SET CLIENT_ENCODING TO :charset",([":charset":charset]));   }    - //! Returns the PostgreSQL name for the current connection charset. + //! @returns + //! The PostgreSQL name for the current connection charset.   //!   //! @seealso - //! @[set_charset], @[getruntimeparameters] + //! @[set_charset()], @[getruntimeparameters()], + //! @url{http://search.postgresql.org/search?u=%2Fdocs%2F&q=character+sets@}   string get_charset()   { return runtimeparameter->client_encoding;   }    - //! Returns the set of currently active runtimeparameters for - //! the open session; these are initialised by the options parameter + //! @returns + //! Currently active runtimeparameters for + //! the open session; these are initialised by the @ref{options@} parameter   //! during session creation, and then processed and returned by the server. - //! +    //! Common values are: - //! @string - //! @value "client_encoding" + //! @mapping + //! @member string "client_encoding"   //! Character encoding for the client side, e.g.: "SQL_ASCII" - //! @value "server_encoding" + //! @member string "server_encoding"   //! Character encoding for the server side as determined when the   //! database was created, e.g.: "SQL_ASCII" - //! @value "DateStyle" + //! @member string "DateStyle"   //! Date parsing/display, e.g.: "ISO, DMY" - //! @value "TimeZone" + //! @member string "TimeZone"   //! Default timezone used by the database, e.g.: "localtime" - //! @value "standard_conforming_strings" + //! @member string "standard_conforming_strings"   //! When on, backslashes in strings must not be escaped any longer - //! @value "session_authorization" + //! @member string "session_authorization"   //! Displays the authorisationrole which the current session runs under - //! @value "is_superuser" + //! @member string "is_superuser"   //! Indicates if the current authorisationrole has database-superuser   //! privileges - //! @value "integer_datetimes" + //! @member string "integer_datetimes"   //! Reports wether the database supports 64-bit-integer dates and times - //! @value "server_version" + //! @member string "server_version"   //! Shows the server version, e.g.: "8.3.3" - //! @endstring + //! @endmapping   //!   //! The values can be changed during a session using SET commands to the   //! database.   //! For other runtimeparameters check the PostgreSQL documentation.   //! -  + //! @seealso + //! @url{http://search.postgresql.org/search?u=%2Fdocs%2F&q=client+connection+defaults@} + //! + //! @note   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface.   mapping(string:string) getruntimeparameters() {    return runtimeparameter+([]);   }    - //! Returns a mapping with a set of statistics for the current session. - //! - //! @param warnings_dropped + //! @returns + //! A set of statistics for the current session: + //! @mapping + //! @member int "warnings_dropped"   //! Number of warnings/notices generated by the database but not   //! collected by the application by using @[error] after the statements   //! that generated them. - //! - //! @param skipped_describe_count + //! @member int "skipped_describe_count"   //! Number of times the driver skipped asking the database to   //! describe the statement parameters because it was already cached. - //! - //! @param used_prepared_statements + //! @member int "used_prepared_statements"   //! Numer of times prepared statements were used from cache instead of   //! reparsing in the current session. - //! - //! @param current_prepared_statements + //! @member int "current_prepared_statements"   //! Cache size of currently prepared statements. - //! - //! @param current_prepared_statement_hits + //! @member int "current_prepared_statement_hits"   //! Sum of the number hits on statements in the current statement cache. - //! - //! @param prepared_portal_count + //! @member int "prepared_portal_count"   //! Total number of prepared portals generated. - //! - //! @param prepared_statement_count + //! @member int "prepared_statement_count"   //! Total number of prepared statements generated. - //! - //! @param portals_opened_count + //! @member int "portals_opened_count"   //! Total number of portals opened, i.e. number of statements issued   //! to the database. - //! - //! @param blocked_count + //! @member int "blocked_count"   //! Number of times the driver had to (briefly) wait for the database to   //! send additional data. - //! - //! @param bytes_received + //! @member int "bytes_received"   //! Total number of bytes received from the database so far. - //! - //! @param messages_received + //! @member int "messages_received"   //! Total number of messages received from the database (one SQL-statement   //! requires multiple messages to be exchanged). - //! - //! @param bytes_sent + //! @member int "bytes_sent"   //! Total number of bytes sent to the database so far. - //! - //! @param packets_sent + //! @member int "packets_sent"   //! Total number of packets sent to the database (one packet usually   //! contains multiple messages). - //! - //! @param reconnect_count + //! @member int "reconnect_count"   //! Number of times the connection to the database has been lost. - //! - //! @param portals_in_flight + //! @member int "portals_in_flight"   //! Currently still open portals, i.e. running statements. -  + //! @endmapping   //! -  + //! @note   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface.   mapping(string:mixed) getstatistics() {    mapping(string:mixed) stats=([    "warnings_dropped":warningsdropcount,    "skipped_describe_count":skippeddescribe,    "used_prepared_statements":prepstmtused,    "current_prepared_statements":sizeof(prepareds),    "current_prepared_statement_hits":totalhits,    "prepared_portal_count":pportalcount,
pike.git/lib/modules/Sql.pmod/pgsql.pike:435:    "messages_received":_msgsreceived,    "bytes_received":_bytesreceived,    "packets_sent":_packetssent,    "bytes_sent":_bytessent,    "reconnect_count":reconnected,    "portals_in_flight":portalsinflight,    ]);    return stats;   }    - //! Returns the old cachedepth, sets the new cachedepth for prepared - //! statements automatic caching. + //! @param newdepth + //! Sets the new cachedepth for automatic caching of prepared statements.   //! -  + //! @returns + //! The previous cachedepth. + //! + //! @note   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface.   int setcachedepth(void|int newdepth) {    int olddepth=cachedepth;    if(!zero_type(newdepth) && newdepth>=0)    cachedepth=newdepth;    return olddepth;   }    - //! Returns the old timeout, sets the new timeout for long running - //! queries. + //! @param newtimeout + //! Sets the new timeout for long running queries.   //! -  + //! @returns + //! The previous timeout. + //! + //! @note   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface.   int settimeout(void|int newtimeout) {    int oldtimeout=timeout;    if(!zero_type(newtimeout) && newtimeout>0)    timeout=newtimeout;    return oldtimeout;   }      //! Returns the old portalbuffersize, sets the new portalbuffersize   //! for buffering partially concurrent queries.   //! -  + //! @note   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface.   int setportalbuffersize(void|int newportalbuffersize) {    int oldportalbuffersize=portalbuffersize;    if(!zero_type(newportalbuffersize) && newportalbuffersize>0)    portalbuffersize=newportalbuffersize;    return oldportalbuffersize;   }      //! Returns the old fetchlimit, sets the new fetchlimit to interleave   //! queries.   //! -  + //! @note   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface.   int setfetchlimit(void|int newfetchlimit) {    int oldfetchlimit=_fetchlimit;    if(!zero_type(newfetchlimit) && newfetchlimit>=0)    _fetchlimit=newfetchlimit;    return oldfetchlimit;   }      final private string glob2reg(string glob) {
pike.git/lib/modules/Sql.pmod/pgsql.pike:951: Inside #if undefined(UNBUFFEREDIO)
   _c.unread(d);    do _decodemsg();    while(_c.bpeek(0)==1);    return 0;   }   #endif      //! Closes the connection to the database, any running queries are   //! terminated instantly.   //! + //! @note   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface.   void close() {    cancelquery();    if(_c)    _c.sendterminate();   }      void destroy() {    close();
pike.git/lib/modules/Sql.pmod/pgsql.pike:1028:    runcallback(backendpid,"_reconnect","");    }    return 1;   }      //! @decl void reload()   //!   //! For PostgreSQL this function performs the same function as @[resync()].   //!   //! @seealso - //! @[resync], @[cancelquery] + //! @[resync()], @[cancelquery()]   void reload() {    resync();   }      //! @decl void resync()   //!   //! Resyncs the database session; typically used to make sure the session is   //! not still in a dangling transaction.   //!   //! If called while queries/portals are still in-flight, this function   //! is a no-op.   //!   //! If called while the connection is in idle state, the function is   //! lightweight and briefly touches base with the database server to   //! make sure client and server are in sync.   //!   //! If issued while inside a transaction, it will rollback the transaction,   //! close all open cursors, drop all temporary tables and reset all   //! session variables to their default values.   //! -  + //! @seealso + //! @[cancelquery()], @[reload()] + //! + //! @note   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface. - //! - //! @seealso - //! @[cancelquery], @[reload] +    void resync(void|int special) {    mixed err;    int didsync;    if(err = catch {    sendclose(1);    PD("Portalsinflight: %d\n",portalsinflight);    if(!portalsinflight) {    if(!earlyclose) {    PD("Sync\n");    _c.sendcmd(({"S",_c.plugint32(4)}),2);
pike.git/lib/modules/Sql.pmod/pgsql.pike:1105:   //! 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] + //! @[create()]   void select_db(string dbname) {    database=dbname;    reconnect();    reconnected=0;   }      //! With PostgreSQL you can LISTEN to NOTIFY events.   //! This function allows you to detect and handle such events.   //!   //! @param condition
pike.git/lib/modules/Sql.pmod/pgsql.pike:1143:   //! verbatim from @[args].   //! The callback function must return no value.   //!   //! @param selfnotify   //! Normally notify events generated by your own session are ignored.   //! If you want to receive those as well, set @[selfnotify] to one.   //!   //! @param args   //! Extra arguments to pass to @[notify_cb].   //! + //! @note   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface.   void set_notify_callback(string condition,    void|function(int,string,string,mixed ...:void) notify_cb,void|int selfnotify,    mixed ... args) {    if(!notify_cb)    m_delete(notifylist,condition);    else {    array old=notifylist[condition];    if(!old)
pike.git/lib/modules/Sql.pmod/pgsql.pike:1169:    }   }      final private void runcallback(int pid,string condition,string extrainfo) {    array cb;    if((cb=notifylist[condition]||notifylist[""])    && (pid!=backendpid || sizeof(cb)>1 && cb[1]))    cb[0](pid,condition,extrainfo,@cb[2..]);   }    - //! This function quotes magic characters inside strings embedded in a - //! textual query. Quoting must not be done for parameters passed in - //! bindings. + //! @returns + //! The given string, but escapes/quotes all contained magic characters + //! according to the quoting rules of the current session for non-binary + //! arguments in textual SQL-queries.   //! -  + //! @note + //! Quoting must not be done for parameters passed in bindings. + //!   //! @seealso - //! @[big_query], @[quotebinary], @[create] + //! @[big_query()], @[quotebinary()], @[create()]   string quote(string s) {    string r=runtimeparameter->standard_conforming_strings;    if(r && r=="on")    return replace(s, "'", "''");    return replace(s, ({ "'", "\\" }), ({ "''", "\\\\" }) );   }    - //! This function quotes magic characters inside binaries (bytea) embedded in a - //! textual query. Quoting must not be done for parameters passed in - //! bindings. + //! @returns + //! The given string, but escapes/quotes all contained magic characters + //! according to the quoting rules of the current session for binary (bytea) + //! arguments in textual SQL-queries.   //! -  + //! @note + //! Quoting must not be done for parameters passed in bindings. + //!   //! @seealso - //! @[big_query], @[quote] + //! @[big_query()], @[quote()]   //! -  + //! @note   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface.   string quotebinary(string s) {    return replace(s, ({ "'", "\\", "\0" }), ({ "''", "\\\\", "\\000" }) );   }    - //! This function creates a new database with the given name (assuming we - //! have enough permissions to do this). + //! This function creates a new database (assuming we + //! have enough privileges to do this).   //! -  + //! @param db + //! Name of the new database. + //!   //! @seealso - //! @[drop_db] + //! @[drop_db()]   void create_db(string db) {    big_query("CREATE DATABASE :db",([":db":db]));   }      //! This function destroys a database and all the data it contains (assuming - //! we have enough permissions to do so). It is not possible to delete + //! we have enough privileges to do so). It is not possible to delete   //! the database you're currently connected to. You can connect to database - //! @[template1] to avoid connecting to any live database. + //! @ref{template1@} to avoid connecting to any live database.   //! -  + //! @param db + //! Name of the database to be deleted. + //!   //! @seealso - //! @[create_db] + //! @[create_db()]   void drop_db(string db) {    big_query("DROP DATABASE :db",([":db":db]));   }    - //! This function returns a string describing the server we are + //! @returns + //! A string describing the server we are   //! talking to. It has the form @expr{"servername/serverversion"@}   //! (like the HTTP protocol description) and is most useful in   //! conjunction with the generic SQL-server module.   //!   //! @seealso - //! @[host_info] + //! @[host_info()]   string server_info () {    return DRIVERNAME"/"+(runtimeparameter->server_version||"unknown");   }    - //! Lists all the databases available on the server. - //! If glob is specified, lists only those databases matching it. + //! @returns + //! An array of the databases available on the server. + //! + //! @param glob + //! If specified, list only those databases matching it.   array(string) list_dbs (void|string glob) {    array row,ret=({});    object res=big_query("SELECT d.datname "    "FROM pg_database d "    "WHERE d.datname ILIKE :glob "    "ORDER BY d.datname",    ([":glob":glob2reg(glob)]));    while(row=res->fetch_row())    ret+=({row[0]});    return ret;   }    - //! Returns an array containing the names of all the tables and views in the + //! @returns + //! An array containing the names of all the tables and views in the   //! path in the currently selected database. - //! If a glob is specified, it will return only those tables with matching - //! names. + //! + //! @param glob + //! If specified, list only the tables with matching names.   array(string) list_tables (void|string glob) {    array row,ret=({}); // This query might not work on PostgreSQL 7.4    object res=big_query( // due to missing schemasupport    "SELECT CASE WHEN 'public'=n.nspname THEN '' ELSE n.nspname||'.' END "    " ||c.relname AS name "    "FROM pgcatalog.pgclass c "    " LEFT JOIN pgcatalog.pg_namespace n ON n.oid=c.relnamespace "    "WHERE c.relkind IN ('r','v') AND n.nspname<>'pgcatalog' "    " AND n.nspname !~ '^pg_toast' AND pgcatalog.pg_table_is_visible(c.oid) "    " AND c.relname ILIKE :glob "    " ORDER BY 1",    ([":glob":glob2reg(glob)]));    while(row=res->fetch_row())    ret+=({row[0]});    return ret;   }    - //! Returns a mapping, indexed on the column name, of mappings describing + //! @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 currently defined fields are:   //!   //! @mapping   //! @member int "is_shared" - //! +    //! @member string "owner"   //! Tableowner - //! +    //! @member string "length"   //! Size of the columndatatype - //! +    //! @member string "text"   //! A textual description of the internal (to the server) type-name - //! +    //! @member mixed "default"   //! Default value for the column - //! +    //! @member mixed "schema"   //! Schema the table belongs to - //! +    //! @member mixed "table"   //! Name of the table - //! +    //! @member mixed "kind"   //! Type of table - //! +    //! @member mixed "has_index"   //! If the table has any indices - //! +    //! @member mixed "has_primarykey"   //! If the table has a primary key - //! +    //! @member mixed "rowcount"   //! Estimated rowcount of the table - //! +    //! @member mixed "pagecount"   //! Estimated pagecount of the table - //! +    //! @endmapping   //! - //! Setting wild to * will include system columns in the list. - //! - array(mapping(string:mixed)) list_fields(void|string table, void|string wild) { + //! @param glob + //! If specified, list only the tables with matching names. + //! Setting it to @expr{*@} will include system columns in the list. + array(mapping(string:mixed)) list_fields(void|string table, void|string glob) {    array row, ret=({});    string schema=UNDEFINED;       sscanf(table||"*", "%s.%s", schema, table);       object res = big_query(    "SELECT a.attname, a.atttypid, t.typname, a.attlen, "    " c.relhasindex, c.relhaspkey, c.reltuples, c.relpages, "    " c.relisshared, t.typdefault, "    " n.nspname, c.relname, "
pike.git/lib/modules/Sql.pmod/pgsql.pike:1338:    " r.rolname "    "FROM pgcatalog.pgclass c "    " LEFT JOIN pgcatalog.pg_namespace n ON n.oid=c.relnamespace "    " JOIN pgcatalog.pg_roles r ON r.oid=c.relowner "    " JOIN pgcatalog.pg_attribute a ON c.oid=a.attrelid "    " JOIN pgcatalog.pg_type t ON a.atttypid=t.oid "    "WHERE c.relname ILIKE :table AND "    " (n.nspname ILIKE :schema OR "    " :schema IS NULL "    " AND n.nspname<>'pgcatalog' AND n.nspname !~ '^pg_toast') " -  " AND a.attname ILIKE :wild " -  " AND (a.attnum>0 OR '*'=:realwild) " +  " AND a.attname ILIKE :glob " +  " AND (a.attnum>0 OR '*'=:realglob) "    "ORDER BY n.nspname,c.relname,a.attnum,a.attname",    ([":schema":glob2reg(schema),":table":glob2reg(table), -  ":wild":glob2reg(wild),":realwild":wild])); +  ":glob":glob2reg(glob),":realglob":glob]));       array colnames=res->fetch_fields();    { mapping(string:string) renames=([    "attname":"name",    "nspname":"schema",    "relname":"table",    "rolname":"owner",    "typname":"type",    "attlen":"length",    "typdefault":"default",
pike.git/lib/modules/Sql.pmod/pgsql.pike:1453:      final private string trbackendst(int c) {    switch(c) {    case 'I':return "idle";    case 'T':return "intransaction";    case 'E':return "infailedtransaction";    }    return "";   }    - //! Returns the current commitstatus of the connection. Returns either one of: - //! idle - //! intransaction - //! infailedtransaction + //! @returns + //! The current commitstatus of the connection. Returns either one of: + //! @string + //! @value "idle" + //! @value "intransaction" + //! @value "infailedtransaction" + //! @endstring   //! -  + //! @note   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface.   final string status_commit() {    return trbackendst(backendstatus);   }      final private array(string) closestatement(mapping tp) {    string oldprep=tp->preparedname;    array(string) ret=({});    if(oldprep) {
pike.git/lib/modules/Sql.pmod/pgsql.pike:1482:    return ret;   }      //! @decl Sql.pgsql_util.pgsql_result big_query(string query)   //! @decl Sql.pgsql_util.pgsql_result big_query(string query, mapping bindings)   //!   //! 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 pgsql_result object (which conforms to the + //! Bindings are supported natively straight through the network. + //! Special bindings supported are: + //! @mapping + //! @member int ":_cache" + //! Forces caching or no caching for the query at hand. + //! @endmapping + //! + //! @returns + //! A @[Sql.pgsql_util.pgsql_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 fetches results on demand).   //! - //! Bindings are supported natively straight through the network. - //! Special bindings supported are: ":_cache", to force caching or - //! not caching for the query at hand depending on the mappingvalue. - //! +    //! @note   //! This function @b{can@} raise exceptions.   //!   //! @note -  + //! This function supports multiple simultaneous queries (portals) on a single + //! database connection. This is a feature not commonly supported by other + //! database backends. + //! + //! @note   //! This function does not support multiple queries in one querystring.   //! I.e. it allows for but does not require a trailing semicolon, but it   //! simply ignores any commands after the first semicolon. This can be   //! viewed as a limited protection against SQL-injection attacks.   //!   //! @seealso   //! @[Sql.Sql], @[Sql.sql_result], @[Sql.pgsql_util.pgsql_result]   object big_query(string q,void|mapping(string|int:mixed) bindings,    void|int _alltyped) {    string preparedname="";
pike.git/lib/modules/Sql.pmod/pgsql.pike:1777:    { object tportal=_c.portal; // Make copy, because it might dislodge    tportal->fetch_row(1); // upon initial fetch_row()    return tportal;    }   }      //! This is an alias for @[big_query()], since @[big_query()] already supports   //! streaming of multiple simultaneous queries through the same connection.   //!   //! @seealso - //! @[big_query], @[Sql.Sql], @[Sql.sql_result] + //! @[big_query()], @[Sql.Sql], @[Sql.sql_result]   object streaming_query(string q,void|mapping(string|int:mixed) bindings) {    return big_query(q,bindings);   }      //! This function returns an object that allows streaming and typed   //! results.   //!   //! @seealso - //! @[big_query], @[Sql.Sql], @[Sql.sql_result] + //! @[big_query()], @[Sql.Sql], @[Sql.sql_result]   object big_typed_query(string q,void|mapping(string|int:mixed) bindings) {    return big_query(q,bindings,1);   }