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.

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 }
static struct connection * all_connections
Definition: connect.c:19
static struct connection * actual_connection
Definition: connect.c:18
@ ECPG_COMPAT_PGSQL
void ecpg_log(const char *format,...) pg_attribute_printf(1
void ecpg_free(void *)
Definition: memory.c:13
struct var_list * ivlist
Definition: misc.c:529
bool ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *conn)
Definition: prepare.c:337
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4261
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 74 of file connect.c.

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 }
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: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 36 of file connect.c.

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 }

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

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 
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  if (dbname == NULL && connection_name == NULL)
321  connection_name = "DEFAULT";
322 
323 #if ENABLE_THREAD_SAFETY
324  ecpg_pthreads_init();
325 #endif
326 
327  /* check if the identifier is unique */
328  if (ecpg_get_connection(connection_name))
329  {
330  ecpg_free(dbname);
331  ecpg_log("ECPGconnect: connection identifier %s is already in use\n",
332  connection_name);
333  return false;
334  }
335 
336  if ((this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno)) == NULL)
337  {
338  ecpg_free(dbname);
339  return false;
340  }
341 
342  if (dbname != NULL)
343  {
344  /* get the detail information from dbname */
345  if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0)
346  {
347  int offset = 0;
348 
349  /*
350  * only allow protocols tcp and unix
351  */
352  if (strncmp(dbname, "tcp:", 4) == 0)
353  offset = 4;
354  else if (strncmp(dbname, "unix:", 5) == 0)
355  offset = 5;
356 
357  if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0)
358  {
359 
360  /*------
361  * new style:
362  * <tcp|unix>:postgresql://server[:port][/db-name][?options]
363  *------
364  */
365  offset += strlen("postgresql://");
366 
367  tmp = strrchr(dbname + offset, '?');
368  if (tmp != NULL) /* options given */
369  {
370  options = ecpg_strdup(tmp + 1, lineno);
371  *tmp = '\0';
372  }
373 
374  tmp = last_dir_separator(dbname + offset);
375  if (tmp != NULL) /* database name given */
376  {
377  if (tmp[1] != '\0') /* non-empty database name */
378  {
379  realname = ecpg_strdup(tmp + 1, lineno);
380  connect_params++;
381  }
382  *tmp = '\0';
383  }
384 
385  tmp = strrchr(dbname + offset, ':');
386  if (tmp != NULL) /* port number given */
387  {
388  *tmp = '\0';
389  port = ecpg_strdup(tmp + 1, lineno);
390  connect_params++;
391  }
392 
393  if (strncmp(dbname, "unix:", 5) == 0)
394  {
395  /*
396  * The alternative of using "127.0.0.1" here is deprecated
397  * and undocumented; we'll keep it for backward
398  * compatibility's sake, but not extend it to allow IPv6.
399  */
400  if (strcmp(dbname + offset, "localhost") != 0 &&
401  strcmp(dbname + offset, "127.0.0.1") != 0)
402  {
403  ecpg_log("ECPGconnect: non-localhost access via sockets on line %d\n", lineno);
405  if (host)
406  ecpg_free(host);
407  if (port)
408  ecpg_free(port);
409  if (options)
411  if (realname)
412  ecpg_free(realname);
413  if (dbname)
414  ecpg_free(dbname);
415  free(this);
416  return false;
417  }
418  }
419  else
420  {
421  if (*(dbname + offset) != '\0')
422  {
423  host = ecpg_strdup(dbname + offset, lineno);
424  connect_params++;
425  }
426  }
427  }
428  }
429  else
430  {
431  /* old style: dbname[@server][:port] */
432  tmp = strrchr(dbname, ':');
433  if (tmp != NULL) /* port number given */
434  {
435  port = ecpg_strdup(tmp + 1, lineno);
436  connect_params++;
437  *tmp = '\0';
438  }
439 
440  tmp = strrchr(dbname, '@');
441  if (tmp != NULL) /* host name given */
442  {
443  host = ecpg_strdup(tmp + 1, lineno);
444  connect_params++;
445  *tmp = '\0';
446  }
447 
448  if (strlen(dbname) > 0)
449  {
450  realname = ecpg_strdup(dbname, lineno);
451  connect_params++;
452  }
453  else
454  realname = NULL;
455  }
456  }
457  else
458  realname = NULL;
459 
460  /*
461  * Count options for the allocation done below (this may produce an
462  * overestimate, it's ok).
463  */
464  if (options)
465  for (i = 0; options[i]; i++)
466  if (options[i] == '=')
467  connect_params++;
468 
469  if (user && strlen(user) > 0)
470  connect_params++;
471  if (passwd && strlen(passwd) > 0)
472  connect_params++;
473 
474  /*
475  * Allocate enough space for all connection parameters. These allocations
476  * are done before manipulating the list of connections to ease the error
477  * handling on failure.
478  */
479  conn_keywords = (const char **) ecpg_alloc((connect_params + 1) * sizeof(char *), lineno);
480  conn_values = (const char **) ecpg_alloc(connect_params * sizeof(char *), lineno);
481  if (conn_keywords == NULL || conn_values == NULL)
482  {
483  if (host)
484  ecpg_free(host);
485  if (port)
486  ecpg_free(port);
487  if (options)
489  if (realname)
490  ecpg_free(realname);
491  if (dbname)
492  ecpg_free(dbname);
493  if (conn_keywords)
494  ecpg_free(conn_keywords);
495  if (conn_values)
496  ecpg_free(conn_values);
497  free(this);
498  return false;
499  }
500 
501  /* add connection to our list */
502 #ifdef ENABLE_THREAD_SAFETY
503  pthread_mutex_lock(&connections_mutex);
504 #endif
505  if (connection_name != NULL)
506  this->name = ecpg_strdup(connection_name, lineno);
507  else
508  this->name = ecpg_strdup(realname, lineno);
509 
510  this->cache_head = NULL;
511  this->prep_stmts = NULL;
512 
513  if (all_connections == NULL)
514  this->next = NULL;
515  else
516  this->next = all_connections;
517 
518  all_connections = this;
519 #ifdef ENABLE_THREAD_SAFETY
520  pthread_setspecific(actual_connection_key, all_connections);
521 #endif
523 
524  ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
525  realname ? realname : "<DEFAULT>",
526  host ? host : "<DEFAULT>",
527  port ? (ecpg_internal_regression_mode ? "<REGRESSION_PORT>" : port) : "<DEFAULT>",
528  options ? "with options " : "", options ? options : "",
529  (user && strlen(user) > 0) ? "for user " : "", user ? user : "");
530 
531  i = 0;
532  if (realname)
533  {
534  conn_keywords[i] = "dbname";
535  conn_values[i] = realname;
536  i++;
537  }
538  if (host)
539  {
540  conn_keywords[i] = "host";
541  conn_values[i] = host;
542  i++;
543  }
544  if (port)
545  {
546  conn_keywords[i] = "port";
547  conn_values[i] = port;
548  i++;
549  }
550  if (user && strlen(user) > 0)
551  {
552  conn_keywords[i] = "user";
553  conn_values[i] = user;
554  i++;
555  }
556  if (passwd && strlen(passwd) > 0)
557  {
558  conn_keywords[i] = "password";
559  conn_values[i] = passwd;
560  i++;
561  }
562  if (options)
563  {
564  char *str;
565 
566  /*
567  * The options string contains "keyword=value" pairs separated by
568  * '&'s. We must break this up into keywords and values to pass to
569  * libpq (it's okay to scribble on the options string). We ignore
570  * spaces just before each keyword or value.
571  */
572  for (str = options; *str;)
573  {
574  int e,
575  a;
576  char *token1,
577  *token2;
578 
579  /* Skip spaces before keyword */
580  for (token1 = str; *token1 == ' '; token1++)
581  /* skip */ ;
582  /* Find end of keyword */
583  for (e = 0; token1[e] && token1[e] != '='; e++)
584  /* skip */ ;
585  if (token1[e]) /* found "=" */
586  {
587  token1[e] = '\0';
588  /* Skip spaces before value */
589  for (token2 = token1 + e + 1; *token2 == ' '; token2++)
590  /* skip */ ;
591  /* Find end of value */
592  for (a = 0; token2[a] && token2[a] != '&'; a++)
593  /* skip */ ;
594  if (token2[a]) /* found "&" => another option follows */
595  {
596  token2[a] = '\0';
597  str = token2 + a + 1;
598  }
599  else
600  str = token2 + a;
601 
602  conn_keywords[i] = token1;
603  conn_values[i] = token2;
604  i++;
605  }
606  else
607  {
608  /* Bogus options syntax ... ignore trailing garbage */
609  str = token1 + e;
610  }
611  }
612  }
613 
614  Assert(i <= connect_params);
615  conn_keywords[i] = NULL; /* terminator */
616 
617  this->connection = PQconnectdbParams(conn_keywords, conn_values, 0);
618 
619  if (host)
620  ecpg_free(host);
621  if (port)
622  ecpg_free(port);
623  if (options)
625  if (dbname)
626  ecpg_free(dbname);
627  ecpg_free(conn_values);
628  ecpg_free(conn_keywords);
629 
630  if (PQstatus(this->connection) == CONNECTION_BAD)
631  {
632  const char *errmsg = PQerrorMessage(this->connection);
633  const char *db = realname ? realname : ecpg_gettext("<DEFAULT>");
634 
635  /* PQerrorMessage's result already has a trailing newline */
636  ecpg_log("ECPGconnect: %s", errmsg);
637 
638  ecpg_finish(this);
639 #ifdef ENABLE_THREAD_SAFETY
640  pthread_mutex_unlock(&connections_mutex);
641 #endif
642 
644  if (realname)
645  ecpg_free(realname);
646 
647  return false;
648  }
649 
650  if (realname)
651  ecpg_free(realname);
652 
653 #ifdef ENABLE_THREAD_SAFETY
654  pthread_mutex_unlock(&connections_mutex);
655 #endif
656 
657  this->autocommit = autocommit;
658 
659  PQsetNoticeReceiver(this->connection, &ECPGnoticeReceiver, (void *) this);
660 
661  return true;
662 }
static int32 next
Definition: blutils.c:219
static void ecpg_finish(struct connection *act)
Definition: connect.c:113
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
static void ECPGnoticeReceiver(void *arg, const PGresult *result)
Definition: connect.c:219
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
char * ecpg_alloc(long, int)
Definition: memory.c:19
#define ecpg_gettext(x)
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
COMPAT_MODE
void ecpg_clear_auto_mem(void)
Definition: memory.c:158
#define INFORMIX_MODE(X)
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
char * ecpg_strdup(const char *, int)
Definition: memory.c:47
int errmsg(const char *fmt,...)
Definition: elog.c:904
const char * name
Definition: encode.c:561
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:658
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6908
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6855
PQnoticeReceiver PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg)
Definition: fe-connect.c:7059
#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:95
static int port
Definition: pg_regress.c:92
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

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(), 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 665 of file connect.c.

