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 (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 {

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 (ecpg\_init(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";

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 }

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';

612 str = token2 + a + 1;

613 }

614 else

615 str = token2 + a;

616

617 conn_keywords[i] = token1;

618 conn_values[i] = token2;

619 i++;

620 }

621 else

622 {

623

624 str = token1 + e;

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 (ecpg\_init(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