PDO.hx 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. /*
  2. * Copyright (C)2005-2017 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. */
  22. package php.db;
  23. import php.NativeArray;
  24. import sys.db.Connection;
  25. import sys.db.ResultSet;
  26. import php.Lib;
  27. class PDO
  28. {
  29. public static function open(dsn : String, ?user : String, ?password : String, ?options : Dynamic) : Connection {
  30. return new PDOConnection(dsn, user, password, options);
  31. }
  32. }
  33. @:native("PDO")
  34. extern class PDOClass
  35. {
  36. public static var ATTR_CASE(get, never):Int;
  37. private static inline function get_ATTR_CASE() : Int return untyped __php__("PDO::ATTR_CASE");
  38. public static var CASE_LOWER(get, never):Int;
  39. private static inline function get_CASE_LOWER() : Int return untyped __php__("PDO::CASE_LOWER");
  40. public static var CASE_NATURAL(get, never):Int;
  41. private static inline function get_CASE_NATURAL() : Int return untyped __php__("PDO::CASE_NATURAL");
  42. public static var CASE_UPPER(get, never):Int;
  43. private static inline function get_CASE_UPPER() : Int return untyped __php__("PDO::CASE_UPPER");
  44. public static var ATTR_ERRMODE(get, never):Int;
  45. private static inline function get_ATTR_ERRMODE() : Int return untyped __php__("PDO::ATTR_ERRMODE");
  46. public static var ERRMODE_SILENT(get, never):Int;
  47. private static inline function get_ERRMODE_SILENT() : Int return untyped __php__("PDO::ERRMODE_SILENT");
  48. public static var ERRMODE_WARNING(get, never):Int;
  49. private static inline function get_ERRMODE_WARNING() : Int return untyped __php__("PDO::ERRMODE_WARNING");
  50. public static var ERRMODE_EXCEPTION(get, never):Int;
  51. private static inline function get_ERRMODE_EXCEPTION() : Int return untyped __php__("PDO::ERRMODE_EXCEPTION");
  52. public static var ATTR_ORACLE_NULLS(get, never):Int;
  53. private static inline function get_ATTR_ORACLE_NULLS() : Int return untyped __php__("PDO::ATTR_ORACLE_NULLS");
  54. public static var NULL_NATURAL(get, never):Int;
  55. private static inline function get_NULL_NATURAL() : Int return untyped __php__("PDO::NULL_NATURAL");
  56. public static var NULL_EMPTY_STRING(get, never):Int;
  57. private static inline function get_NULL_EMPTY_STRING() : Int return untyped __php__("PDO::NULL_EMPTY_STRING");
  58. public static var NULL_TO_STRING(get, never):Int;
  59. private static inline function get_NULL_TO_STRING() : Int return untyped __php__("PDO::NULL_TO_STRING");
  60. public static var ATTR_STRINGIFY_FETCHES(get, never):Int;
  61. private static inline function get_ATTR_STRINGIFY_FETCHES() : Int return untyped __php__("PDO::ATTR_STRINGIFY_FETCHES");
  62. public static var ATTR_STATEMENT_CLASS(get, never):Int;
  63. private static inline function get_ATTR_STATEMENT_CLASS() : Int return untyped __php__("PDO::ATTR_STATEMENT_CLASS");
  64. public static var ATTR_TIMEOUT(get, never):Int;
  65. private static inline function get_ATTR_TIMEOUT() : Int return untyped __php__("PDO::ATTR_TIMEOUT");
  66. public static var ATTR_AUTOCOMMIT(get, never):Int;
  67. private static inline function get_ATTR_AUTOCOMMIT() : Int return untyped __php__("PDO::ATTR_AUTOCOMMIT");
  68. public static var ATTR_EMULATE_PREPARES(get, never):Int;
  69. private static inline function get_ATTR_EMULATE_PREPARES() : Int return untyped __php__("PDO::ATTR_EMULATE_PREPARES");
  70. public static var ATTR_DEFAULT_FETCH_MODE(get, never):Int;
  71. private static inline function get_ATTR_DEFAULT_FETCH_MODE() : Int return untyped __php__("PDO::ATTR_DEFAULT_FETCH_MODE");
  72. public static var FETCH_ASSOC(get, never):Int;
  73. private static inline function get_FETCH_ASSOC() : Int return untyped __php__("PDO::FETCH_ASSOC");
  74. public static var FETCH_BOTH(get, never):Int;
  75. private static inline function get_FETCH_BOTH() : Int return untyped __php__("PDO::FETCH_BOTH");
  76. public static var FETCH_BOUND(get, never):Int;
  77. private static inline function get_FETCH_BOUND() : Int return untyped __php__("PDO::FETCH_BOUND");
  78. public static var FETCH_INTO(get, never):Int;
  79. private static inline function get_FETCH_INTO() : Int return untyped __php__("PDO::FETCH_INTO");
  80. public static var FETCH_LAZY(get, never):Int;
  81. private static inline function get_FETCH_LAZY() : Int return untyped __php__("PDO::FETCH_LAZY");
  82. public static var FETCH_NAMED(get, never):Int;
  83. private static inline function get_FETCH_NAMED() : Int return untyped __php__("PDO::FETCH_NAMED");
  84. public static var FETCH_NUM(get, never):Int;
  85. private static inline function get_FETCH_NUM() : Int return untyped __php__("PDO::FETCH_NUM");
  86. public static var FETCH_OBJ(get, never):Int;
  87. private static inline function get_FETCH_OBJ() : Int return untyped __php__("PDO::FETCH_OBJ");
  88. public static var FETCH_ORI_NEXT(get, never):Int;
  89. private static inline function get_FETCH_ORI_NEXT() : Int return untyped __php__("PDO::FETCH_ORI_NEXT");
  90. public static var PARAM_STR(get, never):Int;
  91. private static inline function get_PARAM_STR():Int return untyped __php__("PDO::PARAM_STR");
  92. public static var MYSQL_ATTR_USE_BUFFERED_QUERY(get, never):Int;
  93. private static inline function get_MYSQL_ATTR_USE_BUFFERED_QUERY():Int return untyped __php__("PDO::MYSQL_ATTR_USE_BUFFERED_QUERY");
  94. public static var MYSQL_ATTR_LOCAL_INFILE(get, never):Int;
  95. private static inline function get_MYSQL_ATTR_LOCAL_INFILE():Int return untyped __php__("PDO::MYSQL_ATTR_LOCAL_INFILE");
  96. public static var MYSQL_ATTR_INIT_COMMAND(get, never):Int;
  97. private static inline function get_MYSQL_ATTR_INIT_COMMAND():Int return untyped __php__("PDO::MYSQL_ATTR_INIT_COMMAND");
  98. public static var MYSQL_ATTR_READ_DEFAULT_FILE(get, never):Int;
  99. private static inline function get_MYSQL_ATTR_READ_DEFAULT_FILE():Int return untyped __php__("PDO::MYSQL_ATTR_READ_DEFAULT_FILE");
  100. public static var MYSQL_ATTR_READ_DEFAULT_GROUP(get, never):Int;
  101. private static inline function get_MYSQL_ATTR_READ_DEFAULT_GROUP():Int return untyped __php__("PDO::MYSQL_ATTR_READ_DEFAULT_GROUP");
  102. public static var MYSQL_ATTR_MAX_BUFFER_SIZE(get, never):Int;
  103. private static inline function get_MYSQL_ATTR_MAX_BUFFER_SIZE():Int return untyped __php__("PDO::MYSQL_ATTR_MAX_BUFFER_SIZE");
  104. public static var MYSQL_ATTR_DIRECT_QUERY(get, never):Int;
  105. private static inline function get_MYSQL_ATTR_DIRECT_QUERY():Int return untyped __php__("PDO::MYSQL_ATTR_DIRECT_QUERY");
  106. public static var MYSQL_ATTR_FOUND_ROWS(get, never):Int;
  107. private static inline function get_MYSQL_ATTR_FOUND_ROWS():Int return untyped __php__("PDO::MYSQL_ATTR_FOUND_ROWS");
  108. public static var MYSQL_ATTR_IGNORE_SPACE(get, never):Int;
  109. private static inline function get_MYSQL_ATTR_IGNORE_SPACE():Int return untyped __php__("PDO::MYSQL_ATTR_IGNORE_SPACE");
  110. public static var MYSQL_ATTR_COMPRESS(get, never):Int;
  111. private static inline function get_MYSQL_ATTR_COMPRESS():Int return untyped __php__("PDO::MYSQL_ATTR_COMPRESS");
  112. public static var MYSQL_ATTR_SSL_CA(get, never):Int;
  113. private static inline function get_MYSQL_ATTR_SSL_CA():Int return untyped __php__("PDO::MYSQL_ATTR_SSL_CA");
  114. public static var MYSQL_ATTR_SSL_CAPATH(get, never):Int;
  115. private static inline function get_MYSQL_ATTR_SSL_CAPATH():Int return untyped __php__("PDO::MYSQL_ATTR_SSL_CAPATH");
  116. public static var MYSQL_ATTR_SSL_CERT(get, never):Int;
  117. private static inline function get_MYSQL_ATTR_SSL_CERT():Int return untyped __php__("PDO::MYSQL_ATTR_SSL_CERT");
  118. public static var MYSQL_ATTR_SSL_CIPHER(get, never):Int;
  119. private static inline function get_MYSQL_ATTR_SSL_CIPHER():Int return untyped __php__("PDO::MYSQL_ATTR_SSL_CIPHER");
  120. public static var MYSQL_ATTR_SSL_KEY(get, never):Int;
  121. private static inline function get_MYSQL_ATTR_SSL_KEY():Int return untyped __php__("PDO::MYSQL_ATTR_SSL_KEY");
  122. public static var MYSQL_ATTR_MULTI_STATEMENTS(get, never):Int;
  123. private static inline function get_MYSQL_ATTR_MULTI_STATEMENTS():Int return untyped __php__("PDO::MYSQL_ATTR_MULTI_STATEMENTS");
  124. @:overload(function(dns : String):Void{})
  125. @:overload(function(dns : String, username : String):Void{})
  126. @:overload(function(dns : String, username : String, password : String):Void { } )
  127. public function new(dns : String, username : String, password : String, driver_options : NativeArray):Void;
  128. public function beginTransaction() : Bool;
  129. public function commit() : Bool;
  130. public function errorCode() : Dynamic;
  131. public function errorInfo() : NativeArray;
  132. public function exec(statement : String) : Int;
  133. public function getAttribute(attribute : Int) : Dynamic;
  134. public function getAvailableDrivers() : NativeArray;
  135. public function lastInsertId(?name : String) : String;
  136. @:overload(function(statement : String):PDOStatement { })
  137. public function prepare(statement : String, driver_options : NativeArray) : PDOStatement;
  138. @:overload(function(statement : String, mode : Int):PDOStatement { })
  139. @:overload(function(statement : String, mode : Int, colno:Int):PDOStatement { })
  140. @:overload(function(statement : String, mode : Int, object:Dynamic):PDOStatement { })
  141. @:overload(function(statement : String, mode : Int, classname:String, ctorargs:NativeArray):PDOStatement { })
  142. public function query(statement : String) : PDOStatement;
  143. @:overload(function(string:String):String {})
  144. public function quote(string : String, parameter_type : Int) : String;
  145. public function rollBack() : Bool;
  146. public function setAttribute(attribute : Int, value : Dynamic) : Bool;
  147. public function inTransaction():Bool;
  148. }
  149. extern class PDOStatement
  150. {
  151. public var queryString(default, null):String;
  152. @:overload(function(column : Dynamic, param : Dynamic):Bool { })
  153. @:overload(function(column : Dynamic, param : Dynamic, type : Int):Bool { })
  154. @:overload(function(column : Dynamic, param : Dynamic, type : Int, maxlen : Int):Bool { })
  155. public function bindColumn(column : Dynamic, param : Dynamic, type : Int, maxlen : Int, driverdata : Dynamic) : Bool;
  156. @:overload(function(parameter : Dynamic, variable : Dynamic, data_type : Int, length : Int):Bool{})
  157. @:overload(function(parameter : Dynamic, variable : Dynamic, data_type : Int, length : Int, driver_options : Dynamic):Bool{})
  158. public function bindParam(parameter : Dynamic, variable : Dynamic, ?data_type : Int = PDOClass.PARAM_STR) : Bool;
  159. @:overload(function(parameter : Dynamic, value : Dynamic) : Bool{})
  160. public function bindValue(parameter : Dynamic, value : Dynamic, data_type : Int) : Bool;
  161. public function closeCursor() : Bool;
  162. public function columnCount() : Int;
  163. public function debugDumpParams() : Bool;
  164. public function errorCode() : String;
  165. public function errorInfo() : NativeArray;
  166. @:overload(function():Bool{})
  167. public function execute(input_parameters : NativeArray) : Bool;
  168. @:overload(function():Dynamic{})
  169. @:overload(function(fetch_style : Int):Dynamic{})
  170. @:overload(function(fetch_style : Int, cursor_orientation : Int):Dynamic{})
  171. public function fetch(fetch_style : Int, cursor_orientation : Int, cursor_offset : Int) : Dynamic;
  172. @:overload(function():Dynamic{})
  173. @:overload(function(fetch_style : Int):Dynamic{})
  174. @:overload(function(fetch_style : Int, fetch_argument:Dynamic):Dynamic{})
  175. public function fetchAll(fetch_style : Int, fetch_argument:Dynamic, ctor_args:NativeArray) : NativeArray;
  176. @:overload(function():String{})
  177. public function fetchColumn(column_number : Int) : String;
  178. @:overload(function(): Dynamic{})
  179. @:overload(function(class_name : String): Dynamic{})
  180. public function fetchObject(class_name : String, ctor_args : NativeArray) : Dynamic;
  181. public function getAttribute(attribute : Int) : Dynamic;
  182. public function getColumnMeta(column : Int) : NativeArray;
  183. public function nextRowset() : Bool;
  184. public function rowCount() : Int;
  185. public function setAttribute(attribute : Int, value : Dynamic) : Bool;
  186. @:overload(function(mode : Int) : Bool{})
  187. @:overload(function(mode : Int, fetch : Dynamic) : Bool{})
  188. public function setFetchMode(mode : Int, fetch : Dynamic, ctorargs : NativeArray) : Bool;
  189. }
  190. private class PDOConnection implements Connection {
  191. var pdo : PDOClass;
  192. var dbname : String;
  193. public function new(dsn : String, ?user : String, ?password : String, ?options : Dynamic) {
  194. if(null == options)
  195. pdo = new PDOClass(dsn, user, password);
  196. else
  197. {
  198. var arr : NativeArray = untyped __call__("array");
  199. for (key in Reflect.fields(options))
  200. arr[untyped key] = Reflect.field(options, key);
  201. pdo = new PDOClass(dsn, user, password, arr);
  202. }
  203. dbname = dsn.split(':').shift();
  204. switch(dbname.toLowerCase())
  205. {
  206. case "sqlite":
  207. dbname = "SQLite";
  208. case "mysql":
  209. dbname = "MySQL";
  210. }
  211. }
  212. public function close() {
  213. pdo = null;
  214. untyped __call__("unset", pdo);
  215. }
  216. public function request( s : String ) : ResultSet {
  217. var result = pdo.query(s, untyped __php__("PDO::PARAM_STR"));
  218. if(untyped __physeq__(result, false))
  219. {
  220. var info = Lib.toHaxeArray(pdo.errorInfo());
  221. throw "Error while executing " + s + " (" + info[2] + ")";
  222. }
  223. var db = dbname.toLowerCase();
  224. switch(db)
  225. {
  226. case "sqlite":
  227. return new AllResultSet(result, new DBNativeStrategy(db));
  228. default: // mysql
  229. return new PDOResultSet(result, new PHPNativeStrategy());
  230. }
  231. }
  232. public function escape( s : String ) {
  233. var output = pdo.quote(s);
  234. return output.length > 2 ? output.substr(1, output.length-2) : output;
  235. }
  236. public function quote( s : String ) {
  237. if( s.indexOf("\000") >= 0 )
  238. return "x'"+untyped __call__('bin2hex', s)+"'";
  239. return pdo.quote(s);
  240. }
  241. public function addValue( s : StringBuf, v : Dynamic ) {
  242. if( untyped __call__("is_int", v) || __call__("is_null", v))
  243. s.add(v);
  244. else if( untyped __call__("is_bool", v) )
  245. s.add(if( v ) 1 else 0);
  246. else
  247. s.add(quote(Std.string(v)));
  248. }
  249. public function lastInsertId() {
  250. return cast(Std.parseInt(pdo.lastInsertId()), Int);
  251. }
  252. public function dbName() {
  253. return dbname;
  254. }
  255. public function startTransaction() {
  256. pdo.beginTransaction();
  257. }
  258. public function commit() {
  259. pdo.commit();
  260. }
  261. public function rollback() {
  262. pdo.rollBack();
  263. }
  264. }
  265. private class TypeStrategy {
  266. public function new() {
  267. }
  268. public function map(data : NativeArray) : Dynamic
  269. {
  270. return throw "must override";
  271. }
  272. public static function convert(v : String, type : String) : Dynamic {
  273. if (v == null) return v;
  274. switch(type) {
  275. case "bool":
  276. return untyped __call__("(bool)", v);
  277. case "int":
  278. return untyped __call__("intval", v);
  279. case "float":
  280. return untyped __call__("floatval", v);
  281. case "date":
  282. return Date.fromString(v);
  283. case "blob":
  284. return haxe.io.Bytes.ofString(v);
  285. default:
  286. return v;
  287. }
  288. }
  289. }
  290. private class PHPNativeStrategy extends TypeStrategy {
  291. static inline var KEY = "native_type";
  292. override function map(data : NativeArray) : Dynamic {
  293. if (!untyped __call__("isset", data[KEY])) {
  294. if (untyped __call__("isset", data["precision"])) {
  295. // if (untyped __call__("isset", data["len"]) && data["len"] == 1)
  296. // return "bool"
  297. // else
  298. return "int";
  299. } else
  300. return "string";
  301. }
  302. var pdo_type_str:Int = untyped __php__("PDO::PARAM_STR");
  303. var pdo_type : Int = untyped data["pdo_type"];
  304. var type : String = untyped data[KEY];
  305. type = type.toLowerCase();
  306. switch(type)
  307. {
  308. case "float", "decimal", "double", "newdecimal":
  309. return "float";
  310. case "date", "datetime", "timestamp":
  311. return "date";
  312. case "bool", "tinyint(1)":
  313. return "bool";
  314. case "int", "int24", "int32", "long", "longlong", "short", "tiny":
  315. return "int";
  316. case "blob" if (pdo_type == pdo_type_str):
  317. return "string";
  318. case "blob":
  319. return "blob";
  320. default:
  321. return "string";
  322. }
  323. }
  324. }
  325. private class DBNativeStrategy extends PHPNativeStrategy {
  326. static inline var SUFFIX = ":decl_type";
  327. var dbname : String;
  328. var key : String;
  329. public function new(dbname : String)
  330. {
  331. super();
  332. this.dbname = dbname.toLowerCase();
  333. this.key = dbname + SUFFIX;
  334. }
  335. override function map(data : NativeArray) : Dynamic {
  336. if (!untyped __call__("isset", data[key]))
  337. return super.map(data);
  338. var type : String = untyped data[key];
  339. type = type.toLowerCase();
  340. switch(type)
  341. {
  342. case "real":
  343. return "float";
  344. case "integer":
  345. return "int";
  346. default:
  347. return "string";
  348. }
  349. }
  350. }
  351. private class BaseResultSet implements ResultSet {
  352. var pdo : PDOStatement;
  353. var typeStrategy : TypeStrategy;
  354. var _fields : Int;
  355. var _columnNames : Array<String>;
  356. var _columnTypes : Array<String>;
  357. public var length(get, null) : Int;
  358. public var nfields(get, null) : Int;
  359. public function new(pdo : PDOStatement, typeStrategy : TypeStrategy)
  360. {
  361. this.pdo = pdo;
  362. this.typeStrategy = typeStrategy;
  363. this._fields = pdo.columnCount();
  364. this._columnNames = [];
  365. this._columnTypes = [];
  366. feedColumns();
  367. }
  368. private function feedColumns() {
  369. for (i in 0..._fields) {
  370. var data = pdo.getColumnMeta(i);
  371. _columnNames.push(data[untyped 'name']);
  372. _columnTypes.push(typeStrategy.map(data));
  373. }
  374. }
  375. public function getFloatResult(index : Int) : Float {
  376. return untyped __call__("floatval", getResult(index));
  377. }
  378. public function getIntResult(index : Int) : Int {
  379. return untyped __call__("intval", getResult(index));
  380. }
  381. public function getResult(index : Int) : String {
  382. return throw "must override";
  383. }
  384. public function hasNext() : Bool {
  385. return throw "must override";
  386. }
  387. function get_length() : Int {
  388. return throw "must override";
  389. }
  390. function nextRow() : NativeArray {
  391. return throw "must override";
  392. }
  393. public function next() : Dynamic {
  394. var row = nextRow();
  395. var o : Dynamic = { };
  396. for (i in 0..._fields)
  397. Reflect.setField(o, _columnNames[i], TypeStrategy.convert(row[i], _columnTypes[i]));
  398. return o;
  399. }
  400. function get_nfields() : Int {
  401. return _fields;
  402. }
  403. public function results() : List<Dynamic>
  404. {
  405. var list = new List();
  406. while (hasNext())
  407. list.add(next());
  408. return list;
  409. }
  410. public function getFieldsNames() : Array<String> {
  411. return throw "Not implemented";
  412. }
  413. }
  414. private class AllResultSet extends BaseResultSet {
  415. var all : NativeArray;
  416. var pos : Int;
  417. var _length : Int;
  418. public function new(pdo : PDOStatement, typeStrategy : TypeStrategy)
  419. {
  420. super(pdo, typeStrategy);
  421. this.all = pdo.fetchAll(untyped __php__("PDO::FETCH_NUM"));
  422. this.pos = 0;
  423. this._length = untyped __call__("count", all);
  424. }
  425. override function getResult(index : Int) : String {
  426. untyped if(__call__("isset", all[0]) && __call__("isset", all[0][index]))
  427. return all[0][index];
  428. else
  429. return null;
  430. }
  431. override function hasNext() : Bool {
  432. return pos < _length;
  433. }
  434. override function get_length() : Int {
  435. return _length;
  436. }
  437. override function nextRow() : NativeArray {
  438. return all[pos++];
  439. }
  440. }
  441. private class PDOResultSet extends BaseResultSet {
  442. private var cache : NativeArray;
  443. public function new(pdo : PDOStatement, typeStrategy : TypeStrategy)
  444. {
  445. super(pdo, typeStrategy);
  446. }
  447. override function getResult(index : Int) : String {
  448. if (!hasNext())
  449. return null;
  450. return cache[index];
  451. }
  452. override function hasNext() {
  453. if(untyped __physeq__(null, cache))
  454. cacheRow();
  455. return (untyped cache);
  456. }
  457. override function get_length() {
  458. if (untyped __physeq__(pdo, false))
  459. return 0;
  460. return pdo.rowCount();
  461. }
  462. private function cacheRow() {
  463. cache = untyped pdo.fetch(__php__("PDO::FETCH_NUM"), __php__("PDO::FETCH_ORI_NEXT"));
  464. }
  465. override function nextRow()
  466. {
  467. if (!hasNext())
  468. return null;
  469. else {
  470. var v = cache;
  471. cache = null;
  472. return v;
  473. }
  474. }
  475. }