666 {
667  struct sqlca_t *sqlca = ECPGget_sqlca();
668  struct connection *con;
669 
670  if (sqlca == NULL)
671  {
674  return false;
675  }
676 
677 #ifdef ENABLE_THREAD_SAFETY
678  pthread_mutex_lock(&connections_mutex);
679 #endif
680 
681  if (strcmp(connection_name, "ALL") == 0)
682  {
684  for (con = all_connections; con;)
685  {
686  struct connection *f = con;
687 
688  con = con->next;
689  ecpg_finish(f);
690  }
691  }
692  else
693  {
694  con = ecpg_get_connection_nr(connection_name);
695 
696  if (!ecpg_init(con, connection_name, lineno))
697  {
698 #ifdef ENABLE_THREAD_SAFETY
699  pthread_mutex_unlock(&connections_mutex);
700 #endif
701  return false;
702  }
703  else
704  ecpg_finish(con);
705  }
706 
707 #ifdef ENABLE_THREAD_SAFETY
708  pthread_mutex_unlock(&connections_mutex);
709 #endif
710 
711  return true;
712 }
bool ecpg_init(const struct connection *, const char *, const int)
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 715 of file connect.c.

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

References connection::connection, and ecpg_get_connection().

◆ ECPGnoticeReceiver()

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

Definition at line 219 of file connect.c.

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 */
248  else if (strcmp(sqlstate, ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION) == 0)
250  else if (strcmp(sqlstate, ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION) == 0)
252  else if (strcmp(sqlstate, ECPG_SQLSTATE_DUPLICATE_CURSOR) == 0)
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 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:3325
void * arg
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
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 165 of file connect.c.

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 }
bool ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE)
Definition: error.c:282
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6863
void PQclear(PGresult *res)
Definition: fe-exec.c:718
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2273
@ 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 202 of file connect.c.

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 }

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

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