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 void ecpg_actual_connection_init (void)
 
void ecpg_pthreads_init (void)
 
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 pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER
 
static pthread_key_t actual_connection_key
 
static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT
 
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_actual_connection_init()

static void ecpg_actual_connection_init ( void  )
static

Definition at line 24 of file connect.c.

25 {
26  pthread_key_create(&actual_connection_key, NULL);
27 }
static pthread_key_t actual_connection_key
Definition: connect.c:18

References actual_connection_key.

Referenced by ecpg_pthreads_init().

◆ ecpg_finish()

static void ecpg_finish ( struct connection act)
static

Definition at line 103 of file connect.c.

104 {
105  if (act != NULL)
106  {
107  struct ECPGtype_information_cache *cache,
108  *ptr;
109 
111  PQfinish(act->connection);
112 
113  /*
114  * no need to lock connections_mutex - we're always called by
115  * ECPGdisconnect or ECPGconnect, which are holding the lock
116  */
117 
118  /* remove act from the list */
119  if (act == all_connections)
120  all_connections = act->next;
121  else
122  {
123  struct connection *con;
124 
125  for (con = all_connections; con->next && con->next != act; con = con->next);
126  if (con->next)
127  con->next = act->next;
128  }
129 
132  if (actual_connection == act)
134 
135  ecpg_log("ecpg_finish: connection %s closed\n", act->name ? act->name : "(null)");
136 
137  for (cache = act->cache_head; cache; ptr = cache, cache = cache->next, ecpg_free(ptr));
138  ecpg_free(act->name);
139  ecpg_free(act);
140  /* delete cursor variables when last connection gets closed */
141  if (all_connections == NULL)
142  {
143  struct var_list *iv_ptr;
144 
145  for (; ivlist; iv_ptr = ivlist, ivlist = ivlist->next, ecpg_free(iv_ptr));
146  }
147  }
148  else
149  ecpg_log("ecpg_finish: called an extra time\n");
150 }
static struct connection * all_connections
Definition: connect.c:21
static struct connection * actual_connection
Definition: connect.c:20
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:516
void ecpg_free(void *ptr)
Definition: memory.c:13
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4562
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, actual_connection_key, 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 71 of file connect.c.

72 {
73  struct connection *ret = NULL;
74 
75  if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
76  {
77  ecpg_pthreads_init(); /* ensure actual_connection_key is valid */
78 
80 
81  /*
82  * if no connection in TSD for this thread, get the global default
83  * connection and hope the user knows what they're doing (i.e. using
84  * their own mutex to protect that connection from concurrent accesses
85  */
86  if (ret == NULL)
87  /* no TSD connection here either, using global */
88  ret = actual_connection;
89  }
90  else
91  {
93 
94  ret = ecpg_get_connection_nr(connection_name);
95 
97  }
98 
99  return ret;
100 }
static pthread_mutex_t connections_mutex
Definition: connect.c:17
void ecpg_pthreads_init(void)
Definition: connect.c:30
static struct connection * ecpg_get_connection_nr(const char *connection_name)
Definition: connect.c:36
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:60
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:42

References actual_connection, actual_connection_key, connections_mutex, ecpg_get_connection_nr(), ecpg_pthreads_init(), 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 36 of file connect.c.

37 {
38  struct connection *ret = NULL;
39 
40  if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
41  {
42  ecpg_pthreads_init(); /* ensure actual_connection_key is valid */
43 
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  */
51  if (ret == NULL)
52  /* no TSD connection, going for global */
53  ret = actual_connection;
54  }
55  else
56  {
57  struct connection *con;
58 
59  for (con = all_connections; con != NULL; con = con->next)
60  {
61  if (strcmp(connection_name, con->name) == 0)
62  break;
63  }
64  ret = con;
65  }
66 
67  return ret;
68 }

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

Referenced by ecpg_get_connection(), and ECPGdisconnect().

◆ ecpg_pthreads_init()

void ecpg_pthreads_init ( void  )

Definition at line 30 of file connect.c.

31 {
33 }
static pthread_once_t actual_connection_key_once
Definition: connect.c:19
static void ecpg_actual_connection_init(void)
Definition: connect.c:24

References actual_connection_key_once, and ecpg_actual_connection_init().

Referenced by ecpg_do_prologue(), ecpg_get_connection(), ecpg_get_connection_nr(), and ECPGconnect().

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

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

References a, actual_connection, actual_connection_key, all_connections, Assert(), autocommit, connection::cache_head, compat, CONNECTION_BAD, connections_mutex, 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_pthreads_init(), 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 fn(), main(), test(), and test_thread().

◆ ECPGdisconnect()

bool ECPGdisconnect ( int  lineno,
const char *  connection_name 
)

Definition at line 673 of file connect.c.

