adodb-pear.inc.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. <?php
  2. /**
  3. * @version v5.20.17 31-Mar-2020
  4. * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
  5. * @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
  6. * Released under both BSD license and Lesser GPL library license.
  7. * Whenever there is any discrepancy between the two licenses,
  8. * the BSD license will take precedence.
  9. *
  10. * Set tabs to 4 for best viewing.
  11. *
  12. * PEAR DB Emulation Layer for ADODB.
  13. *
  14. * The following code is modelled on PEAR DB code by Stig Bakken <ssb@fast.no> |
  15. * and Tomas V.V.Cox <cox@idecnet.com>. Portions (c)1997-2002 The PHP Group.
  16. */
  17. /*
  18. We support:
  19. DB_Common
  20. ---------
  21. query - returns PEAR_Error on error
  22. limitQuery - return PEAR_Error on error
  23. prepare - does not return PEAR_Error on error
  24. execute - does not return PEAR_Error on error
  25. setFetchMode - supports ASSOC and ORDERED
  26. errorNative
  27. quote
  28. nextID
  29. disconnect
  30. getOne
  31. getAssoc
  32. getRow
  33. getCol
  34. getAll
  35. DB_Result
  36. ---------
  37. numRows - returns -1 if not supported
  38. numCols
  39. fetchInto - does not support passing of fetchmode
  40. fetchRows - does not support passing of fetchmode
  41. free
  42. */
  43. define('ADODB_PEAR',dirname(__FILE__));
  44. include_once "PEAR.php";
  45. include_once ADODB_PEAR."/adodb-errorpear.inc.php";
  46. include_once ADODB_PEAR."/adodb.inc.php";
  47. if (!defined('DB_OK')) {
  48. define("DB_OK", 1);
  49. define("DB_ERROR",-1);
  50. /**
  51. * This is a special constant that tells DB the user hasn't specified
  52. * any particular get mode, so the default should be used.
  53. */
  54. define('DB_FETCHMODE_DEFAULT', 0);
  55. /**
  56. * Column data indexed by numbers, ordered from 0 and up
  57. */
  58. define('DB_FETCHMODE_ORDERED', 1);
  59. /**
  60. * Column data indexed by column names
  61. */
  62. define('DB_FETCHMODE_ASSOC', 2);
  63. /* for compatibility */
  64. define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
  65. define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC);
  66. /**
  67. * these are constants for the tableInfo-function
  68. * they are bitwised or'ed. so if there are more constants to be defined
  69. * in the future, adjust DB_TABLEINFO_FULL accordingly
  70. */
  71. define('DB_TABLEINFO_ORDER', 1);
  72. define('DB_TABLEINFO_ORDERTABLE', 2);
  73. define('DB_TABLEINFO_FULL', 3);
  74. }
  75. /**
  76. * The main "DB" class is simply a container class with some static
  77. * methods for creating DB objects as well as some utility functions
  78. * common to all parts of DB.
  79. *
  80. */
  81. class DB
  82. {
  83. /**
  84. * Create a new DB object for the specified database type
  85. *
  86. * @param $type string database type, for example "mysql"
  87. *
  88. * @return object a newly created DB object, or a DB error code on
  89. * error
  90. */
  91. function factory($type)
  92. {
  93. include_once(ADODB_DIR."/drivers/adodb-$type.inc.php");
  94. $obj = NewADOConnection($type);
  95. if (!is_object($obj)) $obj = new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
  96. return $obj;
  97. }
  98. /**
  99. * Create a new DB object and connect to the specified database
  100. *
  101. * @param $dsn mixed "data source name", see the DB::parseDSN
  102. * method for a description of the dsn format. Can also be
  103. * specified as an array of the format returned by DB::parseDSN.
  104. *
  105. * @param $options mixed if boolean (or scalar), tells whether
  106. * this connection should be persistent (for backends that support
  107. * this). This parameter can also be an array of options, see
  108. * DB_common::setOption for more information on connection
  109. * options.
  110. *
  111. * @return object a newly created DB connection object, or a DB
  112. * error object on error
  113. *
  114. * @see DB::parseDSN
  115. * @see DB::isError
  116. */
  117. function connect($dsn, $options = false)
  118. {
  119. if (is_array($dsn)) {
  120. $dsninfo = $dsn;
  121. } else {
  122. $dsninfo = DB::parseDSN($dsn);
  123. }
  124. switch ($dsninfo["phptype"]) {
  125. case 'pgsql': $type = 'postgres7'; break;
  126. case 'ifx': $type = 'informix9'; break;
  127. default: $type = $dsninfo["phptype"]; break;
  128. }
  129. if (is_array($options) && isset($options["debug"]) &&
  130. $options["debug"] >= 2) {
  131. // expose php errors with sufficient debug level
  132. @include_once("adodb-$type.inc.php");
  133. } else {
  134. @include_once("adodb-$type.inc.php");
  135. }
  136. @$obj = NewADOConnection($type);
  137. if (!is_object($obj)) {
  138. $obj = new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
  139. return $obj;
  140. }
  141. if (is_array($options)) {
  142. foreach($options as $k => $v) {
  143. switch(strtolower($k)) {
  144. case 'persist':
  145. case 'persistent': $persist = $v; break;
  146. #ibase
  147. case 'dialect': $obj->dialect = $v; break;
  148. case 'charset': $obj->charset = $v; break;
  149. case 'buffers': $obj->buffers = $v; break;
  150. #ado
  151. case 'charpage': $obj->charPage = $v; break;
  152. #mysql
  153. case 'clientflags': $obj->clientFlags = $v; break;
  154. }
  155. }
  156. } else {
  157. $persist = false;
  158. }
  159. if (isset($dsninfo['socket'])) $dsninfo['hostspec'] .= ':'.$dsninfo['socket'];
  160. else if (isset($dsninfo['port'])) $dsninfo['hostspec'] .= ':'.$dsninfo['port'];
  161. if($persist) $ok = $obj->PConnect($dsninfo['hostspec'], $dsninfo['username'],$dsninfo['password'],$dsninfo['database']);
  162. else $ok = $obj->Connect($dsninfo['hostspec'], $dsninfo['username'],$dsninfo['password'],$dsninfo['database']);
  163. if (!$ok) $obj = ADODB_PEAR_Error();
  164. return $obj;
  165. }
  166. /**
  167. * Return the DB API version
  168. *
  169. * @return int the DB API version number
  170. */
  171. function apiVersion()
  172. {
  173. return 2;
  174. }
  175. /**
  176. * Tell whether a result code from a DB method is an error
  177. *
  178. * @param $value int result code
  179. *
  180. * @return bool whether $value is an error
  181. */
  182. function isError($value)
  183. {
  184. if (!is_object($value)) return false;
  185. $class = strtolower(get_class($value));
  186. return $class == 'pear_error' || is_subclass_of($value, 'pear_error') ||
  187. $class == 'db_error' || is_subclass_of($value, 'db_error');
  188. }
  189. /**
  190. * Tell whether a result code from a DB method is a warning.
  191. * Warnings differ from errors in that they are generated by DB,
  192. * and are not fatal.
  193. *
  194. * @param $value mixed result value
  195. *
  196. * @return bool whether $value is a warning
  197. */
  198. function isWarning($value)
  199. {
  200. return false;
  201. /*
  202. return is_object($value) &&
  203. (get_class( $value ) == "db_warning" ||
  204. is_subclass_of($value, "db_warning"));*/
  205. }
  206. /**
  207. * Parse a data source name
  208. *
  209. * @param $dsn string Data Source Name to be parsed
  210. *
  211. * @return array an associative array with the following keys:
  212. *
  213. * phptype: Database backend used in PHP (mysql, odbc etc.)
  214. * dbsyntax: Database used with regards to SQL syntax etc.
  215. * protocol: Communication protocol to use (tcp, unix etc.)
  216. * hostspec: Host specification (hostname[:port])
  217. * database: Database to use on the DBMS server
  218. * username: User name for login
  219. * password: Password for login
  220. *
  221. * The format of the supplied DSN is in its fullest form:
  222. *
  223. * phptype(dbsyntax)://username:password@protocol+hostspec/database
  224. *
  225. * Most variations are allowed:
  226. *
  227. * phptype://username:password@protocol+hostspec:110//usr/db_file.db
  228. * phptype://username:password@hostspec/database_name
  229. * phptype://username:password@hostspec
  230. * phptype://username@hostspec
  231. * phptype://hostspec/database
  232. * phptype://hostspec
  233. * phptype(dbsyntax)
  234. * phptype
  235. *
  236. * @author Tomas V.V.Cox <cox@idecnet.com>
  237. */
  238. function parseDSN($dsn)
  239. {
  240. if (is_array($dsn)) {
  241. return $dsn;
  242. }
  243. $parsed = array(
  244. 'phptype' => false,
  245. 'dbsyntax' => false,
  246. 'protocol' => false,
  247. 'hostspec' => false,
  248. 'database' => false,
  249. 'username' => false,
  250. 'password' => false
  251. );
  252. // Find phptype and dbsyntax
  253. if (($pos = strpos($dsn, '://')) !== false) {
  254. $str = substr($dsn, 0, $pos);
  255. $dsn = substr($dsn, $pos + 3);
  256. } else {
  257. $str = $dsn;
  258. $dsn = NULL;
  259. }
  260. // Get phptype and dbsyntax
  261. // $str => phptype(dbsyntax)
  262. if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
  263. $parsed['phptype'] = $arr[1];
  264. $parsed['dbsyntax'] = (empty($arr[2])) ? $arr[1] : $arr[2];
  265. } else {
  266. $parsed['phptype'] = $str;
  267. $parsed['dbsyntax'] = $str;
  268. }
  269. if (empty($dsn)) {
  270. return $parsed;
  271. }
  272. // Get (if found): username and password
  273. // $dsn => username:password@protocol+hostspec/database
  274. if (($at = strpos($dsn,'@')) !== false) {
  275. $str = substr($dsn, 0, $at);
  276. $dsn = substr($dsn, $at + 1);
  277. if (($pos = strpos($str, ':')) !== false) {
  278. $parsed['username'] = urldecode(substr($str, 0, $pos));
  279. $parsed['password'] = urldecode(substr($str, $pos + 1));
  280. } else {
  281. $parsed['username'] = urldecode($str);
  282. }
  283. }
  284. // Find protocol and hostspec
  285. // $dsn => protocol+hostspec/database
  286. if (($pos=strpos($dsn, '/')) !== false) {
  287. $str = substr($dsn, 0, $pos);
  288. $dsn = substr($dsn, $pos + 1);
  289. } else {
  290. $str = $dsn;
  291. $dsn = NULL;
  292. }
  293. // Get protocol + hostspec
  294. // $str => protocol+hostspec
  295. if (($pos=strpos($str, '+')) !== false) {
  296. $parsed['protocol'] = substr($str, 0, $pos);
  297. $parsed['hostspec'] = urldecode(substr($str, $pos + 1));
  298. } else {
  299. $parsed['hostspec'] = urldecode($str);
  300. }
  301. // Get dabase if any
  302. // $dsn => database
  303. if (!empty($dsn)) {
  304. $parsed['database'] = $dsn;
  305. }
  306. return $parsed;
  307. }
  308. /**
  309. * Load a PHP database extension if it is not loaded already.
  310. *
  311. * @access public
  312. *
  313. * @param $name the base name of the extension (without the .so or
  314. * .dll suffix)
  315. *
  316. * @return bool true if the extension was already or successfully
  317. * loaded, false if it could not be loaded
  318. */
  319. function assertExtension($name)
  320. {
  321. if (function_exists('dl') && !extension_loaded($name)) {
  322. $dlext = (strncmp(PHP_OS,'WIN',3) === 0) ? '.dll' : '.so';
  323. @dl($name . $dlext);
  324. }
  325. if (!extension_loaded($name)) {
  326. return false;
  327. }
  328. return true;
  329. }
  330. }