Subversion Repositories oidplus

Rev

Rev 231 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 231 Rev 236
Line 22... Line 22...
22
class OIDplusDataBasePluginODBC extends OIDplusDataBasePlugin {
22
class OIDplusDataBasePluginODBC extends OIDplusDataBasePlugin {
23
        private $odbc;
23
        private $odbc;
24
        private $last_query;
24
        private $last_query;
25
        private $prepare_cache = array();
25
        private $prepare_cache = array();
26
 
26
 
27
        public static function getPluginInformation() {
27
        public static function getPluginInformation(): array {
28
                $out = array();
28
                $out = array();
29
                $out['name'] = 'ODBC';
29
                $out['name'] = 'ODBC';
30
                $out['author'] = 'ViaThinkSoft';
30
                $out['author'] = 'ViaThinkSoft';
31
                $out['version'] = null;
31
                $out['version'] = null;
32
                $out['descriptionHTML'] = null;
32
                $out['descriptionHTML'] = null;
33
                return $out;
33
                return $out;
34
        }
34
        }
35
 
35
 
36
        public static function name() {
36
        public static function name(): string {
37
                return "ODBC";
37
                return "ODBC";
38
        }
38
        }
39
 
39
 
40
        public function query($sql, $prepared_args=null) {
40
        public function query($sql, $prepared_args=null): OIDplusQueryResult {
41
                $this->last_query = $sql;
41
                $this->last_query = $sql;
42
                if (is_null($prepared_args)) {
42
                if (is_null($prepared_args)) {
43
                        return @odbc_exec($this->odbc, $sql);
43
                        $res = @odbc_exec($this->odbc, $sql);
44
                } else {
-
 
45
 
-
 
46
 
44
 
-
 
45
                        if ($res === false) {
-
 
46
                                throw new OIDplusSQLException($sql, $this->error());
-
 
47
                        } else {
-
 
48
                                return new OIDplusQueryResultODBC($res);
-
 
49
                        }
-
 
50
                } else {
47
                        // TEST: Emulate the prepared statement
51
                        // TEST: Emulate the prepared statement
48
 
-
 
49
/*
52
                        /*
50
                        foreach ($prepared_args as $arg) {
53
                        foreach ($prepared_args as $arg) {
51
                                $needle = '?';
54
                                $needle = '?';
52
                                $replace = "'$arg'"; // TODO: types
55
                                $replace = "'$arg'"; // TODO: types
53
                                $pos = strpos($sql, $needle);
56
                                $pos = strpos($sql, $needle);
54
                                if ($pos !== false) {
57
                                if ($pos !== false) {
55
                                        $sql = substr_replace($sql, $replace, $pos, strlen($needle));
58
                                        $sql = substr_replace($sql, $replace, $pos, strlen($needle));
56
                                }
59
                                }
57
                        }
60
                        }
58
                        return @odbc_exec($this->odbc, $sql);
61
                        return OIDplusQueryResultODBC(@odbc_exec($this->odbc, $sql));
59
*/
62
                        */
60
 
63
 
61
 
-
 
62
                        if (!is_array($prepared_args)) {
64
                        if (!is_array($prepared_args)) {
63
                                throw new Exception("'prepared_args' must be either NULL or an ARRAY.");
65
                                throw new Exception("'prepared_args' must be either NULL or an ARRAY.");
64
                        }
66
                        }
65
                        if (isset($this->prepare_cache[$sql])) {
67
                        if (isset($this->prepare_cache[$sql])) {
66
                                $ps = $this->prepare_cache[$sql];
68
                                $ps = $this->prepare_cache[$sql];
67
                        } else {
69
                        } else {
68
                                $ps = odbc_prepare($this->odbc, $sql);
70
                                $ps = odbc_prepare($this->odbc, $sql);
69
                                if (!$ps) {
71
                                if (!$ps) {
70
                                        throw new Exception("Cannot prepare statement '$sql'");
72
                                        throw new OIDplusSQLException($sql, 'Cannot prepare statement');
71
                                }
73
                                }
72
                                $this->prepare_cache[$sql] = $ps;
74
                                $this->prepare_cache[$sql] = $ps;
73
                        }
75
                        }
74
                        if (!@odbc_execute($ps, $prepared_args)) {
76
                        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);
77
                                throw new OIDplusSQLException($sql, $this->error());
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
                }
78
                        }
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);
79
                        return new OIDplusQueryResultODBC($ps);
101
                }
80
                }
102
        }
81
        }
-
 
82
 
103
        public function insert_id() {
83
        public function insert_id(): int {
-
 
84
                try {
104
                $res = $this->query("SELECT LAST_INSERT_ID AS ID"); // MySQL
85
                        $res = $this->query("SELECT LAST_INSERT_ID AS ID"); // MySQL
-
 
86
                } catch (Exception $e) {
-
 
87
                        $res = null;
-
 
88
                }
-
 
89
 
-
 
90
                try {
105
                if (!$res) $res = $this->query("SELECT @@IDENTITY AS ID"); // MS SQL
91
                        if (!$res) $res = $this->query("SELECT @@IDENTITY AS ID"); // MS SQL
106
                if (!$res) return false;
92
                } catch (Exception $e) {
107
                $row = $this->fetch_array($res);
-
 
108
                return $row['ID'];
93
                        $res = null;
109
        }
94
                }
-
 
95
 
-
 
96
                if (!$res) return 0;
-
 
97
 
-
 
98
                $row = $res->fetch_array();
-
 
99
                return (int)$row['ID'];
-
 
100
        }
