Пример #1
0
/** Helper function to build and send a database-related event to the server hook.
 *
 * \param self Database on which the event happened
 * \param event event to report
 *
 * \return 0 on success (even if the hook is disabled), -1 otherwise
 *
 * \see HOOK_CMD_DBCREATED, HOOK_CMD_DBOPENED, HOOK_CMD_DBCLOSED
 */
static int
database_hook_send_event(Database *self, const char* event){
  char dburi[PATH_MAX+1];
  MString *hook_command = mstring_create();

  if(hook_enabled()) {
    if(!self->get_uri(self, dburi, sizeof(dburi))) {
      logwarn("%s: Unable to get full URI to database for hook\n", self->name);

    } else if (mstring_sprintf(hook_command, "%s %s\n",
          event, dburi) == -1) {
      logwarn("%s: Failed to construct command string for event hook\n", self->name);
      mstring_delete(hook_command);
      return -1;

    } else if(hook_write(mstring_buf(hook_command), mstring_len(hook_command)) < (int)mstring_len(hook_command)) {
      logwarn("%s: Failed to send command string to event hook: %s\n", self->name, strerror(errno));
      mstring_delete(hook_command);
      return -1;
    }
  }

  return 0;
}
Пример #2
0
/** Create or open an PostgreSQL database
 * \param db the databse to associate with the sqlite3 database
 * \return 0 if successful, -1 otherwise
 */
