123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584 |
- /*
- * Copyright (C)2005-2017 Haxe Foundation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
- package php.db;
- import php.NativeArray;
- import sys.db.Connection;
- import sys.db.ResultSet;
- import php.Lib;
- class PDO
- {
- public static function open(dsn : String, ?user : String, ?password : String, ?options : Dynamic) : Connection {
- return new PDOConnection(dsn, user, password, options);
- }
- }
- @:native("PDO")
- extern class PDOClass
- {
- public static var ATTR_CASE(get, never):Int;
- private static inline function get_ATTR_CASE() : Int return untyped __php__("PDO::ATTR_CASE");
-
- public static var CASE_LOWER(get, never):Int;
- private static inline function get_CASE_LOWER() : Int return untyped __php__("PDO::CASE_LOWER");
-
- public static var CASE_NATURAL(get, never):Int;
- private static inline function get_CASE_NATURAL() : Int return untyped __php__("PDO::CASE_NATURAL");
-
- public static var CASE_UPPER(get, never):Int;
- private static inline function get_CASE_UPPER() : Int return untyped __php__("PDO::CASE_UPPER");
-
- public static var ATTR_ERRMODE(get, never):Int;
- private static inline function get_ATTR_ERRMODE() : Int return untyped __php__("PDO::ATTR_ERRMODE");
-
- public static var ERRMODE_SILENT(get, never):Int;
- private static inline function get_ERRMODE_SILENT() : Int return untyped __php__("PDO::ERRMODE_SILENT");
-
- public static var ERRMODE_WARNING(get, never):Int;
- private static inline function get_ERRMODE_WARNING() : Int return untyped __php__("PDO::ERRMODE_WARNING");
-
- public static var ERRMODE_EXCEPTION(get, never):Int;
- private static inline function get_ERRMODE_EXCEPTION() : Int return untyped __php__("PDO::ERRMODE_EXCEPTION");
-
- public static var ATTR_ORACLE_NULLS(get, never):Int;
- private static inline function get_ATTR_ORACLE_NULLS() : Int return untyped __php__("PDO::ATTR_ORACLE_NULLS");
-
- public static var NULL_NATURAL(get, never):Int;
- private static inline function get_NULL_NATURAL() : Int return untyped __php__("PDO::NULL_NATURAL");
-
- public static var NULL_EMPTY_STRING(get, never):Int;
- private static inline function get_NULL_EMPTY_STRING() : Int return untyped __php__("PDO::NULL_EMPTY_STRING");
-
- public static var NULL_TO_STRING(get, never):Int;
- private static inline function get_NULL_TO_STRING() : Int return untyped __php__("PDO::NULL_TO_STRING");
-
- public static var ATTR_STRINGIFY_FETCHES(get, never):Int;
- private static inline function get_ATTR_STRINGIFY_FETCHES() : Int return untyped __php__("PDO::ATTR_STRINGIFY_FETCHES");
-
- public static var ATTR_STATEMENT_CLASS(get, never):Int;
- private static inline function get_ATTR_STATEMENT_CLASS() : Int return untyped __php__("PDO::ATTR_STATEMENT_CLASS");
-
- public static var ATTR_TIMEOUT(get, never):Int;
- private static inline function get_ATTR_TIMEOUT() : Int return untyped __php__("PDO::ATTR_TIMEOUT");
-
- public static var ATTR_AUTOCOMMIT(get, never):Int;
- private static inline function get_ATTR_AUTOCOMMIT() : Int return untyped __php__("PDO::ATTR_AUTOCOMMIT");
-
- public static var ATTR_EMULATE_PREPARES(get, never):Int;
- private static inline function get_ATTR_EMULATE_PREPARES() : Int return untyped __php__("PDO::ATTR_EMULATE_PREPARES");
-
- public static var ATTR_DEFAULT_FETCH_MODE(get, never):Int;
- private static inline function get_ATTR_DEFAULT_FETCH_MODE() : Int return untyped __php__("PDO::ATTR_DEFAULT_FETCH_MODE");
-
- public static var FETCH_ASSOC(get, never):Int;
- private static inline function get_FETCH_ASSOC() : Int return untyped __php__("PDO::FETCH_ASSOC");
-
- public static var FETCH_BOTH(get, never):Int;
- private static inline function get_FETCH_BOTH() : Int return untyped __php__("PDO::FETCH_BOTH");
-
- public static var FETCH_BOUND(get, never):Int;
- private static inline function get_FETCH_BOUND() : Int return untyped __php__("PDO::FETCH_BOUND");
-
- public static var FETCH_INTO(get, never):Int;
- private static inline function get_FETCH_INTO() : Int return untyped __php__("PDO::FETCH_INTO");
-
- public static var FETCH_LAZY(get, never):Int;
- private static inline function get_FETCH_LAZY() : Int return untyped __php__("PDO::FETCH_LAZY");
-
- public static var FETCH_NAMED(get, never):Int;
- private static inline function get_FETCH_NAMED() : Int return untyped __php__("PDO::FETCH_NAMED");
-
- public static var FETCH_NUM(get, never):Int;
- private static inline function get_FETCH_NUM() : Int return untyped __php__("PDO::FETCH_NUM");
-
- public static var FETCH_OBJ(get, never):Int;
- private static inline function get_FETCH_OBJ() : Int return untyped __php__("PDO::FETCH_OBJ");
-
- public static var FETCH_ORI_NEXT(get, never):Int;
- private static inline function get_FETCH_ORI_NEXT() : Int return untyped __php__("PDO::FETCH_ORI_NEXT");
-
- public static var PARAM_STR(get, never):Int;
- private static inline function get_PARAM_STR():Int return untyped __php__("PDO::PARAM_STR");
-
- public static var MYSQL_ATTR_USE_BUFFERED_QUERY(get, never):Int;
- private static inline function get_MYSQL_ATTR_USE_BUFFERED_QUERY():Int return untyped __php__("PDO::MYSQL_ATTR_USE_BUFFERED_QUERY");
-
- public static var MYSQL_ATTR_LOCAL_INFILE(get, never):Int;
- private static inline function get_MYSQL_ATTR_LOCAL_INFILE():Int return untyped __php__("PDO::MYSQL_ATTR_LOCAL_INFILE");
-
- public static var MYSQL_ATTR_INIT_COMMAND(get, never):Int;
- private static inline function get_MYSQL_ATTR_INIT_COMMAND():Int return untyped __php__("PDO::MYSQL_ATTR_INIT_COMMAND");
-
- public static var MYSQL_ATTR_READ_DEFAULT_FILE(get, never):Int;
- private static inline function get_MYSQL_ATTR_READ_DEFAULT_FILE():Int return untyped __php__("PDO::MYSQL_ATTR_READ_DEFAULT_FILE");
-
- public static var MYSQL_ATTR_READ_DEFAULT_GROUP(get, never):Int;
- private static inline function get_MYSQL_ATTR_READ_DEFAULT_GROUP():Int return untyped __php__("PDO::MYSQL_ATTR_READ_DEFAULT_GROUP");
-
- public static var MYSQL_ATTR_MAX_BUFFER_SIZE(get, never):Int;
- private static inline function get_MYSQL_ATTR_MAX_BUFFER_SIZE():Int return untyped __php__("PDO::MYSQL_ATTR_MAX_BUFFER_SIZE");
-
- public static var MYSQL_ATTR_DIRECT_QUERY(get, never):Int;
- private static inline function get_MYSQL_ATTR_DIRECT_QUERY():Int return untyped __php__("PDO::MYSQL_ATTR_DIRECT_QUERY");
-
- public static var MYSQL_ATTR_FOUND_ROWS(get, never):Int;
- private static inline function get_MYSQL_ATTR_FOUND_ROWS():Int return untyped __php__("PDO::MYSQL_ATTR_FOUND_ROWS");
-
- public static var MYSQL_ATTR_IGNORE_SPACE(get, never):Int;
- private static inline function get_MYSQL_ATTR_IGNORE_SPACE():Int return untyped __php__("PDO::MYSQL_ATTR_IGNORE_SPACE");
-
- public static var MYSQL_ATTR_COMPRESS(get, never):Int;
- private static inline function get_MYSQL_ATTR_COMPRESS():Int return untyped __php__("PDO::MYSQL_ATTR_COMPRESS");
-
- public static var MYSQL_ATTR_SSL_CA(get, never):Int;
- private static inline function get_MYSQL_ATTR_SSL_CA():Int return untyped __php__("PDO::MYSQL_ATTR_SSL_CA");
-
- public static var MYSQL_ATTR_SSL_CAPATH(get, never):Int;
- private static inline function get_MYSQL_ATTR_SSL_CAPATH():Int return untyped __php__("PDO::MYSQL_ATTR_SSL_CAPATH");
-
- public static var MYSQL_ATTR_SSL_CERT(get, never):Int;
- private static inline function get_MYSQL_ATTR_SSL_CERT():Int return untyped __php__("PDO::MYSQL_ATTR_SSL_CERT");
-
- public static var MYSQL_ATTR_SSL_CIPHER(get, never):Int;
- private static inline function get_MYSQL_ATTR_SSL_CIPHER():Int return untyped __php__("PDO::MYSQL_ATTR_SSL_CIPHER");
-
- public static var MYSQL_ATTR_SSL_KEY(get, never):Int;
- private static inline function get_MYSQL_ATTR_SSL_KEY():Int return untyped __php__("PDO::MYSQL_ATTR_SSL_KEY");
-
- public static var MYSQL_ATTR_MULTI_STATEMENTS(get, never):Int;
- private static inline function get_MYSQL_ATTR_MULTI_STATEMENTS():Int return untyped __php__("PDO::MYSQL_ATTR_MULTI_STATEMENTS");
-
- @:overload(function(dns : String):Void{})
- @:overload(function(dns : String, username : String):Void{})
- @:overload(function(dns : String, username : String, password : String):Void { } )
- public function new(dns : String, username : String, password : String, driver_options : NativeArray):Void;
-
- public function beginTransaction() : Bool;
- public function commit() : Bool;
- public function errorCode() : Dynamic;
- public function errorInfo() : NativeArray;
- public function exec(statement : String) : Int;
- public function getAttribute(attribute : Int) : Dynamic;
- public function getAvailableDrivers() : NativeArray;
- public function lastInsertId(?name : String) : String;
-
- @:overload(function(statement : String):PDOStatement { })
- public function prepare(statement : String, driver_options : NativeArray) : PDOStatement;
-
- @:overload(function(statement : String, mode : Int):PDOStatement { })
- @:overload(function(statement : String, mode : Int, colno:Int):PDOStatement { })
- @:overload(function(statement : String, mode : Int, object:Dynamic):PDOStatement { })
- @:overload(function(statement : String, mode : Int, classname:String, ctorargs:NativeArray):PDOStatement { })
- public function query(statement : String) : PDOStatement;
-
- @:overload(function(string:String):String {})
- public function quote(string : String, parameter_type : Int) : String;
- public function rollBack() : Bool;
- public function setAttribute(attribute : Int, value : Dynamic) : Bool;
- public function inTransaction():Bool;
- }
- extern class PDOStatement
- {
- public var queryString(default, null):String;
-
- @:overload(function(column : Dynamic, param : Dynamic):Bool { })
- @:overload(function(column : Dynamic, param : Dynamic, type : Int):Bool { })
- @:overload(function(column : Dynamic, param : Dynamic, type : Int, maxlen : Int):Bool { })
- public function bindColumn(column : Dynamic, param : Dynamic, type : Int, maxlen : Int, driverdata : Dynamic) : Bool;
-
- @:overload(function(parameter : Dynamic, variable : Dynamic, data_type : Int, length : Int):Bool{})
- @:overload(function(parameter : Dynamic, variable : Dynamic, data_type : Int, length : Int, driver_options : Dynamic):Bool{})
- public function bindParam(parameter : Dynamic, variable : Dynamic, ?data_type : Int = PDOClass.PARAM_STR) : Bool;
-
- @:overload(function(parameter : Dynamic, value : Dynamic) : Bool{})
- public function bindValue(parameter : Dynamic, value : Dynamic, data_type : Int) : Bool;
- public function closeCursor() : Bool;
- public function columnCount() : Int;
- public function debugDumpParams() : Bool;
- public function errorCode() : String;
- public function errorInfo() : NativeArray;
-
- @:overload(function():Bool{})
- public function execute(input_parameters : NativeArray) : Bool;
-
- @:overload(function():Dynamic{})
- @:overload(function(fetch_style : Int):Dynamic{})
- @:overload(function(fetch_style : Int, cursor_orientation : Int):Dynamic{})
- public function fetch(fetch_style : Int, cursor_orientation : Int, cursor_offset : Int) : Dynamic;
-
- @:overload(function():Dynamic{})
- @:overload(function(fetch_style : Int):Dynamic{})
- @:overload(function(fetch_style : Int, fetch_argument:Dynamic):Dynamic{})
- public function fetchAll(fetch_style : Int, fetch_argument:Dynamic, ctor_args:NativeArray) : NativeArray;
-
- @:overload(function():String{})
- public function fetchColumn(column_number : Int) : String;
-
- @:overload(function(): Dynamic{})
- @:overload(function(class_name : String): Dynamic{})
- public function fetchObject(class_name : String, ctor_args : NativeArray) : Dynamic;
-
- public function getAttribute(attribute : Int) : Dynamic;
- public function getColumnMeta(column : Int) : NativeArray;
- public function nextRowset() : Bool;
- public function rowCount() : Int;
- public function setAttribute(attribute : Int, value : Dynamic) : Bool;
-
- @:overload(function(mode : Int) : Bool{})
- @:overload(function(mode : Int, fetch : Dynamic) : Bool{})
- public function setFetchMode(mode : Int, fetch : Dynamic, ctorargs : NativeArray) : Bool;
- }
- private class PDOConnection implements Connection {
- var pdo : PDOClass;
- var dbname : String;
- public function new(dsn : String, ?user : String, ?password : String, ?options : Dynamic) {
- if(null == options)
- pdo = new PDOClass(dsn, user, password);
- else
- {
- var arr : NativeArray = untyped __call__("array");
- for (key in Reflect.fields(options))
- arr[untyped key] = Reflect.field(options, key);
- pdo = new PDOClass(dsn, user, password, arr);
- }
- dbname = dsn.split(':').shift();
- switch(dbname.toLowerCase())
- {
- case "sqlite":
- dbname = "SQLite";
- case "mysql":
- dbname = "MySQL";
- }
- }
- public function close() {
- pdo = null;
- untyped __call__("unset", pdo);
- }
- public function request( s : String ) : ResultSet {
- var result = pdo.query(s, untyped __php__("PDO::PARAM_STR"));
- if(untyped __physeq__(result, false))
- {
- var info = Lib.toHaxeArray(pdo.errorInfo());
- throw "Error while executing " + s + " (" + info[2] + ")";
- }
- var db = dbname.toLowerCase();
- switch(db)
- {
- case "sqlite":
- return new AllResultSet(result, new DBNativeStrategy(db));
- default: // mysql
- return new PDOResultSet(result, new PHPNativeStrategy());
- }
- }
- public function escape( s : String ) {
- var output = pdo.quote(s);
- return output.length > 2 ? output.substr(1, output.length-2) : output;
- }
- public function quote( s : String ) {
- if( s.indexOf("\000") >= 0 )
- return "x'"+untyped __call__('bin2hex', s)+"'";
- return pdo.quote(s);
- }
- public function addValue( s : StringBuf, v : Dynamic ) {
- if( untyped __call__("is_int", v) || __call__("is_null", v))
- s.add(v);
- else if( untyped __call__("is_bool", v) )
- s.add(if( v ) 1 else 0);
- else
- s.add(quote(Std.string(v)));
- }
- public function lastInsertId() {
- return cast(Std.parseInt(pdo.lastInsertId()), Int);
- }
- public function dbName() {
- return dbname;
- }
- public function startTransaction() {
- pdo.beginTransaction();
- }
- public function commit() {
- pdo.commit();
- }
- public function rollback() {
- pdo.rollBack();
- }
- }
- private class TypeStrategy {
- public function new() {
- }
- public function map(data : NativeArray) : Dynamic
- {
- return throw "must override";
- }
- public static function convert(v : String, type : String) : Dynamic {
- if (v == null) return v;
- switch(type) {
- case "bool":
- return untyped __call__("(bool)", v);
- case "int":
- return untyped __call__("intval", v);
- case "float":
- return untyped __call__("floatval", v);
- case "date":
- return Date.fromString(v);
- case "blob":
- return haxe.io.Bytes.ofString(v);
- default:
- return v;
- }
- }
- }
- private class PHPNativeStrategy extends TypeStrategy {
- static inline var KEY = "native_type";
- override function map(data : NativeArray) : Dynamic {
- if (!untyped __call__("isset", data[KEY])) {
- if (untyped __call__("isset", data["precision"])) {
- // if (untyped __call__("isset", data["len"]) && data["len"] == 1)
- // return "bool"
- // else
- return "int";
- } else
- return "string";
- }
- var pdo_type_str:Int = untyped __php__("PDO::PARAM_STR");
- var pdo_type : Int = untyped data["pdo_type"];
- var type : String = untyped data[KEY];
- type = type.toLowerCase();
- switch(type)
- {
- case "float", "decimal", "double", "newdecimal":
- return "float";
- case "date", "datetime", "timestamp":
- return "date";
- case "bool", "tinyint(1)":
- return "bool";
- case "int", "int24", "int32", "long", "longlong", "short", "tiny":
- return "int";
- case "blob" if (pdo_type == pdo_type_str):
- return "string";
- case "blob":
- return "blob";
- default:
- return "string";
- }
- }
- }
- private class DBNativeStrategy extends PHPNativeStrategy {
- static inline var SUFFIX = ":decl_type";
- var dbname : String;
- var key : String;
- public function new(dbname : String)
- {
- super();
- this.dbname = dbname.toLowerCase();
- this.key = dbname + SUFFIX;
- }
- override function map(data : NativeArray) : Dynamic {
- if (!untyped __call__("isset", data[key]))
- return super.map(data);
- var type : String = untyped data[key];
- type = type.toLowerCase();
- switch(type)
- {
- case "real":
- return "float";
- case "integer":
- return "int";
- default:
- return "string";
- }
- }
- }
- private class BaseResultSet implements ResultSet {
- var pdo : PDOStatement;
- var typeStrategy : TypeStrategy;
- var _fields : Int;
- var _columnNames : Array<String>;
- var _columnTypes : Array<String>;
- public var length(get, null) : Int;
- public var nfields(get, null) : Int;
- public function new(pdo : PDOStatement, typeStrategy : TypeStrategy)
- {
- this.pdo = pdo;
- this.typeStrategy = typeStrategy;
- this._fields = pdo.columnCount();
- this._columnNames = [];
- this._columnTypes = [];
- feedColumns();
- }
- private function feedColumns() {
- for (i in 0..._fields) {
- var data = pdo.getColumnMeta(i);
- _columnNames.push(data[untyped 'name']);
- _columnTypes.push(typeStrategy.map(data));
- }
- }
- public function getFloatResult(index : Int) : Float {
- return untyped __call__("floatval", getResult(index));
- }
- public function getIntResult(index : Int) : Int {
- return untyped __call__("intval", getResult(index));
- }
- public function getResult(index : Int) : String {
- return throw "must override";
- }
- public function hasNext() : Bool {
- return throw "must override";
- }
- function get_length() : Int {
- return throw "must override";
- }
- function nextRow() : NativeArray {
- return throw "must override";
- }
- public function next() : Dynamic {
- var row = nextRow();
- var o : Dynamic = { };
- for (i in 0..._fields)
- Reflect.setField(o, _columnNames[i], TypeStrategy.convert(row[i], _columnTypes[i]));
- return o;
- }
- function get_nfields() : Int {
- return _fields;
- }
- public function results() : List<Dynamic>
- {
- var list = new List();
- while (hasNext())
- list.add(next());
- return list;
- }
- public function getFieldsNames() : Array<String> {
- return throw "Not implemented";
- }
- }
- private class AllResultSet extends BaseResultSet {
- var all : NativeArray;
- var pos : Int;
- var _length : Int;
- public function new(pdo : PDOStatement, typeStrategy : TypeStrategy)
- {
- super(pdo, typeStrategy);
- this.all = pdo.fetchAll(untyped __php__("PDO::FETCH_NUM"));
- this.pos = 0;
- this._length = untyped __call__("count", all);
- }
- override function getResult(index : Int) : String {
- untyped if(__call__("isset", all[0]) && __call__("isset", all[0][index]))
- return all[0][index];
- else
- return null;
- }
- override function hasNext() : Bool {
- return pos < _length;
- }
- override function get_length() : Int {
- return _length;
- }
- override function nextRow() : NativeArray {
- return all[pos++];
- }
- }
- private class PDOResultSet extends BaseResultSet {
- private var cache : NativeArray;
- public function new(pdo : PDOStatement, typeStrategy : TypeStrategy)
- {
- super(pdo, typeStrategy);
- }
- override function getResult(index : Int) : String {
- if (!hasNext())
- return null;
- return cache[index];
- }
- override function hasNext() {
- if(untyped __physeq__(null, cache))
- cacheRow();
- return (untyped cache);
- }
- override function get_length() {
- if (untyped __physeq__(pdo, false))
- return 0;
- return pdo.rowCount();
- }
- private function cacheRow() {
- cache = untyped pdo.fetch(__php__("PDO::FETCH_NUM"), __php__("PDO::FETCH_ORI_NEXT"));
- }
- override function nextRow()
- {
- if (!hasNext())
- return null;
- else {
- var v = cache;
- cache = null;
- return v;
- }
- }
- }
|