PostgreSQL Source Code  git master
connect.c File Reference
#include "postgres_fe.h"
#include "ecpg-pthread-win32.h"
#include "ecpgerrno.h"
#include "ecpglib.h"
#include "ecpglib_extern.h"
#include "ecpgtype.h"
#include "sqlca.h"
Include dependency graph for connect.c:

Go to the source code of this file.

Macros

#define POSTGRES_ECPG_INTERNAL
 

Functions

static struct connectionecpg_get_connection_nr (const char *connection_name)
 
struct connectionecpg_get_connection (const char *connection_name)
 
static void ecpg_finish (struct connection *act)
 
bool ECPGsetcommit (int lineno, const char *mode, const char *connection_name)
 
bool ECPGsetconn (int lineno, const char *connection_name)
 
static void ECPGnoticeReceiver (void *arg, const PGresult *result)
 
bool ECPGconnect (int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
 
bool ECPGdisconnect (int lineno, const char *connection_name)
 
PGconnECPGget_PGconn (const char *connection_name)
 

Variables

static struct connectionactual_connection = NULL
 
static struct connectionall_connections = NULL
 

Macro Definition Documentation

◆ POSTGRES_ECPG_INTERNAL

#define POSTGRES_ECPG_INTERNAL

Definition at line 3 of file connect.c.

Function Documentation

◆ ecpg_finish()

static void ecpg_finish ( struct connection act)
static

Definition at line 113 of file connect.c.

References all_connections, connection::cache_head, connection::connection, ECPG_COMPAT_PGSQL, ecpg_deallocate_all_conn(), ecpg_free(), ecpg_log(), ivlist, connection::name, ECPGtype_information_cache::next, connection::next, var_list::next, PQfinish(), pthread_getspecific(), and pthread_setspecific().

Referenced by ECPGconnect(), and ECPGdisconnect().

114 {
115  if (act != NULL)
116  {
117  struct ECPGtype_information_cache *cache,
118  *ptr;
119 
121  PQfinish(act->connection);
122 
123  /*
124  * no need to lock connections_mutex - we're always called by
125  * ECPGdisconnect or ECPGconnect, which are holding the lock
126  */
127 
128  /* remove act from the list */
129  if (act == all_connections)
130  all_connections = act->next;
131  else
132  {
133  struct connection *con;
134 
135  for (con = all_connections; con->next && con->next != act; con = con->next);
136  if (con->next)
137  con->next = act->next;
138  }
139 
140 #ifdef ENABLE_THREAD_SAFETY
141  if (pthread_getspecific(actual_connection_key) == act)
142  pthread_setspecific(actual_connection_key, all_connections);
143 #endif
144  if (actual_connection == act)
146 
147  ecpg_log("ecpg_finish: connection %s closed\n", act->name ? act->name : "(null)");
148 
149  for (cache = act->cache_head; cache; ptr = cache, cache = cache->next, ecpg_free(ptr));
150  ecpg_free(act->name);
151  ecpg_free(act);
152  /* delete cursor variables when last connection gets closed */
153  if (all_connections == NULL)
154  {
155  struct var_list *iv_ptr;
156 
157  for (; ivlist; iv_ptr = ivlist, ivlist = ivlist->next, ecpg_free(iv_ptr));
158  }
159  }
160  else
161  ecpg_log("ecpg_finish: called an extra time\n");
162 }
struct var_list * next
void ecpg_free(void *)
Definition: memory.c:13
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4221
struct ECPGtype_information_cache * next
static struct connection * all_connections
Definition: connect.c:19
struct ECPGtype_information_cache * cache_head
struct connection * next
void ecpg_log(const char *format,...) pg_attribute_printf(1
struct var_list * ivlist
Definition: misc.c:523
PGconn * connection
void * pthread_getspecific(pthread_key_t key)
Definition: pthread-win32.c:29
void pthread_setspecific(pthread_key_t key, void *val)
Definition: pthread-win32.c:24
static struct connection * actual_connection
Definition: connect.c:18
bool ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *conn)
Definition: prepare.c:337

◆ ecpg_get_connection()

struct connection* ecpg_get_connection ( const char *  connection_name)

Definition at line 74 of file connect.c.

References actual_connection, ecpg_get_connection_nr(), pthread_getspecific(), pthread_mutex_lock(), and pthread_mutex_unlock().

Referenced by ecpg_auto_prepare(), ecpg_do_prologue(), ecpg_freeStmtCacheEntry(), ECPGconnect(), ECPGdeallocate(), ECPGdeallocate_all(), ECPGdescribe(), ECPGget_desc(), ECPGget_PGconn(), ECPGprepare(), ECPGprepared_statement(), ECPGsetcommit(), ECPGsetconn(), ECPGstatus(), ECPGtrans(), and ECPGtransactionStatus().

75 {
76  struct connection *ret = NULL;
77 
78  if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
79  {
80 #ifdef ENABLE_THREAD_SAFETY
81  ret = pthread_getspecific(actual_connection_key);
82 
83  /*
84  * if no connection in TSD for this thread, get the global default
85  * connection and hope the user knows what they're doing (i.e. using
86  * their own mutex to protect that connection from concurrent accesses
87  */
88  /* if !ret then we got the connection from TSD */
89  if (NULL == ret)
90  /* no TSD connection here either, using global */
91  ret = actual_connection;
92 #else
93  ret = actual_connection;
94 #endif
95  }
96  else
97  {
98 #ifdef ENABLE_THREAD_SAFETY
99  pthread_mutex_lock(&connections_mutex);
100 #endif
101 
102  ret = ecpg_get_connection_nr(connection_name);
103 
104 #ifdef ENABLE_THREAD_SAFETY
105  pthread_mutex_unlock(&connections_mutex);
106 #endif
107  }
108 
109  return ret;
110 }
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:45
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:54
void * pthread_getspecific(pthread_key_t key)
Definition: pthread-win32.c:29
static struct connection * ecpg_get_connection_nr(const char *connection_name)
Definition: connect.c:36
static struct connection * actual_connection
Definition: connect.c:18

◆ ecpg_get_connection_nr()

static struct connection* ecpg_get_connection_nr ( const char *  connection_name)
static

Definition at line 36 of file connect.c.

References actual_connection, connection::name, connection::next, and pthread_getspecific().

Referenced by ecpg_get_connection(), and ECPGdisconnect().

37 {
38  struct connection *ret = NULL;
39 
40  if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
41  {
42 #ifdef ENABLE_THREAD_SAFETY
43  ret = pthread_getspecific(actual_connection_key);
44 
45  /*
46  * if no connection in TSD for this thread, get the global default
47  * connection and hope the user knows what they're doing (i.e. using
48  * their own mutex to protect that connection from concurrent accesses
49  */
50  /* if !ret then we got the connection from TSD */
51  if (NULL == ret)
52  /* no TSD connection, going for global */
53  ret = actual_connection;
54 #else
55  ret = actual_connection;
56 #endif
57  }
58  else
59  {
60  struct connection *con;
61 
62  for (con = all_connections; con != NULL; con = con->next)
63  {
64  if (strcmp(connection_name, con->name) == 0)
65  break;
66  }
67  ret = con;
68  }
69 
70  return ret;
71 }
static struct connection * all_connections
Definition: connect.c:19
struct connection * next
void * pthread_getspecific(pthread_key_t key)
Definition: pthread-win32.c:29
static struct connection * actual_connection
Definition: connect.c:18

◆ ECPGconnect()

bool ECPGconnect ( int  lineno,
int  c,
const char *  name,
const char *  user,
const char *  passwd,
const char *  connection_name,
int  autocommit 
)

Definition at line 271 of file connect.c.

References all_connections, Assert, autocommit, connection::cache_head, compat, CONNECTION_BAD, dbname, ecpg_alloc(), ecpg_clear_auto_mem(), ECPG_CONNECT, ecpg_finish(), ecpg_free(), ecpg_get_connection(), ecpg_gettext, ecpg_init_sqlca(), ecpg_internal_regression_mode, ecpg_log(), ECPG_OUT_OF_MEMORY, ecpg_raise(), ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, ecpg_strdup(), ECPGget_sqlca(), ECPGnoticeReceiver(), errmsg(), free, i, INFORMIX_MODE, last_dir_separator(), next, port, PQconnectdbParams(), PQerrorMessage(), PQsetNoticeReceiver(), PQstatus(), connection::prep_stmts, pthread_mutex_lock(), pthread_mutex_unlock(), pthread_setspecific(), sqlca, generate_unaccent_rules::str, and user.

Referenced by main(), and test().

272 {
273  struct sqlca_t *sqlca = ECPGget_sqlca();
274  enum COMPAT_MODE compat = c;
275  struct connection *this;
276  int i,
277  connect_params = 0;
278  char *dbname = name ? ecpg_strdup(name, lineno) : NULL,
279  *host = NULL,
280  *tmp,
281  *port = NULL,
282  *realname = NULL,
283  *options = NULL;
284  const char **conn_keywords;
285  const char **conn_values;
286 
287  if (sqlca == NULL)
288  {
291  ecpg_free(dbname);
292  return false;
293  }
294 
295  ecpg_init_sqlca(sqlca);
296 
297  /*
298  * clear auto_mem structure because some error handling functions might
299  * access it
300  */
302 
303  if (INFORMIX_MODE(compat))
304  {
305  char *envname;
306 
307  /*
308  * Informix uses an environment variable DBPATH that overrides the
309  * connection parameters given here. We do the same with PG_DBPATH as
310  * the syntax is different.
311  */
312  envname = getenv("PG_DBPATH");
313  if (envname)
314  {
315  ecpg_free(dbname);
316  dbname = ecpg_strdup(envname, lineno);
317  }
318 
319  }
320 
321  if (dbname == NULL && connection_name == NULL)
322  connection_name = "DEFAULT";
323 
324 #if ENABLE_THREAD_SAFETY
325  ecpg_pthreads_init();
326 #endif
327 
328  /* check if the identifier is unique */
329  if (ecpg_get_connection(connection_name))
330  {
331  ecpg_free(dbname);
332  ecpg_log("ECPGconnect: connection identifier %s is already in use\n",
333  connection_name);
334  return false;
335  }
336 
337  if ((this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno)) == NULL)
338  {
339  ecpg_free(dbname);
340  return false;
341  }
342 
343  if (dbname != NULL)
344  {
345  /* get the detail information from dbname */
346  if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0)
347  {
348  int offset = 0;
349 
350  /*
351  * only allow protocols tcp and unix
352  */
353  if (strncmp(dbname, "tcp:", 4) == 0)
354  offset = 4;
355  else if (strncmp(dbname, "unix:", 5) == 0)
356  offset = 5;
357 
358  if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0)
359  {
360 
361  /*------
362  * new style:
363  * <tcp|unix>:postgresql://server[:port][/db-name][?options]
364  *------
365  */
366  offset += strlen("postgresql://");
367 
368  tmp = strrchr(dbname + offset, '?');
369  if (tmp != NULL) /* options given */
370  {
371  options = ecpg_strdup(tmp + 1, lineno);
372  *tmp = '\0';
373  }
374 
375  tmp = last_dir_separator(dbname + offset);
376  if (tmp != NULL) /* database name given */
377  {
378  if (tmp[1] != '\0') /* non-empty database name */
379  {
380  realname = ecpg_strdup(tmp + 1, lineno);
381  connect_params++;
382  }
383  *tmp = '\0';
384  }
385 
386  tmp = strrchr(dbname + offset, ':');
387  if (tmp != NULL) /* port number given */
388  {
389  *tmp = '\0';
390  port = ecpg_strdup(tmp + 1, lineno);
391  connect_params++;
392  }
393 
394  if (strncmp(dbname, "unix:", 5) == 0)
395  {
396  /*
397  * The alternative of using "127.0.0.1" here is deprecated
398  * and undocumented; we'll keep it for backward
399  * compatibility's sake, but not extend it to allow IPv6.
400  */
401  if (strcmp(dbname + offset, "localhost") != 0 &&
402  strcmp(dbname + offset, "127.0.0.1") != 0)
403  {
404  ecpg_log("ECPGconnect: non-localhost access via sockets on line %d\n", lineno);
406  if (host)
407  ecpg_free(host);
408  if (port)
409  ecpg_free(port);
410  if (options)
412  if (realname)
413  ecpg_free(realname);
414  if (dbname)
415  ecpg_free(dbname);
416  free(this);
417  return false;
418  }
419  }
420  else
421  {
422  if (*(dbname + offset) != '\0')
423  {
424  host = ecpg_strdup(dbname + offset, lineno);
425  connect_params++;
426  }
427  }
428  }
429  }
430  else
431  {
432  /* old style: dbname[@server][:port] */
433  tmp = strrchr(dbname, ':');
434  if (tmp != NULL) /* port number given */
435  {
436  port = ecpg_strdup(tmp + 1, lineno);
437  connect_params++;
438  *tmp = '\0';
439  }
440 
441  tmp = strrchr(dbname, '@');
442  if (tmp != NULL) /* host name given */
443  {
444  host = ecpg_strdup(tmp + 1, lineno);
445  connect_params++;
446  *tmp = '\0';
447  }
448 
449  if (strlen(dbname) > 0)
450  {
451  realname = ecpg_strdup(dbname, lineno);
452  connect_params++;
453  }
454  else
455  realname = NULL;
456  }
457  }
458  else
459  realname = NULL;
460 
461  /* add connection to our list */
462 #ifdef ENABLE_THREAD_SAFETY
463  pthread_mutex_lock(&connections_mutex);
464 #endif
465  if (connection_name != NULL)
466  this->name = ecpg_strdup(connection_name, lineno);
467  else
468  this->name = ecpg_strdup(realname, lineno);
469 
470  this->cache_head = NULL;
471  this->prep_stmts = NULL;
472 
473  if (all_connections == NULL)
474  this->next = NULL;
475  else
476  this->next = all_connections;
477 
478  all_connections = this;
479 #ifdef ENABLE_THREAD_SAFETY
480  pthread_setspecific(actual_connection_key, all_connections);
481 #endif
483 
484  ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
485  realname ? realname : "<DEFAULT>",
486  host ? host : "<DEFAULT>",
487  port ? (ecpg_internal_regression_mode ? "<REGRESSION_PORT>" : port) : "<DEFAULT>",
488  options ? "with options " : "", options ? options : "",
489  (user && strlen(user) > 0) ? "for user " : "", user ? user : "");
490 
491  /* count options (this may produce an overestimate, it's ok) */
492  if (options)
493  for (i = 0; options[i]; i++)
494  if (options[i] == '=')
495  connect_params++;
496 
497  if (user && strlen(user) > 0)
498  connect_params++;
499  if (passwd && strlen(passwd) > 0)
500  connect_params++;
501 
502  /* allocate enough space for all connection parameters */
503  conn_keywords = (const char **) ecpg_alloc((connect_params + 1) * sizeof(char *), lineno);
504  conn_values = (const char **) ecpg_alloc(connect_params * sizeof(char *), lineno);
505  if (conn_keywords == NULL || conn_values == NULL)
506  {
507  if (host)
508  ecpg_free(host);
509  if (port)
510  ecpg_free(port);
511  if (options)
512  ecpg_free(options);
513  if (realname)
514  ecpg_free(realname);
515  if (dbname)
516  ecpg_free(dbname);
517  if (conn_keywords)
518  ecpg_free(conn_keywords);
519  if (conn_values)
520  ecpg_free(conn_values);
521  free(this);
522  return false;
523  }
524 
525  i = 0;
526  if (realname)
527  {
528  conn_keywords[i] = "dbname";
529  conn_values[i] = realname;
530  i++;
531  }
532  if (host)
533  {
534  conn_keywords[i] = "host";
535  conn_values[i] = host;
536  i++;
537  }
538  if (port)
539  {
540  conn_keywords[i] = "port";
541  conn_values[i] = port;
542  i++;
543  }
544  if (user && strlen(user) > 0)
545  {
546  conn_keywords[i] = "user";
547  conn_values[i] = user;
548  i++;
549  }
550  if (passwd && strlen(passwd) > 0)
551  {
552  conn_keywords[i] = "password";
553  conn_values[i] = passwd;
554  i++;
555  }
556  if (options)
557  {
558  char *str;
559 
560  /*
561  * The options string contains "keyword=value" pairs separated by
562  * '&'s. We must break this up into keywords and values to pass to
563  * libpq (it's okay to scribble on the options string). We ignore
564  * spaces just before each keyword or value.
565  */
566  for (str = options; *str;)
567  {
568  int e,
569  a;
570  char *token1,
571  *token2;
572 
573  /* Skip spaces before keyword */
574  for (token1 = str; *token1 == ' '; token1++)
575  /* skip */ ;
576  /* Find end of keyword */
577  for (e = 0; token1[e] && token1[e] != '='; e++)
578  /* skip */ ;
579  if (token1[e]) /* found "=" */
580  {
581  token1[e] = '\0';
582  /* Skip spaces before value */
583  for (token2 = token1 + e + 1; *token2 == ' '; token2++)
584  /* skip */ ;
585  /* Find end of value */
586  for (a = 0; token2[a] && token2[a] != '&'; a++)
587  /* skip */ ;
588  if (token2[a]) /* found "&" => another option follows */
589  {
590  token2[a] = '\0';
591  str = token2 + a + 1;
592  }
593  else
594  str = token2 + a;
595 
596  conn_keywords[i] = token1;
597  conn_values[i] = token2;
598  i++;
599  }
600  else
601  {
602  /* Bogus options syntax ... ignore trailing garbage */
603  str = token1 + e;
604  }
605  }
606  }
607 
608  Assert(i <= connect_params);
609  conn_keywords[i] = NULL; /* terminator */
610 
611  this->connection = PQconnectdbParams(conn_keywords, conn_values, 0);
612 
613  if (host)
614  ecpg_free(host);
615  if (port)
616  ecpg_free(port);
617  if (options)
618  ecpg_free(options);
619  if (dbname)
620  ecpg_free(dbname);
621  ecpg_free(conn_values);
622  ecpg_free(conn_keywords);
623 
624  if (PQstatus(this->connection) == CONNECTION_BAD)
625  {
626  const char *errmsg = PQerrorMessage(this->connection);
627  const char *db = realname ? realname : ecpg_gettext("<DEFAULT>");
628 
629  /* PQerrorMessage's result already has a trailing newline */
630  ecpg_log("ECPGconnect: %s", errmsg);
631 
632  ecpg_finish(this);
633 #ifdef ENABLE_THREAD_SAFETY
634  pthread_mutex_unlock(&connections_mutex);
635 #endif
636 
638  if (realname)
639  ecpg_free(realname);
640 
641  return false;
642  }
643 
644  if (realname)
645  ecpg_free(realname);
646 
647 #ifdef ENABLE_THREAD_SAFETY
648  pthread_mutex_unlock(&connections_mutex);
649 #endif
650 
651  this->autocommit = autocommit;
652 
653  PQsetNoticeReceiver(this->connection, &ECPGnoticeReceiver, (void *) this);
654 
655  return true;
656 }
#define ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6727
COMPAT_MODE
static void ecpg_finish(struct connection *act)
Definition: connect.c:113
#define ECPG_CONNECT
Definition: ecpgerrno.h:51
static int32 next
Definition: blutils.c:219
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
#define sqlca
Definition: sqlca.h:59
void ecpg_free(void *)
Definition: memory.c:13
char * ecpg_strdup(const char *, int)
Definition: memory.c:47
#define INFORMIX_MODE(X)
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:662
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
#define ecpg_gettext(x)
#define ECPG_OUT_OF_MEMORY
Definition: ecpgerrno.h:15
static struct connection * all_connections
Definition: connect.c:19
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:141
struct ECPGtype_information_cache * cache_head
Definition: sqlca.h:19
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:45
char * c
bool ecpg_internal_regression_mode
Definition: misc.c:29
void ecpg_log(const char *format,...) pg_attribute_printf(1
enum COMPAT_MODE compat
Definition: ecpg.c:25
static int port
Definition: pg_regress.c:92
char * ecpg_alloc(long, int)
Definition: memory.c:19
void ecpg_clear_auto_mem(void)
Definition: memory.c:158
void ecpg_init_sqlca(struct sqlca_t *sqlca)
Definition: misc.c:98
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:54
char * last_dir_separator(const char *filename)
Definition: path.c:138
#define free(a)
Definition: header.h:65
#define Assert(condition)
Definition: c.h:804
bool autocommit
Definition: ecpg.c:15
char * dbname
Definition: streamutil.c:51
const char * name
Definition: encode.c:515
e
Definition: preproc-init.c:82
static char * user
Definition: pg_regress.c:95
int errmsg(const char *fmt,...)
Definition: elog.c:909
void pthread_setspecific(pthread_key_t key, void *val)
Definition: pthread-win32.c:24
static struct connection * actual_connection
Definition: connect.c:18
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
int i
static void ECPGnoticeReceiver(void *arg, const PGresult *result)
Definition: connect.c:219
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6674
PQnoticeReceiver PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg)
Definition: fe-connect.c:6870
struct prepared_statement * prep_stmts