-
 
101
 
110
        public function error() {
102
        public function error(): string {
111
                return odbc_errormsg($this->odbc);
103
                return odbc_errormsg($this->odbc);
112
        }
104
        }
-
 
105
 
113
        private $html = null;
106
        private $html = null;
114
        public function init($html = true) {
107
        public function init($html = true): void {
115
                $this->html = $html;
108
                $this->html = $html;
116
        }
109
        }
-
 
110
 
117
        public function connect() {
111
        public function connect(): void {
118
                // Try connecting to the database
112
                // Try connecting to the database
119
                $this->odbc = @odbc_connect(OIDPLUS_ODBC_DSN, OIDPLUS_ODBC_USERNAME, base64_decode(OIDPLUS_ODBC_PASSWORD));
113
                $this->odbc = @odbc_connect(OIDPLUS_ODBC_DSN, OIDPLUS_ODBC_USERNAME, base64_decode(OIDPLUS_ODBC_PASSWORD));
120
 
114
 
121
                if (!$this->odbc) {
115
                if (!$this->odbc) {
122
                        if ($this->html) {
116
                        if ($this->html) {
Line 131... Line 125...
131
                                }
125
                                }
132
                        }
126
                        }
133
                        die();
127
                        die();
134
                }
128
                }
135
 
129
 
-
 
130
                try {
136
                $this->query("SET NAMES 'utf8'"); // Does most likely NOT work with ODBC. Try adding ";CHARSET=UTF8" (or similar) to the DSN
131
                        $this->query("SET NAMES 'utf8'"); // Does most likely NOT work with ODBC. Try adding ";CHARSET=UTF8" (or similar) to the DSN
-
 
132
                } catch (Exception $e) {
-
 
133
                }
137
                $this->afterConnect($this->html);
134
                $this->afterConnect($this->html);
138
                $this->connected = true;
135
                $this->connected = true;
139
        }
136
        }
140
 
137
 
141
        private $intransaction = false;
138
        private $intransaction = false;
142
 
139
 
143
        public function transaction_begin() {
140
        public function transaction_begin(): void {
144
                if ($this->intransaction) throw new Exception("Nested transactions are not supported by this database plugin.");
141
                if ($this->intransaction) throw new Exception("Nested transactions are not supported by this database plugin.");
145
                odbc_autocommit($this->odbc, true);
142
                odbc_autocommit($this->odbc, true);
146
                $this->intransaction = true;
143
                $this->intransaction = true;
147
        }
144
        }
148
 
145
 
149
        public function transaction_commit() {
146
        public function transaction_commit(): void {
150
                odbc_commit($this->odbc);
147
                odbc_commit($this->odbc);
151
                odbc_autocommit($this->odbc, false);
148
                odbc_autocommit($this->odbc, false);
152
                $this->intransaction = false;
149
                $this->intransaction = false;
153
        }
150
        }
154
 
151
 
155
        public function transaction_rollback() {
152
        public function transaction_rollback(): void {
156
                odbc_rollback($this->odbc);
153
                odbc_rollback($this->odbc);
157
                odbc_autocommit($this->odbc, false);
154
                odbc_autocommit($this->odbc, false);
158
                $this->intransaction = false;
155
                $this->intransaction = false;
159
        }
156
        }
160
}
157
}
-
 
158
 
-
 
159
class OIDplusQueryResultODBC extends OIDplusQueryResult {
-
 
160
        protected $no_resultset;
-
 
161
        protected $res;
-
 
162
 
-
 
163
        public function __construct($res) {
-
 
164
                $this->no_resultset = $res === false;
-
 
165
                $this->res = $res;
-
 
166
        }
-
 
167
 
-
 
168
        public function containsResultSet(): bool {
-
 
169
                return !$this->no_resultset;
-
 
170
        }
-
 
171
 
-
 
172
        public function num_rows(): int {
-
 
173
                if ($this->no_resultset) throw new Exception("The query has returned no result set (i.e. it was not a SELECT query)");
-
 
174
                return odbc_num_rows($this->res);
-
 
175
        }
-
 
176
 
-
 
177
        public function fetch_array()/*: ?array*/ {
-
 
178
                if ($this->no_resultset) throw new Exception("The query has returned no result set (i.e. it was not a SELECT query)");
-
 
179
                $ret = odbc_fetch_array($this->res);
-
 
180
                if ($ret === false) $ret = null;
-
 
181
                return $ret;
-
 
182
        }
-
 
183
 
-
 
184
        public function fetch_object()/*: ?object*/ {
-
 
185
                if ($this->no_resultset) throw new Exception("The query has returned no result set (i.e. it was not a SELECT query)");
-
 
186
                $ret = odbc_fetch_object($this->res);
-
 
187
                if ($ret === false) $ret = null;
-
 
188
                return $ret;
-
 
189
        }
-
 
190
}