Subversion Repositories oidplus

Rev

Rev 224 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
150 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
5
 * Copyright 2019 Daniel Marschall, ViaThinkSoft
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
20
if (!defined('IN_OIDPLUS')) die();
21
 
227 daniel-mar 22
class OIDplusDataBasePluginODBC extends OIDplusDataBasePlugin {
150 daniel-mar 23
        private $odbc;
24
        private $last_query;
25
        private $prepare_cache = array();
26
 
222 daniel-mar 27
        public static function getPluginInformation() {
28
                $out = array();
29
                $out['name'] = 'ODBC';
30
                $out['author'] = 'ViaThinkSoft';
31
                $out['version'] = null;
32
                $out['descriptionHTML'] = null;
33
                return $out;
34
        }
35
 
150 daniel-mar 36
        public static function name() {
37
                return "ODBC";
38
        }
39
 
40
        public function query($sql, $prepared_args=null) {
41
                $this->last_query = $sql;
42
                if (is_null($prepared_args)) {
43
                        return @odbc_exec($this->odbc, $sql);
44
                } else {
45
 
46
 
47
                        // TEST: Emulate the prepared statement
48
 
49
/*
50
                        foreach ($prepared_args as $arg) {
51
                                $needle = '?';
52
                                $replace = "'$arg'"; // TODO: types
53
                                $pos = strpos($sql, $needle);
54
                                if ($pos !== false) {
55
                                        $sql = substr_replace($sql, $replace, $pos, strlen($needle));
56
                                }
57
                        }
58
                        return @odbc_exec($this->odbc, $sql);
59
*/
60
 
61
 
62
                        if (!is_array($prepared_args)) {
63
                                throw new Exception("'prepared_args' must be either NULL or an ARRAY.");
64
                        }
65
                        if (isset($this->prepare_cache[$sql])) {
66
                                $ps = $this->prepare_cache[$sql];
67
                        } else {
68
                                $ps = odbc_prepare($this->odbc, $sql);
69
                                if (!$ps) {
70
                                        throw new Exception("Cannot prepare statement '$sql'");
71
                                }
72
                                $this->prepare_cache[$sql] = $ps;
73
                        }
74
                        if (!@odbc_execute($ps, $prepared_args)) {
75
                                // Note: Our plugins prepare the configs by trying to insert stuff, which raises a Primary Key exception. So we cannot throw an Exception.
76
                                return false;
77
                        }
78
                        return $ps;
79
 
80
                }
81
        }
82
        public function num_rows($res) {
83
                if (!is_resource($res)) {
84
                        throw new Exception("num_rows called on non object. Last query: ".$this->last_query);
85
                } else {
86
                        return odbc_num_rows($res);
87
                }
88
        }
89
        public function fetch_array($res) {
90
                if (!is_resource($res)) {
91
                        throw new Exception("fetch_array called on non object. Last query: ".$this->last_query);
92
                } else {
93
                        return odbc_fetch_array($res);
94
                }
95
        }
96
        public function fetch_object($res) {
97
                if (!is_resource($res)) {
98
                        throw new Exception("fetch_object called on non object. Last query: ".$this->last_query);
99
                } else {
100
                        return odbc_fetch_object($res);
101
                }
102
        }
103
        public function insert_id() {
104
                $res = $this->query("SELECT LAST_INSERT_ID AS ID"); // MySQL
105
                if (!$res) $res = $this->query("SELECT @@IDENTITY AS ID"); // MS SQL
106
                if (!$res) return false;
107
                $row = $this->fetch_array($res);
108
                return $row['ID'];
109
        }
110
        public function error() {
111
                return odbc_errormsg($this->odbc);
112
        }
113
        public function connect() {
114
                $html = OIDPLUS_HTML_OUTPUT;
115
 
116
                // Try connecting to the database
117
                $this->odbc = @odbc_connect(OIDPLUS_ODBC_DSN, OIDPLUS_ODBC_USERNAME, base64_decode(OIDPLUS_ODBC_PASSWORD));
118
 
119
                if (!$this->odbc) {
120
                        if ($html) {
121
                                echo "<h1>Error</h1><p>Database connection failed! (".odbc_errormsg().")</p>";
122
                                if (is_dir(__DIR__.'/../../../setup')) {
123
                                        echo '<p>If you believe that the login credentials are wrong, please run <a href="setup/">setup</a> again.</p>';
124
                                }
125
                        } else {
126
                                echo "Error: Database connection failed! (".odbc_errormsg().")";
127
                                if (is_dir(__DIR__.'/../../../setup')) {
128
                                        echo ' If you believe that the login credentials are wrong, please run setup again.';
129
                                }
130
                        }
131
                        die();
132
                }
133
 
134
                $this->query("SET NAMES 'utf8'"); // Does most likely NOT work with ODBC. Try adding ";CHARSET=UTF8" (or similar) to the DSN
135
                $this->afterConnect($html);
136
                $this->connected = true;
137
        }
138
 
139
        private $intransaction = false;
140
 
141
        public function transaction_begin() {
142
                if ($this->intransaction) throw new Exception("Nested transactions are not supported by this database plugin.");
143
                odbc_autocommit($this->odbc, true);
144
                $this->intransaction = true;
145
        }
146
 
147
        public function transaction_commit() {
148
                odbc_commit($this->odbc);
149
                odbc_autocommit($this->odbc, false);
150
                $this->intransaction = false;
151
        }
152
 
153
        public function transaction_rollback() {
154
                odbc_rollback($this->odbc);
155
                odbc_autocommit($this->odbc, false);
156
                $this->intransaction = false;
157
        }
158
}