mm_db.c revision cee0fb94c0d4227de0a00efc162fb2739844b641
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <ctype.h>
#include <syslog.h>
#include <unistd.h>
#include <libpq-fe.h>
#include <mms_list.h>
#include <mms_parser.h>
#include <msg_sub.h>
#include <mms_trace.h>
#include <mms_strapp.h>
#include "mm_commands.h"
#include "mm_db.h"
#include "mm.h"
#include "mm_util.h"
#include "mm_db_version.h"
#include <mms_cfg.h>
static void notice_receiver(void *, const PGresult *);
/*
* Initialize database, called once at startup.
*
* The MMS installation process must up-grade or down-grade the
* postgres database to the same version as mm is expecting.
*/
{
int exists;
int rows;
int row;
int try = 0;
const int retrys = 10;
char *initialized;
int db_version;
"HINT: make sure mms:db is configured and running");
return (MM_DB_ERROR);
} else if (try > 1) {
}
try++;
sleep(2);
goto try_again;
}
return (MM_DB_ERROR);
}
exists = 1;
break;
}
}
if (exists == 0) {
return (MM_DB_ERROR);
}
return (MM_DB_ERROR);
}
"FROM \"MM\";") != MM_DB_DATA) {
return (MM_DB_ERROR);
}
return (MM_DB_ERROR);
}
return (MM_DB_ERROR);
}
if (db_version != MM_DB_VERSION) {
if (db_version > MM_DB_VERSION) {
"down-grade database version from %d to %d",
} else {
"up-grade database version from %d to %d",
}
return (MM_DB_ERROR);
}
return (MM_DB_ERROR);
}
return (MM_DB_OK);
}
/* Connect to the database. */
static mm_db_rval_t
{
char *sql_cmd;
if (db_cfg->mm_db_passwd) {
}
return (MM_DB_ERROR);
}
switch (db->mm_db_rval) {
case CONNECTION_OK:
(void) mm_db_disconnect(db);
rval = MM_DB_ERROR;
"connect command status, no sockfd");
} else {
NULL);
}
break;
default:
rval = MM_DB_ERROR;
}
return (rval);
}
/* Disconnect from the database. */
void
{
}
}
int num_retry = 0;
int rc;
int max_retry = 10;
int timeout = 3;
/* MM has disconnected from the db */
/* attempt to reconnect and resend all commands */
/* in the currect transaction block for this db connection */
/* report service configuration repoistory scf_error() */
max_retry = 50;
} else {
}
/* report service configuration repoistory scf_error() */
timeout = 3;
} else {
}
"mm_db_resend: "
"connection to db lost fd - %d, "
"attempt to reconnect, max retry = %d, timeout = %d",
timeout);
num_retry ++;
"mm_db_resend: "
"reconnect for db fd - %d failed "
"to many times %d, MM exiting",
exit(1);
}
"mm_db_resend: "
"error reconnecting to db fd - %d"
", retry %d",
}
"mm_db_resend: "
"reconnect successful db fd -%d, "
"try to resend commands",
(db->mm_db_has_list)) {
"mm_db_resend: "
"commands in list");
/* have commands in list */
}
} else {
"mm_db_resend: "
"single command");
/* don't have commands in list */
/* resend sql_cmd */
}
"mm_db_resend: "
"reconnect successful db fd - %d, "
"commands sent",
db->mm_db_resending = 0;
return (rc);
}
/*
* Execute sql command with sensitive information.
*/
{
int rval;
return (rval);
}
/*
* Execute sql command.
*/
{
int rval;
return (rval);
}
/*
* Add sql command terminator if needed.
*/
static char *
{
int i;
char *sql_cmd;
/* add sql command terminator if needed */
if (sql_cmd[i] == ';') {
break;
}
break;
}
}
}
return (sql_cmd);
}
/*
* Execute synchronous sql command in auto-commit mode, no txn needed.
* Multiple commands can be wrapped in transaction block.
*/
static mm_db_rval_t
{
int rval;
char *count;
char *sql_cmd;
return (MM_DB_ERROR);
}
/* add this cmd to this db's cmd list */
if (db->mm_db_has_list &&
db->mm_db_txn_blk &&
(db->mm_db_resending == 0)) {
}
if (flag) {
} else {
}
switch (db->mm_db_rval) {
case PGRES_COMMAND_OK:
db->mm_db_count);
break;
case PGRES_TUPLES_OK:
rval = MM_DB_DATA;
"Exec %s:%d fd %d status - ok, data (%d %d)",
db->mm_db_count);
break;
default:
rval = MM_DB_ERROR;
"no connection to the server") != NULL) ||
"terminating connection due "
"to administrator command") != NULL) ||
"server closed the connection unexpectedly") != NULL))) {
/* DB has disconnected, attempt to reconnect */
/* and resend the entire transaction block */
/* associated with this db fd */
return (rval);
}
}
return (rval);
}
/* Trace query execution notice and warning messages. */
static void
/* LINTED: void *arg is required arg in PQsetNoticeReceiver */
{
int rval;
if (rval != 6) {
}
}
/* Get database oids for mms string conversions. */
static mm_db_rval_t
{
char *value;
"WHERE typname = 'bool';") != MM_DB_DATA) {
return (MM_DB_ERROR);
}
return (MM_DB_ERROR);
}
"WHERE typname = 'timestamp';") != MM_DB_DATA) {
return (MM_DB_ERROR);
}
return (MM_DB_ERROR);
}
return (MM_DB_OK);
}
/* Connect to database. */
{
return (MM_DB_ERROR);
}
return (MM_DB_OK);
}
/* Reconnect to the database. */
{
return (MM_DB_ERROR);
}
return (MM_DB_OK);
}
return (MM_DB_ERROR);
}
/* Determine if database connection exists. */
{
return (B_TRUE);
}
return (B_FALSE);
}
/* Database transaction begin. */
{
int rc;
/* clear this db's cmd list */
if (db->mm_db_has_list)
(void) mm_add_char("BEGIN;",
&db->mm_db_cmds);
} else {
db->mm_db_txn_blk = 0;
}
return (rc);
}
/* Database transaction rollback. */
{
int rc;
db->mm_db_txn_blk = 0;
/* clear this db's cmd list */
if (db->mm_db_has_list)
return (rc);
}
/* Database transaction savepoint rollback. */
{
if (db->mm_db_txn_blk) {
}
return (MM_DB_OK);
}
/* Database transaction savepoint. */
{
if (db->mm_db_txn_blk) {
}
return (MM_DB_OK);
}
/* Database transaction release savepoint. */
{
int rc;
if (db->mm_db_txn_blk) {
return (rc);
}
return (MM_DB_OK);
}
/* Database transaction commit. */
{
int rc;
db->mm_db_txn_blk = 0;
/* clear this db's cmd list */
if (db->mm_db_has_list)
return (rc);
}
/* Add attribute (column) to object (table). */
{
int col;
int cols;
int rows;
int found;
/* does this object allow user-defined attributes? */
return (MM_DB_ERROR);
}
if (rows == 0) {
/* user-defined attributes not allowed */
return (MM_DB_OK);
}
/* does attribute already exist? */
return (MM_DB_ERROR);
}
found = 0;
found = 1;
}
}
if (found) {
/* user-defined attributes already exists */
return (MM_DB_OK);
}
/* add user-defined table column */
return (MM_DB_ERROR);
}
/* user-defined table column added */
return (MM_DB_OK);
}
{
int col;
int cols;
int rows;
int found;
/* does this object allow user-defined attributes? */
return (MM_DB_ERROR);
}
if (rows == 0) {
/* user-defined attributes not allowed */
return (MM_DB_OK);
}
/* does attribute already exist? */
return (MM_DB_ERROR);
}
found = 0;
found = 1;
}
}
if (found) {
/* user-defined attributes already exists */
return (MM_DB_OK);
}
/* add user-defined table column */
/* user-defined table column added */
return (MM_DB_OK);
}
/* Delete attribute (column) from object (table). */
{
int row;
int rows;
int col;
int cols;
int found;
/* does object allow user-defined attributes? */
return (MM_DB_ERROR);
}
if (rows == 0) {
/* user-defined attributes not allowed */
return (MM_DB_OK);
}
/* does object attribute exists? */
return (MM_DB_ERROR);
}
found = 0;
found = 1;
}
}
if (!found) {
/* user-defined attribute not found */
return (MM_DB_OK);
}
/* is attribute part of base data model? */
return (MM_DB_ERROR);
}
found = 0;
attribute) == 0) {
found = 1;
}
}
if (found) {
/* attribute is part of base data model */
return (MM_DB_OK);
}
/* remove user-defined object attribute */
return (MM_DB_ERROR);
}
/* user-defined object attribute removed */
return (MM_DB_DROPPED);
}
/*
* This is hard coded without database access because we are probably in a
* database transaction block that has failed and thus an additional database
* message catalog lookup would fail.
*/
char *
{
char *dberrmsg;
char *response;
char args[100];
char *p;
/*
* Replace ', ", ... with multi-character mms_escape sequences not
* processed by the parser.
*/
== NULL) {
return (NULL);
}
/*
* Remove last new line from database error message(s). Leave new
* lines in-between multiline database error messages.
*/
*p = '\0';
}
/*
* Build command error response with loctext.
*/
} else {
}
return (response);
}
char *
mm_db_escape_string(char *from)
{
char *to;
int len;
return (NULL);
}
}
return (to);
}