LCOV - differential code coverage report
Current view: top level - src/interfaces/ecpg/ecpglib - connect.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DUB DCB
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 70.5 % 356 251 12 93 9 242 6 9
Current Date: 2025-09-06 07:49:51 +0900 Functions: 90.9 % 11 10 1 1 9
Baseline: lcov-20250906-005545-baseline Branches: 58.0 % 286 166 12 108 10 156
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 31.8 % 44 14 12 18 9 5
(360..) days: 76.0 % 312 237 75 237
Function coverage date bins:
(360..) days: 90.9 % 11 10 1 1 9
Branch coverage date bins:
(30,360] days: 36.4 % 44 16 12 16 10 6
(360..) days: 62.0 % 242 150 92 150

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /* src/interfaces/ecpg/ecpglib/connect.c */
                                  2                 :                : 
                                  3                 :                : #define POSTGRES_ECPG_INTERNAL
                                  4                 :                : #include "postgres_fe.h"
                                  5                 :                : 
                                  6                 :                : #include "ecpg-pthread-win32.h"
                                  7                 :                : #include "ecpgerrno.h"
                                  8                 :                : #include "ecpglib.h"
                                  9                 :                : #include "ecpglib_extern.h"
                                 10                 :                : #include "ecpgtype.h"
                                 11                 :                : #include "sqlca.h"
                                 12                 :                : 
                                 13                 :                : #ifdef HAVE_USELOCALE
                                 14                 :                : locale_t    ecpg_clocale = (locale_t) 0;
                                 15                 :                : #endif
                                 16                 :                : 
                                 17                 :                : static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
                                 18                 :                : static pthread_key_t actual_connection_key;
                                 19                 :                : static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT;
                                 20                 :                : static struct connection *actual_connection = NULL;
                                 21                 :                : static struct connection *all_connections = NULL;
                                 22                 :                : 
                                 23                 :                : static void
 7846 meskes@postgresql.or       24                 :CBC          57 : ecpg_actual_connection_init(void)
                                 25                 :                : {
 7678 bruce@momjian.us           26                 :             57 :     pthread_key_create(&actual_connection_key, NULL);
 7846 meskes@postgresql.or       27                 :             57 : }
                                 28                 :                : 
                                 29                 :                : void
 6912 bruce@momjian.us           30                 :           6364 : ecpg_pthreads_init(void)
                                 31                 :                : {
 6975 meskes@postgresql.or       32                 :           6364 :     pthread_once(&actual_connection_key_once, ecpg_actual_connection_init);
                                 33                 :           6364 : }
                                 34                 :                : 
                                 35                 :                : static struct connection *
 8103                            36                 :            520 : ecpg_get_connection_nr(const char *connection_name)
                                 37                 :                : {
 8069 bruce@momjian.us           38                 :            520 :     struct connection *ret = NULL;
                                 39                 :                : 
                                 40   [ +  -  +  + ]:            520 :     if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
                                 41                 :                :     {
 1180 tgl@sss.pgh.pa.us          42                 :             41 :         ecpg_pthreads_init();   /* ensure actual_connection_key is valid */
                                 43                 :                : 
 7846 meskes@postgresql.or       44                 :             41 :         ret = pthread_getspecific(actual_connection_key);
                                 45                 :                : 
                                 46                 :                :         /*
                                 47                 :                :          * if no connection in TSD for this thread, get the global default
                                 48                 :                :          * connection and hope the user knows what they're doing (i.e. using
                                 49                 :                :          * their own mutex to protect that connection from concurrent accesses
                                 50                 :                :          */
 1180 tgl@sss.pgh.pa.us          51         [ +  + ]:             41 :         if (ret == NULL)
                                 52                 :                :             /* no TSD connection, going for global */
 7450 meskes@postgresql.or       53                 :              1 :             ret = actual_connection;
                                 54                 :                :     }
                                 55                 :                :     else
                                 56                 :                :     {
                                 57                 :                :         struct connection *con;
                                 58                 :                : 
 8069 bruce@momjian.us           59         [ +  + ]:           2009 :         for (con = all_connections; con != NULL; con = con->next)
                                 60                 :                :         {
                                 61                 :                :             /*
                                 62                 :                :              * Check for the case of a NULL connection name, stored as such in
                                 63                 :                :              * the connection information by ECPGconnect() when the database
                                 64                 :                :              * name is not specified by its caller.
                                 65                 :                :              */
   46 michael@paquier.xyz        66   [ +  -  +  + ]:           1921 :             if (con->name != NULL && strcmp(connection_name, con->name) == 0)
 8069 bruce@momjian.us           67                 :            391 :                 break;
                                 68                 :                :         }
                                 69                 :            479 :         ret = con;
                                 70                 :                :     }
                                 71                 :                : 
 2942 peter_e@gmx.net            72                 :            520 :     return ret;
                                 73                 :                : }
                                 74                 :                : 
                                 75                 :                : struct connection *
 6548 meskes@postgresql.or       76                 :           3940 : ecpg_get_connection(const char *connection_name)
                                 77                 :                : {
 8069 bruce@momjian.us           78                 :           3940 :     struct connection *ret = NULL;
                                 79                 :                : 
 7845                            80   [ +  +  -  + ]:           3940 :     if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
                                 81                 :                :     {
 1180 tgl@sss.pgh.pa.us          82                 :           3532 :         ecpg_pthreads_init();   /* ensure actual_connection_key is valid */
                                 83                 :                : 
 7845 bruce@momjian.us           84                 :           3532 :         ret = pthread_getspecific(actual_connection_key);
                                 85                 :                : 
                                 86                 :                :         /*
                                 87                 :                :          * if no connection in TSD for this thread, get the global default
                                 88                 :                :          * connection and hope the user knows what they're doing (i.e. using
                                 89                 :                :          * their own mutex to protect that connection from concurrent accesses
                                 90                 :                :          */
 1180 tgl@sss.pgh.pa.us          91         [ +  + ]:           3532 :         if (ret == NULL)
                                 92                 :                :             /* no TSD connection here either, using global */
 7266 bruce@momjian.us           93                 :             54 :             ret = actual_connection;
                                 94                 :                :     }
                                 95                 :                :     else
                                 96                 :                :     {
 7845                            97                 :            408 :         pthread_mutex_lock(&connections_mutex);
                                 98                 :                : 
                                 99                 :            408 :         ret = ecpg_get_connection_nr(connection_name);
                                100                 :                : 
                                101                 :            408 :         pthread_mutex_unlock(&connections_mutex);
                                102                 :                :     }
                                103                 :                : 
 2942 peter_e@gmx.net           104                 :           3940 :     return ret;
                                105                 :                : }
                                106                 :                : 
                                107                 :                : static void
 2999 tgl@sss.pgh.pa.us         108                 :            123 : ecpg_finish(struct connection *act)
                                109                 :                : {
 8210 meskes@postgresql.or      110         [ +  - ]:            123 :     if (act != NULL)
                                111                 :                :     {
                                112                 :                :         struct ECPGtype_information_cache *cache,
                                113                 :                :                    *ptr;
                                114                 :                : 
 6548                           115                 :            123 :         ecpg_deallocate_all_conn(0, ECPG_COMPAT_PGSQL, act);
 8210                           116                 :            123 :         PQfinish(act->connection);
                                117                 :                : 
                                118                 :                :         /*
                                119                 :                :          * no need to lock connections_mutex - we're always called by
                                120                 :                :          * ECPGdisconnect or ECPGconnect, which are holding the lock
                                121                 :                :          */
                                122                 :                : 
                                123                 :                :         /* remove act from the list */
                                124         [ +  + ]:            123 :         if (act == all_connections)
                                125                 :             74 :             all_connections = act->next;
                                126                 :                :         else
                                127                 :                :         {
                                128                 :                :             struct connection *con;
                                129                 :                : 
                                130   [ +  -  +  + ]:            250 :             for (con = all_connections; con->next && con->next != act; con = con->next);
                                131         [ +  - ]:             49 :             if (con->next)
                                132                 :             49 :                 con->next = act->next;
                                133                 :                :         }
                                134                 :                : 
 7678 bruce@momjian.us          135         [ +  - ]:            123 :         if (pthread_getspecific(actual_connection_key) == act)
                                136                 :            123 :             pthread_setspecific(actual_connection_key, all_connections);
 8210 meskes@postgresql.or      137         [ +  + ]:            123 :         if (actual_connection == act)
                                138                 :             74 :             actual_connection = all_connections;
                                139                 :                : 
 6107                           140         [ +  - ]:            123 :         ecpg_log("ecpg_finish: connection %s closed\n", act->name ? act->name : "(null)");
                                141                 :                : 
 6548                           142         [ +  + ]:           2509 :         for (cache = act->cache_head; cache; ptr = cache, cache = cache->next, ecpg_free(ptr));
                                143                 :            123 :         ecpg_free(act->name);
                                144                 :            123 :         ecpg_free(act);
                                145                 :                :         /* delete cursor variables when last connection gets closed */
 4993                           146         [ +  + ]:            123 :         if (all_connections == NULL)
                                147                 :                :         {
                                148                 :                :             struct var_list *iv_ptr;
                                149                 :                : 
                                150         [ +  + ]:             82 :             for (; ivlist; iv_ptr = ivlist, ivlist = ivlist->next, ecpg_free(iv_ptr));
                                151                 :                :         }
                                152                 :                :     }
                                153                 :                :     else
 6322 peter_e@gmx.net           154                 :UBC           0 :         ecpg_log("ecpg_finish: called an extra time\n");
 8210 meskes@postgresql.or      155                 :CBC         123 : }
                                156                 :                : 
                                157                 :                : bool
                                158                 :             43 : ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
                                159                 :                : {
 6548                           160                 :             43 :     struct connection *con = ecpg_get_connection(connection_name);
                                161                 :                :     PGresult   *results;
                                162                 :                : 
                                163         [ -  + ]:             43 :     if (!ecpg_init(con, connection_name, lineno))
 2942 peter_e@gmx.net           164                 :UBC           0 :         return false;
                                165                 :                : 
 6322 peter_e@gmx.net           166                 :CBC          43 :     ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, mode, con->name);
                                167                 :                : 
 5410 rhaas@postgresql.org      168   [ -  +  -  - ]:             43 :     if (con->autocommit && strncmp(mode, "off", strlen("off")) == 0)
                                169                 :                :     {
 5441 meskes@postgresql.or      170         [ #  # ]:UBC           0 :         if (PQtransactionStatus(con->connection) == PQTRANS_IDLE)
                                171                 :                :         {
 6598                           172                 :              0 :             results = PQexec(con->connection, "begin transaction");
 6548                           173         [ #  # ]:              0 :             if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
 8210                           174                 :              0 :                 return false;
                                175                 :              0 :             PQclear(results);
                                176                 :                :         }
                                177                 :              0 :         con->autocommit = false;
                                178                 :                :     }
 5410 rhaas@postgresql.org      179   [ +  -  +  + ]:CBC          43 :     else if (!con->autocommit && strncmp(mode, "on", strlen("on")) == 0)
                                180                 :                :     {
 5441 meskes@postgresql.or      181         [ -  + ]:             40 :         if (PQtransactionStatus(con->connection) != PQTRANS_IDLE)
                                182                 :                :         {
 6598 meskes@postgresql.or      183                 :UBC           0 :             results = PQexec(con->connection, "commit");
 6548                           184         [ #  # ]:              0 :             if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
 8210                           185                 :              0 :                 return false;
                                186                 :              0 :             PQclear(results);
                                187                 :                :         }
 8210 meskes@postgresql.or      188                 :CBC          40 :         con->autocommit = true;
                                189                 :                :     }
                                190                 :                : 
                                191                 :             43 :     return true;
                                192                 :                : }
                                193                 :                : 
                                194                 :                : bool
                                195                 :              2 : ECPGsetconn(int lineno, const char *connection_name)
                                196                 :                : {
 6548                           197                 :              2 :     struct connection *con = ecpg_get_connection(connection_name);
                                198                 :                : 
                                199         [ -  + ]:              2 :     if (!ecpg_init(con, connection_name, lineno))
 2942 peter_e@gmx.net           200                 :UBC           0 :         return false;
                                201                 :                : 
 7846 meskes@postgresql.or      202                 :CBC           2 :     pthread_setspecific(actual_connection_key, con);
 8210                           203                 :              2 :     return true;
                                204                 :                : }
                                205                 :                : 
                                206                 :                : 
                                207                 :                : static void
 8072 peter_e@gmx.net           208                 :              2 : ECPGnoticeReceiver(void *arg, const PGresult *result)
                                209                 :                : {
 8049                           210                 :              2 :     char       *sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
                                211                 :              2 :     char       *message = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
 8119 bruce@momjian.us          212                 :              2 :     struct sqlca_t *sqlca = ECPGget_sqlca();
                                213                 :                :     int         sqlcode;
                                214                 :                : 
 3736 meskes@postgresql.or      215         [ -  + ]:              2 :     if (sqlca == NULL)
                                216                 :                :     {
 3736 meskes@postgresql.or      217                 :UBC           0 :         ecpg_log("out of memory");
                                218                 :              0 :         return;
                                219                 :                :     }
                                220                 :                : 
                                221                 :                :     (void) arg;                 /* keep the compiler quiet */
 8065 peter_e@gmx.net           222         [ -  + ]:CBC           2 :     if (sqlstate == NULL)
 8065 peter_e@gmx.net           223                 :UBC           0 :         sqlstate = ECPG_SQLSTATE_ECPG_INTERNAL_ERROR;
                                224                 :                : 
 6912 bruce@momjian.us          225         [ -  + ]:CBC           2 :     if (message == NULL)        /* Shouldn't happen, but need to be sure */
 6078 peter_e@gmx.net           226                 :UBC           0 :         message = ecpg_gettext("empty message text");
                                227                 :                : 
                                228                 :                :     /* these are not warnings */
 8069 bruce@momjian.us          229         [ +  + ]:CBC           2 :     if (strncmp(sqlstate, "00", 2) == 0)
 8210 meskes@postgresql.or      230                 :              1 :         return;
                                231                 :                : 
 6322 peter_e@gmx.net           232                 :              1 :     ecpg_log("ECPGnoticeReceiver: %s\n", message);
                                233                 :                : 
                                234                 :                :     /* map to SQLCODE for backward compatibility */
 8069 bruce@momjian.us          235         [ -  + ]:              1 :     if (strcmp(sqlstate, ECPG_SQLSTATE_INVALID_CURSOR_NAME) == 0)
 8072 peter_e@gmx.net           236                 :UBC           0 :         sqlcode = ECPG_WARNING_UNKNOWN_PORTAL;
 8069 bruce@momjian.us          237         [ -  + ]:CBC           1 :     else if (strcmp(sqlstate, ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION) == 0)
 8072 peter_e@gmx.net           238                 :UBC           0 :         sqlcode = ECPG_WARNING_IN_TRANSACTION;
 8069 bruce@momjian.us          239         [ -  + ]:CBC           1 :     else if (strcmp(sqlstate, ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION) == 0)
 8072 peter_e@gmx.net           240                 :UBC           0 :         sqlcode = ECPG_WARNING_NO_TRANSACTION;
 8069 bruce@momjian.us          241         [ -  + ]:CBC           1 :     else if (strcmp(sqlstate, ECPG_SQLSTATE_DUPLICATE_CURSOR) == 0)
 8072 peter_e@gmx.net           242                 :UBC           0 :         sqlcode = ECPG_WARNING_PORTAL_EXISTS;
                                243                 :                :     else
 8072 peter_e@gmx.net           244                 :CBC           1 :         sqlcode = 0;
                                245                 :                : 
                                246                 :              1 :     strncpy(sqlca->sqlstate, sqlstate, sizeof(sqlca->sqlstate));
                                247                 :              1 :     sqlca->sqlcode = sqlcode;
 8119 bruce@momjian.us          248                 :              1 :     sqlca->sqlwarn[2] = 'W';
                                249                 :              1 :     sqlca->sqlwarn[0] = 'W';
                                250                 :                : 
 8072 peter_e@gmx.net           251                 :              1 :     strncpy(sqlca->sqlerrm.sqlerrmc, message, sizeof(sqlca->sqlerrm.sqlerrmc));
                                252                 :              1 :     sqlca->sqlerrm.sqlerrmc[sizeof(sqlca->sqlerrm.sqlerrmc) - 1] = 0;
                                253                 :              1 :     sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
                                254                 :                : 
 6548 meskes@postgresql.or      255                 :              1 :     ecpg_log("raising sqlcode %d\n", sqlcode);
                                256                 :                : }
                                257                 :                : 
                                258                 :                : /* this contains some quick hacks, needs to be cleaned up, but it works */
                                259                 :                : bool
 8109                           260                 :            131 : ECPGconnect(int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
                                261                 :                : {
 8119 bruce@momjian.us          262                 :            131 :     struct sqlca_t *sqlca = ECPGget_sqlca();
 8109 meskes@postgresql.or      263                 :            131 :     enum COMPAT_MODE compat = c;
                                264                 :                :     struct connection *this;
                                265                 :                :     int         i,
 4836 bruce@momjian.us          266                 :            131 :                 connect_params = 0;
   45 michael@paquier.xyz       267                 :GNC         131 :     bool        alloc_failed = (sqlca == NULL);
                                268         [ +  - ]:            131 :     char       *dbname = name ? ecpg_strdup(name, lineno, &alloc_failed) : NULL,
 8210 meskes@postgresql.or      269                 :CBC         131 :                *host = NULL,
                                270                 :                :                *tmp,
                                271                 :            131 :                *port = NULL,
                                272                 :            131 :                *realname = NULL,
 4964                           273                 :            131 :                *options = NULL;
                                274                 :                :     const char **conn_keywords;
                                275                 :                :     const char **conn_values;
                                276                 :                : 
   45 michael@paquier.xyz       277         [ -  + ]:GNC         131 :     if (alloc_failed)
                                278                 :                :     {
 3736 meskes@postgresql.or      279                 :UBC           0 :         ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
                                280                 :                :                    ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
   45 michael@paquier.xyz       281         [ #  # ]:UNC           0 :         if (dbname)
                                282                 :              0 :             ecpg_free(dbname);
 3736 meskes@postgresql.or      283                 :UBC           0 :         return false;
                                284                 :                :     }
                                285                 :                : 
 6548 meskes@postgresql.or      286                 :CBC         131 :     ecpg_init_sqlca(sqlca);
                                287                 :                : 
                                288                 :                :     /*
                                289                 :                :      * clear auto_mem structure because some error handling functions might
                                290                 :                :      * access it
                                291                 :                :      */
                                292                 :            131 :     ecpg_clear_auto_mem();
                                293                 :                : 
 8108                           294   [ +  +  -  + ]:            131 :     if (INFORMIX_MODE(compat))
                                295                 :                :     {
                                296                 :                :         char       *envname;
                                297                 :                : 
                                298                 :                :         /*
                                299                 :                :          * Informix uses an environment variable DBPATH that overrides the
                                300                 :                :          * connection parameters given here. We do the same with PG_DBPATH as
                                301                 :                :          * the syntax is different.
                                302                 :                :          */
 8109                           303                 :              6 :         envname = getenv("PG_DBPATH");
                                304         [ -  + ]:              6 :         if (envname)
                                305                 :                :         {
 6548 meskes@postgresql.or      306                 :UBC           0 :             ecpg_free(dbname);
   45 michael@paquier.xyz       307                 :UNC           0 :             dbname = ecpg_strdup(envname, lineno, &alloc_failed);
                                308                 :                :         }
                                309                 :                :     }
                                310                 :                : 
 8210 meskes@postgresql.or      311   [ -  +  -  - ]:CBC         131 :     if (dbname == NULL && connection_name == NULL)
 8210 meskes@postgresql.or      312                 :UBC           0 :         connection_name = "DEFAULT";
                                313                 :                : 
 6975 meskes@postgresql.or      314                 :CBC         131 :     ecpg_pthreads_init();
                                315                 :                : 
                                316                 :                :     /* check if the identifier is unique */
 6548                           317         [ +  + ]:            131 :     if (ecpg_get_connection(connection_name))
                                318                 :                :     {
                                319                 :              2 :         ecpg_free(dbname);
                                320                 :              2 :         ecpg_log("ECPGconnect: connection identifier %s is already in use\n",
                                321                 :                :                  connection_name);
 6980                           322                 :              2 :         return false;
                                323                 :                :     }
                                324                 :                : 
 6548                           325         [ -  + ]:            129 :     if ((this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno)) == NULL)
                                326                 :                :     {
 3736 meskes@postgresql.or      327                 :UBC           0 :         ecpg_free(dbname);
 6980                           328                 :              0 :         return false;
                                329                 :                :     }
                                330                 :                : 
 7555 meskes@postgresql.or      331         [ +  - ]:CBC         129 :     if (dbname != NULL)
                                332                 :                :     {
                                333                 :                :         /* get the detail information from dbname */
 6950                           334   [ +  -  +  + ]:            129 :         if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0)
 7555                           335                 :              5 :         {
                                336                 :              6 :             int         offset = 0;
                                337                 :                : 
                                338                 :                :             /*
                                339                 :                :              * only allow protocols tcp and unix
                                340                 :                :              */
                                341         [ -  + ]:              6 :             if (strncmp(dbname, "tcp:", 4) == 0)
 7555 meskes@postgresql.or      342                 :UBC           0 :                 offset = 4;
 7555 meskes@postgresql.or      343         [ +  - ]:CBC           6 :             else if (strncmp(dbname, "unix:", 5) == 0)
                                344                 :              6 :                 offset = 5;
                                345                 :                : 
                                346         [ +  - ]:              6 :             if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0)
                                347                 :                :             {
                                348                 :                : 
                                349                 :                :                 /*------
                                350                 :                :                  * new style:
                                351                 :                :                  *  <tcp|unix>:postgresql://server[:port][/db-name][?options]
                                352                 :                :                  *------
                                353                 :                :                  */
                                354                 :              6 :                 offset += strlen("postgresql://");
                                355                 :                : 
                                356                 :              6 :                 tmp = strrchr(dbname + offset, '?');
                                357         [ +  + ]:              6 :                 if (tmp != NULL)    /* options given */
                                358                 :                :                 {
   45 michael@paquier.xyz       359                 :GNC           2 :                     options = ecpg_strdup(tmp + 1, lineno, &alloc_failed);
 7555 meskes@postgresql.or      360                 :CBC           2 :                     *tmp = '\0';
                                361                 :                :                 }
                                362                 :                : 
                                363                 :              6 :                 tmp = last_dir_separator(dbname + offset);
                                364         [ +  - ]:              6 :                 if (tmp != NULL)    /* database name given */
                                365                 :                :                 {
 6372                           366         [ +  + ]:              6 :                     if (tmp[1] != '\0') /* non-empty database name */
                                367                 :                :                     {
   45 michael@paquier.xyz       368                 :GNC           5 :                         realname = ecpg_strdup(tmp + 1, lineno, &alloc_failed);
 4950 meskes@postgresql.or      369                 :CBC           5 :                         connect_params++;
                                370                 :                :                     }
 7555                           371                 :              6 :                     *tmp = '\0';
                                372                 :                :                 }
                                373                 :                : 
                                374                 :              6 :                 tmp = strrchr(dbname + offset, ':');
 1668 tgl@sss.pgh.pa.us         375         [ -  + ]:              6 :                 if (tmp != NULL)    /* port number given */
                                376                 :                :                 {
 7555 meskes@postgresql.or      377                 :UBC           0 :                     *tmp = '\0';
   45 michael@paquier.xyz       378                 :UNC           0 :                     port = ecpg_strdup(tmp + 1, lineno, &alloc_failed);
 1668 tgl@sss.pgh.pa.us         379                 :UBC           0 :                     connect_params++;
                                380                 :                :                 }
                                381                 :                : 
 7555 meskes@postgresql.or      382         [ +  - ]:CBC           6 :                 if (strncmp(dbname, "unix:", 5) == 0)
                                383                 :                :                 {
                                384                 :                :                     /*
                                385                 :                :                      * The alternative of using "127.0.0.1" here is deprecated
                                386                 :                :                      * and undocumented; we'll keep it for backward
                                387                 :                :                      * compatibility's sake, but not extend it to allow IPv6.
                                388                 :                :                      */
 1668 tgl@sss.pgh.pa.us         389         [ +  + ]:              6 :                     if (strcmp(dbname + offset, "localhost") != 0 &&
                                390         [ +  - ]:              1 :                         strcmp(dbname + offset, "127.0.0.1") != 0)
                                391                 :                :                     {
 6322 peter_e@gmx.net           392                 :              1 :                         ecpg_log("ECPGconnect: non-localhost access via sockets on line %d\n", lineno);
 6078                           393         [ -  + ]:              1 :                         ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : ecpg_gettext("<DEFAULT>"));
 8210 meskes@postgresql.or      394         [ -  + ]:              1 :                         if (host)
 6548 meskes@postgresql.or      395                 :UBC           0 :                             ecpg_free(host);
 8210 meskes@postgresql.or      396         [ -  + ]:CBC           1 :                         if (port)
 6548 meskes@postgresql.or      397                 :UBC           0 :                             ecpg_free(port);
 8210 meskes@postgresql.or      398         [ -  + ]:CBC           1 :                         if (options)
 6548 meskes@postgresql.or      399                 :UBC           0 :                             ecpg_free(options);
 8210 meskes@postgresql.or      400         [ +  - ]:CBC           1 :                         if (realname)
 6548                           401                 :              1 :                             ecpg_free(realname);
 8210                           402         [ +  - ]:              1 :                         if (dbname)
 6548                           403                 :              1 :                             ecpg_free(dbname);
 6950                           404                 :              1 :                         free(this);
 8210                           405                 :              1 :                         return false;
                                406                 :                :                     }
                                407                 :                :                 }
                                408                 :                :                 else
                                409                 :                :                 {
 4266 meskes@postgresql.or      410         [ #  # ]:UBC           0 :                     if (*(dbname + offset) != '\0')
                                411                 :                :                     {
   45 michael@paquier.xyz       412                 :UNC           0 :                         host = ecpg_strdup(dbname + offset, lineno, &alloc_failed);
 4266 meskes@postgresql.or      413                 :UBC           0 :                         connect_params++;
                                414                 :                :                     }
                                415                 :                :                 }
                                416                 :                :             }
                                417                 :                :         }
                                418                 :                :         else
                                419                 :                :         {
                                420                 :                :             /* old style: dbname[@server][:port] */
 6950 meskes@postgresql.or      421                 :CBC         123 :             tmp = strrchr(dbname, ':');
                                422         [ -  + ]:            123 :             if (tmp != NULL)    /* port number given */
                                423                 :                :             {
   45 michael@paquier.xyz       424                 :UNC           0 :                 port = ecpg_strdup(tmp + 1, lineno, &alloc_failed);
 4950 meskes@postgresql.or      425                 :UBC           0 :                 connect_params++;
 6950                           426                 :              0 :                 *tmp = '\0';
                                427                 :                :             }
                                428                 :                : 
 6950 meskes@postgresql.or      429                 :CBC         123 :             tmp = strrchr(dbname, '@');
                                430         [ -  + ]:            123 :             if (tmp != NULL)    /* host name given */
                                431                 :                :             {
   45 michael@paquier.xyz       432                 :UNC           0 :                 host = ecpg_strdup(tmp + 1, lineno, &alloc_failed);
 4950 meskes@postgresql.or      433                 :UBC           0 :                 connect_params++;
 6950                           434                 :              0 :                 *tmp = '\0';
                                435                 :                :             }
                                436                 :                : 
 4950 meskes@postgresql.or      437         [ +  - ]:CBC         123 :             if (strlen(dbname) > 0)
                                438                 :                :             {
   45 michael@paquier.xyz       439                 :GNC         123 :                 realname = ecpg_strdup(dbname, lineno, &alloc_failed);
 4950 meskes@postgresql.or      440                 :CBC         123 :                 connect_params++;
                                441                 :                :             }
                                442                 :                :             else
 4950 meskes@postgresql.or      443                 :UBC           0 :                 realname = NULL;
                                444                 :                :         }
                                445                 :                :     }
                                446                 :                :     else
 7555                           447                 :              0 :         realname = NULL;
                                448                 :                : 
                                449                 :                :     /*
                                450                 :                :      * Count options for the allocation done below (this may produce an
                                451                 :                :      * overestimate, it's ok).
                                452                 :                :      */
 4950 meskes@postgresql.or      453         [ +  + ]:CBC         128 :     if (options)
 6372                           454         [ +  + ]:             65 :         for (i = 0; options[i]; i++)
 4950                           455         [ +  + ]:             63 :             if (options[i] == '=')
                                456                 :              3 :                 connect_params++;
                                457                 :                : 
                                458   [ +  +  +  - ]:            128 :     if (user && strlen(user) > 0)
                                459                 :              6 :         connect_params++;
                                460   [ +  +  +  - ]:            128 :     if (passwd && strlen(passwd) > 0)
                                461                 :              6 :         connect_params++;
                                462                 :                : 
                                463                 :                :     /*
                                464                 :                :      * Allocate enough space for all connection parameters.  These allocations
                                465                 :                :      * are done before manipulating the list of connections to ease the error
                                466                 :                :      * handling on failure.
                                467                 :                :      */
 4836 bruce@momjian.us          468                 :            128 :     conn_keywords = (const char **) ecpg_alloc((connect_params + 1) * sizeof(char *), lineno);
                                469                 :            128 :     conn_values = (const char **) ecpg_alloc(connect_params * sizeof(char *), lineno);
                                470                 :                : 
                                471                 :                :     /* Decide on a connection name */
   45 michael@paquier.xyz       472   [ +  +  +  - ]:GNC         128 :     if (connection_name != NULL || realname != NULL)
                                473                 :                :     {
                                474         [ +  + ]:            128 :         this->name = ecpg_strdup(connection_name ? connection_name : realname,
                                475                 :                :                                  lineno, &alloc_failed);
                                476                 :                :     }
                                477                 :                :     else
   45 michael@paquier.xyz       478                 :UNC           0 :         this->name = NULL;
                                479                 :                : 
                                480                 :                :     /* Deal with any failed allocations above */
   45 michael@paquier.xyz       481   [ +  -  +  -  :GNC         128 :     if (conn_keywords == NULL || conn_values == NULL || alloc_failed)
                                              -  + ]
                                482                 :                :     {
 4950 meskes@postgresql.or      483         [ #  # ]:UBC           0 :         if (host)
                                484                 :              0 :             ecpg_free(host);
                                485         [ #  # ]:              0 :         if (port)
                                486                 :              0 :             ecpg_free(port);
                                487         [ #  # ]:              0 :         if (options)
                                488                 :              0 :             ecpg_free(options);
                                489         [ #  # ]:              0 :         if (realname)
                                490                 :              0 :             ecpg_free(realname);
                                491         [ #  # ]:              0 :         if (dbname)
                                492                 :              0 :             ecpg_free(dbname);
 4930 peter_e@gmx.net           493         [ #  # ]:              0 :         if (conn_keywords)
                                494                 :              0 :             ecpg_free(conn_keywords);
                                495         [ #  # ]:              0 :         if (conn_values)
                                496                 :              0 :             ecpg_free(conn_values);
   45 michael@paquier.xyz       497         [ #  # ]:UNC           0 :         if (this->name)
                                498                 :              0 :             ecpg_free(this->name);
 4950 meskes@postgresql.or      499                 :UBC           0 :         free(this);
                                500                 :              0 :         return false;
                                501                 :                :     }
                                502                 :                : 
                                503                 :                :     /* add connection to our list */
 1454 michael@paquier.xyz       504                 :CBC         128 :     pthread_mutex_lock(&connections_mutex);
                                505                 :                : 
                                506                 :                :     /*
                                507                 :                :      * ... but first, make certain we have created ecpg_clocale.  Rely on
                                508                 :                :      * holding connections_mutex to ensure this is done by only one thread.
                                509                 :                :      */
                                510                 :                : #ifdef HAVE_USELOCALE
  162 peter@eisentraut.org      511         [ +  + ]:            128 :     if (!ecpg_clocale)
                                512                 :                :     {
                                513                 :             56 :         ecpg_clocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
                                514         [ -  + ]:             56 :         if (!ecpg_clocale)
                                515                 :                :         {
  162 peter@eisentraut.org      516                 :UBC           0 :             pthread_mutex_unlock(&connections_mutex);
                                517                 :              0 :             ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
                                518                 :                :                        ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
                                519         [ #  # ]:              0 :             if (host)
                                520                 :              0 :                 ecpg_free(host);
                                521         [ #  # ]:              0 :             if (port)
                                522                 :              0 :                 ecpg_free(port);
                                523         [ #  # ]:              0 :             if (options)
                                524                 :              0 :                 ecpg_free(options);
                                525         [ #  # ]:              0 :             if (realname)
                                526                 :              0 :                 ecpg_free(realname);
                                527         [ #  # ]:              0 :             if (dbname)
                                528                 :              0 :                 ecpg_free(dbname);
                                529         [ #  # ]:              0 :             if (conn_keywords)
                                530                 :              0 :                 ecpg_free(conn_keywords);
                                531         [ #  # ]:              0 :             if (conn_values)
                                532                 :              0 :                 ecpg_free(conn_values);
   45 michael@paquier.xyz       533         [ #  # ]:UNC           0 :             if (this->name)
                                534                 :              0 :                 ecpg_free(this->name);
  162 peter@eisentraut.org      535                 :UBC           0 :             free(this);
                                536                 :              0 :             return false;
                                537                 :                :         }
                                538                 :                :     }
                                539                 :                : #endif
                                540                 :                : 
 1454 michael@paquier.xyz       541                 :CBC         128 :     this->cache_head = NULL;
                                542                 :            128 :     this->prep_stmts = NULL;
                                543                 :                : 
                                544         [ +  + ]:            128 :     if (all_connections == NULL)
                                545                 :             73 :         this->next = NULL;
                                546                 :                :     else
                                547                 :             55 :         this->next = all_connections;
                                548                 :                : 
                                549                 :            128 :     all_connections = this;
                                550                 :            128 :     pthread_setspecific(actual_connection_key, all_connections);
                                551                 :            128 :     actual_connection = all_connections;
                                552                 :                : 
                                553   [ +  +  +  +  :            134 :     ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
                                     +  +  +  +  -  
                                        +  -  +  +  
                                                 + ]
                                554                 :                :              realname ? realname : "<DEFAULT>",
                                555                 :                :              host ? host : "<DEFAULT>",
 1454 michael@paquier.xyz       556         [ #  # ]:UBC           0 :              port ? (ecpg_internal_regression_mode ? "<REGRESSION_PORT>" : port) : "<DEFAULT>",
                                557                 :                :              options ? "with options " : "", options ? options : "",
 1454 michael@paquier.xyz       558         [ +  - ]:CBC           6 :              (user && strlen(user) > 0) ? "for user " : "", user ? user : "");
                                559                 :                : 
 4964 meskes@postgresql.or      560                 :            128 :     i = 0;
                                561         [ +  + ]:            128 :     if (realname)
                                562                 :                :     {
                                563                 :            127 :         conn_keywords[i] = "dbname";
                                564                 :            127 :         conn_values[i] = realname;
                                565                 :            127 :         i++;
                                566                 :                :     }
                                567         [ -  + ]:            128 :     if (host)
                                568                 :                :     {
 4964 meskes@postgresql.or      569                 :UBC           0 :         conn_keywords[i] = "host";
                                570                 :              0 :         conn_values[i] = host;
                                571                 :              0 :         i++;
                                572                 :                :     }
 4964 meskes@postgresql.or      573         [ -  + ]:CBC         128 :     if (port)
                                574                 :                :     {
 4964 meskes@postgresql.or      575                 :UBC           0 :         conn_keywords[i] = "port";
                                576                 :              0 :         conn_values[i] = port;
                                577                 :              0 :         i++;
                                578                 :                :     }
 4964 meskes@postgresql.or      579   [ +  +  +  - ]:CBC         128 :     if (user && strlen(user) > 0)
                                580                 :                :     {
                                581                 :              6 :         conn_keywords[i] = "user";
                                582                 :              6 :         conn_values[i] = user;
                                583                 :              6 :         i++;
                                584                 :                :     }
                                585   [ +  +  +  - ]:            128 :     if (passwd && strlen(passwd) > 0)
                                586                 :                :     {
                                587                 :              6 :         conn_keywords[i] = "password";
                                588                 :              6 :         conn_values[i] = passwd;
                                589                 :              6 :         i++;
                                590                 :                :     }
                                591         [ +  + ]:            128 :     if (options)
                                592                 :                :     {
                                593                 :                :         char       *str;
                                594                 :                : 
                                595                 :                :         /*
                                596                 :                :          * The options string contains "keyword=value" pairs separated by
                                597                 :                :          * '&'s.  We must break this up into keywords and values to pass to
                                598                 :                :          * libpq (it's okay to scribble on the options string).  We ignore
                                599                 :                :          * spaces just before each keyword or value.  (The preprocessor used
                                600                 :                :          * to add spaces around '&'s, making it necessary to ignore spaces
                                601                 :                :          * before keywords here.  While it no longer does that, we still must
                                602                 :                :          * skip spaces to support code compiled with older preprocessors.)
                                603                 :                :          */
 4948                           604         [ +  + ]:              5 :         for (str = options; *str;)
                                605                 :                :         {
                                606                 :                :             int         e,
                                607                 :                :                         a;
                                608                 :                :             char       *token1,
                                609                 :                :                        *token2;
                                610                 :                : 
                                611                 :                :             /* Skip spaces before keyword */
 2198 tgl@sss.pgh.pa.us         612         [ -  + ]:              3 :             for (token1 = str; *token1 == ' '; token1++)
                                613                 :                :                  /* skip */ ;
                                614                 :                :             /* Find end of keyword */
                                615   [ +  -  +  + ]:             43 :             for (e = 0; token1[e] && token1[e] != '='; e++)
                                616                 :                :                  /* skip */ ;
 4836 bruce@momjian.us          617         [ +  - ]:              3 :             if (token1[e])      /* found "=" */
                                618                 :                :             {
 4948 meskes@postgresql.or      619                 :              3 :                 token1[e] = '\0';
                                620                 :                :                 /* Skip spaces before value */
 2198 tgl@sss.pgh.pa.us         621         [ -  + ]:              3 :                 for (token2 = token1 + e + 1; *token2 == ' '; token2++)
                                622                 :                :                      /* skip */ ;
                                623                 :                :                 /* Find end of value */
                                624   [ +  +  +  + ]:             22 :                 for (a = 0; token2[a] && token2[a] != '&'; a++)
                                625                 :                :                      /* skip */ ;
 4836 bruce@momjian.us          626         [ +  + ]:              3 :                 if (token2[a])  /* found "&" => another option follows */
                                627                 :                :                 {
 4948 meskes@postgresql.or      628                 :              1 :                     token2[a] = '\0';
                                629                 :              1 :                     str = token2 + a + 1;
                                630                 :                :                 }
                                631                 :                :                 else
                                632                 :              2 :                     str = token2 + a;
                                633                 :                : 
                                634                 :              3 :                 conn_keywords[i] = token1;
                                635                 :              3 :                 conn_values[i] = token2;
                                636                 :              3 :                 i++;
                                637                 :                :             }
                                638                 :                :             else
                                639                 :                :             {
                                640                 :                :                 /* Bogus options syntax ... ignore trailing garbage */
 4836 bruce@momjian.us          641                 :UBC           0 :                 str = token1 + e;
                                642                 :                :             }
                                643                 :                :         }
                                644                 :                :     }
                                645                 :                : 
 2198 tgl@sss.pgh.pa.us         646         [ -  + ]:CBC         128 :     Assert(i <= connect_params);
 4964 meskes@postgresql.or      647                 :            128 :     conn_keywords[i] = NULL;    /* terminator */
                                648                 :                : 
                                649                 :            128 :     this->connection = PQconnectdbParams(conn_keywords, conn_values, 0);
                                650                 :                : 
 6372                           651         [ -  + ]:            128 :     if (host)
 6372 meskes@postgresql.or      652                 :UBC           0 :         ecpg_free(host);
 6372 meskes@postgresql.or      653         [ -  + ]:CBC         128 :     if (port)
 6372 meskes@postgresql.or      654                 :UBC           0 :         ecpg_free(port);
 6372 meskes@postgresql.or      655         [ +  + ]:CBC         128 :     if (options)
                                656                 :              2 :         ecpg_free(options);
                                657         [ +  - ]:            128 :     if (dbname)
                                658                 :            128 :         ecpg_free(dbname);
 4950                           659                 :            128 :     ecpg_free(conn_values);
                                660                 :            128 :     ecpg_free(conn_keywords);
                                661                 :                : 
 8210                           662         [ +  + ]:            128 :     if (PQstatus(this->connection) == CONNECTION_BAD)
                                663                 :                :     {
 8069 bruce@momjian.us          664                 :              1 :         const char *errmsg = PQerrorMessage(this->connection);
 6078 peter_e@gmx.net           665         [ +  - ]:              1 :         const char *db = realname ? realname : ecpg_gettext("<DEFAULT>");
                                666                 :                : 
                                667                 :                :         /* PQerrorMessage's result already has a trailing newline */
 1688 tgl@sss.pgh.pa.us         668                 :              1 :         ecpg_log("ECPGconnect: %s", errmsg);
                                669                 :                : 
 7019 meskes@postgresql.or      670                 :              1 :         ecpg_finish(this);
                                671                 :              1 :         pthread_mutex_unlock(&connections_mutex);
                                672                 :                : 
 6548                           673                 :              1 :         ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, db);
 8210                           674         [ -  + ]:              1 :         if (realname)
 6548 meskes@postgresql.or      675                 :UBC           0 :             ecpg_free(realname);
                                676                 :                : 
 8210 meskes@postgresql.or      677                 :CBC           1 :         return false;
                                678                 :                :     }
                                679                 :                : 
                                680         [ +  - ]:            127 :     if (realname)
 6548                           681                 :            127 :         ecpg_free(realname);
                                682                 :                : 
 6372                           683                 :            127 :     pthread_mutex_unlock(&connections_mutex);
                                684                 :                : 
 8210                           685                 :            127 :     this->autocommit = autocommit;
                                686                 :                : 
  282 peter@eisentraut.org      687                 :            127 :     PQsetNoticeReceiver(this->connection, &ECPGnoticeReceiver, this);
                                688                 :                : 
 8210 meskes@postgresql.or      689                 :            127 :     return true;
                                690                 :                : }
                                691                 :                : 
                                692                 :                : bool
                                693                 :            128 : ECPGdisconnect(int lineno, const char *connection_name)
                                694                 :                : {
 8119 bruce@momjian.us          695                 :            128 :     struct sqlca_t *sqlca = ECPGget_sqlca();
                                696                 :                :     struct connection *con;
                                697                 :                : 
 3736 meskes@postgresql.or      698         [ -  + ]:            128 :     if (sqlca == NULL)
                                699                 :                :     {
 3736 meskes@postgresql.or      700                 :UBC           0 :         ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
                                701                 :                :                    ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
 2942 peter_e@gmx.net           702                 :              0 :         return false;
                                703                 :                :     }
                                704                 :                : 
 8119 bruce@momjian.us          705                 :CBC         128 :     pthread_mutex_lock(&connections_mutex);
                                706                 :                : 
 8210 meskes@postgresql.or      707         [ +  + ]:            128 :     if (strcmp(connection_name, "ALL") == 0)
                                708                 :                :     {
 6548                           709                 :             16 :         ecpg_init_sqlca(sqlca);
 8210                           710         [ +  + ]:             34 :         for (con = all_connections; con;)
                                711                 :                :         {
                                712                 :             18 :             struct connection *f = con;
                                713                 :                : 
                                714                 :             18 :             con = con->next;
                                715                 :             18 :             ecpg_finish(f);
                                716                 :                :         }
                                717                 :                :     }
                                718                 :                :     else
                                719                 :                :     {
 8103                           720                 :            112 :         con = ecpg_get_connection_nr(connection_name);
                                721                 :                : 
 6548                           722         [ +  + ]:            112 :         if (!ecpg_init(con, connection_name, lineno))
                                723                 :                :         {
 8069 bruce@momjian.us          724                 :              8 :             pthread_mutex_unlock(&connections_mutex);
 2942 peter_e@gmx.net           725                 :              8 :             return false;
                                726                 :                :         }
                                727                 :                :         else
 8069 bruce@momjian.us          728                 :            104 :             ecpg_finish(con);
                                729                 :                :     }
                                730                 :                : 
 8119                           731                 :            120 :     pthread_mutex_unlock(&connections_mutex);
                                732                 :                : 
 8210 meskes@postgresql.or      733                 :            120 :     return true;
                                734                 :                : }
                                735                 :                : 
                                736                 :                : PGconn *
 5931 bruce@momjian.us          737                 :UBC           0 : ECPGget_PGconn(const char *connection_name)
                                738                 :                : {
                                739                 :                :     struct connection *con;
                                740                 :                : 
                                741                 :              0 :     con = ecpg_get_connection(connection_name);
                                742         [ #  # ]:              0 :     if (con == NULL)
                                743                 :              0 :         return NULL;
                                744                 :                : 
 6379 meskes@postgresql.or      745                 :              0 :     return con->connection;
                                746                 :                : }
        

Generated by: LCOV version 2.4-beta