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 119 of file connect.c.

120 {
121  if (act != NULL)
122  {
123  struct ECPGtype_information_cache *cache,
124  *ptr;
125 
127  PQfinish(act->connection);
128 
129  /*
130  * no need to lock connections_mutex - we're always called by
131  * ECPGdisconnect or ECPGconnect, which are holding the lock
132  */
133 
134  /* remove act from the list */
135  if (act == all_connections)
136  all_connections = act->next;
137  else
138  {
139  struct connection *con;
140 
141  for (con = all_connections; con->next && con->next != act; con = con->next);
142  if (con->next)
143  con->next = act->next;
144  }
145 
146 #ifdef ENABLE_THREAD_SAFETY
147  if (pthread_getspecific(actual_connection_key) == act)
148  pthread_setspecific(actual_connection_key, all_connections);
149 #endif
150  if (actual_connection == act)
152 
153  ecpg_log("ecpg_finish: connection %s closed\n", act->name ? act->name : "(null)");
154 
155  for (cache = act->cache_head; cache; ptr = cache, cache = cache->next, ecpg_free(ptr));
156  ecpg_free(act->name);
157  ecpg_free(act);
158  /* delete cursor variables when last connection gets closed */
159  if (all_connections == NULL)
160  {
161  struct var_list *iv_ptr;
162 
163  for (; ivlist; iv_ptr = ivlist, ivlist = ivlist->next, ecpg_free(iv_ptr));
164  }
165  }
166  else
167  ecpg_log("ecpg_finish: called an extra time\n");
168 }
static struct connection * all_connections
Definition: connect.c:23
static struct connection * actual_connection
Definition: connect.c:22
bool ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *con)
Definition: prepare.c:337
@ ECPG_COMPAT_PGSQL
void ecpg_log(const char *format,...) pg_attribute_printf(1
struct var_list * ivlist
Definition: misc.c:529
void ecpg_free(void *ptr)
Definition: memory.c:13
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4181
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
struct ECPGtype_information_cache * next
PGconn * connection
struct ECPGtype_information_cache * cache_head
struct connection * next
struct var_list * next

References actual_connection, 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().

◆ ecpg_get_connection()

struct connection* ecpg_get_connection ( const char *  connection_name)

Definition at line 79 of file connect.c.

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

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().

◆ ecpg_get_connection_nr()

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

Definition at line 40 of file connect.c.

41 {
42  struct connection *ret = NULL;
43 
44  if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
45  {
46 #ifdef ENABLE_THREAD_SAFETY
47  ecpg_pthreads_init(); /* ensure actual_connection_key is valid */
48 
49  ret = pthread_getspecific(actual_connection_key);
50 
51  /*
52  * if no connection in TSD for this thread, get the global default
53  * connection and hope the user knows what they're doing (i.e. using
54  * their own mutex to protect that connection from concurrent accesses
55  */
56  if (ret == NULL)
57  /* no TSD connection, going for global */
58  ret = actual_connection;
59 #else
60  ret = actual_connection;
61 #endif
62  }
63  else
64  {
65  struct connection *con;
66 
67  for (con = all_connections; con != NULL; con = con->next)
68  {
69  if (strcmp(connection_name, con->name) == 0)
70  break;
71  }
72  ret = con;
73  }
74 
75  return ret;
76 }

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

Referenced by ecpg_get_connection(), and ECPGdisconnect().

◆ 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 277 of file connect.c.

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

References a, actual_connection, 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(), locale_t, name, 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().

◆ ECPGdisconnect()

bool ECPGdisconnect ( int  lineno,
const char *  connection_name 
)

Definition at line 707 of file connect.c.

708 {
709  struct sqlca_t *sqlca = ECPGget_sqlca();
710  struct connection *con;
711 
712  if (sqlca == NULL)
713  {
716  return false;
717  }
718 
719 #ifdef ENABLE_THREAD_SAFETY
720  pthread_mutex_lock(&connections_mutex);
721 #endif
722 
723  if (strcmp(connection_name, "ALL") == 0)
724  {
726  for (con = all_connections; con;)
727  {
728  struct connection *f = con;
729 
730  con = con->next;
731  ecpg_finish(f);
732  }
733  }
734  else
735  {
736  con = ecpg_get_connection_nr(connection_name);
737 
738  if (!ecpg_init(con, connection_name, lineno))
739  {
740 #ifdef ENABLE_THREAD_SAFETY
741  pthread_mutex_unlock(&connections_mutex);
742 #endif
743  return false;
744  }
745  else
746  ecpg_finish(con);
747  }
748 
749 #ifdef ENABLE_THREAD_SAFETY
750  pthread_mutex_unlock(&connections_mutex);
751 #endif
752 
753  return true;
754 }
bool ecpg_init(const struct connection *con, const char *connection_name, const int lineno)
Definition: misc.c:104

References all_connections, 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().

◆ ECPGget_PGconn()

PGconn* ECPGget_PGconn ( const char *  connection_name)

Definition at line 757 of file connect.c.

758 {
759  struct connection *con;
760 
761  con = ecpg_get_connection(connection_name);
762  if (con == NULL)
763  return NULL;
764 
765  return con->connection;
766 }

References connection::connection, and ecpg_get_connection().

◆ ECPGnoticeReceiver()

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

Definition at line 225 of file connect.c.

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

References arg, 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, and sqlca_t::sqlstate.

Referenced by ECPGconnect().

◆ ECPGsetcommit()

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

Definition at line 171 of file connect.c.

172 {
173  struct connection *con = ecpg_get_connection(connection_name);
174  PGresult *results;
175 
176  if (!ecpg_init(con, connection_name, lineno))
177  return false;
178 
179  ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, mode, con->name);
180 
181  if (con->autocommit && strncmp(mode, "off", strlen("off")) == 0)
182  {
184  {
185  results = PQexec(con->connection, "begin transaction");
186  if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
187  return false;
188  PQclear(results);
189  }
190  con->autocommit = false;
191  }
192  else if (!con->autocommit && strncmp(mode, "on", strlen("on")) == 0)
193  {
195  {
196  results = PQexec(con->connection, "commit");
197  if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
198  return false;
199  PQclear(results);
200  }
201  con->autocommit = true;
202  }
203 
204  return true;
205 }
bool ecpg_check_PQresult(PGresult *results, int lineno, PGconn *connection, enum COMPAT_MODE compat)
Definition: error.c:281
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6773
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2243
@ PQTRANS_IDLE
Definition: libpq-fe.h:118
static PgChecksumMode mode
Definition: pg_checksums.c:65

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

Referenced by main().

◆ ECPGsetconn()

bool ECPGsetconn ( int  lineno,
const char *  connection_name 
)

Definition at line 208 of file connect.c.

209 {
210  struct connection *con = ecpg_get_connection(connection_name);
211 
212  if (!ecpg_init(con, connection_name, lineno))
213  return false;
214 
215 #ifdef ENABLE_THREAD_SAFETY
216  pthread_setspecific(actual_connection_key, con);
217 #else
218  actual_connection = con;
219 #endif
220  return true;
221 }

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

Referenced by main().

Variable Documentation

◆ actual_connection

struct connection* actual_connection = NULL
static

◆ all_connections

struct connection* all_connections = NULL
static

Definition at line 23 of file connect.c.

Referenced by ecpg_finish(), ecpg_get_connection_nr(), ECPGconnect(), and ECPGdisconnect().