◆ ECPGdisconnect()

bool ECPGdisconnect ( int  lineno,
const char *  connection_name 
)

Definition at line 659 of file connect.c.

References ecpg_finish(), ecpg_get_connection_nr(), ecpg_init(), ecpg_init_sqlca(), ECPG_OUT_OF_MEMORY, ecpg_raise(), ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, ECPGget_sqlca(), connection::next, pthread_mutex_lock(), pthread_mutex_unlock(), and sqlca.

Referenced by main(), and test().

660 {
661  struct sqlca_t *sqlca = ECPGget_sqlca();
662  struct connection *con;
663 
664  if (sqlca == NULL)
665  {
668  return false;
669  }
670 
671 #ifdef ENABLE_THREAD_SAFETY
672  pthread_mutex_lock(&connections_mutex);
673 #endif
674 
675  if (strcmp(connection_name, "ALL") == 0)
676  {
677  ecpg_init_sqlca(sqlca);
678  for (con = all_connections; con;)
679  {
680  struct connection *f = con;
681 
682  con = con->next;
683  ecpg_finish(f);
684  }
685  }
686  else
687  {
688  con = ecpg_get_connection_nr(connection_name);
689 
690  if (!ecpg_init(con, connection_name, lineno))
691  {
692 #ifdef ENABLE_THREAD_SAFETY
693  pthread_mutex_unlock(&connections_mutex);
694 #endif
695  return false;
696  }
697  else
698  ecpg_finish(con);
699  }
700 
701 #ifdef ENABLE_THREAD_SAFETY
702  pthread_mutex_unlock(&connections_mutex);
703 #endif
704 
705  return true;
706 }
static void ecpg_finish(struct connection *act)
Definition: connect.c:113
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
#define sqlca
Definition: sqlca.h:59
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
#define ECPG_OUT_OF_MEMORY
Definition: ecpgerrno.h:15
static struct connection * all_connections
Definition: connect.c:19
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:141
Definition: sqlca.h:19
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:45
struct connection * next
void ecpg_init_sqlca(struct sqlca_t *sqlca)
Definition: misc.c:98
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:54
static struct connection * ecpg_get_connection_nr(const char *connection_name)
Definition: connect.c:36
bool ecpg_init(const struct connection *, const char *, const int)
Definition: misc.c:104

