<?php
// $Id: install.pdo_pgsql.inc,v 1.2 2007/12/11 07:21:32 hswong3i Exp $

// pdo_pgsql specific install functions.

/**
 * Check if PDO PostgreSQL is available.
 *
 * @return
 *  TRUE/FALSE
 */
function pdo_pgsql_is_available() {
  return class_exists('PDO') && extension_loaded('pdo_pgsql');
}

/**
 * Check if we can connect to PostgreSQL.
 *
 * @return
 *  TRUE/FALSE
 */
function drupal_test_pdo_pgsql($url, &$success) {
  if (!pdo_pgsql_is_available()) {
    drupal_set_message(st('PHP pdo_pgsql support not enabled.'), 'error');
    return FALSE;
  }

  $url = parse_url($url);

  // Decode url-encoded information in the db connection string.
  $username = isset($url['user']) ? urldecode($url['user']) : NULL;
  $password = isset($url['pass']) ? urldecode($url['pass']) : NULL;

  // Build pdo_pgsql connection string and allow for non-standard PostgreSQL port.
  $dsn[] = isset($url['host']) ? 'host='. urldecode($url['host']) : NULL;
  $dsn[] = isset($url['path']) ? 'dbname='. substr(urldecode($url['path']), 1) : NULL;
  $dsn[] = isset($url['port']) ? 'port='. urldecode($url['port']) : NULL;
  $dsn = 'pgsql:'. implode(' ', $dsn);

  $driver_options = array(
    // Throw a PDOException and set its properties to reflect the error code
    // and error information.
    PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING,
    //  Leave column names as returned by the database driver.
    PDO::ATTR_CASE => PDO::CASE_NATURAL,
  );

  try {
    $connection = new PDO($dsn, $username, $password, $driver_options);
  } catch (PDOExecption $e) {
    drupal_set_message(st('Failed to connect to your PostgreSQL database server. PostgreSQL reports the following message: %error.<ul><li>Are you sure you have the correct username and password?</li><li>Are you sure that you have typed the correct database hostname?</li><li>Are you sure that the database server is running?</li><li>Are you sure you typed the correct database name?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', array('%error' => $e->getMessage())), 'error');
    return FALSE;
  }

  $success = array('CONNECT');

  // Test CREATE.
  $query = 'CREATE TABLE "drupal_install_test" ("id" INT NOT NULL)';
  $stmt = $connection->prepare($query);
  $stmt->execute();
  $error = $stmt->errorInfo();
  if (is_array($error) && $error[0] != 0 && isset($error[2])) {
    drupal_set_message(st('Failed to create a test table on your PostgreSQL database server with the command %query. PostgreSQL reports the following message: %error.<ul><li>Are you sure the configured username has the necessary PostgreSQL permissions to create tables in the database?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', array('%query' => $query, '%error' => $error[2])), 'error');
    return FALSE;
  }
  $err = FALSE;
  $success[] = 'SELECT';
  $success[] = 'CREATE';

  // Test INSERT.
  $query = 'INSERT INTO "drupal_install_test" ("id") VALUES (1)';
  $stmt = $connection->prepare($query);
  $stmt->execute();
  $error = $stmt->errorInfo();
  if (is_array($error) && $error[0] != 0 && isset($error[2])) {
    drupal_set_message(st('Failed to insert a value into a test table on your PostgreSQL database server. We tried inserting a value with the command %query and PostgreSQL reported the following error: %error.', array('%query' => $query, '%error' => $error[2])), 'error');
    $err = TRUE;
  }
  else {
    $success[] = 'INSERT';
  }

  // Test UPDATE.
  $query = 'UPDATE "drupal_install_test" SET "id" = 2';
  $stmt = $connection->prepare($query);
  $stmt->execute();
  $error = $stmt->errorInfo();
  if (is_array($error) && $error[0] != 0 && isset($error[2])) {
    drupal_set_message(st('Failed to update a value in a test table on your PostgreSQL database server. We tried updating a value with the command %query and PostgreSQL reported the following error: %error.', array('%query' => $query, '%error' => $error[2])), 'error');
    $err = TRUE;
  }
  else {
    $success[] = 'UPDATE';
  }

  // Test LOCK.
  $query = 'LOCK "drupal_install_test" IN SHARE ROW EXCLUSIVE MODE';
  $stmt = $connection->prepare($query);
  $stmt->execute();
  $error = $stmt->errorInfo();
  if (is_array($error) && $error[0] != 0 && isset($error[2])) {
    drupal_set_message(st('Failed to lock a test table on your PostgreSQL database server. We tried locking a table with the command %query and PostgreSQL reported the following error: %error.', array('%query' => $query, '%error' => $error[2])), 'error');
    $err = TRUE;
  }
  else {
    $success[] = 'LOCK';
  }

  // Test UNLOCK, which is done automatically upon transaction end in PostgreSQL.
  $query = 'COMMIT';
  $stmt = $connection->prepare($query);
  $stmt->execute();
  $error = $stmt->errorInfo();
  if (is_array($error) && $error[0] != 0 && isset($error[2])) {
    drupal_set_message(st('Failed to unlock a test table on your PostgreSQL database server. We tried unlocking a table with the command %query and PostgreSQL reported the following error: %error.', array('%query' => $query, '%error' => $error[2])), 'error');
    $err = TRUE;
  }
  else {
    $success[] = 'UNLOCK';
  }

  // Test DELETE.
  $query = 'DELETE FROM "drupal_install_test"';
  $stmt = $connection->prepare($query);
  $stmt->execute();
  $error = $stmt->errorInfo();
  if (is_array($error) && $error[0] != 0 && isset($error[2])) {
    drupal_set_message(st('Failed to delete a value from a test table on your PostgreSQL database server. We tried deleting a value with the command %query and PostgreSQL reported the following error: %error.', array('%query' => $query, '%error' => $error[2])), 'error');
    $err = TRUE;
  }
  else {
    $success[] = 'DELETE';
  }

  // Test DROP.
  $query = 'DROP TABLE "drupal_install_test"';
  $stmt = $connection->prepare($query);
  $stmt->execute();
  $error = $stmt->errorInfo();
  if (is_array($error) && $error[0] != 0 && isset($error[2])) {
    drupal_set_message(st('Failed to drop a test table from your PostgreSQL database server. We tried dropping a table with the command %query and PostgreSQL reported the following error %error.', array('%query' => $query, '%error' => $error[2])), 'error');
    $err = TRUE;
  }
  else {
    $success[] = 'DROP';
  }

  if ($err) {
    return FALSE;
  }

  $connection = NULL;
  return TRUE;
}