PostgreSQL Source Code: src/interfaces/ecpg/ecpglib/connect.c Source File (original) (raw)
1
2
3#define POSTGRES_ECPG_INTERNAL
5
12
13#ifdef HAVE_USELOCALE
15#endif
16
22
23static void
25{
27}
28
29void
31{
33}
34
37{
39
40 if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
41 {
43
45
46
47
48
49
50
51 if (ret == NULL)
52
54 }
55 else
56 {
58
60 {
61 if (strcmp(connection_name, con->name) == 0)
62 break;
63 }
64 ret = con;
65 }
66
67 return ret;
68}
69
72{
74
75 if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
76 {
78
80
81
82
83
84
85
86 if (ret == NULL)
87
89 }
90 else
91 {
93
95
97 }
98
99 return ret;
100}
101
102static void
104{
105 if (act != NULL)
106 {
108 *ptr;
109
112
113
114
115
116
117
118
121 else
122 {
124
126 if (con->next)
128 }
129
134
135 ecpg_log("ecpg_finish: connection %s closed\n", act->name ? act->name : "(null)");
136
140
142 {
144
146 }
147 }
148 else
149 ecpg_log("ecpg_finish: called an extra time\n");
150}
151
152bool
154{
157
158 if ((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 {
169 return false;
171 }
173 }
174 else if (!con->autocommit && strncmp(mode, "on", strlen("on")) == 0)
175 {
177 {
180 return false;
182 }
184 }
185
186 return true;
187}
188
189bool
191{
193
194 if ((con, connection_name, lineno))
195 return false;
196
198 return true;
199}
200
201
202static void
204{
209
210 if (sqlca == NULL)
211 {
213 return;
214 }
215
216 (void) arg;
219
220 if (message == NULL)
221 message = ecpg_gettext("empty message text");
222
223
224 if (strncmp(sqlstate, "00", 2) == 0)
225 return;
226
227 ecpg_log("ECPGnoticeReceiver: %s\n", message);
228
229
238 else
240
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
251}
252
253
254bool
255ECPGconnect(int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
256{
260 int i,
261 connect_params = 0;
263 *host = NULL,
264 *tmp,
265 *port = NULL,
266 *realname = NULL,
268 const char **conn_keywords;
269 const char **conn_values;
270
271 if (sqlca == NULL)
272 {
276 return false;
277 }
278
280
281
282
283
284
286
288 {
289 char *envname;
290
291
292
293
294
295
296 envname = getenv("PG_DBPATH");
297 if (envname)
298 {
301 }
302 }
303
304 if (dbname == NULL && connection_name == NULL)
305 connection_name = "DEFAULT";
306
308
309
311 {
313 ecpg_log("ECPGconnect: connection identifier %s is already in use\n",
314 connection_name);
315 return false;
316 }
317
319 {
321 return false;
322 }
323
325 {
326
327 if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0)
328 {
329 int offset = 0;
330
331
332
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
344
345
346
347 offset += strlen("postgresql://");
348
349 tmp = strrchr(dbname + offset, '?');
350 if (tmp != NULL)
351 {
353 *tmp = '\0';
354 }
355
357 if (tmp != NULL)
358 {
359 if (tmp[1] != '\0')
360 {
362 connect_params++;
363 }
364 *tmp = '\0';
365 }
366
367 tmp = strrchr(dbname + offset, ':');
368 if (tmp != NULL)
369 {
370 *tmp = '\0';
372 connect_params++;
373 }
374
375 if (strncmp(dbname, "unix:", 5) == 0)
376 {
377
378
379
380
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)
393 if (realname)
398 return false;
399 }
400 }
401 else
402 {
403 if (*(dbname + offset) != '\0')
404 {
406 connect_params++;
407 }
408 }
409 }
410 }
411 else
412 {
413
414 tmp = strrchr(dbname, ':');
415 if (tmp != NULL)
416 {
418 connect_params++;
419 *tmp = '\0';
420 }
421
422 tmp = strrchr(dbname, '@');
423 if (tmp != NULL)
424 {
426 connect_params++;
427 *tmp = '\0';
428 }
429
430 if (strlen(dbname) > 0)
431 {
433 connect_params++;
434 }
435 else
436 realname = NULL;
437 }
438 }
439 else
440 realname = NULL;
441
442
443
444
445
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
458
459
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)
471 if (realname)
475 if (conn_keywords)
477 if (conn_values)
480 return false;
481 }
482
483
485
486
487
488
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)
505 if (realname)
509 if (conn_keywords)
511 if (conn_values)
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
526
528 this->next = NULL;
529 else
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 : "",
538 host ? host : "",
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 }
557 {
558 conn_keywords[i] = "port";
560 i++;
561 }
562 if (user && strlen(user) > 0)
563 {
564 conn_keywords[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 }
575 {
576 char *str;
577
578
579
580
581
582
583
584
585
586
588 {
589 int e,
590 a;
591 char *token1,
592 *token2;
593
594
595 for (token1 = str; *token1 == ' '; token1++)
596 ;
597
598 for (e = 0; token1[e] && token1[e] != '='; e++)
599 ;
600 if (token1[e])
601 {
602 token1[e] = '\0';
603
604 for (token2 = token1 + e + 1; *token2 == ' '; token2++)
605 ;
606
607 for (a = 0; token2[a] && token2[a] != '&'; a++)
608 ;
609 if (token2[a])
610 {
611 token2[a] = '\0';
613 }
614 else
616
617 conn_keywords[i] = token1;
618 conn_values[i] = token2;
619 i++;
620 }
621 else
622 {
623
625 }
626 }
627 }
628
629 Assert(i <= connect_params);
630 conn_keywords[i] = NULL;
631
633
634 if (host)
644
646 {
648 const char *db = realname ? realname : ecpg_gettext("");
649
650
652
655
657 if (realname)
659
660 return false;
661 }
662
663 if (realname)
665
667
669
671
672 return true;
673}
674
675bool
677{
680
681 if (sqlca == NULL)
682 {
685 return false;
686 }
687
689
690 if (strcmp(connection_name, "ALL") == 0)
691 {
694 {
696
697 con = con->next;
699 }
700 }
701 else
702 {
704
705 if ((con, connection_name, lineno))
706 {
708 return false;
709 }
710 else
712 }
713
715
716 return true;
717}
718
721{
723
725 if (con == NULL)
726 return NULL;
727
729}
static struct connection * ecpg_get_connection_nr(const char *connection_name)
static void ecpg_finish(struct connection *act)
static pthread_mutex_t connections_mutex
void ecpg_pthreads_init(void)
static pthread_key_t actual_connection_key
static struct connection * all_connections
PGconn * ECPGget_PGconn(const char *connection_name)
bool ECPGsetconn(int lineno, const char *connection_name)
bool ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
bool ECPGdisconnect(int lineno, const char *connection_name)
static void ECPGnoticeReceiver(void *arg, const PGresult *result)
static pthread_once_t actual_connection_key_once
static struct connection * actual_connection
bool ECPGconnect(int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
struct connection * ecpg_get_connection(const char *connection_name)
static void ecpg_actual_connection_init(void)
#define ECPG_WARNING_IN_TRANSACTION
#define ECPG_WARNING_UNKNOWN_PORTAL
#define ECPG_WARNING_PORTAL_EXISTS
#define ECPG_WARNING_NO_TRANSACTION
#define ECPG_OUT_OF_MEMORY
#define ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION
bool ecpg_check_PQresult(PGresult *results, int lineno, PGconn *connection, enum COMPAT_MODE compat)
bool ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *con)
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
char * ecpg_alloc(long size, int lineno)
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
#define ECPG_SQLSTATE_INVALID_CURSOR_NAME
void ecpg_log(const char *format,...) pg_attribute_printf(1
void ecpg_clear_auto_mem(void)
bool ecpg_init(const struct connection *con, const char *connection_name, const int lineno)
#define ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION
#define ECPG_SQLSTATE_DUPLICATE_CURSOR
void ecpg_init_sqlca(struct sqlca_t *sqlca)
#define ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
bool ecpg_internal_regression_mode
char * ecpg_strdup(const char *string, int lineno)
void ecpg_free(void *ptr)
int errmsg(const char *fmt,...)
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
ConnStatusType PQstatus(const PGconn *conn)
void PQfinish(PGconn *conn)
PQnoticeReceiver PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg)
char * PQerrorMessage(const PGconn *conn)
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
void PQclear(PGresult *res)
char * PQresultErrorField(const PGresult *res, int fieldcode)
PGresult * PQexec(PGconn *conn, const char *query)
Assert(PointerIsAligned(start, uint64))
struct sqlca_t * ECPGget_sqlca(void)
static PgChecksumMode mode
char * last_dir_separator(const char *filename)
#define PG_DIAG_MESSAGE_PRIMARY
int pthread_mutex_unlock(pthread_mutex_t *mp)
int pthread_mutex_lock(pthread_mutex_t *mp)
void pthread_setspecific(pthread_key_t key, void *val)
void * pthread_getspecific(pthread_key_t key)
#define PTHREAD_MUTEX_INITIALIZER
struct ECPGtype_information_cache * next
struct ECPGtype_information_cache * cache_head
struct prepared_statement * prep_stmts