int
psql_create_database(Database* db)
{
  MString *conninfo;
  MString *str;
  PGconn  *conn;
  PGresult *res = NULL;
  int ret = -1;

  loginfo ("psql:%s: Accessing database\n", db->name);

  /*
   * Make a connection to the database server -- check if the
   * requested database exists or not by connecting to the 'postgres'
   * database and querying that.
   */
  conninfo = psql_prepare_conninfo("postgres", pg_host, pg_port, pg_user, pg_pass, pg_conninfo);
  conn = PQconnectdb(mstring_buf (conninfo));

  /* Check to see that the backend connection was successfully made */
  if (PQstatus(conn) != CONNECTION_OK) {
    logerror ("psql: Could not connect to PostgreSQL database (conninfo \"%s\"): %s\n",
         mstring_buf(conninfo), PQerrorMessage (conn));
    goto cleanup_exit;
  }
  PQsetNoticeReceiver(conn, psql_receive_notice, "postgres");

  str = mstring_create();
  mstring_sprintf (str, "SELECT datname from pg_database where datname='%s';", db->name);
  res = PQexec (conn, mstring_buf (str));

  if (PQresultStatus (res) != PGRES_TUPLES_OK) {
    logerror ("psql: Could not get list of existing databases\n");
    goto cleanup_exit;
  }

  /* No result rows means database doesn't exist, so create it instead */
  if (PQntuples (res) == 0) {
    loginfo ("psql:%s: Database does not exist, creating it\n", db->name);
    mstring_set (str, "");
    mstring_sprintf (str, "CREATE DATABASE \"%s\";", db->name);

    res = PQexec (conn, mstring_buf (str));
    if (PQresultStatus (res) != PGRES_COMMAND_OK) {
      logerror ("psql:%s: Could not create database: %s\n", db->name, PQerrorMessage (conn));
      goto cleanup_exit;
    }
  }

  PQfinish (conn);
  mstring_delete(conninfo);

  /* Now that the database should exist, make a connection to the it for real */
  conninfo = psql_prepare_conninfo(db->name, pg_host, pg_port, pg_user, pg_pass, pg_conninfo);
  conn = PQconnectdb(mstring_buf (conninfo));

  /* Check to see that the backend connection was successfully made */
  if (PQstatus(conn) != CONNECTION_OK) {
    logerror ("psql:%s: Could not connect to PostgreSQL database (conninfo \"%s\"): %s\n",
        db->name, mstring_buf(conninfo), PQerrorMessage (conn));
    goto cleanup_exit;
  }
  PQsetNoticeReceiver(conn, psql_receive_notice, db->name);

  PsqlDB* self = (PsqlDB*)xmalloc(sizeof(PsqlDB));
  self->conn = conn;
  self->last_commit = time (NULL);

  db->create = psql_create_database;
  db->release = psql_release;
  db->table_create = psql_table_create;
  db->table_create_meta = psql_table_create_meta;
  db->table_free = psql_table_free;
  db->insert = psql_insert;
  db->add_sender_id = psql_add_sender_id;
  db->get_metadata = psql_get_metadata;
  db->set_metadata = psql_set_metadata;
  db->get_uri = psql_get_uri;
  db->get_table_list = psql_get_table_list;

  db->handle = self;

  begin_transaction (self);

  /* Everything was successufl, prepare for cleanup */
  ret = 0;

cleanup_exit:
  if (res) PQclear (res);
  if (ret) PQfinish (conn); /* If return !=0, cleanup connection */

  mstring_delete (str);
  mstring_delete (conninfo);
  return ret;
}
Пример #3
0
TableDescr*
psql_get_table_list (Database *database, int *num_tables)
{
  PsqlDB *self = database->handle;
  const char *stmt_tablename =
    "SELECT tablename FROM pg_tables WHERE tablename NOT LIKE 'pg%' AND tablename NOT LIKE 'sql%';";
  PGresult *res;
  TableDescr *tables = NULL;
  int rows, cols, i;

  *num_tables = -1;
  res = PQexec (self->conn, stmt_tablename);
  if (PQresultStatus (res) != PGRES_TUPLES_OK) {
    logerror("psql:%s: Couldn't get list of tables: %s\n",
        database->name, PQerrorMessage (self->conn));
    PQclear (res);
    return NULL;
  }
  rows = PQntuples (res);
  cols = PQnfields (res);

  if (cols < 1)
    return NULL;

  int have_meta = 0;
  for (i = 0; i < rows && !have_meta; i++)
    if (strcmp (PQgetvalue (res, i, 0), "_experiment_metadata") == 0)
      have_meta = 1;

  if(!have_meta)
    logdebug("psql:%s: No metadata found\n", database->name);

  *num_tables = 0;

  for (i = 0; i < rows; i++) {
    char *val = PQgetvalue (res, i, 0);
    logdebug("psql:%s: Found table '%s'", database->name, val);
    MString *str = mstring_create ();
    TableDescr *t = NULL;

    if (have_meta) {
      mstring_sprintf (str, "SELECT value FROM _experiment_metadata WHERE key='table_%s';", val);
      PGresult *schema_res = PQexec (self->conn, mstring_buf (str));
      if (PQresultStatus (schema_res) != PGRES_TUPLES_OK) {
        logdebug("psql:%s: Couldn't get schema for table '%s': %s; skipping\n",
            database->name, val, PQerrorMessage (self->conn));
        mstring_delete (str);
        continue;
      }
      int rows = PQntuples (schema_res);
      if (rows == 0) {
        logdebug("psql:%s: Metadata for table '%s' found but empty\n", database->name, val);
        t = table_descr_new (val, NULL); // Don't know the schema for this table
      } else {
        logdebug("psql:%s: Stored schema for table '%s': %s\n", database->name, val, PQgetvalue (schema_res, 0, 0));
        struct schema *schema = schema_from_meta (PQgetvalue (schema_res, 0, 0));
        t = table_descr_new (val, schema);
      }
      PQclear (schema_res);
      mstring_delete (str);
    } else {
      t = table_descr_new (val, NULL);
    }

    if (t) {
      t->next = tables;
      tables = t;
      (*num_tables)++;
    }
  }

  return tables;
}
Пример #4
0
/**
 * @brief Create a PostgreSQL table
 * @param db the database that contains the sqlite3 db
 * @param table the table to associate in sqlite3 database
 * @return 0 if successful, -1 otherwise
 */
