FrxPDO.inc 4.41 KB
Newer Older
1
2
<?php
/**
metzlerd's avatar
metzlerd committed
3
 * @file
metzlerd's avatar
metzlerd committed
4
 * General database engine used to do sql queries.
5
6
7
 *
 */

metzlerd's avatar
metzlerd committed
8
class FrxPDO extends FrxDataSource {
metzlerd's avatar
metzlerd committed
9

metzlerd's avatar
metzlerd committed
10

11
  private $db;
metzlerd's avatar
metzlerd committed
12
13
14
  public $debug;


15
16
17
18
19
20
  /**
   * Object constructor
   *
   * @param unknown_type $uri Database connection string.
   * @param string $repos_path Path to location of data block definitions
   */
21
22
  public function __construct($conf, $repos_path, $name) {
    parent::__construct($conf, $repos_path, $name);
metzlerd's avatar
metzlerd committed
23
24
25
    $uri = $conf['uri'];
    $this->debug = $conf['debug'];
    if ($uri) {
metzlerd's avatar
metzlerd committed
26
      // Test for PDO suport
metzlerd's avatar
metzlerd committed
27
      if (!class_exists('PDO')) {
28
        FrxReportGenerator::instance()->error('PDO support not installed.', 'PDO support not installed.');
metzlerd's avatar
metzlerd committed
29
30
        return;
      }
metzlerd's avatar
metzlerd committed
31

metzlerd's avatar
metzlerd committed
32
33
      $options = array();
      if (@$conf['mysql_charset']) {
metzlerd's avatar
metzlerd committed
34
        $options = array(
metzlerd's avatar
metzlerd committed
35
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . $conf['mysql_charset'],
metzlerd's avatar
metzlerd committed
36
37
38
        );
      }

metzlerd's avatar
metzlerd committed
39
      // Test for driver support
metzlerd's avatar
metzlerd committed
40
41
      @list($prot, $c) = explode(':', $uri, 2);
      $drivers = PDO::getAvailableDrivers();
metzlerd's avatar
metzlerd committed
42
      if ($drivers && (array_search($prot, $drivers)===FALSE)) {
metzlerd's avatar
metzlerd committed
43
        $msg = 'PDO driver support for ' . $prot . ' not installed';
44
        FrxReportGenerator::instance()->error($msg, $msg);
metzlerd's avatar
metzlerd committed
45
        return;
metzlerd's avatar
metzlerd committed
46
      }
metzlerd's avatar
metzlerd committed
47
48
      try {
        if (isset($conf['user'])) {
metzlerd's avatar
metzlerd committed
49
          $db = new PDO($uri, $conf['user'], $conf['password'], $options);
50
        }
metzlerd's avatar
metzlerd committed
51
        else {
metzlerd's avatar
metzlerd committed
52
          $db = new PDO($uri, NULL, NULL, $options);
metzlerd's avatar
metzlerd committed
53
54
55
        }
        $this->db = $db;
        if (!is_object($db)) {
56
          FrxReportGenerator::instance()->error('Unknown error connecting to database ' . $uri);
metzlerd's avatar
metzlerd committed
57
58
        }
      } catch (PDOException $e) {
59
        FrxReportGenerator::instance()->error('Unable to connect to database', $e->getMessage());
60
      }
metzlerd's avatar
metzlerd committed
61
62
63

    }
    else {
64
      FrxReportGenerator::instance()->error('No database connection string specified');
65
    }
metzlerd's avatar
metzlerd committed
66
67
68

    // Set up the stuff required to translate.
    $this->te = new FrxSyntaxEngine(FRX_SQL_TOKEN, ':', $this);
69
70
  }
  /**
metzlerd's avatar
metzlerd committed
71
   * Get data based on file data block in the repository.
72
73
74
75
76
   *
   * @param String $block_name
   * @param Array $parm_data
   * @param Query $subQuery
   */
metzlerd's avatar
metzlerd committed
77
  public function sqlData($sql) {
78
    // Load the block from the file
metzlerd's avatar
metzlerd committed
79
80
    $db = $this->db;
    $xml ='';
metzlerd's avatar
metzlerd committed
81
    if ($sql && $db) {
82
      $sql = $this->te->replace($sql);
metzlerd's avatar
metzlerd committed
83
84
      $rs = $db->query($sql);
      $xml = new SimpleXMLElement('<table/>');
85
      $e = $db->errorCode();
metzlerd's avatar
metzlerd committed
86
      if ($e != '00000') {
metzlerd's avatar
metzlerd committed
87
        $i = $db->errorInfo();
88
        FrxReportGenerator::instance()->error($i[2] . ':' . $sql, $i[2]);
metzlerd's avatar
metzlerd committed
89
90
91
92
93
94
95
      }
      else {

        //$rs->debugDumpParams();
        $data = $rs->fetchAll(PDO::FETCH_ASSOC);
        foreach ($data as $row) {
          $row_node = $xml->addChild('row');
metzlerd's avatar
metzlerd committed
96
          foreach ($row as $key => $value) {
metzlerd's avatar
metzlerd committed
97
            $row_node->addChild($key, htmlspecialchars($value));
98
99
          }
        }
metzlerd's avatar
metzlerd committed
100

101
      }
metzlerd's avatar
metzlerd committed
102
103
104

      if ($this->debug) {
        if ($xml) $d = htmlspecialchars($xml->asXML);
105
        FrxReportGenerator::instance()->debug('SQL: ' . $sql, '<pre> SQL:' . $sql . "\n XML: " . $d . "/n</pre>");
metzlerd's avatar
metzlerd committed
106
107
      }
      return $xml;
108
    }
metzlerd's avatar
metzlerd committed
109

110
  }
metzlerd's avatar
metzlerd committed
111

112
113
114
115
116
117
118
  /**
   * 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);
119
    if (($value!=='' || $value!==NULL) && !$new_value) {
metzlerd's avatar
metzlerd committed
120
      $value = "'" . str_replace("'", "''", $value) . "'";
121
122
    }
    else {
metzlerd's avatar
metzlerd committed
123
      $value = $new_value;
124
125
126
127
    }
    return $value;
  }

128
129
  /**
   * Implement custom SQL formatter to make sure that strings are properly escaped.
metzlerd's avatar
metzlerd committed
130
131
   * Ideally we'd replace this with something that handles prepared statements, but it
   * wouldn't work for
132
133
134
135
136
   *
   * @param unknown_type $value
   * @param unknown_type $key
   * @param unknown_type $data
   */
metzlerd's avatar
metzlerd committed
137
138
  public function format($value, $key, $data) {
    $db = $this->db;
139
    if ($db) {
metzlerd's avatar
metzlerd committed
140
      if ($value==='' || $value ===NULL || $value === array()) {
metzlerd's avatar
metzlerd committed
141
        $value = 'NULL';
142
143
      }
      elseif (is_array($value)) {
metzlerd's avatar
metzlerd committed
144
145
146
147
148
149
150
151
152
153
154
        if ($value == array()) {
          $value = 'NULL';
        }
        else {
          // Build a array of values string
          $i=0;
          $val ='';
          foreach ($value as $v) {
            $i++;
            if ($i!=1) {
              $val .= ',';
metzlerd's avatar
metzlerd committed
155
156
            }
            $val .= $this->quote($v);
metzlerd's avatar
metzlerd committed
157
          }
metzlerd's avatar
metzlerd committed
158
          $value = $val;
159
160
        }
      }
161
      else  $value =  $this->quote($value);
162
    }
163
    return (string)$value;
164
  }
metzlerd's avatar
metzlerd committed
165

166
}