◆ ECPGget_PGconn()

PGconn* ECPGget_PGconn ( const char *  connection_name)

Definition at line 709 of file connect.c.

References connection::connection, and ecpg_get_connection().

710 {
711  struct connection *con;
712 
713  con = ecpg_get_connection(connection_name);
714  if (con == NULL)
715  return NULL;
716 
717  return con->connection;
718 }
PGconn * connection
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74

◆ ECPGnoticeReceiver()

static void ECPGnoticeReceiver ( void *  arg,
const PGresult result 
)
static

Definition at line 219 of file connect.c.

References ecpg_gettext, ecpg_log(), ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION, ECPG_SQLSTATE_DUPLICATE_CURSOR, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ECPG_SQLSTATE_INVALID_CURSOR_NAME, ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION, ECPG_WARNING_IN_TRANSACTION, ECPG_WARNING_NO_TRANSACTION, ECPG_WARNING_PORTAL_EXISTS, ECPG_WARNING_UNKNOWN_PORTAL, ECPGget_sqlca(), PG_DIAG_MESSAGE_PRIMARY, PG_DIAG_SQLSTATE, PQresultErrorField(), sqlca, sqlca_t::sqlcode, sqlca_t::sqlerrm, sqlca_t::sqlerrmc, sqlca_t::sqlerrml, sqlca_t::sqlstate, and sqlca_t::sqlwarn.