674 {
675  struct sqlca_t *sqlca = ECPGget_sqlca();
676  struct connection *con;
677 
678  if (sqlca == NULL)
679  {
682  return false;
683  }
684 
686 
687  if (strcmp(connection_name, "ALL") == 0)
688  {
690  for (con = all_connections; con;)
691  {
692  struct connection *f = con;
693 
694  con = con->next;
695  ecpg_finish(f);
696  }
697  }
698  else
699  {
700  con = ecpg_get_connection_nr(connection_name);
701 
702  if (!ecpg_init(con, connection_name, lineno))
703  {
705  return false;
706  }
707  else
708  ecpg_finish(con);
709  }
710 
712 
713  return true;
714 }
bool ecpg_init(const struct connection *con, const char *connection_name, const int lineno)
Definition: misc.c:73

References all_connections, connections_mutex, 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 fn(), main(), test(), and test_thread().

◆ ECPGget_PGconn()

PGconn* ECPGget_PGconn ( const char *  connection_name)

Definition at line 717 of file connect.c.

718 {
719  struct connection *con;
720 
721  con = ecpg_get_connection(connection_name);
722  if (con == NULL)
723  return NULL;
724 
725  return con->connection;
726 }

References connection::connection, and ecpg_get_connection().

◆ ECPGnoticeReceiver()

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

Definition at line 203 of file connect.c.

204 {
205  char *sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
206  char *message = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
207  struct sqlca_t *sqlca = ECPGget_sqlca();
208  int sqlcode;
209 
210  if (sqlca == NULL)
211  {
212  ecpg_log("out of memory");
213  return;
214  }
215 
216  (void) arg; /* keep the compiler quiet */
217  if (sqlstate == NULL)
219 
220  if (message == NULL) /* Shouldn't happen, but need to be sure */
221  message = ecpg_gettext("empty message text");
222 
223  /* these are not warnings */
224  if (strncmp(sqlstate, "00", 2) == 0)
225  return;
226 
227  ecpg_log("ECPGnoticeReceiver: %s\n", message);
228 
229  /* map to SQLCODE for backward compatibility */
232  else if (strcmp(sqlstate, ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION) == 0)
234  else if (strcmp(sqlstate, ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION) == 0)
236  else if (strcmp(sqlstate, ECPG_SQLSTATE_DUPLICATE_CURSOR) == 0)
238  else
239  sqlcode = 0;
240 
241  strncpy(sqlca->sqlstate, sqlstate, sizeof(sqlca->sqlstate));
242  sqlca->sqlcode = sqlcode;
243  sqlca->sqlwarn[2] = 'W';
244  sqlca->sqlwarn[0] = 'W';
245 
246  strncpy(sqlca->sqlerrm.sqlerrmc, message, sizeof(sqlca->sqlerrm.sqlerrmc));
247  sqlca->sqlerrm.sqlerrmc[sizeof(sqlca->sqlerrm.sqlerrmc) - 1] = 0;
248  sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
249 
250  ecpg_log("raising sqlcode %d\n", sqlcode);
251 }
#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:3426
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 153 of file connect.c.

154 {
155  struct connection *con = ecpg_get_connection(connection_name);
156  PGresult *results;
157 
158  if (!ecpg_init(con, connection_name, lineno))
159  return false;
160 
161  ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, mode, con->name);
162 
163  if (con->autocommit && strncmp(mode, "off", strlen("off")) == 0)
164  {
166  {
167  results = PQexec(con->connection, "begin transaction");
168  if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
169  return false;
170  PQclear(results);
171  }
172  con->autocommit = false;
173  }
174  else if (!con->autocommit && strncmp(mode, "on", strlen("on")) == 0)
175  {
177  {
178  results = PQexec(con->connection, "commit");
179  if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
180  return false;
181  PQclear(results);
182  }
183  con->autocommit = true;
184  }
185 
186  return true;
187 }
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:6796
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2224
@ PQTRANS_IDLE
Definition: libpq-fe.h:118
static PgChecksumMode mode
Definition: pg_checksums.c:56

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 fn(), and main().

◆ ECPGsetconn()

bool ECPGsetconn ( int  lineno,
const char *  connection_name 
)

Definition at line 190 of file connect.c.

191 {
192  struct connection *con = ecpg_get_connection(connection_name);
193 
194  if (!ecpg_init(con, connection_name, lineno))
195  return false;
196 
198  return true;
199 }

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

Referenced by main().

Variable Documentation

◆ actual_connection

struct connection* actual_connection = NULL
static

Definition at line 20 of file connect.c.

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

◆ actual_connection_key

◆ actual_connection_key_once

pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT
static

Definition at line 19 of file connect.c.

Referenced by ecpg_pthreads_init().

◆ all_connections

struct connection* all_connections = NULL
static

Definition at line 21 of file connect.c.

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

◆ connections_mutex

pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER
static

Definition at line 17 of file connect.c.

Referenced by ecpg_get_connection(), ECPGconnect(), and ECPGdisconnect().