You are here

class FrxPDO in Forena Reports 8

Class FrxPDO

Plugin annotation


@FrxDriver(
  id="FrxPDO",
  name="PDO Driver"
)

Hierarchy

Expanded class hierarchy of FrxPDO

3 string references to 'FrxPDO'
DataSourceDefinitionForm::buildForm in src/Form/DataSourceDefinitionForm.php
[@inheritdoc}
forena.forena.yml in ./forena.forena.yml
forena.forena.yml
settings.php in data/sample/settings.php

File

src/FrxPlugin/Driver/FrxPDO.php, line 19
General database engine used to do sql queries.

Namespace

Drupal\forena\FrxPlugin\Driver
View source
class FrxPDO extends DriverBase {
  private $db;
  public $debug;

  /**
   * Object constructor
   *
   * @param string $name
   *   PDO data connection name
   * @param array $conf
   *   Array containing configuration data.
   */
  public function __construct($name, $conf, DataFileSystem $fileSystem) {
    parent::__construct($name, $conf, $fileSystem);
    $uri = $conf['uri'];
    $this->debug = @$conf['debug'];
    if ($uri) {

      // Test for PDO suport
      if (!class_exists('PDO')) {
        $this
          ->app()
          ->error('PDO support not installed.', 'PDO support not installed.');
        return NULL;
      }
      $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();
      $this->db_type = $prot;
      if ($drivers && array_search($prot, $drivers) === FALSE) {
        $msg = 'PDO driver support for ' . $prot . ' not installed';
        $this
          ->app()
          ->error($msg, $msg);
        return NULL;
      }
      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)) {
          $this
            ->app()
            ->error('Unknown error connecting to database ' . $uri);
        }
      } catch (\PDOException $e) {
        $this
          ->app()
          ->error('Unable to connect to database', $e
          ->getMessage());
      }
      if ($this->db) {
        $this->db
          ->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
      }
    }
    else {
      $this
        ->app()
        ->error('No database connection string specified');
    }

    // Set up the stuff required to translate.
    $this->te = new SQLReplacer($this);
  }
  public function parseConnectionStr() {
    $uri = @$this->conf['uri'];
    @(list($prot, $conn) = explode(':', $uri, 2));
    $conn = str_replace(';', ' ', $conn);
    $info = array();
    foreach (explode(' ', $conn) as $pairs) {
      if (strpos($pairs, '=') !== FALSE) {
        list($key, $value) = @explode('=', $pairs, 2);
        $info[trim($key)] = trim($value);
      }
    }
    return $info;
  }

  /**
   * Get data based on file data block in the repository.
   *
   * @param string $sql
   *   Query to execute
   * @param array $options
   *   Array of parameter types for the query.
   * @return SimpleXMLElement | array
   *   Data from executed SQL query.
   */
  public function sqlData($sql, $options = array()) {

    // Load the block from the file
    $db = $this->db;
    $xml = '';

    // Load the types array based on data
    $this->types = isset($options['type']) ? $options['type'] : array();
    if ($sql && $db) {
      $sql = $this->te
        ->replace($sql);
      try {
        $rs = $db
          ->query($sql);
      } catch (\PDOException $e) {
        $line = $e
          ->getLine();
        $text = $e
          ->getMessage();
        $this
          ->app()
          ->error('PDO_error: $line', $text);
        return NULL;
      }
      if (@$options['return_type'] == 'raw') {
        return $rs;
      }
      $xml = new \SimpleXMLElement('<table/>');
      $e = $db
        ->errorCode();
      if ($e != '00000') {
        $i = $db
          ->errorInfo();
        $text = $i[0] . ':' . $i[2];

        //if (forena_user_access_check('build forena sql blocks')) {
        if (!$this->block_name) {
          $short = t('%e', array(
            '%e' => $text,
          ));
        }
        else {
          $short = t('SQL Error in %b.sql', array(
            '%b' => $this->block_name,
          ));
        }
        $this
          ->app()
          ->error($short, $text);
      }
      else {
        if ($rs && $rs
          ->columnCount()) {
          if (@$options['return_type'] == 'raw') {
            return $rs;
          }
          $rownum = 0;
          foreach ($rs as $data) {
            $rownum++;
            $row_node = $xml
              ->addChild('row');
            $row_node['num'] = $rownum;
            foreach ($data as $key => $value) {
              $row_node
                ->addChild($key, htmlspecialchars($value));
            }
          }
        }
      }
      if ($this->debug) {
        $d = '';
        if ($xml) {
          $d = htmlspecialchars($xml
            ->asXML());
        }
        $this
          ->app()
          ->debug('SQL: ' . $sql, '<pre> SQL:' . $sql . "\n XML: " . $d . "/n</pre>");
      }
      return $xml;
    }
    else {
      return NULL;
    }
  }

  /**
   * Wrapper method cause some ODBC providers do not support
   * quoting.   We're going to assume the MSSQL method of quoting.
   * @param string $value
   *   Value to be quoted.
   * @return string
   *   Properly quoted 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 string $value
   *   The value being formatted.
   * @param string $key
   *   The name of the token being replaced.
   * @param bool $raw
   *   TRUE implies the value should not be formatted for human consumption.
   * @return string
   *   Formatted value.
   */
  public function format($value, $key, $raw = FALSE) {
    if ($raw) {
      return $value;
    }
    $db = $this->db;
    $value = $this
      ->parmConvert($key, $value);
    if ($db) {
      if ($value === '' || $value === NULL || $value === array()) {
        $value = 'NULL';
      }
      elseif (is_int($value)) {
        $value = (int) $value;
        $value = (string) $value;
      }
      elseif (is_float($value)) {
        $value = (double) $value;
        $value = (string) $value;
      }
      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;
  }
  public function searchTables($str) {
    $str .= '%';
    $sql = $this
      ->searchTablesSQL();
    if ($sql) {
      $st = $this->db
        ->prepare($sql);
      if ($st) {
        $st
          ->execute(array(
          ':str' => $str,
        ));
      }
      if ($st) {
        return $st
          ->fetchAll(\PDO::FETCH_COLUMN, 0);
      }
      else {
        return NULL;
      }
    }
    else {
      return NULL;
    }
  }
  public function searchTableColumns($table, $str) {
    $str .= '%';
    $sql = $this
      ->searchTableColumnsSQL();
    $info = $this
      ->parseConnectionStr();
    $database = isset($info['dbname']) ? $info['dbname'] : @$info['database'];
    if ($sql) {
      $st = $this->db
        ->prepare($sql);
      if ($st) {
        $st
          ->execute(array(
          ':table' => $table,
          ':database' => $database,
          ':str' => $str,
        ));
      }
      if ($st) {
        return $st
          ->fetchAll(\PDO::FETCH_COLUMN, 0);
      }
      else {
        return NULL;
      }
    }
    else {
      return NULL;
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DriverBase::$block_ext public property
DriverBase::$block_extensions public property
DriverBase::$block_name public property
DriverBase::$block_path public property
DriverBase::$comment_prefix public property
DriverBase::$comment_suffix public property
DriverBase::$conf public property
DriverBase::$fileSvc public property
DriverBase::$name public property
DriverBase::$te protected property
DriverBase::$types public property
DriverBase::access public function Implements the basic default security check of calling an access method. Overrides DriverInterface::access
DriverBase::buildFilterSQL public function Build the SQL clause based on builder data.
DriverBase::data public function Return data based on block definition. Overrides DriverInterface::data
DriverBase::getSQLInclude public function
DriverBase::listDataBlocks public function Find all the blocks matching a provided search string
DriverBase::listDBBlocks public function @TODO: Determine whether we still need this.
DriverBase::loadBlock function Load blcok data from filesystem Overrides DriverInterface::loadBlock
DriverBase::loadBlockFromFile protected function
DriverBase::parmConvert public function Perform generic type conversion based on attributes.
DriverBase::parseSQLFile public function Break the contents of a sql file down to its source.
DriverBase::parseXMLFile public function Parse XML File contents into contents.
DriverBase::phpData public function
DriverBase::searchTableColumnsSQL public function
DriverBase::searchTablesSQL public function
DriverBase::tokens public function Load tokens from block source
DriverBase::xmlData public function Implement static XML functioin
FrxAPI::app public function Returns containing application service
FrxAPI::currentDataContext public function Get the current data context.
FrxAPI::currentDataContextArray public function
FrxAPI::dataManager public function Returns the data manager service
FrxAPI::dataService public function Return Data Service
FrxAPI::documentManager public function Returns the fornea document manager
FrxAPI::error public function Report an error
FrxAPI::getDataContext public function Get the context of a specific id.
FrxAPI::getDocument public function Get the current document
FrxAPI::getReportFileContents public function Load the contents of a file in the report file system.
FrxAPI::innerXML function Enter description here... 1
FrxAPI::popData public function Pop data off of the stack.
FrxAPI::pushData public function Push data onto the Stack
FrxAPI::report public function Run a report with a particular format. 1
FrxAPI::reportFileSystem public function Get the current report file system.
FrxAPI::setDataContext public function Set Data context by id.
FrxAPI::setDocument public function Change to a specific document type.
FrxAPI::skins public function Get list of skins.
FrxPDO::$db private property
FrxPDO::$debug public property Overrides DriverBase::$debug
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::parseConnectionStr public function
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::searchTableColumns public function Overrides DriverBase::searchTableColumns
FrxPDO::searchTables public function Method to return an array of tables that start with the string indicated in $str Overrides DriverBase::searchTables
FrxPDO::sqlData public function Get data based on file data block in the repository.
FrxPDO::__construct public function Object constructor Overrides DriverBase::__construct