Referenced by ECPGconnect().

220 {
221  char *sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
222  char *message = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
223  struct sqlca_t *sqlca = ECPGget_sqlca();
224  int sqlcode;
225 
226  if (sqlca == NULL)
227  {
228  ecpg_log("out of memory");
229  return;
230  }
231 
232  (void) arg; /* keep the compiler quiet */
233  if (sqlstate == NULL)
235 
236  if (message == NULL) /* Shouldn't happen, but need to be sure */
237  message = ecpg_gettext("empty message text");
238 
239  /* these are not warnings */
240  if (strncmp(sqlstate, "00", 2) == 0)
241  return;
242 
243  ecpg_log("ECPGnoticeReceiver: %s\n", message);
244 
245  /* map to SQLCODE for backward compatibility */
246  if (strcmp(sqlstate, ECPG_SQLSTATE_INVALID_CURSOR_NAME) == 0)
247  sqlcode = ECPG_WARNING_UNKNOWN_PORTAL;
248  else if (strcmp(sqlstate, ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION) == 0)
249  sqlcode = ECPG_WARNING_IN_TRANSACTION;
250  else if (strcmp(sqlstate, ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION) == 0)
251  sqlcode = ECPG_WARNING_NO_TRANSACTION;
252  else if (strcmp(sqlstate, ECPG_SQLSTATE_DUPLICATE_CURSOR) == 0)
253  sqlcode = ECPG_WARNING_PORTAL_EXISTS;
254  else
255  sqlcode = 0;
256 
257  strncpy(sqlca->sqlstate, sqlstate, sizeof(sqlca->sqlstate));
258  sqlca->sqlcode = sqlcode;
259  sqlca->sqlwarn[2] = 'W';
260  sqlca->sqlwarn[0] = 'W';
261 
262  strncpy(sqlca->sqlerrm.sqlerrmc, message, sizeof(sqlca->sqlerrm.sqlerrmc));
263  sqlca->sqlerrm.sqlerrmc[sizeof(sqlca->sqlerrm.sqlerrmc) - 1] = 0;
264  sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
265 
266  ecpg_log("raising sqlcode %d\n", sqlcode);
267 }
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
#define sqlca
Definition: sqlca.h:59
char sqlwarn[8]
Definition: sqlca.h:39
int sqlerrml
Definition: sqlca.h:26
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
#define ecpg_gettext(x)
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:141
Definition: sqlca.h:19
#define ECPG_WARNING_PORTAL_EXISTS
Definition: ecpgerrno.h:77
char sqlstate[5]
Definition: sqlca.h:53
void ecpg_log(const char *format,...) pg_attribute_printf(1
#define ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION
#define ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION
long sqlcode
Definition: sqlca.h:23
#define ECPG_WARNING_IN_TRANSACTION
Definition: ecpgerrno.h:72
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3152
#define ECPG_SQLSTATE_INVALID_CURSOR_NAME
char sqlerrmc[SQLERRMC_LEN]
Definition: sqlca.h:27
void * arg
#define ECPG_WARNING_NO_TRANSACTION
Definition: ecpgerrno.h:75
struct sqlca_t::@145 sqlerrm
#define ECPG_SQLSTATE_DUPLICATE_CURSOR
#define ECPG_WARNING_UNKNOWN_PORTAL
Definition: ecpgerrno.h:70

◆ ECPGsetcommit()

bool ECPGsetcommit ( int  lineno,
const char *  mode,
const char *  connection_name 
)

Definition at line 165 of file connect.c.

References connection::autocommit, connection::connection, ecpg_check_PQresult(), ECPG_COMPAT_PGSQL, ecpg_get_connection(), ecpg_init(), ecpg_log(), connection::name, PQclear(), PQexec(), PQTRANS_IDLE, and PQtransactionStatus().

Referenced by main().

166 {
167  struct connection *con = ecpg_get_connection(connection_name);
168  PGresult *results;
169 
170  if (!ecpg_init(con, connection_name, lineno))
171  return false;
172 
173  ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, mode, con->name);
174 
175  if (con->autocommit && strncmp(mode, "off", strlen("off")) == 0)
176  {
178  {
179  results = PQexec(con->connection, "begin transaction");
180  if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
181  return false;
182  PQclear(results);
183  }
184  con->autocommit = false;
185  }
186  else if (!con->autocommit && strncmp(mode, "on", strlen("on")) == 0)
187  {
189  {
190  results = PQexec(con->connection, "commit");
191  if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
192  return false;
193  PQclear(results);
194  }
195  con->autocommit = true;
196  }
197 
198  return true;
199 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
void ecpg_log(const char *format,...) pg_attribute_printf(1
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6682
void PQclear(PGresult *res)
Definition: fe-exec.c:680
bool ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE)
Definition: error.c:282
PGconn * connection
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2142
bool ecpg_init(const struct connection *, const char *, const int)
Definition: misc.c:104

◆ ECPGsetconn()

bool ECPGsetconn ( int  lineno,
const char *  connection_name 
)

Definition at line 202 of file connect.c.

References ecpg_get_connection(), ecpg_init(), and pthread_setspecific().

Referenced by main().

203 {
204  struct connection *con = ecpg_get_connection(connection_name);
205 
206  if (!ecpg_init(con, connection_name, lineno))
207  return false;
208 
209 #ifdef ENABLE_THREAD_SAFETY
210  pthread_setspecific(actual_connection_key, con);
211 #else
212  actual_connection = con;
213 #endif
214  return true;
215 }
void pthread_setspecific(pthread_key_t key, void *val)
Definition: pthread-win32.c:24
static struct connection * actual_connection
Definition: connect.c:18
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
bool ecpg_init(const struct connection *, const char *, const int)
Definition: misc.c:104

Variable Documentation

◆ actual_connection

struct connection* actual_connection = NULL
static

Definition at line 18 of file connect.c.

Referenced by ecpg_get_connection(), and ecpg_get_connection_nr().

◆ all_connections

struct connection* all_connections = NULL
static

Definition at line 19 of file connect.c.

Referenced by ecpg_finish(), and ECPGconnect().