name=$name; $this->type=$type; } //Получить PDO тип function getPDOType() { if($this->type==TCField::$BD_UINT1) return PDO::PARAM_BOOL; if($this->type==TCField::$BD_INT4) return PDO::PARAM_INT; if($this->type==TCField::$BD_INT8) return PDO::PARAM_INT; if($this->type==TCField::$BD_FLOAT4) return PDO::PARAM_STR; if($this->type==TCField::$BD_FLOAT8) return PDO::PARAM_STR; if($this->type==TCField::$BD_UTF8_1) return PDO::PARAM_STR; if($this->type==TCField::$BD_UTF8_2) return PDO::PARAM_STR; if($this->type==TCField::$BD_UTF8_4) return PDO::PARAM_STR; if($this->type==TCField::$BD_BLOB_4) return PDO::PARAM_LOB; return PDO::PARAM_STR; } //Прочитать значение из файла в соответствии с типом function ReadValue($fileHandle) { if($this->type==TCField::$BD_UINT1) { $this->value=fread($fileHandle, 1); }else if($this->type==TCField::$BD_UINT2) { $this->value=fread($fileHandle, 2); }else if($this->type==TCField::$BD_UINT4) { $this->value=fread($fileHandle, 4); }else if($this->type==TCField::$BD_INT1) { $this->value=fread($fileHandle, 1); }else if($this->type==TCField::$BD_INT2) { $this->value=fread($fileHandle, 2); }else if($this->type==TCField::$BD_INT4) { $this->value=fread($fileHandle, 4); }else if($this->type==TCField::$BD_INT8) { $this->value=fread($fileHandle, 8); }else if($this->type==TCField::$BD_FLOAT4) { $this->value=fread($fileHandle, 4); }else if($this->type==TCField::$BD_FLOAT8) { $this->value=fread($fileHandle, 8); }else if($this->type==TCField::$BD_UTF8_1) { $s=getBin('C',fread($fileHandle, 1)); if($s==0) $this->value=''; else $this->value=fread($fileHandle, $s); }else if($this->type==TCField::$BD_UTF8_2) { $s=getBin('S',fread($fileHandle, 2)); if($s==0) $this->value=''; else { //В цикле так как из зип потока читало порциями $this->value=''; while($s>strlen($this->value)) $this->value.=fread($fileHandle, $s-strlen($this->value)); } }else if($this->type==TCField::$BD_UTF8_4) { $s=getBin('I',fread($fileHandle, 4)); if($s==0) $this->value=''; else { //В цикле так как из зип потока читало порциями $this->value=''; while($s>strlen($this->value)) $this->value.=fread($fileHandle, $s-strlen($this->value)); } }else if($this->type==TCField::$BD_BLOB_4) { $s=getBin('I',fread($fileHandle, 4)); if($s==0) $this->value=''; else { //В цикле так как из зип потока читало порциями $this->value=''; while($s>strlen($this->value)) $this->value.=fread($fileHandle, $s-strlen($this->value)); } } } function pack($value) { if($value===NULL){ return NULL; } if($this->type==TCField::$BD_UINT1) { return pack("C",$value); }else if($this->type==TCField::$BD_UINT2) { return pack("S",$value); }else if($this->type==TCField::$BD_UINT4) { return pack("I",$value); }else if($this->type==TCField::$BD_INT1) { return pack("c",$value); }else if($this->type==TCField::$BD_INT2) { return pack("s",$value); }else if($this->type==TCField::$BD_INT4) { return pack("i",$value); }else if($this->type==TCField::$BD_INT8) { /*$str='0000000000000000000000000000000000000000000000000000000000000000'.decbin($value); //TODO decbin c 64 битами не работает на 32 битном php только 32 unpack('H*', '01010101'); $str=substr($str,-64,64); for($ii=0;$ii<8;$ii++)//побайтно записываем все 8 байт { $szRez=$szRez.pack("C",bindec(substr($str,-8,8))); $str=substr($str,0,-8); }*/ }else if($this->type==TCField::$BD_FLOAT4) { $value=str_replace(',','.',$value); //Чтоб не зависело от настроек оракла return pack("f",$value); }else if($this->type==TCField::$BD_FLOAT8) { $value=str_replace(',','.',$value); //Чтоб не зависело от настроек оракла return pack("d",$value); }else if($this->type==TCField::$BD_UTF8_1) { //$str=iconv('WINDOWS-1251', 'UTF-8', $value); return pack("C",strlen($value)).$value; }else if($this->type==TCField::$BD_UTF8_2) { //$str=iconv('WINDOWS-1251', 'UTF-8', $value); return pack("S",strlen($value)).$value; }else if($this->type==TCField::$BD_UTF8_4) { //$str=iconv('WINDOWS-1251', 'UTF-8', $value); return pack("I",strlen($value)).$value; }else if($this->type==TCField::$BD_BLOB_4) { return pack("I",strlen($value)).$value; } } function setValue($value) //пакуем данные в соответствии с типом { $this->value=$this->pack($value); } //Распаковываем данные в соответствии с типом function getValue() { if($this->value===NULL) return NULL; if($this->type==TCField::$BD_UINT1) { return getBin ("C", $this->value); }else if($this->type==TCField::$BD_UINT2) { return getBin ("S", $this->value); }else if($this->type==TCField::$BD_UINT4) { return getBin ("I", $this->value); }else if($this->type==TCField::$BD_INT1) { return getBin ("c", $this->value); }else if($this->type==TCField::$BD_INT2) { return getBin ("s", $this->value); }else if($this->type==TCField::$BD_INT4) { return getBin ("i", $this->value); }else if($this->type==TCField::$BD_INT8) { //return getBin ("S", $this->value); }else if($this->type==TCField::$BD_FLOAT4) { return getBin ("f", $this->value); }else if($this->type==TCField::$BD_FLOAT8) { return getBin ("d", $this->value); }else if($this->type==TCField::$BD_UTF8_1 || $this->type==TCField::$BD_UTF8_2 || $this->type==TCField::$BD_UTF8_4) { return $this->value; }else if($this->type==TCField::$BD_BLOB_2 || $this->type==TCField::$BD_BLOB_4) { return $this->value; } return ''; } } class TCTable { public $id=0; //Идентификатор таблицы public $name=''; //Название таблицы public $fields = array(); //Массив полей private $nc=0; //Байтов под NULL значения private $m_NULL; //NULL значения private $m_file; /** * Конструктор * @param string $name Название таблицы * @param integer $id Идентификатор таблицы */ function TCTable($name,$id) { $this->name=$name; $this->id=$id; } //Открыть таблицу по названию файла function OpenTableF($file) { if(file_exists($file)) { $this->OpenTableH(fopen($file,'r')); } } //Открыть таблицу из HANDLE (файла) function OpenTableH($handle) { $this->m_file=$handle; if(getBin('S',fread($this->m_file, 2))!=65500) return false; //id файла if(getBin('S',fread($this->m_file, 2))!=1) return false; //Версия файла $this->id=getBin('I',fread($this->m_file, 4)); //ID таблицы или запроса (4 байта можно сделать 2) if(getBin('C',fread($this->m_file, 1))!=0) return false; //Только плотные таблицы $this->name=fread($this->m_file, getBin('C',fread($this->m_file, 1))); //Название таблицы //Считываем столбцы $count=getBin('C',fread($this->m_file, 1)); //Количество столбцов for($i=0;$i<$count;$i++) { $field=new TCField (fread($this->m_file, getBin('C',fread($this->m_file, 1))),getBin('C',fread($this->m_file, 1))); $this->addField($field); //echo $field->name.'
'; } return true; } //Открыть таблицу из потока //OpenTable //Прочитать следующую запись из таблицы function ReadNextRecord() { if(feof($this->m_file)) return; //Неработает $this->m_NULL=''; for($j=0;$j<$this->nc;$j++) //Побайтно { $v=fread($this->m_file, 1); if(strlen($v)==0) return; //Проверка конца файла $v=getBin('C',$v); $v=decbin($v); for($i=strlen($v);$i<8;$i++) $v='0'.$v; $this->m_NULL.=$v; } $this->clearRows(); for($i=0;$ifields);$i++) { if($this->m_NULL[$i]=="1") { $this->fields[$i]->ReadValue($this->m_file); } } return true; } //Добавить поле к таблице function addField($field) { if($field!=NULL) { $this->fields[]=$field; $this->nc=ceil(count($this->fields)/8.0); //Байтов под NULL } } //Получить заголовок плотной таблицы в виде двоичной строки function getHeader() { $szRez=''; //Данные из таблицы в двоичном формате $szRez=$szRez.pack("S",65500); //id файла (2 байта) $szRez=$szRez.pack("S",1); //Версия файла (2 байта) $szRez=$szRez.pack("I",$this->id); //ID таблицы или запроса (4 байта) $szRez=$szRez.pack("C",0); //Тип таблицы 0-"Плотная" 1-"Мягкая" (1 байт) $szRez=$szRez.pack("C",strlen($this->name)).$this->name; //UTF8_1 строка $szRez=$szRez.pack("C",count($this->fields)); //Колво столбцов (1 байт) //Записываем id типов столбцов for($i=0;$ifields);$i++) { $szRez.=pack("C",strlen($this->fields[$i]->name)).$this->fields[$i]->name; $szRez.=pack("C",$this->fields[$i]->type); } return $szRez; } //Получить данные 1 записи в виде строки function getCol() { $szRez=''; //Запишем NULL значения побайтно (1-есть данные 0-нету данных) $str=''; for($i=0;$i<$this->nc*8;$i++) { if($i>=count($this->fields)) $str.='0'; else if($this->fields[$i]->value===NULL) $str.='0'; else $str.='1'; if(strlen($str)==8) { $szRez=$szRez.pack("C",bindec($str)); $str=''; } } //Запишем сами данные в строку for($i=0;$ifields);$i++) { $szRez.=$this->fields[$i]->value; } return $szRez; } //Row очистить запись function clearRows() { for($i=0;$ifields);$i++) { $this->fields[$i]->value=null; } } //Получить обьект столбца по имени function getRowByName($name) { for($i=0;$ifields);$i++) { if($this->fields[$i]->name==$name) return $this->fields[$i]; } } //Получить объект столбца по номеру function getRowByNum($num) { return $this->fields[$num]; } } ?>