static int
table_create (Database* db, DbTable* table, int backend_create)
{
  if (db == NULL) {
    logerror("psql: Tried to create a table in a NULL database\n");
    return -1;
  }
  if (table == NULL) {
    logerror("psql:%s: Tried to create a table from a NULL definition\n", db->name);
    return -1;
  }
  if (table->schema == NULL) {
    logerror("psql:%s: No schema defined for table, cannot create\n", db->name);
    return -1;
  }
  MString *insert = NULL, *create = NULL;
  PsqlDB* psqldb = (PsqlDB*)db->handle;
  PGresult *res;

  if (backend_create) {
    int sindex = table->schema->index;
    table->schema->index = -1;
    MString *mstr = mstring_create ();
    mstring_sprintf (mstr, "table_%s", table->schema->name);
    const char *meta = schema_to_meta (table->schema);
    table->schema->index = sindex;
    logdebug("psql:%s: SET META: %s\n", db->name, meta);
    psql_set_metadata (db, mstring_buf (mstr), meta);
    create = schema_to_sql (table->schema, oml_to_postgresql_type);
    if (!create) {
      logerror("psql:%s: Failed to build SQL CREATE TABLE statement string for table '%s'\n",
          db->name, table->schema->name);
      goto fail_exit;
    }
    if (sql_stmt (psqldb, mstring_buf (create))) {
      logerror("psql:%s: Could not create table '%s': %s\n",
          db->name, table->schema->name,
          PQerrorMessage (psqldb->conn));
      goto fail_exit;
    }
  }

  insert = psql_make_sql_insert (table);
  if (!insert) {
    logerror("psql:%s: Failed to build SQL INSERT INTO statement for table '%s'\n",
          db->name, table->schema->name);
    goto fail_exit;
  }
  /* Prepare the insert statement and update statement  */
  PsqlTable* psqltable = (PsqlTable*)xmalloc(sizeof(PsqlTable));
  table->handle = psqltable;

  MString *insert_name = mstring_create();
  mstring_set (insert_name, "OMLInsert-");
  mstring_cat (insert_name, table->schema->name);
  res = PQprepare(psqldb->conn,
                  mstring_buf (insert_name),
                  mstring_buf (insert),
                  table->schema->nfields + 4, // FIXME:  magic number of metadata cols
                  NULL);

  if (PQresultStatus(res) != PGRES_COMMAND_OK) {
    logerror("psql:%s: Could not prepare statement: %s\n",
        db->name, PQerrorMessage(psqldb->conn));
    PQclear(res);
    goto fail_exit;
    return -1;
  }
  PQclear(res);
  psqltable->insert_stmt = insert_name;

  if (create) mstring_delete (create);
  if (insert) mstring_delete (insert);
  return 0;

fail_exit:
  if (create) mstring_delete (create);
  if (insert) mstring_delete (insert);
  return -1;
}
Пример #5
0
bool
loadStandardState ()
{
  cstring fpath;
  FILE *stdlib;
  bool result;
  cstring libname = fileLib_addExtension (context_selectedLibrary (), 
					  cstring_makeLiteralTemp (DUMP_SUFFIX));
  
  if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
    {
      lldiagmsg (message ("Cannot find %sstandard library: %s", 
			  cstring_makeLiteralTemp 
			  (context_getFlag (FLG_STRICTLIB) ? "strict " 
			   : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
			  libname));
      lldiagmsg (cstring_makeLiteral ("     Check LARCH_PATH environment variable."));
      result = FALSE;
    }
  else
    {
      stdlib = fileTable_openReadFile (context_fileTable (), fpath);

      if (stdlib == NULL)
	{
	  lldiagmsg (message ("Cannot read standard library: %s",
			      fpath));
	  lldiagmsg (cstring_makeLiteral ("     Check LARCH_PATH environment variable."));

	  result = FALSE;
	}
      else
	{
	  if (context_getFlag (FLG_WHICHLIB))
	    {
	      char *t = mstring_create (MAX_NAME_LENGTH);
	      char *ot = t;

	      if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
		{
		  llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
		}

	      if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
		{
		  if (*t == ';' && *(t + 1) == ';') 
		    {
		      t += 2;
		    }
		}

	      if (t == NULL)
		{
		  lldiagmsg (message ("Standard library: %s <cannot read creation information>", 
				      fpath));
		}
	      else
		{
		  char *tt;

		  tt = strrchr (t, '\n');
		  if (tt != NULL)
		    *tt = '\0';

		  lldiagmsg (message ("Standard library: %s", fpath));
		  /* evans 2004-01-13: removed this (it is the libversion which is confusing) */
		  /*   lldiagmsg (message ("   (created using %s)", cstring_fromChars (t)));		    */
		}

	      sfree (ot);
	      
	      check (fileTable_closeFile (context_fileTable (), stdlib));
	      stdlib = fileTable_openReadFile (context_fileTable (), fpath);
	    }

	  llassert (stdlib != NULL);

	  fileloc_reallyFree (g_currentloc);
	  g_currentloc = fileloc_createLib (libname);

	  DPRINTF (("Loading: %s", fpath));

	  displayScanOpen (message ("loading standard library %s ", fpath));
	  result = loadLCDFile (stdlib, fpath);
	  displayScanClose ();

	  check (fileTable_closeFile (context_fileTable (), stdlib));
	}
    }

  cstring_free (libname);
  return result;
}
Пример #6
0
mstring_t*
mstring_wrap(byte* str){
    mstring_t* ret = mstring_create();
    mstring_put(ret, str, strlen((const char *) str));
    return ret;
}