You are here

class FrxPDO in Forena Reports 7.2

Same name and namespace in other branches
  1. 6.2 plugins/FrxPDO.inc \FrxPDO
  2. 6 plugins/FrxPDO.inc \FrxPDO
  3. 7 plugins/FrxPDO.inc \FrxPDO
  4. 7.3 plugins/FrxPDO.inc \FrxPDO
  5. 7.4 plugins/FrxPDO.inc \FrxPDO

@file General database engine used to do sql queries.

Hierarchy

Expanded class hierarchy of FrxPDO

4 string references to 'FrxPDO'
forena_data_settings_edit in ./forena.admin.inc
forena_forena_plugins in ./forena.module
Self register plugins with forena.
FrxHostApplication::plugins in ./FrxHostApplication.inc
settings.php in repos/sample/settings.php

File

plugins/FrxPDO.inc, line 9
General database engine used to do sql queries.

View source
class FrxPDO extends FrxDataProvider {
  private $db;
  public $debug;

  /**
   * Object constructor
   *
   * @param unknown_type $uri Database connection string.
   * @param string $repos_path Path to location of data block definitions
   */
  public function __construct($conf, $repos_path) {
    parent::__construct($conf, $repos_path);
    $uri = $conf['uri'];
    $this->debug = $conf['debug'];
    if ($uri) {

      // Test for PDO suport
      if (!class_exists('PDO')) {
        FrxReportGenerator::instance()
          ->error('PDO support not installed.', 'PDO support not installed.');
        return;
      }
      $options = array();
      if (@$conf['mysql_charset']) {
        $options = array(
          PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . $conf['mysql_charset'],
        );
      }

      // Test for driver support
      @(list($prot, $c) = explode(':', $uri, 2));
      $drivers = PDO::getAvailableDrivers();
      if ($drivers && array_search($prot, $drivers) === FALSE) {
        $msg = 'PDO driver support for ' . $prot . ' not installed';
        FrxReportGenerator::instance()
          ->error($msg, $msg);
        return;
      }
      try {
        if (isset($conf['user'])) {
          $db = new PDO($uri, $conf['user'], $conf['password'], $options);
        }
        else {
          $db = new PDO($uri, NULL, NULL, $options);
        }
        $this->db = $db;
        if (!is_object($db)) {
          FrxReportGenerator::instance()
            ->error('Unknown error connecting to database ' . $uri);
        }
      } catch (PDOException $e) {
        FrxReportGenerator::instance()
          ->error('Unable to connect to database', $e
          ->getMessage());
      }
    }
    else {
      FrxReportGenerator::instance()
        ->error('No database connection string specified');
    }

    // Set up the stuff required to translate.
    $this->te = new FrxSyntaxEngine(FRX_SQL_TOKEN, ':', $this);
  }

  /**
   * Get data based on file data block in the repository.
   *
   * @param String $block_name
   * @param Array $parm_data
   * @param Query $subQuery
   */
  public function data($block_name, $params = array(), $clause = '') {

    // Load the block from the file
    $db = $this->db;
    $block = $this
      ->load_block($block_name);
    $xml = '';
    if ($block['source'] && $this
      ->access($block['access']) && $db) {
      $sql = $block['source'];
      if ($clause) {
        $sql = 'SELECT * FROM (' . trim($sql, ' ;') . ') forena_table ' . $clause;
      }
      $sql = $this->te
        ->replace($sql);
      $rs = $db
        ->query($sql);
      $xml = new SimpleXMLElement('<table/>');
      $e = $db
        ->errorCode();
      if ($e != '00000') {
        $i = $db
          ->errorInfo();
        FrxReportGenerator::instance()
          ->error($i[2] . ':' . $sql, $i[2]);
      }
      else {

        //$rs->debugDumpParams();
        $data = $rs
          ->fetchAll(PDO::FETCH_ASSOC);
        foreach ($data as $row) {
          $row_node = $xml
            ->addChild('row');
          foreach ($row as $key => $value) {
            $row_node
              ->addChild($key, htmlspecialchars($value));
          }
        }
      }
      if ($this->debug) {
        if ($xml) {
          $d = htmlspecialchars($xml->asXML);
        }
        FrxReportGenerator::instance()
          ->debug('SQL: ' . $sql, '<pre> SQL:' . $sql . "\n XML: " . $d . "/n</pre>");
      }
      return $xml;
    }
  }

  /**
   * Wrapper method cause some ODBC providers do not support
   * quoting.   We're going to assume the MSSQL method of quoting.
   * @param $value
   */
  public function quote($value) {
    $new_value = $this->db
      ->quote($value);
    if (($value === '' || $value === NULL) && !$new_value) {
      $value = "'" . str_replace("'", "''", $value) . "'";
    }
    else {
      $value = $new_value;
    }
    return $value;
  }

  /**
   * Implement custom SQL formatter to make sure that strings are properly escaped.
   * Ideally we'd replace this with something that handles prepared statements, but it
   * wouldn't work for
   *
   * @param unknown_type $value
   * @param unknown_type $key
   * @param unknown_type $data
   */
  public function format($value, $key, $data) {
    $db = $this->db;
    if ($db) {
      drupal_set_message('value:' . $value);
      if ($value === '' || $value === NULL || $value === array()) {
        $value = 'NULL';
      }
      elseif (is_array($value)) {
        if ($value == array()) {
          $value = 'NULL';
        }
        else {

          // Build a array of values string
          $i = 0;
          $val = '';
          foreach ($value as $v) {
            $i++;
            if ($i != 1) {
              $val .= ',';
            }
            $val .= $this
              ->quote($v);
          }
          $value = $val;
        }
      }
      else {
        $value = $this
          ->quote($value);
      }
    }
    return (string) $value;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
FrxDataProvider::$block_ext public property
FrxDataProvider::$block_path public property
FrxDataProvider::$comment_prefix public property
FrxDataProvider::$comment_suffix public property
FrxDataProvider::$conf public property
FrxDataProvider::$te protected property
FrxDataProvider::access public function Implements the basic default security check of calling an access method.
FrxDataProvider::debug public function
FrxDataProvider::error public function
FrxDataProvider::list_blocks public function Find all the blocks matching a provided search string
FrxDataProvider::load_block public function Default block load Loads the data block based on the block name from the file system. The classes that are derived from this will set the block_ext property, which in most cases is .sql but might be something different. The load of the block file…
FrxDataProvider::parseSQLFile public function
FrxDataProvider::parseXMLFile public function
FrxPDO::$db private property
FrxPDO::$debug public property
FrxPDO::data public function Get data based on file data block in the repository.
FrxPDO::format public function Implement custom SQL formatter to make sure that strings are properly escaped. Ideally we'd replace this with something that handles prepared statements, but it wouldn't work for
FrxPDO::quote public function Wrapper method cause some ODBC providers do not support quoting. We're going to assume the MSSQL method of quoting.
FrxPDO::__construct public function Object constructor Overrides FrxDataProvider::__construct