summaryrefslogtreecommitdiffstats
path: root/codebase/Dhtmlx/Connector/DataStorage
diff options
context:
space:
mode:
authorEgor <egor.26.93@gmail.com>2015-06-12 16:06:06 +0300
committerEgor <egor.26.93@gmail.com>2015-06-12 16:06:06 +0300
commit9abd184a386a2594398df9f5cd7bd6d5b9c240fc (patch)
tree6b237196dd4ae8bdee61093308f5c3dcdcc5c79e /codebase/Dhtmlx/Connector/DataStorage
parent5fbd0adda5155853e86001fad4c571008f09f01b (diff)
downloadconnector-php-9abd184a386a2594398df9f5cd7bd6d5b9c240fc.zip
connector-php-9abd184a386a2594398df9f5cd7bd6d5b9c240fc.tar.gz
connector-php-9abd184a386a2594398df9f5cd7bd6d5b9c240fc.tar.bz2
Updated structure. Added connectors.
Diffstat (limited to 'codebase/Dhtmlx/Connector/DataStorage')
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/AdoDBDataWrapper.php69
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/ArrayDBDataWrapper.php5
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/ArrayQueryWrapper.php2
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/DBDataWrapper.php13
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/DataConfig.php227
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/DataRequestConfig.php284
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/DataWrapper.php5
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/ExcelDBDataWrapper.php105
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/FileSystemDBDataWrapper.php140
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/MsSQLDBDataWrapper.php5
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/MySQLDBDataWrapper.php5
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/OracleDBDataWrapper.php86
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/PDODBDataWrapper.php8
-rwxr-xr-xcodebase/Dhtmlx/Connector/DataStorage/PHPCI2DBDataWrapper.php1
-rwxr-xr-xcodebase/Dhtmlx/Connector/DataStorage/PHPCIDBDataWrapper.php1
-rwxr-xr-xcodebase/Dhtmlx/Connector/DataStorage/PHPCakeDBDataWrapper.php1
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/PHPYii1DBDataWrapper.php1
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/PHPYiiDBDataWrapper.php1
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/PostgreDBDataWrapper.php5
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/ResultHandler/ExcelResultHandler.php75
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/ResultHandler/FileSystemResultHandler.php76
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/ResultHandler/PDOResultHandler.php (renamed from codebase/Dhtmlx/Connector/DataStorage/PDOResultSet.php)5
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/SQLSrvDBDataWrapper.php95
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/SQLite3DBDataWrapper.php30
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/SQLiteDBDataWrapper.php69
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/SaSQLDBDataWrapper.php86
-rw-r--r--codebase/Dhtmlx/Connector/DataStorage/TypeHandler/FileSystemTypeHandler.php119
27 files changed, 978 insertions, 541 deletions
diff --git a/codebase/Dhtmlx/Connector/DataStorage/AdoDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/AdoDBDataWrapper.php
new file mode 100644
index 0000000..b1e1e3b
--- /dev/null
+++ b/codebase/Dhtmlx/Connector/DataStorage/AdoDBDataWrapper.php
@@ -0,0 +1,69 @@
+<?php
+namespace Dhtmlx\Connector\DataStorage;
+use Dhtmlx\Connector\Tools\LogMaster;
+use \Exception;
+
+/*! Implementation of DataWrapper for ADO
+**/
+class AdoDBDataWrapper extends DBDataWrapper {
+ protected $last_result;
+ public function query($sql){
+ LogMaster::log($sql);
+ if (is_array($sql)) {
+ $res = $this->connection->SelectLimit($sql['sql'], $sql['numrows'], $sql['offset']);
+ } else {
+ $res = $this->connection->Execute($sql);
+ }
+
+ if ($res===false) throw new Exception("ADODB operation failed\n".$this->connection->ErrorMsg());
+ $this->last_result = $res;
+ return $res;
+ }
+
+ public function get_next($res){
+ if (!$res)
+ $res = $this->last_result;
+
+ if ($res->EOF)
+ return false;
+
+ $row = $res->GetRowAssoc(false);
+ $res->MoveNext();
+ return $row;
+ }
+
+ public function get_new_id(){
+ return $this->connection->Insert_ID();
+ }
+
+ public function escape($data){
+ return $this->connection->addq($data);
+ }
+
+ /*! escape field name to prevent sql reserved words conflict
+ @param data
+ unescaped data
+ @return
+ escaped data
+ */
+ public function escape_name($data){
+ if ((strpos($data,"`")!==false || is_int($data)) || (strpos($data,".")!==false))
+ return $data;
+ return '`'.$data.'`';
+ }
+
+
+ protected function select_query($select,$from,$where,$sort,$start,$count){
+ if (!$from)
+ return $select;
+
+ $sql="SELECT ".$select." FROM ".$from;
+ if ($where) $sql.=" WHERE ".$where;
+ if ($sort) $sql.=" ORDER BY ".$sort;
+
+ if ($start || $count) {
+ $sql=array("sql"=>$sql,'numrows'=>$count, 'offset'=>$start);
+ }
+ return $sql;
+ }
+} \ No newline at end of file
diff --git a/codebase/Dhtmlx/Connector/DataStorage/ArrayDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/ArrayDBDataWrapper.php
index e5bbae9..b72aec6 100644
--- a/codebase/Dhtmlx/Connector/DataStorage/ArrayDBDataWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/ArrayDBDataWrapper.php
@@ -1,9 +1,8 @@
<?php
-
namespace Dhtmlx\Connector\DataStorage;
+use \Exception;
-class ArrayDBDataWrapper extends DBDataWrapper
-{
+class ArrayDBDataWrapper extends DBDataWrapper {
public function get_next($res)
{
if ($res->index < sizeof($res->data))
diff --git a/codebase/Dhtmlx/Connector/DataStorage/ArrayQueryWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/ArrayQueryWrapper.php
index 5fa079a..f2ba5b5 100644
--- a/codebase/Dhtmlx/Connector/DataStorage/ArrayQueryWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/ArrayQueryWrapper.php
@@ -1,7 +1,7 @@
<?php
namespace Dhtmlx\Connector\DataStorage;
-class ArrayQueryWrapper{
+class ArrayQueryWrapper {
public function __construct($data){
$this->data = $data;
$this->index = 0;
diff --git a/codebase/Dhtmlx/Connector/DataStorage/DBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/DBDataWrapper.php
index bc93fee..6975c5f 100644
--- a/codebase/Dhtmlx/Connector/DataStorage/DBDataWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/DBDataWrapper.php
@@ -1,15 +1,10 @@
<?php
-/**
- * Created by PhpStorm.
- * User: user
- * Date: 26.3.15
- * Time: 15.50
- */
-
namespace Dhtmlx\Connector\DataStorage;
+use Dhtmlx\Connector\Data\DataRequestConfig;
+use Dhtmlx\Connector\Event\SortInterface;
+use \Exception;
-abstract class DBDataWrapper extends DataWrapper
-{
+abstract class DBDataWrapper extends DataWrapper {
private $transaction = false; //!< type of transaction
private $sequence = false;//!< sequence name
private $sqls = array();//!< predefined sql actions
diff --git a/codebase/Dhtmlx/Connector/DataStorage/DataConfig.php b/codebase/Dhtmlx/Connector/DataStorage/DataConfig.php
deleted file mode 100644
index 99af751..0000000
--- a/codebase/Dhtmlx/Connector/DataStorage/DataConfig.php
+++ /dev/null
@@ -1,227 +0,0 @@
-<?php
-
-namespace Dhtmlx\Connector\DataStorage;
-/*! manager of data configuration
-**/
-class DataConfig{
- public $id;////!< name of ID field
- public $relation_id;//!< name or relation ID field
- public $text;//!< array of text fields
- public $data;//!< array of all known fields , fields which exists only in this collection will not be included in dataprocessor's operations
-
-
- /*! converts self to the string, for logging purposes
- **/
- public function __toString(){
- $str="ID:{$this->id['db_name']}(ID:{$this->id['name']})\n";
- $str.="Relation ID:{$this->relation_id['db_name']}({$this->relation_id['name']})\n";
- $str.="Data:";
- for ($i=0; $i<sizeof($this->text); $i++)
- $str.="{$this->text[$i]['db_name']}({$this->text[$i]['name']}),";
-
- $str.="\nExtra:";
- for ($i=0; $i<sizeof($this->data); $i++)
- $str.="{$this->data[$i]['db_name']}({$this->data[$i]['name']}),";
-
- return $str;
- }
-
- /*! removes un-used fields from configuration
- @param name
- name of field , which need to be preserved
- */
- public function minimize($name){
- for ($i=0; $i < sizeof($this->text); $i++){
- if ($this->text[$i]["db_name"]==$name || $this->text[$i]["name"]==$name){
- $this->text[$i]["name"]="value";
- $this->data=array($this->text[$i]);
- $this->text=array($this->text[$i]);
- return;
- }
- }
- throw new Exception("Incorrect dataset minimization, master field not found.");
- }
-
- public function limit_fields($data){
- if (isset($this->full_field_list))
- $this->restore_fields();
- $this->full_field_list = $this->text;
- $this->text = array();
-
- for ($i=0; $i < sizeof($this->full_field_list); $i++) {
- if (array_key_exists($this->full_field_list[$i]["name"],$data))
- $this->text[] = $this->full_field_list[$i];
- }
- }
-
- public function restore_fields(){
- if (isset($this->full_field_list))
- $this->text = $this->full_field_list;
- }
-
- /*! initialize inner state by parsing configuration parameters
-
- @param id
- name of id field
- @param fields
- name of data field(s)
- @param extra
- name of extra field(s)
- @param relation
- name of relation field
-
- */
- public function init($id,$fields,$extra,$relation){
- $this->id = $this->parse($id,false);
- $this->text = $this->parse($fields,true);
- $this->data = array_merge($this->text,$this->parse($extra,true));
- $this->relation_id = $this->parse($relation,false);
- }
-
- /*! parse configuration string
-
- @param key
- key string from configuration
- @param mode
- multi names flag
- @return
- parsed field name object
- */
- private function parse($key,$mode){
- if ($mode){
- if (!$key) return array();
- $key=explode(",",$key);
- for ($i=0; $i < sizeof($key); $i++)
- $key[$i]=$this->parse($key[$i],false);
- return $key;
- }
- $key=explode("(",$key);
- $data=array("db_name"=>trim($key[0]), "name"=>trim($key[0]));
- if (sizeof($key)>1)
- $data["name"]=substr(trim($key[1]),0,-1);
- return $data;
- }
-
- /*! constructor
- init public collectons
- @param proto
- DataConfig object used as prototype for new one, optional
- */
- public function __construct($proto=false){
- if ($proto!==false)
- $this->copy($proto);
- else {
- $this->text=array();
- $this->data=array();
- $this->id=array("name"=>"dhx_auto_id", "db_name"=>"dhx_auto_id");
- $this->relation_id=array("name"=>"", "db_name"=>"");
- }
- }
-
- /*! copy properties from source object
-
- @param proto
- source object
- */
- public function copy($proto){
- $this->id = $proto->id;
- $this->relation_id = $proto->relation_id;
- $this->text = $proto->text;
- $this->data = $proto->data;
- }
-
- /*! returns list of data fields (db_names)
- @return
- list of data fields ( ready to be used in SQL query )
- */
- public function db_names_list($db){
- $out=array();
- if ($this->id["db_name"])
- array_push($out,$db->escape_name($this->id["db_name"]));
- if ($this->relation_id["db_name"])
- array_push($out,$db->escape_name($this->relation_id["db_name"]));
-
- for ($i=0; $i < sizeof($this->data); $i++){
- if ($this->data[$i]["db_name"]!=$this->data[$i]["name"])
- $out[]=$db->escape_name($this->data[$i]["db_name"])." as ".$this->data[$i]["name"];
- else
- $out[]=$db->escape_name($this->data[$i]["db_name"]);
- }
-
- return $out;
- }
-
- /*! add field to dataset config ($text collection)
-
- added field will be used in all auto-generated queries
- @param name
- name of field
- @param aliase
- aliase of field, optional
- */
- public function add_field($name,$aliase=false){
- if ($aliase===false) $aliase=$name;
-
- //adding to list of data-active fields
- if ($this->id["db_name"]==$name || $this->relation_id["db_name"] == $name){
- LogMaster::log("Field name already used as ID, be sure that it is really necessary.");
- }
- if ($this->is_field($name,$this->text)!=-1)
- throw new Exception('Data field already registered: '.$name);
- array_push($this->text,array("db_name"=>$name,"name"=>$aliase));
-
- //adding to list of all fields as well
- if ($this->is_field($name,$this->data)==-1)
- array_push($this->data,array("db_name"=>$name,"name"=>$aliase));
-
- }
-
- /*! remove field from dataset config ($text collection)
-
- removed field will be excluded from all auto-generated queries
- @param name
- name of field, or aliase of field
- */
- public function remove_field($name){
- $ind = $this->is_field($name);
- if ($ind==-1) throw new Exception('There was no such data field registered as: '.$name);
- array_splice($this->text,$ind,1);
- //we not deleting field from $data collection, so it will not be included in data operation, but its data still available
- }
-
- /*! remove field from dataset config ($text and $data collections)
-
- removed field will be excluded from all auto-generated queries
- @param name
- name of field, or aliase of field
- */
- public function remove_field_full($name){
- $ind = $this->is_field($name);
- if ($ind==-1) throw new Exception('There was no such data field registered as: '.$name);
- array_splice($this->text,$ind,1);
-
- $ind = $this->is_field($name, $this->data);
- if ($ind==-1) throw new Exception('There was no such data field registered as: '.$name);
- array_splice($this->data,$ind,1);
- }
-
- /*! check if field is a part of dataset
-
- @param name
- name of field
- @param collection
- collection, against which check will be done, $text collection by default
- @return
- returns true if field already a part of dataset, otherwise returns true
- */
- public function is_field($name,$collection = false){
- if (!$collection)
- $collection=$this->text;
-
- for ($i=0; $i<sizeof($collection); $i++)
- if ($collection[$i]["name"] == $name || $collection[$i]["db_name"] == $name) return $i;
- return -1;
- }
-
-
-} \ No newline at end of file
diff --git a/codebase/Dhtmlx/Connector/DataStorage/DataRequestConfig.php b/codebase/Dhtmlx/Connector/DataStorage/DataRequestConfig.php
deleted file mode 100644
index c9f3913..0000000
--- a/codebase/Dhtmlx/Connector/DataStorage/DataRequestConfig.php
+++ /dev/null
@@ -1,284 +0,0 @@
-<?php
-
-namespace Dhtmlx\Connector\DataStorage;
-
-/*! manager of data request
-**/
-class DataRequestConfig{
- private $filters; //!< array of filtering rules
- private $relation=false; //!< ID or other element used for linking hierarchy
- private $sort_by; //!< sorting field
- private $start; //!< start of requested data
- private $count; //!< length of requested data
-
- private $order = false;
- private $user;
- private $version;
-
- //for render_sql
- private $source; //!< souce table or another source destination
- private $fieldset; //!< set of data, which need to be retrieved from source
-
- /*! constructor
-
- @param proto
- DataRequestConfig object, optional, if provided then new request object will copy all properties from provided one
- */
- public function __construct($proto=false){
- if ($proto)
- $this->copy($proto);
- else{
- $start=0;
- $this->filters=array();
- $this->sort_by=array();
- }
- }
-
- /*! copy parameters of source object into self
-
- @param proto
- source object
- */
- public function copy($proto){
- $this->filters =$proto->get_filters();
- $this->sort_by =$proto->get_sort_by();
- $this->count =$proto->get_count();
- $this->start =$proto->get_start();
- $this->source =$proto->get_source();
- $this->fieldset =$proto->get_fieldset();
- $this->relation =$proto->get_relation();
- $this->user = $proto->user;
- $this->version = $proto->version;
- }
-
- /*! convert self to string ( for logs )
- @return
- self as plain string,
- */
- public function __toString(){
- $str="Source:{$this->source}\nFieldset:{$this->fieldset}\nWhere:";
- for ($i=0; $i < sizeof($this->filters); $i++)
- $str.=$this->filters[$i]["name"]." ".$this->filters[$i]["operation"]." ".$this->filters[$i]["value"].";";
- $str.="\nStart:{$this->start}\nCount:{$this->count}\n";
- for ($i=0; $i < sizeof($this->sort_by); $i++)
- $str.=$this->sort_by[$i]["name"]."=".$this->sort_by[$i]["direction"].";";
- $str.="\nRelation:{$this->relation}";
- return $str;
- }
-
- /*! returns set of filtering rules
- @return
- set of filtering rules
- */
- public function get_filters(){
- return $this->filters;
- }
- public function &get_filters_ref(){
- return $this->filters;
- }
- public function set_filters($data){
- $this->filters=$data;
- }
-
-
- public function get_order(){
- return $this->order;
- }
- public function set_order($order){
- $this->order = $order;
- }
- public function get_user(){
- return $this->user;
- }
- public function set_user($user){
- $this->user = $user;
- }
- public function get_version(){
- return $this->version;
- }
- public function set_version($version){
- $this->version = $version;
- }
-
- /*! returns list of used fields
- @return
- list of used fields
- */
- public function get_fieldset(){
- return $this->fieldset;
- }
- /*! returns name of source table
- @return
- name of source table
- */
- public function get_source(){
- return $this->source;
- }
- /*! returns set of sorting rules
- @return
- set of sorting rules
- */
- public function get_sort_by(){
- return $this->sort_by;
- }
- public function &get_sort_by_ref(){
- return $this->sort_by;
- }
- public function set_sort_by($data){
- $this->sort_by=$data;
- }
-
- /*! returns start index
- @return
- start index
- */
- public function get_start(){
- return $this->start;
- }
- /*! returns count of requested records
- @return
- count of requested records
- */
- public function get_count(){
- return $this->count;
- }
- /*! returns name of relation id
- @return
- relation id name
- */
- public function get_relation(){
- return $this->relation;
- }
-
- /*! sets sorting rule
-
- @param field
- name of column
- @param order
- direction of sorting
- */
- public function set_sort($field,$order=false){
- if (!$field && !$order)
- $this->sort_by=array();
- else{
- if ($order===false)
- $this->sort_by[] = $field;
- else {
- $order=strtolower($order)=="asc"?"ASC":"DESC";
- $this->sort_by[]=array("name"=>$field,"direction" => $order);
- }
- }
- }
- /*! sets filtering rule
-
- @param field
- name of column
- @param value
- value for filtering
- @param operation
- operation for filtering, optional , LIKE by default
- */
- public function set_filter($field,$value=false,$operation=false){
- if ($value === false)
- array_push($this->filters,$field);
- else
- array_push($this->filters,array("name"=>$field,"value"=>$value,"operation"=>$operation));
- }
-
- /*! sets list of used fields
-
- @param value
- list of used fields
- */
- public function set_fieldset($value){
- $this->fieldset=$value;
- }
- /*! sets name of source table
-
- @param value
- name of source table
- */
- public function set_source($value){
- if (is_string($value))
- $value = trim($value);
- $this->source = $value;
- if (!$this->source) throw new Exception("Source of data can't be empty");
- }
- /*! sets data limits
-
- @param start
- start index
- @param count
- requested count of data
- */
- public function set_limit($start,$count){
- $this->start=$start;
- $this->count=$count;
- }
- /*! sets name of relation id
-
- @param value
- name of relation id field
- */
- public function set_relation($value){
- $this->relation=$value;
- }
- /*! parse incoming sql, to fill other properties
-
- @param sql
- incoming sql string
- */
- public function parse_sql($sql, $as_is = false){
- if ($as_is){
- $this->fieldset = $sql;
- return;
- }
-
- $sql= preg_replace("/[ \n\t]+limit[\n\t ,0-9]*$/i","",$sql);
-
- $data = preg_split("/[ \n\t]+\\_from\\_/i",$sql,2);
- if (count($data)!=2)
- $data = preg_split("/[ \n\t]+from/i",$sql,2);
- $this->fieldset = preg_replace("/^[\s]*select/i","",$data[0],1);
-
- //Ignore next type of calls
- //direct call to stored procedure without FROM
- if ((count($data) == 1) ||
- //UNION select
- preg_match("#[ \n\r\t]union[ \n\t\r]#i", $sql)){
- $this->fieldset = $sql;
- return;
- }
-
- $table_data = preg_split("/[ \n\t]+where/i",$data[1],2);
- /*
- if sql code contains group_by we will place all sql query in the FROM
- it will not allow to use any filtering against the query
- still it is better than just generate incorrect sql commands for any group by query
- */
- if (sizeof($table_data)>1 && !preg_match("#.*group by.*#i",$table_data[1])){ //where construction exists
- $this->set_source($table_data[0]);
- $where_data = preg_split("/[ \n\t]+order[ ]+by/i",$table_data[1],2);
- $this->filters[]=$where_data[0];
- if (sizeof($where_data)==1) return; //end of line detected
- $data=$where_data[1];
- } else {
- $table_data = preg_split("/[ \n\t]+order[ ]+by/i",$data[1],2);
- $this->set_source($table_data[0]);
- if (sizeof($table_data)==1) return; //end of line detected
- $data=$table_data[1];
- }
-
- if (trim($data)){ //order by construction exists
- $s_data = preg_split("/\\,/",trim($data));
- for ($i=0; $i < count($s_data); $i++) {
- $data=preg_split("/[ ]+/",trim($s_data[$i]),2);
- if (sizeof($data)>1)
- $this->set_sort($data[0],$data[1]);
- else
- $this->set_sort($data[0]);
- }
-
- }
- }
-} \ No newline at end of file
diff --git a/codebase/Dhtmlx/Connector/DataStorage/DataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/DataWrapper.php
index e6b706f..304d0a2 100644
--- a/codebase/Dhtmlx/Connector/DataStorage/DataWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/DataWrapper.php
@@ -1,10 +1,11 @@
<?php
-
namespace Dhtmlx\Connector\DataStorage;
+use \Exception;
+
/*! Base abstraction class, used for data operations
Class abstract access to data, it is a base class to all DB wrappers
**/
-abstract class DataWrapper{
+abstract class DataWrapper {
protected $connection;
protected $config;//!< DataConfig instance
/*! constructor
diff --git a/codebase/Dhtmlx/Connector/DataStorage/ExcelDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/ExcelDBDataWrapper.php
new file mode 100644
index 0000000..2626cfd
--- /dev/null
+++ b/codebase/Dhtmlx/Connector/DataStorage/ExcelDBDataWrapper.php
@@ -0,0 +1,105 @@
+<?php
+namespace Dhtmlx\Connector\DataStorage;
+use Dhtmlx\Connector\DataStorage\ResultHandler\ExcelResultHandler;
+
+/*! Implementation of DataWrapper for Excel
+**/
+class ExcelDBDataWrapper extends DBDataWrapper {
+ public $emptyLimit = 10;
+ public function excel_data($points){
+ $path = $this->connection;
+ $excel = PHPExcel_IOFactory::createReaderForFile($path);
+ $excel = $excel->load($path);
+ $result = array();
+ $excelWS = $excel->getActiveSheet();
+
+ for ($i=0; $i < sizeof($points); $i++) {
+ $c = array();
+ preg_match("/^([a-zA-Z]+)(\d+)/", $points[$i], $c);
+ if (count($c) > 0) {
+ $col = PHPExcel_Cell::columnIndexFromString($c[1]) - 1;
+ $cell = $excelWS->getCellByColumnAndRow($col, (int)$c[2]);
+ $result[] = $cell->getValue();
+ }
+ }
+
+ return $result;
+ }
+ public function select($source) {
+ $path = $this->connection;
+ $excel = PHPExcel_IOFactory::createReaderForFile($path);
+ $excel->setReadDataOnly(false);
+ $excel = $excel->load($path);
+ $excRes = new ExcelResultHandler();
+ $excelWS = $excel->getActiveSheet();
+ $addFields = true;
+
+ $coords = array();
+ if ($source->get_source() == '*') {
+ $coords['start_row'] = 0;
+ $coords['end_row'] = false;
+ } else {
+ $c = array();
+ preg_match("/^([a-zA-Z]+)(\d+)/", $source->get_source(), $c);
+ if (count($c) > 0) {
+ $coords['start_row'] = (int) $c[2];
+ } else {
+ $coords['start_row'] = 0;
+ }
+ $c = array();
+ preg_match("/:(.+)(\d+)$/U", $source->get_source(), $c);
+ if (count($c) > 0) {
+ $coords['end_row'] = (int) $c[2];
+ } else {
+ $coords['end_row'] = false;
+ }
+ }
+
+ $i = $coords['start_row'];
+ $end = 0;
+ while ((($coords['end_row'] == false)&&($end < $this->emptyLimit))||(($coords['end_row'] !== false)&&($i < $coords['end_row']))) {
+ $r = Array();
+ $emptyNum = 0;
+ for ($j = 0; $j < count($this->config->text); $j++) {
+ $col = PHPExcel_Cell::columnIndexFromString($this->config->text[$j]['name']) - 1;
+ $cell = $excelWS->getCellByColumnAndRow($col, $i);
+ if (PHPExcel_Shared_Date::isDateTime($cell)) {
+ $r[PHPExcel_Cell::stringFromColumnIndex($col)] = PHPExcel_Shared_Date::ExcelToPHP($cell->getValue());
+ } else if ($cell->getDataType() == 'f') {
+ $r[PHPExcel_Cell::stringFromColumnIndex($col)] = $cell->getCalculatedValue();
+ } else {
+ $r[PHPExcel_Cell::stringFromColumnIndex($col)] = $cell->getValue();
+ }
+ if ($r[PHPExcel_Cell::stringFromColumnIndex($col)] == '') {
+ $emptyNum++;
+ }
+ }
+ if ($emptyNum < count($this->config->text)) {
+ $r['id'] = $i;
+ $excRes->addRecord($r);
+ $end = 0;
+ } else {
+ if (DHX_IGNORE_EMPTY_ROWS == false) {
+ $r['id'] = $i;
+ $excRes->addRecord($r);
+ }
+ $end++;
+ }
+ $i++;
+ }
+ return $excRes;
+ }
+
+ public function query($sql) {
+ }
+
+ public function get_new_id() {
+ }
+
+ public function escape($data) {
+ }
+
+ public function get_next($res) {
+ return $res->next();
+ }
+} \ No newline at end of file
diff --git a/codebase/Dhtmlx/Connector/DataStorage/FileSystemDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/FileSystemDBDataWrapper.php
new file mode 100644
index 0000000..b513556
--- /dev/null
+++ b/codebase/Dhtmlx/Connector/DataStorage/FileSystemDBDataWrapper.php
@@ -0,0 +1,140 @@
+<?php
+namespace Dhtmlx\Connector\DataStorage;
+use Dhtmlx\Connector\DataStorage\TypeHandler\FileSystemTypeHandler;
+use Dhtmlx\Connector\DataStorage\ResultHandler\FileSystemResultHandler;
+use Dhtmlx\Connector\Tools\LogMaster;
+
+/*! Most execution time is a standart functions for workin with FileSystem: is_dir(), dir(), readdir(), stat()
+**/
+class FileSystemDBDataWrapper extends DBDataWrapper {
+
+ // returns list of files and directories
+ public function select($source) {
+ $relation = $this->getFileName($source->get_relation());
+ // for tree checks relation id and forms absolute path
+ if ($relation == '0') {
+ $relation = '';
+ } else {
+ $path = $source->get_source();
+ }
+ $path = $source->get_source();
+ $path = $this->getFileName($path);
+ $path = realpath($path);
+ if ($path == false) {
+ return new FileSystemResultHandler();
+ }
+
+ if (strpos(realpath($path.'/'.$relation), $path) !== 0) {
+ return new FileSystemResultHandler();
+ }
+ // gets files and directories list
+ $res = $this->getFilesList($path, $relation);
+ // sorts list
+ $res = $res->sort($source->get_sort_by(), $this->config->data);
+ return $res;
+ }
+
+ // gets files and directory list
+ private function getFilesList($path, $relation) {
+ $typeHandlerObj = FileSystemTypeHandler::getInstance();
+ LogMaster::log("Query filesystem: ".$path);
+ $dir = opendir($path.'/'.$relation);
+ $result = new FileSystemResultHandler();
+ // forms fields list
+ for ($i = 0; $i < count($this->config->data); $i++) {
+ $fields[] = $this->config->data[$i]['db_name'];
+ }
+ // for every file and directory of folder
+ while ($file = readdir($dir)) {
+ // . and .. should not be in output list
+ if (($file == '.')||($file == '..')) {
+ continue;
+ }
+ $newFile = array();
+ // parse file name as Array('name', 'ext', 'is_dir')
+ $fileNameExt = $this->parseFileName($path.'/'.$relation, $file);
+ // checks if file should be in output array
+ if (!$typeHandlerObj->checkFile($file, $fileNameExt)) {
+ continue;
+ }
+ // takes file stat if it's need
+ if ((in_array('size', $fields))||(in_array('date', $fields))) {
+ $fileInfo = stat($path.'/'.$file);
+ }
+
+ // for every field forms list of fields
+ for ($i = 0; $i < count($fields); $i++) {
+ $field = $fields[$i];
+ switch ($field) {
+ case 'filename':
+ $newFile['filename'] = $file;
+ break;
+ case 'full_filename':
+ $newFile['full_filename'] = $path."/".$file;
+ break;
+ case 'size':
+ $newFile['size'] = $fileInfo['size'];
+ break;
+ case 'extention':
+ $newFile['extention'] = $fileNameExt['ext'];
+ break;
+ case 'name':
+ $newFile['name'] = $fileNameExt['name'];
+ break;
+ case 'date':
+ $newFile['date'] = date("Y-m-d H:i:s", $fileInfo['ctime']);
+ break;
+ }
+ $newFile['relation_id'] = $relation.'/'.$file;
+ $newFile['safe_name'] = $this->setFileName($relation.'/'.$file);
+ $newFile['is_folder'] = $fileNameExt['is_dir'];
+ }
+ // add file in output list
+ $result->addFile($newFile);
+ }
+ return $result;
+ }
+
+ // replaces '.' and '_' in id
+ private function setFileName($filename) {
+ $filename = str_replace(".", "{-dot-}", $filename);
+ $filename = str_replace("_", "{-nizh-}", $filename);
+ return $filename;
+ }
+
+ // replaces '{-dot-}' and '{-nizh-}' in id
+ private function getFileName($filename) {
+ $filename = str_replace("{-dot-}", ".", $filename);
+ $filename = str_replace("{-nizh-}", "_", $filename);
+ return $filename;
+ }
+
+ // parses file name and checks if is directory
+ private function parseFileName($path, $file) {
+ $result = Array();
+ if (is_dir($path.'/'.$file)) {
+ $result['name'] = $file;
+ $result['ext'] = 'dir';
+ $result['is_dir'] = 1;
+ } else {
+ $pos = strrpos($file, '.');
+ $result['name'] = substr($file, 0, $pos);
+ $result['ext'] = substr($file, $pos + 1);
+ $result['is_dir'] = 0;
+ }
+ return $result;
+ }
+
+ public function query($sql) {
+ }
+
+ public function get_new_id() {
+ }
+
+ public function escape($data) {
+ }
+
+ public function get_next($res) {
+ return $res->next();
+ }
+} \ No newline at end of file
diff --git a/codebase/Dhtmlx/Connector/DataStorage/MsSQLDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/MsSQLDBDataWrapper.php
index 048af60..aabf0f7 100644
--- a/codebase/Dhtmlx/Connector/DataStorage/MsSQLDBDataWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/MsSQLDBDataWrapper.php
@@ -1,11 +1,8 @@
<?php
-
namespace Dhtmlx\Connector\DataStorage;
-
use Dhtmlx\Connector\Tools\LogMaster;
-class MsSQLDBDataWrapper extends DBDataWrapper
-{
+class MsSQLDBDataWrapper extends DBDataWrapper {
private $last_id = ""; //!< ID of previously inserted record
private $insert_operation = false; //!< flag of insert operation
private $start_from = false; //!< index of start position
diff --git a/codebase/Dhtmlx/Connector/DataStorage/MySQLDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/MySQLDBDataWrapper.php
index db68cbc..a23c34e 100644
--- a/codebase/Dhtmlx/Connector/DataStorage/MySQLDBDataWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/MySQLDBDataWrapper.php
@@ -1,10 +1,11 @@
<?php
namespace Dhtmlx\Connector\DataStorage;
-
+use Dhtmlx\Connector\Tools\LogMaster;
+use \Exception;
/*! Implementation of DataWrapper for MySQL
**/
-class MySQLDBDataWrapper extends DBDataWrapper{
+class MySQLDBDataWrapper extends DBDataWrapper {
protected $last_result;
public function query($sql){
LogMaster::log($sql);
diff --git a/codebase/Dhtmlx/Connector/DataStorage/OracleDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/OracleDBDataWrapper.php
new file mode 100644
index 0000000..b7505ab
--- /dev/null
+++ b/codebase/Dhtmlx/Connector/DataStorage/OracleDBDataWrapper.php
@@ -0,0 +1,86 @@
+<?php
+namespace Dhtmlx\Connector\DataStorage;
+use Dhtmlx\Connector\Tools\LogMaster;
+use \Exception;
+
+/*! Implementation of DataWrapper for MySQL
+**/
+class OracleDBDataWrapper extends DBDataWrapper {
+ private $last_id=""; //id of previously inserted record
+ private $insert_operation=false; //flag of insert operation
+
+ public function query($sql){
+ LogMaster::log($sql);
+ $stm = oci_parse($this->connection,$sql);
+ if ($stm===false) throw new Exception("Oracle - sql parsing failed\n".oci_error($this->connection));
+
+ $out = array(0=>null);
+ if($this->insert_operation){
+ oci_bind_by_name($stm,":outID",$out[0],999);
+ $this->insert_operation=false;
+ }
+
+
+ $mode = ($this->is_record_transaction() || $this->is_global_transaction())?OCI_DEFAULT:OCI_COMMIT_ON_SUCCESS;
+ $res = @oci_execute($stm,$mode);
+ if ($res===false) throw new Exception(oci_error($this->connection));
+
+ $this->last_id=$out[0];
+
+ return $stm;
+ }
+
+ public function get_next($res){
+ $data = oci_fetch_assoc($res);
+ if ($data){
+ foreach ($data as $k => $v)
+ $data[strtolower($k)] = $v;
+ }
+ return $data;
+ }
+
+ public function get_new_id(){
+ /*
+ Oracle doesn't support identity or auto-increment fields
+ Insert SQL returns new ID value, which stored in last_id field
+ */
+ return $this->last_id;
+ }
+
+ protected function insert_query($data,$request){
+ $sql = parent::insert_query($data,$request);
+ $this->insert_operation=true;
+ return $sql." returning ".$this->config->id["db_name"]." into :outID";
+ }
+
+ protected function select_query($select,$from,$where,$sort,$start,$count){
+ if (!$from)
+ return $select;
+
+ $sql="SELECT ".$select." FROM ".$from;
+ if ($where) $sql.=" WHERE ".$where;
+ if ($sort) $sql.=" ORDER BY ".$sort;
+ if ($start || $count)
+ $sql="SELECT * FROM ( select /*+ FIRST_ROWS(".$count.")*/dhx_table.*, ROWNUM rnum FROM (".$sql.") dhx_table where ROWNUM <= ".($count+$start)." ) where rnum >".$start;
+ return $sql;
+ }
+
+ public function escape($data){
+ /*
+ as far as I can see the only way to escape data is by using oci_bind_by_name
+ while it is neat solution in common case, it conflicts with existing SQL building logic
+ fallback to simple escaping
+ */
+ return str_replace("'","''",$data);
+ }
+
+ public function begin_transaction(){
+ //auto-start of transaction
+ }
+ public function commit_transaction(){
+ oci_commit($this->connection);
+ }
+ public function rollback_transaction(){
+ oci_rollback($this->connection);
+ }
+} \ No newline at end of file
diff --git a/codebase/Dhtmlx/Connector/DataStorage/PDODBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/PDODBDataWrapper.php
index dce146b..8eebe0c 100644
--- a/codebase/Dhtmlx/Connector/DataStorage/PDODBDataWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/PDODBDataWrapper.php
@@ -1,12 +1,14 @@
<?php
-
namespace Dhtmlx\Connector\DataStorage;
+use Dhtmlx\Connector\DataStorage\ResultHandler\PDOResultHandler;
+use Dhtmlx\Connector\Tools\LogMaster;
+use \Exception;
/*! Implementation of DataWrapper for PDO
if you plan to use it for Oracle - use Oracle connection type instead
**/
-class PDODBDataWrapper extends DBDataWrapper{
+class PDODBDataWrapper extends DBDataWrapper {
private $last_result;//!< store result or last operation
public function query($sql){
@@ -18,7 +20,7 @@ class PDODBDataWrapper extends DBDataWrapper{
throw new Exception("PDO - sql execution failed\n".$message[2]);
}
- return new PDOResultSet($res);
+ return new PDOResultHandler($res);
}
protected function select_query($select,$from,$where,$sort,$start,$count){
diff --git a/codebase/Dhtmlx/Connector/DataStorage/PHPCI2DBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/PHPCI2DBDataWrapper.php
index 8819ab5..cd3c13b 100755
--- a/codebase/Dhtmlx/Connector/DataStorage/PHPCI2DBDataWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/PHPCI2DBDataWrapper.php
@@ -2,6 +2,7 @@
namespace Dhtmlx\Connector\DataStorage;
use Dhtmlx\Connector\Connector;
use Dhtmlx\Connector\Tools\LogMaster;
+use \Exception;
class PHPCI2DBDataWrapper extends DBDataWrapper {
diff --git a/codebase/Dhtmlx/Connector/DataStorage/PHPCIDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/PHPCIDBDataWrapper.php
index 3173557..c89786b 100755
--- a/codebase/Dhtmlx/Connector/DataStorage/PHPCIDBDataWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/PHPCIDBDataWrapper.php
@@ -2,6 +2,7 @@
namespace Dhtmlx\Connector\DataStorage;
use Dhtmlx\Connector\Connector;
use Dhtmlx\Connector\Tools\LogMaster;
+use \Exception;
class PHPCIDBDataWrapper extends DBDataWrapper {
diff --git a/codebase/Dhtmlx/Connector/DataStorage/PHPCakeDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/PHPCakeDBDataWrapper.php
index 8297c7f..6c368e3 100755
--- a/codebase/Dhtmlx/Connector/DataStorage/PHPCakeDBDataWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/PHPCakeDBDataWrapper.php
@@ -1,6 +1,7 @@
<?php
namespace Dhtmlx\Connector\DataStorage;
use Cake\ORM\TableRegistry;
+use \Exception;
class PHPCakeDBDataWrapper extends ArrayDBDataWrapper {
diff --git a/codebase/Dhtmlx/Connector/DataStorage/PHPYii1DBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/PHPYii1DBDataWrapper.php
index d585ac2..d22afa5 100644
--- a/codebase/Dhtmlx/Connector/DataStorage/PHPYii1DBDataWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/PHPYii1DBDataWrapper.php
@@ -1,5 +1,6 @@
<?php
namespace Dhtmlx\Connector\DataStorage;
+use \Exception;
class PHPYii1DBDataWrapper extends ArrayDBDataWrapper {
diff --git a/codebase/Dhtmlx/Connector/DataStorage/PHPYiiDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/PHPYiiDBDataWrapper.php
index 6a02d11..f76ce0f 100644
--- a/codebase/Dhtmlx/Connector/DataStorage/PHPYiiDBDataWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/PHPYiiDBDataWrapper.php
@@ -1,5 +1,6 @@
<?php
namespace Dhtmlx\Connector\DataStorage;
+use \Exception;
class PHPYiiDBDataWrapper extends ArrayDBDataWrapper {
diff --git a/codebase/Dhtmlx/Connector/DataStorage/PostgreDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/PostgreDBDataWrapper.php
index ef5b92d..c3ed69d 100644
--- a/codebase/Dhtmlx/Connector/DataStorage/PostgreDBDataWrapper.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/PostgreDBDataWrapper.php
@@ -1,10 +1,9 @@
<?php
-
namespace Dhtmlx\Connector\DataStorage;
-
use Dhtmlx\Connector\Tools\LogMaster;
+use \Exception;
-class PostgreDBDataWrapper extends DBDataWrapper{
+class PostgreDBDataWrapper extends DBDataWrapper {
public function query($sql){
LogMaster::log($sql);
diff --git a/codebase/Dhtmlx/Connector/DataStorage/ResultHandler/ExcelResultHandler.php b/codebase/Dhtmlx/Connector/DataStorage/ResultHandler/ExcelResultHandler.php
new file mode 100644
index 0000000..d8b51fc
--- /dev/null
+++ b/codebase/Dhtmlx/Connector/DataStorage/ResultHandler/ExcelResultHandler.php
@@ -0,0 +1,75 @@
+<?php
+namespace Dhtmlx\Connector\DataStorage\ResultHandler;
+
+class ExcelResultHandler {
+ private $rows;
+ private $currentRecord = 0;
+
+ // add record to output list
+ public function addRecord($file) {
+ $this->rows[] = $file;
+ }
+
+
+ // return next record
+ public function next() {
+ if ($this->currentRecord < count($this->rows)) {
+ $row = $this->rows[$this->currentRecord];
+ $this->currentRecord++;
+ return $row;
+ } else {
+ return false;
+ }
+ }
+
+
+ // sorts records under $sort array
+ public function sort($sort, $data) {
+ if (count($this->files) == 0) {
+ return $this;
+ }
+ // defines fields list if it's need
+ for ($i = 0; $i < count($sort); $i++) {
+ $fieldname = $sort[$i]['name'];
+ if (!isset($this->files[0][$fieldname])) {
+ if (isset($data[$fieldname])) {
+ $fieldname = $data[$fieldname]['db_name'];
+ $sort[$i]['name'] = $fieldname;
+ } else {
+ $fieldname = false;
+ }
+ }
+ }
+
+ // for every sorting field will sort
+ for ($i = 0; $i < count($sort); $i++) {
+ // if field, setted in sort parameter doesn't exist, continue
+ if ($sort[$i]['name'] == false) {
+ continue;
+ }
+ // sorting by current field
+ $flag = true;
+ while ($flag == true) {
+ $flag = false;
+ // checks if previous sorting fields are equal
+ for ($j = 0; $j < count($this->files) - 1; $j++) {
+ $equal = true;
+ for ($k = 0; $k < $i; $k++) {
+ if ($this->files[$j][$sort[$k]['name']] != $this->files[$j + 1][$sort[$k]['name']]) {
+ $equal = false;
+ }
+ }
+ // compares two records in list under current sorting field and sorting direction
+ if (((($this->files[$j][$sort[$i]['name']] > $this->files[$j + 1][$sort[$i]['name']])&&($sort[$i]['direction'] == 'ASC'))||(($this->files[$j][$sort[$i]['name']] < $this->files[$j + 1][$sort[$i]['name']])&&($sort[$i]['direction'] == 'DESC')))&&($equal == true)) {
+ $c = $this->files[$j];
+ $this->files[$j] = $this->files[$j+1];
+ $this->files[$j+1] = $c;
+ $flag = true;
+ }
+ }
+ }
+ }
+ return $this;
+ }
+
+} \ No newline at end of file
diff --git a/codebase/Dhtmlx/Connector/DataStorage/ResultHandler/FileSystemResultHandler.php b/codebase/Dhtmlx/Connector/DataStorage/ResultHandler/FileSystemResultHandler.php
new file mode 100644
index 0000000..f71f421
--- /dev/null
+++ b/codebase/Dhtmlx/Connector/DataStorage/ResultHandler/FileSystemResultHandler.php
@@ -0,0 +1,76 @@
+<?php
+namespace Dhtmlx\Connector\DataStorage\ResultHandler;
+
+class FileSystemResultHandler {
+ private $files;
+ private $currentRecord = 0;
+
+
+ // add record to output list
+ public function addFile($file) {
+ $this->files[] = $file;
+ }
+
+
+ // return next record
+ public function next() {
+ if ($this->currentRecord < count($this->files)) {
+ $file = $this->files[$this->currentRecord];
+ $this->currentRecord++;
+ return $file;
+ } else {
+ return false;
+ }
+ }
+
+
+ // sorts records under $sort array
+ public function sort($sort, $data) {
+ if (count($this->files) == 0) {
+ return $this;
+ }
+ // defines fields list if it's need
+ for ($i = 0; $i < count($sort); $i++) {
+ $fieldname = $sort[$i]['name'];
+ if (!isset($this->files[0][$fieldname])) {
+ if (isset($data[$fieldname])) {
+ $fieldname = $data[$fieldname]['db_name'];
+ $sort[$i]['name'] = $fieldname;
+ } else {
+ $fieldname = false;
+ }
+ }
+ }
+
+ // for every sorting field will sort
+ for ($i = 0; $i < count($sort); $i++) {
+ // if field, setted in sort parameter doesn't exist, continue
+ if ($sort[$i]['name'] == false) {
+ continue;
+ }
+ // sorting by current field
+ $flag = true;
+ while ($flag == true) {
+ $flag = false;
+ // checks if previous sorting fields are equal
+ for ($j = 0; $j < count($this->files) - 1; $j++) {
+ $equal = true;
+ for ($k = 0; $k < $i; $k++) {
+ if ($this->files[$j][$sort[$k]['name']] != $this->files[$j + 1][$sort[$k]['name']]) {
+ $equal = false;
+ }
+ }
+ // compares two records in list under current sorting field and sorting direction
+ if (((($this->files[$j][$sort[$i]['name']] > $this->files[$j + 1][$sort[$i]['name']])&&($sort[$i]['direction'] == 'ASC'))||(($this->files[$j][$sort[$i]['name']] < $this->files[$j + 1][$sort[$i]['name']])&&($sort[$i]['direction'] == 'DESC')))&&($equal == true)) {
+ $c = $this->files[$j];
+ $this->files[$j] = $this->files[$j+1];
+ $this->files[$j+1] = $c;
+ $flag = true;
+ }
+ }
+ }
+ }
+ return $this;
+ }
+
+} \ No newline at end of file
diff --git a/codebase/Dhtmlx/Connector/DataStorage/PDOResultSet.php b/codebase/Dhtmlx/Connector/DataStorage/ResultHandler/PDOResultHandler.php
index 1221d05..d2b13ec 100644
--- a/codebase/Dhtmlx/Connector/DataStorage/PDOResultSet.php
+++ b/codebase/Dhtmlx/Connector/DataStorage/ResultHandler/PDOResultHandler.php
@@ -1,8 +1,7 @@
<?php
+namespace Dhtmlx\Connector\DataStorage\ResultHandler;
-namespace Dhtmlx\Connector\DataStorage;
-
-class PDOResultSet{
+class PDOResultHandler {
private $res;
public function __construct($res){
$this->res = $res;
diff --git a/codebase/Dhtmlx/Connector/DataStorage/SQLSrvDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/SQLSrvDBDataWrapper.php
new file mode 100644
index 0000000..a6d13a2
--- /dev/null
+++ b/codebase/Dhtmlx/Connector/DataStorage/SQLSrvDBDataWrapper.php
@@ -0,0 +1,95 @@
+<?php
+namespace Dhtmlx\Connector\DataStorage;
+use Dhtmlx\Connector\Tools\LogMaster;
+use \Exception;
+
+/*! SQLSrv implementation of DataWrapper
+**/
+class SQLSrvDBDataWrapper extends DBDataWrapper {
+ private $last_id=""; //!< ID of previously inserted record
+ private $insert_operation=false; //!< flag of insert operation
+ private $start_from=false; //!< index of start position
+
+ public function query($sql){
+ LogMaster::log($sql);
+ if ($this->start_from)
+ $res = sqlsrv_query($this->connection,$sql, array(), array("Scrollable" => SQLSRV_CURSOR_STATIC));
+ else
+ $res = sqlsrv_query($this->connection,$sql);
+
+ if ($res === false){
+ $errors = sqlsrv_errors();
+ $message = Array();
+ foreach($errors as $error)
+ $message[]=$error["SQLSTATE"].$error["code"].$error["message"];
+ throw new Exception("SQLSrv operation failed\n".implode("\n\n", $message));
+ }
+
+ if ($this->insert_operation){
+ sqlsrv_next_result($res);
+ $last = sqlsrv_fetch_array($res);
+ $this->last_id = $last["dhx_id"];
+ sqlsrv_free_stmt($res);
+ }
+ if ($this->start_from)
+ $data = sqlsrv_fetch($res, SQLSRV_SCROLL_ABSOLUTE, $this->start_from-1);
+ return $res;
+ }
+
+ public function get_next($res){
+ $data = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC);
+ if ($data)
+ foreach ($data as $key => $value)
+ if (is_a($value, "DateTime"))
+ $data[$key] = $value->format("Y-m-d H:i");
+ return $data;
+ }
+
+ public function get_new_id(){
+ /*
+ MSSQL doesn't support identity or auto-increment fields
+ Insert SQL returns new ID value, which stored in last_id field
+ */
+ return $this->last_id;
+ }
+
+ protected function insert_query($data,$request){
+ $sql = parent::insert_query($data,$request);
+ $this->insert_operation=true;
+ return $sql.";SELECT SCOPE_IDENTITY() as dhx_id";
+ }
+
+ protected function select_query($select,$from,$where,$sort,$start,$count){
+ if (!$from)
+ return $select;
+
+ $sql="SELECT " ;
+ if ($count)
+ $sql.=" TOP ".($count+$start);
+ $sql.=" ".$select." FROM ".$from;
+ if ($where) $sql.=" WHERE ".$where;
+ if ($sort) $sql.=" ORDER BY ".$sort;
+ if ($start && $count)
+ $this->start_from=$start;
+ else
+ $this->start_from=false;
+ return $sql;
+ }
+
+ public function escape($data){
+ /*
+ there is no special escaping method for mssql - use common logic
+ */
+ return str_replace("'","''",$data);
+ }
+
+ public function begin_transaction(){
+ sqlsrv_begin_transaction($this->connection);
+ }
+ public function commit_transaction(){
+ sqlsrv_commit($this->connection);
+ }
+ public function rollback_transaction(){
+ sqlsrv_rollback($this->connection);
+ }
+} \ No newline at end of file
diff --git a/codebase/Dhtmlx/Connector/DataStorage/SQLite3DBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/SQLite3DBDataWrapper.php
new file mode 100644
index 0000000..c44f296
--- /dev/null
+++ b/codebase/Dhtmlx/Connector/DataStorage/SQLite3DBDataWrapper.php
@@ -0,0 +1,30 @@
+<?php
+namespace Dhtmlx\Connector\DataStorage;
+use Dhtmlx\Connector\Tools\LogMaster;
+use \Exception;
+
+/*! SQLite implementation of DataWrapper
+**/
+class SQLite3DBDataWrapper extends DBDataWrapper {
+ public function query($sql){
+ LogMaster::log($sql);
+
+ $res = $this->connection->query($sql);
+ if ($res === false)
+ throw new Exception("SQLLite - sql execution failed\n".$this->connection->lastErrorMsg());
+
+ return $res;
+ }
+
+ public function get_next($res){
+ return $res->fetchArray();
+ }
+
+ public function get_new_id(){
+ return $this->connection->lastInsertRowID();
+ }
+
+ public function escape($data){
+ return $this->connection->escapeString($data);
+ }
+} \ No newline at end of file
diff --git a/codebase/Dhtmlx/Connector/DataStorage/SQLiteDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/SQLiteDBDataWrapper.php
new file mode 100644
index 0000000..7bbf763
--- /dev/null
+++ b/codebase/Dhtmlx/Connector/DataStorage/SQLiteDBDataWrapper.php
@@ -0,0 +1,69 @@
+<?php
+namespace Dhtmlx\Connector\DataStorage;
+use Dhtmlx\Connector\Tools\LogMaster;
+use \Exception;
+
+/*! SQLite implementation of DataWrapper
+**/
+class SQLiteDBDataWrapper extends DBDataWrapper {
+ protected $last_result;
+ public function query($sql){
+ LogMaster::log($sql);
+ if (is_array($sql)) {
+ $res = $this->connection->SelectLimit($sql['sql'], $sql['numrows'], $sql['offset']);
+ } else {
+ $res = $this->connection->Execute($sql);
+ }
+
+ if ($res===false) throw new Exception("ADODB operation failed\n".$this->connection->ErrorMsg());
+ $this->last_result = $res;
+ return $res;
+ }
+
+ public function get_next($res){
+ if (!$res)
+ $res = $this->last_result;
+
+ if ($res->EOF)
+ return false;
+
+ $row = $res->GetRowAssoc(false);
+ $res->MoveNext();
+ return $row;
+ }
+
+ public function get_new_id(){
+ return $this->connection->Insert_ID();
+ }
+
+ public function escape($data){
+ return $this->connection->addq($data);
+ }
+
+ /*! escape field name to prevent sql reserved words conflict
+ @param data
+ unescaped data
+ @return
+ escaped data
+ */
+ public function escape_name($data){
+ if ((strpos($data,"`")!==false || is_int($data)) || (strpos($data,".")!==false))
+ return $data;
+ return '`'.$data.'`';
+ }
+
+
+ protected function select_query($select,$from,$where,$sort,$start,$count){
+ if (!$from)
+ return $select;
+
+ $sql="SELECT ".$select." FROM ".$from;
+ if ($where) $sql.=" WHERE ".$where;
+ if ($sort) $sql.=" ORDER BY ".$sort;
+
+ if ($start || $count) {
+ $sql=array("sql"=>$sql,'numrows'=>$count, 'offset'=>$start);
+ }
+ return $sql;
+ }
+} \ No newline at end of file
diff --git a/codebase/Dhtmlx/Connector/DataStorage/SaSQLDBDataWrapper.php b/codebase/Dhtmlx/Connector/DataStorage/SaSQLDBDataWrapper.php
new file mode 100644
index 0000000..5e6c65a
--- /dev/null
+++ b/codebase/Dhtmlx/Connector/DataStorage/SaSQLDBDataWrapper.php
@@ -0,0 +1,86 @@
+<?php
+namespace Dhtmlx\Connector\DataStorage;
+use Dhtmlx\Connector\Tools\LogMaster;
+use \Exception;
+
+/*! SaSQL implementation of DataWrapper
+**/
+class SaSQLDBDataWrapper extends DBDataWrapper {
+ private $last_id=""; //id of previously inserted record
+ private $insert_operation=false; //flag of insert operation
+
+ public function query($sql){
+ LogMaster::log($sql);
+ $stm = oci_parse($this->connection,$sql);
+ if ($stm===false) throw new Exception("Oracle - sql parsing failed\n".oci_error($this->connection));
+
+ $out = array(0=>null);
+ if($this->insert_operation){
+ oci_bind_by_name($stm,":outID",$out[0],999);
+ $this->insert_operation=false;
+ }
+
+
+ $mode = ($this->is_record_transaction() || $this->is_global_transaction())?OCI_DEFAULT:OCI_COMMIT_ON_SUCCESS;
+ $res = @oci_execute($stm,$mode);
+ if ($res===false) throw new Exception(oci_error($this->connection));
+
+ $this->last_id=$out[0];
+
+ return $stm;
+ }
+
+ public function get_next($res){
+ $data = oci_fetch_assoc($res);
+ if ($data){
+ foreach ($data as $k => $v)
+ $data[strtolower($k)] = $v;
+ }
+ return $data;
+ }
+
+ public function get_new_id(){
+ /*
+ Oracle doesn't support identity or auto-increment fields
+ Insert SQL returns new ID value, which stored in last_id field
+ */
+ return $this->last_id;
+ }
+
+ protected function insert_query($data,$request){
+ $sql = parent::insert_query($data,$request);
+ $this->insert_operation=true;
+ return $sql." returning ".$this->config->id["db_name"]." into :outID";
+ }
+
+ protected function select_query($select,$from,$where,$sort,$start,$count){
+ if (!$from)
+ return $select;
+
+ $sql="SELECT ".$select." FROM ".$from;
+ if ($where) $sql.=" WHERE ".$where;
+ if ($sort) $sql.=" ORDER BY ".$sort;
+ if ($start || $count)
+ $sql="SELECT * FROM ( select /*+ FIRST_ROWS(".$count.")*/dhx_table.*, ROWNUM rnum FROM (".$sql.") dhx_table where ROWNUM <= ".($count+$start)." ) where rnum >".$start;
+ return $sql;
+ }
+
+ public function escape($data){
+ /*
+ as far as I can see the only way to escape data is by using oci_bind_by_name
+ while it is neat solution in common case, it conflicts with existing SQL building logic
+ fallback to simple escaping
+ */
+ return str_replace("'","''",$data);
+ }
+
+ public function begin_transaction(){
+ //auto-start of transaction
+ }
+ public function commit_transaction(){
+ oci_commit($this->connection);
+ }
+ public function rollback_transaction(){
+ oci_rollback($this->connection);
+ }
+} \ No newline at end of file
diff --git a/codebase/Dhtmlx/Connector/DataStorage/TypeHandler/FileSystemTypeHandler.php b/codebase/Dhtmlx/Connector/DataStorage/TypeHandler/FileSystemTypeHandler.php
new file mode 100644
index 0000000..d544f6d
--- /dev/null
+++ b/codebase/Dhtmlx/Connector/DataStorage/TypeHandler/FileSystemTypeHandler.php
@@ -0,0 +1,119 @@
+<?php
+namespace Dhtmlx\Connector\DataStorage\TypeHandler;
+
+// singleton class for setting file types filter
+class FileSystemTypeHandler {
+
+ static private $instance = NULL;
+ private $extentions = Array();
+ private $extentions_not = Array();
+ private $all = true;
+ private $patterns = Array();
+ // predefined types
+ private $types = Array(
+ 'image' => Array('jpg', 'jpeg', 'gif', 'png', 'tiff', 'bmp', 'psd', 'dir'),
+ 'document' => Array('txt', 'doc', 'docx', 'xls', 'xlsx', 'rtf', 'dir'),
+ 'web' => Array('php', 'html', 'htm', 'js', 'css', 'dir'),
+ 'audio' => Array('mp3', 'wav', 'ogg', 'dir'),
+ 'video' => Array('avi', 'mpg', 'mpeg', 'mp4', 'dir'),
+ 'only_dir' => Array('dir')
+ );
+
+
+ static function getInstance() {
+ if (self::$instance == NULL) {
+ self::$instance = new FileSystemTypeHandler();
+ }
+ return self::$instance;
+ }
+
+ // sets array of extentions
+ public function setExtentions($ext) {
+ $this->all = false;
+ $this->extentions = $ext;
+ }
+
+ // adds one extention in array
+ public function addExtention($ext) {
+ $this->all = false;
+ $this->extentions[] = $ext;
+ }
+
+
+ // adds one extention which will not ouputed in array
+ public function addExtentionNot($ext) {
+ $this->extentions_not[] = $ext;
+ }
+
+
+ // returns array of extentions
+ public function getExtentions() {
+ return $this->extentions;
+ }
+
+ // adds regexp pattern
+ public function addPattern($pattern) {
+ $this->all = false;
+ $this->patterns[] = $pattern;
+ }
+
+ // clear extentions array
+ public function clearExtentions() {
+ $this->all = true;
+ $this->extentions = Array();
+ }
+
+ // clear regexp patterns array
+ public function clearPatterns() {
+ $this->all = true;
+ $this->patterns = Array();
+ }
+
+ // clear all filters
+ public function clearAll() {
+ $this->clearExtentions();
+ $this->clearPatterns();
+ }
+
+ // sets predefined type
+ public function setType($type, $clear = false) {
+ $this->all = false;
+ if ($type == 'all') {
+ $this->all = true;
+ return true;
+ }
+ if (isset($this->types[$type])) {
+ if ($clear) {
+ $this->clearExtentions();
+ }
+ for ($i = 0; $i < count($this->types[$type]); $i++) {
+ $this->extentions[] = $this->types[$type][$i];
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ // check file under setted filter
+ public function checkFile($filename, $fileNameExt) {
+ if (in_array($fileNameExt['ext'], $this->extentions_not)) {
+ return false;
+ }
+ if ($this->all) {
+ return true;
+ }
+
+ if ((count($this->extentions) > 0)&&(!in_array($fileNameExt['ext'], $this->extentions))) {
+ return false;
+ }
+
+ for ($i = 0; $i < count($this->patterns); $i++) {
+ if (!preg_match($this->patterns[$i], $filename)) {
+ return false;
+ }
+ }
+ return true;
+ }
+} \ No newline at end of file