Pgsql.php 81 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739
  1. <?php
  2. require_once dirname(__FILE__) . '/../../' . 'Lib.php';
  3. Lib::loadClass( 'Core_Database' );
  4. class Core_Database_Pgsql extends Core_Database {
  5. function __construct($host, $user, $password, $database, $names = '', $params = array()) {
  6. parent::__construct($host, $user, $password, $database, $names, $params);
  7. list($host,$port)=explode(":", $host);
  8. $this->_conn = @pg_connect("host=".$host." port=".$port." dbname=".$database." user=".$user." password=".$password);
  9. //DEBUG_S(-3,'conn'.$names." ",$params);
  10. if (!is_resource($this->_conn)) {
  11. $this->_set_error('CREATE CONNECTION FAILED');
  12. return;
  13. }
  14. //if (false === mysql_select_db($database, $this->_conn)) {
  15. // $this->_set_error('SELECT DATABASE FAILED');
  16. // return;
  17. //}
  18. if ($names != '') {
  19. $this->query("SET CLIENT_ENCODING TO '".$names."';");
  20. }
  21. }
  22. function getConnection() {
  23. return $this->_conn;
  24. }
  25. function getVersion($version) {
  26. if (!$this->_version) {
  27. //$sql = "SHOW VARIABLES LIKE 'version';";
  28. $this->_version=pg_version($this->_conn);
  29. //if ($r = $this->fetch($res)) {
  30. // // [Variable_name] => version, [Value] => 4.0.26-log
  31. // $this->_version = $r->Value;
  32. //}
  33. }
  34. return $this->_version;
  35. }
  36. /**
  37. * Wykonuje podane zapytanie i zwraca wynik mysql_query().
  38. */
  39. function query( $query, $msg = 'Query ERROR.' ) {
  40. $null = null;
  41. if (!$this->_conn) { return $null; }
  42. $res = pg_query($this->_conn,$query);
  43. if (!$res) {
  44. DEBUG_S(-3,'error ',array($query),__FILE__,__FUNCTION__,__LINE__);
  45. $this->_set_error('SQL QUERY FAILED: '.pg_result_error($this->_conn)."(".$query.")".pg_last_error($this->_conn));
  46. return $null;
  47. }
  48. return $res;
  49. }
  50. function fetch( $res ) {
  51. $ret = null;
  52. if ($res) $ret = pg_fetch_object( $res );
  53. return $ret;
  54. }
  55. function fetch_row( $res ) {
  56. $ret = null;
  57. if ($res) $ret = pg_fetch_row( $res );
  58. return $ret;
  59. }
  60. function fetch_assoc( $res ) {
  61. $ret = null;
  62. if ($res) $ret = pg_fetch_assoc( $res );
  63. return $ret;
  64. }
  65. function fetch_array($res) {
  66. $ret = null;
  67. if ($res) $ret = pg_fetch_array($res);
  68. return $ret;
  69. }
  70. function count( $res ) {
  71. return pg_num_rows( $res );
  72. }
  73. function num_rows( $res ) {
  74. return pg_num_rows( $res );
  75. }
  76. function insert_id() {
  77. $sql="select lastval();";
  78. $res = $this->query($sql);
  79. $last=$this->fetch_array($res);
  80. return $last[0];
  81. //return fetch_row( $res ); //TODO TESTING!!!
  82. //die('TEST THIS FUNCTION!!!');
  83. //return mysql_insert_id( $this->_conn );
  84. }
  85. function show_tables($table=null) {
  86. $sql="SELECT table_name as \"Tables_in_".$this->getDatabaseName()."\", table_type as \"Table_type\" FROM information_schema.tables where table_schema NOT IN ('pg_catalog', 'information_schema'); ";
  87. if(!empty($table)) $sql="SELECT table_name as \"Tables_in_".$this->getDatabaseName()."\", table_type as \"Table_type\" FROM information_schema.tables where table_schema NOT IN ('pg_catalog', 'information_schema') and table_name='".$table."' ";
  88. DEBUG_S(-3,$sql,$sql,__FILE__,__FUNCTION__,__LINE__);
  89. $res = $this->query($sql);
  90. return $res;
  91. }
  92. function describe_table($table) {
  93. $sql="select column_name as \"Field\" from INFORMATION_SCHEMA.COLUMNS where table_name = '".$table."'";
  94. $sql="SELECT
  95. f.attname AS \"Field\",
  96. -- pg_catalog.format_type(f.atttypid,f.atttypmod) AS type,
  97. CASE
  98. when pg_catalog.format_type(f.atttypid,f.atttypmod) like 'double precision' then 'double(8,2)'
  99. when pg_catalog.format_type(f.atttypid,f.atttypmod) like 'numeric' then 'double(8,2)'
  100. when pg_catalog.format_type(f.atttypid,f.atttypmod) like 'smallint' then 'int(11)'
  101. when pg_catalog.format_type(f.atttypid,f.atttypmod) like 'bigint' then 'int(11)'
  102. when pg_catalog.format_type(f.atttypid,f.atttypmod) like 'integer' then
  103. ( select cast(replace(pg_catalog.format_type(f.atttypid,f.atttypmod), 'integer', 'int(11)') as char(255)) )
  104. when pg_catalog.format_type(f.atttypid,f.atttypmod) like '%character varying%' then
  105. ( select cast(replace(pg_catalog.format_type(f.atttypid,f.atttypmod), 'character varying', 'varchar') as char(255)) )
  106. when pg_catalog.format_type(f.atttypid,f.atttypmod) like 'timestamp without time zone' then 'datetime'
  107. when pg_catalog.format_type(f.atttypid,f.atttypmod) like 'date' then 'date'
  108. when pg_catalog.format_type(f.atttypid,f.atttypmod) like 'text' then 'text'
  109. when pg_catalog.format_type(f.atttypid,f.atttypmod) like 'real' then 'double'
  110. when pg_catalog.format_type(f.atttypid,f.atttypmod) like 'geometry(%' then
  111. ( select cast( split_part( lower(replace(replace(pg_catalog.format_type(f.atttypid,f.atttypmod), 'geometry(', ''),')','')) , ',',1) as char(255)) )
  112. else ( select cast( 'enum('''||string_agg(enumlabel,''',''') || ''')' as char(255))
  113. FROM pg_enum e
  114. JOIN pg_type t ON e.enumtypid = t.oid
  115. WHERE t.typname = replace(pg_catalog.format_type(f.atttypid,f.atttypmod ),'\"','' ) )
  116. END as \"Type\" ,
  117. CASE f.attnotnull
  118. WHEN 't' THEN 'NO'
  119. WHEN 'f' THEN 'YES'
  120. END AS \"Null\",
  121. CASE
  122. WHEN p.contype='p' THEN 'PRI'
  123. ELSE ''
  124. END AS Key,
  125. -- CASE
  126. -- WHEN p.contype = 'u' THEN 't'
  127. -- ELSE 'f'
  128. -- END AS uniquekey,
  129. -- CASE
  130. -- WHEN p.contype = 'f' THEN g.relname
  131. -- END AS foreignkey,
  132. -- CASE
  133. -- WHEN p.contype = 'f' THEN p.confkey
  134. -- END AS foreignkey_fieldnum,
  135. -- CASE
  136. -- WHEN p.contype = 'f' THEN g.relname
  137. -- END AS foreignkey,
  138. -- CASE
  139. -- WHEN p.contype = 'f' THEN p.conkey
  140. -- END AS foreignkey_connnum,
  141. CASE
  142. WHEN f.atthasdef = 'n' THEN ''
  143. WHEN f.atthasdef = 't' AND d.adsrc like 'nextval(%' THEN ''
  144. WHEN f.atthasdef = 't' THEN d.adsrc
  145. END AS default,
  146. CASE
  147. WHEN f.atthasdef = 't' AND d.adsrc like 'nextval(%' THEN 'auto_increment'
  148. END AS Extra
  149. FROM pg_attribute f
  150. JOIN pg_class c ON c.oid = f.attrelid
  151. JOIN pg_type t ON t.oid = f.atttypid
  152. LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = f.attnum
  153. LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
  154. LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey)
  155. LEFT JOIN pg_class AS g ON p.confrelid = g.oid
  156. WHERE c.relkind = 'r'::char
  157. AND n.nspname = 'public' -- Replace with Schema name
  158. AND c.relname = '".$table."' -- Replace with table name
  159. AND f.attnum > 0
  160. -- ORDER BY number
  161. ;
  162. ";
  163. // echo "<pre>".$sql."</pre>";
  164. $result = $this->query($sql) or self::die1('\nProblem z '.$sql);
  165. DEBUG_S(-3,'describe table '.$table,array($sql,$result,$this->num_rows),__FILE__,__FUNCTION__,__LINE__);
  166. return $result;
  167. }
  168. function describe_table_value($table) {
  169. $res = self::describe_table($table);
  170. while($h=self::fetch($res)) {
  171. $result[$h->Field]=$h;
  172. }
  173. return $result;
  174. }
  175. function show_index($table,$only_primary_flag=false) {
  176. $sql="select table_name as \"Table\"
  177. ,case string_agg( cast( indisunique as char(255) ) ,'')
  178. when 'true' then '0'
  179. else '1'
  180. END as \"Non_unique\"
  181. , CASE string_agg( cast( indisprimary as char(255) ) ,'')
  182. when 'true' then 'PRIMARY'
  183. else column_name
  184. END as \"Key_name\"
  185. , CASE string_agg( cast( indisprimary as char(255) ) ,'')
  186. when 'true' then 'PRIMARY'
  187. -- else cast(string_agg(index_name) as char(255))
  188. END
  189. ,column_name as \"Column_name\"
  190. from (
  191. select
  192. t.relname as table_name,
  193. i.relname as index_name,
  194. a.attname as column_name,
  195. ix.indnatts as indnatts,
  196. unnest(ix.indkey) as unn,
  197. a.attnum,
  198. ix.indisunique as indisunique,
  199. ix.indisprimary as indisprimary
  200. ,ix.indkey
  201. ,a.attrelid
  202. ,i.oid
  203. from
  204. pg_class t,
  205. pg_class i,
  206. pg_index ix,
  207. pg_attribute a
  208. where
  209. t.oid = ix.indrelid
  210. and i.oid = ix.indexrelid
  211. and a.attrelid = t.oid
  212. and a.attnum = ANY(ix.indkey)
  213. and t.relkind = 'r'
  214. -- and t.relnamespace = 10
  215. and t.relname = '".$table."'
  216. ";
  217. if($only_primary_flag) $sql.=" and ix.indisprimary is true ";
  218. $sql.="
  219. order by
  220. t.relname,
  221. i.relname
  222. , generate_subscripts(ix.indkey,1)) sb
  223. where unn = attnum
  224. group by table_name,column_name
  225. -- group by index_name
  226. ";
  227. DEBUG_S(-3,'Show index',array($sql),__FILE__,__FUNCTION__,__LINE__);
  228. $res = $this->query($sql) or self::die1('\nProblem z '.$sql);
  229. return $res;
  230. }
  231. function show_index_value($table) {
  232. $res=self::show_index($table,true);
  233. while($h=self::fetch($res)) {
  234. return $h->Column_name;
  235. }
  236. }
  237. function die1($txt) {
  238. DEBUG_S(-3,'Died',$txt,__FILE__,__FUNCTION__,__LINE__);
  239. die();
  240. }
  241. function show_triggers($table) {
  242. $sql="SELECT
  243. trigger_name as \"Trigger\"
  244. ,event_manipulation as \"Event\"
  245. ,event_object_table as \"Table\"
  246. ,action_statement as \"Statement\"
  247. ,action_timing as \"Timing\"
  248. FROM information_schema.triggers
  249. WHERE event_object_table='".$table."'
  250. ORDER BY event_object_table,event_manipulation";
  251. DEBUG_S(-3,'Show triggers',array($sql),__FILE__,__FUNCTION__,__LINE__);
  252. $res = $this->query($sql) or self::die1('\nProblem z '.$sql);
  253. return $res;
  254. }
  255. function show_create_trigger($table,$trigger) {
  256. $sql="SELECT
  257. trigger_name as \"Trigger\"
  258. ,action_statement as \"SQL Original Statement\"
  259. -- ,action_timing as \"Timing\"
  260. -- character_set_client=utf8
  261. -- collation_connection=utf8_general_ci
  262. -- Database Collation=latin2_general_ci
  263. FROM information_schema.triggers
  264. WHERE trigger_name='".$trigger."' and event_object_table='".$table."'
  265. ORDER BY event_object_table,event_manipulation";
  266. DEBUG_S(-3,'Show triggers',array($sql),__FILE__,__FUNCTION__,__LINE__);
  267. $res = $this->query($sql) or self::die1('\nProblem z '.$sql);
  268. return $res;
  269. }
  270. function from_mysql_struct($type) {
  271. if(strstr($type, 'int(') ) return 'integer';
  272. else if(strstr($type, 'double') ) return 'double precision';
  273. else if(strstr($type, 'varchar(') ) return $type;
  274. else if(strstr($type, 'char(') ) return $type;
  275. else if(strstr($type, 'enum(') ) return $type; //todo
  276. else if(strstr($type, 'text') ) return $type;
  277. else if(strstr($type, 'datetime') ) return 'TIMESTAMP';
  278. else if(strstr($type, 'date') ) return 'date';
  279. else if(strstr($type, 'polygon') ) return 'geometry(Polygon)';
  280. else if(strstr($type, 'linestring') ) return 'geometry(linestring)';
  281. else if(strstr($type, 'point') ) return 'geometry(point)';
  282. else if(strstr($type, 'timestamp') ) return 'timestamp';
  283. else die('(TODO)Unknowns transl struct:'.$type);
  284. }
  285. //used mainly to translate enum values
  286. function alter_add_struct($table,$column,$type) {
  287. if(strstr($type, "enum('")) {
  288. $sql="DROP TYPE IF EXISTS \"".$table."_".$column."\"";
  289. self::query($sql) or die1($sql);
  290. $sql="CREATE TYPE \"".$table."_".$column."\" AS ".$type;
  291. self::query($sql) or die1($sql);
  292. $sql='alter table "'.$table.'" add "'.$column.'" "'.$table.'_'.$column.'"';
  293. self::query($sql) or die1($sql);
  294. } else if(strstr($type, "datetime")) {
  295. $sql='alter table "'.$table.'" add "'.$column.'" timestamp without time zone ';
  296. self::query($sql) or die1($sql);
  297. } else {
  298. $sql='alter table "'.$table.'" add "'.$column.'" '.$type;
  299. self::query($sql) or die1($sql);
  300. }
  301. if(strstr($type, "linestring'")) {
  302. $sql="SELECT UpdateGeometrySRID('".$table."','".$column."',4326);";
  303. self::query($sql) or die1($sql);
  304. } else if(strstr($type, "polygon'")) {
  305. $sql="SELECT UpdateGeometrySRID('".$table."','".$column."',4326);";
  306. self::query($sql) or die1($sql);
  307. } else if(strstr($type, "multipoint'")) {
  308. $sql="SELECT UpdateGeometrySRID('".$table."','".$column."',4326);";
  309. self::query($sql) or die1($sql);
  310. }
  311. }
  312. /** Returns formated array to parse it to SQL (especialy to get GIS data to keep as WKT)
  313. *
  314. */
  315. function GET_DB_OBJ_cols($table) {
  316. $structure=self::describe_table_value($table);
  317. foreach($structure as $Field=>$Struct) {
  318. //echo $Struct->Type;
  319. if((strstr($Struct->Type,"multipoint") )||strstr($Struct->Type,"linestring") ||strstr($Struct->Type,"polygon"))
  320. $col[]=' ST_AsText("'.$Field.'") as "'.$Field.'"';
  321. else $col[]='"'.$Field.'"';
  322. }
  323. return $col;
  324. }
  325. function get_by_data_column($table,$date_column,$timestamp,$now,$remote_key) {
  326. $structure=self::describe_table_value($table);
  327. if(strlen($timestamp)==0) $timestamp='0';
  328. DEBUG_S(-3,'Struct',$structure,__FILE__,__FUNCTION__,__LINE__);
  329. $col=self::GET_DB_OBJ_cols($table);
  330. $sql='Select '.implode(',', $col).' from "'.$table.'" where extract(epoch from "'.$date_column.'") > '.$timestamp.' and extract(epoch from "'.$date_column.'") < '.$now;
  331. //if(empty($timestamp))
  332. $sql.=' or "'.$date_column.'" is null';
  333. $sql.=' or "'.$remote_key.'" < 0 ';
  334. // $sql.=' or "'.$remote_key.'"=\'\'';
  335. DEBUG_S(-3,'biore dane ',$sql,__FILE__,__FUNCTION__,__LINE__);
  336. $res=self::query($sql) or die1($sql);
  337. return $res;
  338. }
  339. function get_current_time() {
  340. self::query("set timezone to 'UTC'");
  341. $sql=" select extract(epoch from now() at time zone 'utc') as time"; // bo nie dziala extract( epoch from CURRENT_TIMESTAMP at time zone 'UTC')
  342. $res=self::query($sql);
  343. while($h=self::fetch($res)) {
  344. return $h->time;
  345. }
  346. }
  347. function get_current_timestamp() {
  348. self::query("set timezone to 'UTC'"); //TODO jakas glupota nie dziala extract( epoch from CURRENT_TIMESTAMP at time zone 'UTC')
  349. $sql=" select now() at time zone 'utc' as time ";
  350. $res=self::query($sql);
  351. while($h=self::fetch($res)) {
  352. return $h->time;
  353. }
  354. }
  355. function set_last_sync_date($table,$now,$remote_db_id,$local_db_id,$timestamp_column='A_RECORD_UPDATE_DATE') {
  356. $sql="insert into \"_SYNC_DATABASE_TABLE_STATE\" ( \"TABLE_NAME\", \"LAST_SYNCED\" , \"DATABASE_SYNCED_ID\" , \"DATABASE_LOCAL_ID\" )
  357. values ('".$table."' , TIMESTAMP WITH TIME ZONE 'epoch' + ".$now." * INTERVAL '1 second' , '".$remote_db_id."' , '".$local_db_id."')";
  358. DEBUG_S(-3,'update sync date',$sql,__FILE__,__FUNCTION__,__LINE__);
  359. self::query($sql);
  360. $sql="update _SYNC_DATABASE_TABLE_STATE set LAST_SYNCED=from_unixtime('".$now."') where TABLE_NAME='".$table."'
  361. and DATABASE_SYNCED_ID='".$remote_db_id."' and DATABASE_LOCAL_ID='".$local_db_id."' ";
  362. $sql_c="update \"".$table."\" set \"".$timestamp_column."\"=TIMESTAMP WITH TIME ZONE 'epoch' + ".$now." * INTERVAL '1 second' where \"".$timestamp_column."\" is null ";
  363. self::query($sql_c) or die('315Problem z '.$sql_c);
  364. DEBUG_S(-3,'update sync date',array($sql,$sql_c),__FILE__,__FUNCTION__,__LINE__);
  365. }
  366. function get_last_sync_date($table,$remote_db_id,$local_db_id) {
  367. $sql="select \"TABLE_NAME\", extract(epoch from \"LAST_SYNCED\" at time zone 'utc') as \"LAST_SYNCED\" from \"_SYNC_DATABASE_TABLE_STATE\"
  368. where \"DATABASE_SYNCED_ID\"='".$remote_db_id."' and \"DATABASE_LOCAL_ID\"='".$local_db_id."' and \"TABLE_NAME\"='".$table."'
  369. order by \"ID\" desc limit 1
  370. ";
  371. $res=self::query($sql);
  372. DEBUG_S(-3,'Get date',$sql,__FILE__,__FUNCTION__,__LINE__);
  373. while($h=self::fetch($res)) {
  374. return $h->LAST_SYNCED;
  375. }
  376. return 0;
  377. }
  378. /** Use it before pasting obj to UPDATE_OBJ or ADD_NEW_OBJ to maintain GIS data especially
  379. *
  380. */
  381. function MAKE_DB_OBJ($table,$obj) {
  382. $structure=self::describe_table_value($table); //todo to cache optimize
  383. foreach(get_object_vars($obj) as $k=>$v) {
  384. if(trim($structure[$k]->Type)=='multipoint') {
  385. if(empty($v)) $v='null';
  386. else $v = "ST_GeomFromText('".$v."',4326)";
  387. } else if(trim($structure[$k]->Type)=='linestring') {
  388. if(empty($v)) $v='null';
  389. else $v = "ST_GeomFromText('".$v."',4326)";
  390. } else if(trim($structure[$k]->Type)=='polygon') {
  391. if(empty($v)) $v='null';
  392. else $v = "ST_GeomFromText('".$v."',4326)";
  393. } else if(trim($structure[$k]->Type)=='multipolygon') {
  394. if(empty($v)) $v='null';
  395. else $v = "ST_GeomFromText('".$v."',4326)";
  396. } else if(trim($structure[$k]->Type)=='datetime') {
  397. if(empty($v)) continue;
  398. if($v=='0000-00-00 00:00:00') continue;
  399. } else if(strstr($structure[$k]->Type,'double')) {
  400. if(empty($v)) continue;
  401. } else if(trim($structure[$k]->Type)=='date') {
  402. if(empty($v)) continue;
  403. if($v=='0000-00-00') continue;
  404. } else if(strstr(trim($structure[$k]->Type),'enum(')) {
  405. if(empty($v)) continue;
  406. }
  407. $obj_ret->$k=$v;
  408. }
  409. DEBUG_S(-3,'objs',array($obj,$obj_ret),__FILE__,__FUNCTION__,__LINE__);
  410. return $obj_ret;
  411. }
  412. function STRUCTURE_GENERATE($TABLES,$null=null,$TABLES_STRUCTURE_DATA,$flags=array()){
  413. DEBUG_S(-3,'flags',$flags,__FILE__,__FUNCTION__,__LINE__);
  414. //global $this;
  415. //! try to create info for functions and procedures -> ['__SCHEMA_FUNCTIONS__ARRAY__']
  416. /*
  417. $sql="show function status where Db='".$this->getDatabaseName()."';";
  418. DEBUG_S(-3,'sql function detail :: ',$sql,__FILE__,__FUNCTION__,__LINE__) ;
  419. $result=$this->query($sql) or self::die1('\nProblem z '.$sql);
  420. while($h=mysql_fetch_object($result)) {
  421. $sql_="show create function `{$h->Name}`" ;
  422. DEBUG_S(-3,'sql function detail :: ',$sql_,__FILE__,__FUNCTION__,__LINE__) ;
  423. $result_=$this->query($sql_) or self::die1('\nProblem z '.$sql);
  424. while($h_=mysql_fetch_object($result_)) {
  425. $TABLES_IMPORT['__SCHEMA_FUNCTIONS__ARRAY__']['FUNCTION'][$h->Name]=$h_;
  426. }
  427. }
  428. */
  429. /*
  430. $sql="show PROCEDURE status where Db='".$this->getDatabaseName()."';";
  431. DEBUG_S(-3,'sql function detail :: ',$sql_,__FILE__,__FUNCTION__,__LINE__) ;
  432. $result=$this->query($sql) or self::die1('\nProblem z '.$sql);
  433. while($h=mysql_fetch_object($result)) {
  434. $sql_="show create PROCEDURE `{$h->Name}`" ;
  435. DEBUG_S(-3,'sql PROCEDURE detail :: ',$sql_,__FILE__,__FUNCTION__,__LINE__) ;
  436. $result_=$this->query($sql_) or self::die1('\nProblem z '.$sql);
  437. while($h_=mysql_fetch_object($result_)) {
  438. $TABLES_IMPORT['__SCHEMA_FUNCTIONS__ARRAY__']['PROCEDURE'][$h->Name]=$h_;
  439. }
  440. }
  441. DEBUG_S(-3,'struktury funkcji: __SCHEMA_FUNCTIONS__ARRAY__ ',$TABLES_IMPORT['__SCHEMA_FUNCTIONS__ARRAY__'],__FILE__,__FUNCTION__,__LINE__) ;
  442. //self::die1('stop function during dev.');
  443. */
  444. foreach($TABLES as $TABLE ){
  445. //$sql="show tables like '".$TABLE."' ;" ;
  446. DEBUG_S(-3,'//! Listing possible tables to write to config',$TABLE,__FILE__,__FUNCTION__,__LINE__);
  447. $result=$this->show_tables($TABLE) or self::die1('\nProblem z '.$sql);
  448. if($this->num_rows($result)==0) {
  449. // nie ma tabeli - trzeba zapisac
  450. DEBUG_S(-3," BRAK TABELI ".$TABLE,null,__FILE__,__FUNCTION__,__LINE__);
  451. //self::die1();
  452. if(isset($TABLES_IMPORT[$TABLE])) {
  453. DEBUG_S(-3," Table already imported - problem in twice declared table ".$TABLE,null,__FILE__,__FUNCTION__,__LINE__);
  454. self::die1();
  455. }
  456. } else {
  457. DEBUG_S(-3,'We found rows'.$this->num_rows($result),$TABLE,__FILE__,__FUNCTION__,__LINE__);
  458. //$sql="show full tables like '".$TABLE."' ;" ;
  459. //$result=$this->query($sql) or self::die1('\nProblem z '.$sql);
  460. $result=$this->show_tables($TABLE);
  461. while($h=$this->fetch($result)) {
  462. $TABLES_IMPORT[$TABLE]['Table_type']=$h->{'Table_type'};
  463. DEBUG_S(-3,'//! Reading to conf if table is WIEV or not :sql/result',$h->{'Table_type'},__FILE__,__FUNCTION__,__LINE__);
  464. }
  465. $FLAG_CONTABLE=false;
  466. if( ($TABLES_IMPORT[$TABLE]['Table_type']=='BASE TABLE')
  467. || ( in_array('with_view', $flags) && $TABLES_IMPORT[$TABLE]['Table_type']=='VIEW' )
  468. ) {
  469. $FLAG_CONTABLE=true;
  470. //$sql=" describe `".$TABLE."` ;" ;
  471. //echo "\n ".$sql;
  472. // $result=$this->query($sql) or self::die1('\nProblem z '.$sql);
  473. $result=$this->describe_table($TABLE);
  474. while($h=$this->fetch($result)) {
  475. //echo "found ";
  476. $TABLES_IMPORT[$TABLE]['FIELDS'][]=$h;
  477. }
  478. //$sql=" show index from `".$TABLE."` ;" ;
  479. //$result=$this->query($sql) or self::die1('\nProblem z '.$sql);
  480. $result=self::show_index($TABLE);
  481. $TMP_KEYNAME=array();
  482. while($h=self::fetch($result)) {
  483. if(isset($h->Column_name)) { $h->Column_name="`".$h->Column_name."`";
  484. if(!isset($TMP_KEYNAME[$h->Key_name])) $TMP_KEYNAME[$h->Key_name]=$h->Column_name;
  485. else $TMP_KEYNAME[$h->Key_name].=",".$h->Column_name;
  486. }
  487. //if(isset($TABLES_IMPORT[$TABLE]['INDEX'][$h->Key_name])) {
  488. // $TABLES_IMPORT[$TABLE]['INDEX'][$h->Key_name]->Column_name.=", ".$h->Column_name." ";
  489. //} else {
  490. //}
  491. $TABLES_IMPORT[$TABLE]['INDEX'][$h->Key_name]=$h;
  492. $TABLES_IMPORT[$TABLE]['INDEX'][$h->Key_name]->Column_name=$TMP_KEYNAME[$h->Key_name];
  493. }
  494. if(in_array($TABLE,$TABLES_STRUCTURE_DATA)) { //bedziemy dodawac dane tej tabeli
  495. $sql=" select * from `".$TABLE."` ;" ;
  496. $result=$this->query($sql) or self::die1('\nProblem z '.$sql);
  497. while($h=self::fetch($result)) {
  498. $TABLES_IMPORT[$TABLE]['VALUES'][]=$h;
  499. }
  500. }
  501. DEBUG_S(-3,"Dane tabeli KOMORKI ".$TABLE." ",$TABLES_IMPORT[$TABLE]['FIELDS'],__FILE__, __FUNCTION__, __LINE__);
  502. DEBUG_S(-3,"Dane tabeli INDEKSY ".$TABLE." ",$TABLES_IMPORT[$TABLE]['INDEX'],__FILE__, __FUNCTION__, __LINE__);
  503. if(isset($TABLES_IMPORT[$TABLE]['VALUES'])) DEBUG_S(-3,"Dane tabeli VALUES ".$TABLE." ",$TABLES_IMPORT[$TABLE]['VALUES'],__FILE__, __FUNCTION__, __LINE__);
  504. //! reading triggers to conf -> $TABLES_IMPORT[$TABLE]['TRIGGERS']
  505. //$sql=" show triggers like '".$TABLE."' ;" ;
  506. //$result=$this->query($sql) or self::die1('\nProblem z '.$sql);
  507. $result=self::show_triggers($TABLE);
  508. while($h=self::fetch($result)) {
  509. // $sql_="show create trigger {$h->Trigger} ;" ;
  510. // echo $sql_;
  511. // $result_=$this->query($sql_) or self::die1('\nProblem z '.$sql_);
  512. $result_=self::show_create_trigger($TABLE,$h->Trigger);
  513. while($h_=self::fetch($result_)) {
  514. DEBUG_S(-3,"Dane tabeli h_ ".$TABLE." ",$h_,__FILE__, __FUNCTION__, __LINE__);
  515. $TABLES_IMPORT[$TABLE]['TRIGGERS'][$h->Trigger]=$h_;
  516. }
  517. }
  518. if(isset($TABLES_IMPORT[$TABLE]['TRIGGERS'])) DEBUG_S(-3,"Dane tabeli TRIGGERS ".$TABLE." ",$TABLES_IMPORT[$TABLE]['TRIGGERS'],__FILE__, __FUNCTION__, __LINE__);
  519. }
  520. if(($TABLES_IMPORT[$TABLE]['Table_type']=='VIEW')) {
  521. $FLAG_CONTABLE=true;
  522. $sql_="show create view `{$TABLE}` ;" ;
  523. //echo $sql_;
  524. $result_=$this->query($sql_) or self::die1('\nProblem z '.$sql_);
  525. while($h_=self::fetch($result_)) {
  526. DEBUG_S(-3,"//! trying to fetch create view fom".$TABLE." sql/res",array($sql_,$h_),__FILE__, __FUNCTION__, __LINE__);
  527. $TABLES_IMPORT[$TABLE]['VIEW']=$h_;
  528. }
  529. } if(!$FLAG_CONTABLE) {
  530. DEBUG_S(-3,"Unknown table type ! ".$TABLE." ".$TABLES_IMPORT[$TABLE]['Table_type'],$TABLES_IMPORT[$TABLE],__FILE__, __FUNCTION__, __LINE__);
  531. self::die1();
  532. }
  533. }
  534. }
  535. //print_r($TABLES_IMPORT);
  536. if(!function_exists('func_sort_tables_import')) {
  537. function func_sort_tables_import($a,$b){
  538. if($a['Table_type']==$b['Table_type']) return 0;
  539. else if($a['Table_type']=='VIEW') return 1;
  540. else return -1;
  541. }
  542. }
  543. uasort($TABLES_IMPORT,'func_sort_tables_import');
  544. DEBUG_S(-3,'Wygenerowane struktury (TABLES_IMPORT)',$TABLES_IMPORT,__FILE__,__FUNCTION__,__LINE__);
  545. return($TABLES_IMPORT);
  546. }
  547. function STRUCTURE_GENERATE_PARSE($config_base_structure_unserialized,$options=array()) {
  548. //budowa struktur w bazie
  549. DEBUG_S(-3,'config_base_structure_unserialized',$config_base_structure_unserialized,__FILE__, __FUNCTION__, __LINE__) ;
  550. foreach($config_base_structure_unserialized as $TABLE=>$ARR_TABLE) { //dla kazdej tabeli
  551. set_time_limit(36000);
  552. //! if($TABLE<>'_CRM_PROCES_USER_STATS_wiev') continue; //trigger development
  553. //! try to sync __SCHEMA_FUNCTIONS__ARRAY__
  554. // triggers sync disabled
  555. /*
  556. if(in_array('SKIP-PROCEDURE', $options)) {
  557. DEBUG_S(-3,'SKIP-PROCEDURES option',null,__FILE__,__FUNCTION__,__LINE__);
  558. continue;
  559. }
  560. if($TABLE=='__SCHEMA_FUNCTIONS__ARRAY__') {
  561. DEBUG_S(-3,'Try to synchronize functions and procedures',$ARR_TABLE,__FILE__,__FUNCTION__,__LINE__);
  562. //BEGIN PROCEDURE
  563. $sql=" SHOW PROCEDURE STATUS; ;" ; //listujemy nasze procedury
  564. DEBUG_S(-3,'Looking for PROCEDURE ',$sql,__FILE__,__FUNCTION__,__LINE__);
  565. $result=$this->query($sql) or die('\nProblem z '.$sql);
  566. while($h=mysql_fetch_object($result)) {
  567. if($h->Db<>$this->getDatabaseName()) continue;
  568. set_time_limit(36000);
  569. $sql_="show create PROCEDURE {$h->Name} ;" ;
  570. //echo $sql_;
  571. $result_=$this->query($sql_) or die('\nProblem z '.$sql_);
  572. while($h_=mysql_fetch_object($result_)) {
  573. $FIELDS_CHECKED['FOUNDS'][$h->Name]=$h_;
  574. if(!isset($ARR_TABLE['PROCEDURE'][$h->Name])) {
  575. DEBUG_S(-3,'We have some more functions - we will not delete them:'.$h->Name,null,__FILE__,__FUNCTION__,__LINE__);
  576. //$FIELDS_CHECKED['TO_DELETE'][$h->Name]=$h_;
  577. }
  578. }
  579. }
  580. DEBUG_S(-3,'Try to unserialize PROCEDURE and install to db:',$ARR_TABLE['PROCEDURE'],__FILE__,__FUNCTION__,__LINE__);
  581. foreach($ARR_TABLE['PROCEDURE'] as $TRIGGER_INDEX=>$TRIGGER_OBJECT) {
  582. if(!isset($FIELDS_CHECKED['FOUNDS'][$TRIGGER_INDEX])) { $FIELDS_CHECKED['TO_CREATE'][$TRIGGER_INDEX]=$TRIGGER_OBJECT;
  583. DEBUG_S(-3,'We have object to create '.$TRIGGER_INDEX,$TRIGGER_OBJECT,__FILE__,__FUNCTION__,__LINE__);
  584. }
  585. }
  586. //staramy sie zaktualizowac stare triggery, pod warunkiem, ze sie roznia
  587. foreach($FIELDS_CHECKED['FOUNDS'] as $TRIGGER_INDEX=>$TRIGGER_OBJECT) {
  588. DEBUG_S(-3,'OBJ/OBJ for '.$TRIGGER_INDEX,array($TRIGGER_OBJECT->{'Create Procedure'},$ARR_TABLE['PROCEDURE'][$TRIGGER_INDEX]->{'Create Procedure'}),__FILE__, __FUNCTION__, __LINE__);
  589. if(isset($ARR_TABLE['PROCEDURE'][$TRIGGER_INDEX])) //we first try to find if this trigger exists or delete it
  590. if($TRIGGER_OBJECT->{'Create Procedure'}<>$ARR_TABLE['PROCEDURE'][$TRIGGER_INDEX]->{'Create Procedure'} ) {
  591. DEBUG_S(-3,"Data are different ({$TRIGGER_INDEX}). We add object to be created as new.",__FILE__, __FUNCTION__, __LINE__);
  592. $FIELDS_CHECKED['TO_CREATE'][$TRIGGER_INDEX]=$ARR_TABLE['PROCEDURE'][$TRIGGER_INDEX];
  593. $FIELDS_CHECKED['TO_DELETE'][$TRIGGER_INDEX]=true;
  594. }
  595. }
  596. if(isset($FIELDS_CHECKED['TO_DELETE'])) {
  597. DEBUG_S(-3,'We have some data to delete',$FIELDS_CHECKED['TO_DELETE'],__FILE__,__FUNCTION__,__LINE__);
  598. foreach($FIELDS_CHECKED['TO_DELETE'] as $TRIGGER_INDEX=>$TRIGGER_OBJECT ) {
  599. $sql="DROP PROCEDURE IF EXISTS `{$TRIGGER_INDEX}`; ";
  600. DEBUG_S(-3,' sql to delete '.$TRIGGER_INDEX,$sql,__FILE__,__FUNCTION__,__LINE__);
  601. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die();
  602. }
  603. }
  604. //tworzymy brakujace procedury
  605. foreach ($FIELDS_CHECKED['TO_CREATE'] as $TRIGGER_INDEX=>$TRIGGER_OBJECT) {
  606. $sql=$TRIGGER_OBJECT->{'Create Procedure'};
  607. DEBUG_S(-3,'Try to add new '.$TRIGGER_INDEX,$sql,__FILE__,__FUNCTION__,__LINE__);
  608. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die();
  609. }
  610. unset($FIELDS_CHECKED);
  611. //EOF PROCEDURE
  612. //BEGIN FUNCTION
  613. $sql=" SHOW FUNCTION STATUS ;" ; //listujemy nasze procedury
  614. DEBUG_S(-3,'Looking for FUNCTION ',$sql,__FILE__,__FUNCTION__,__LINE__);
  615. $result=$this->query($sql) or die('\nProblem z '.$sql);
  616. while($h=mysql_fetch_object($result)) {
  617. set_time_limit(36000);
  618. $sql_="show create FUNCTION {$h->Name} ;" ;
  619. //echo $sql_;
  620. $result_=$this->query($sql_) or die('\nProblem z '.$sql_);
  621. while($h_=mysql_fetch_object($result_)) {
  622. $FIELDS_CHECKED['FOUNDS'][$h->Name]=$h_;
  623. if(!isset($ARR_TABLE['FUNCTION'][$h->Name])) {
  624. DEBUG_S(-3,'We have some more functions - we will not delete them:'.$h->Name,null,__FILE__,__FUNCTION__,__LINE__);
  625. // $FIELDS_CHECKED['TO_DELETE'][$h->Name]=$h_;
  626. }
  627. }
  628. }
  629. DEBUG_S(-3,'Try to unserialize FUNCTION and install to db:',$ARR_TABLE['FUNCTION'],__FILE__,__FUNCTION__,__LINE__);
  630. foreach($ARR_TABLE['FUNCTION'] as $TRIGGER_INDEX=>$TRIGGER_OBJECT) {
  631. if(!isset($FIELDS_CHECKED['FOUNDS'][$TRIGGER_INDEX])) { $FIELDS_CHECKED['TO_CREATE'][$TRIGGER_INDEX]=$TRIGGER_OBJECT;
  632. DEBUG_S(-3,'We have object to create '.$TRIGGER_INDEX,$TRIGGER_OBJECT,__FILE__,__FUNCTION__,__LINE__);
  633. }
  634. }
  635. //staramy sie zaktualizowac stare triggery, pod warunkiem, ze sie roznia
  636. foreach($FIELDS_CHECKED['FOUNDS'] as $TRIGGER_INDEX=>$TRIGGER_OBJECT) {
  637. DEBUG_S(-3,'OBJ/OBJ for '.$TRIGGER_INDEX,array($TRIGGER_OBJECT->{'Create Function'},$ARR_TABLE['FUNCTION'][$TRIGGER_INDEX]->{'Create Function'}),__FILE__, __FUNCTION__, __LINE__);
  638. if(isset($ARR_TABLE['FUNCTION'][$TRIGGER_INDEX])) //we first try to find if this trigger exists or delete it
  639. if($TRIGGER_OBJECT->{'Create Function'}<>$ARR_TABLE['FUNCTION'][$TRIGGER_INDEX]->{'Create Function'} ) {
  640. DEBUG_S(-3,"Data are different ({$TRIGGER_INDEX}). We add object to be created as new.",__FILE__, __FUNCTION__, __LINE__);
  641. $FIELDS_CHECKED['TO_CREATE'][$TRIGGER_INDEX]=$ARR_TABLE['FUNCTION'][$TRIGGER_INDEX];
  642. $FIELDS_CHECKED['TO_DELETE'][$TRIGGER_INDEX]=true;
  643. }
  644. }
  645. if(isset($FIELDS_CHECKED['TO_DELETE'])) {
  646. DEBUG_S(-3,'We have some data to delete',$FIELDS_CHECKED['TO_DELETE'],__FILE__,__FUNCTION__,__LINE__);
  647. foreach($FIELDS_CHECKED['TO_DELETE'] as $TRIGGER_INDEX=>$TRIGGER_OBJECT ) {
  648. $sql="DROP FUNCTION IF EXISTS `{$TRIGGER_INDEX}`; ";
  649. DEBUG_S(-3,' sql to delete '.$TRIGGER_INDEX,$sql,__FILE__,__FUNCTION__,__LINE__);
  650. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die();
  651. }
  652. }
  653. //tworzymy brakujace procedury
  654. foreach ($FIELDS_CHECKED['TO_CREATE'] as $TRIGGER_INDEX=>$TRIGGER_OBJECT) {
  655. $sql=$TRIGGER_OBJECT->{'Create Function'};
  656. DEBUG_S(-3,'Try to add new '.$TRIGGER_INDEX,$sql,__FILE__,__FUNCTION__,__LINE__);
  657. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die();
  658. }
  659. unset($FIELDS_CHECKED);
  660. //EOF FUNCTION
  661. //die('app in devel');
  662. continue; //no go to another table in loop
  663. } //eof
  664. */
  665. //! detect if src table is TABLE or VIEW
  666. //foreach($TABLES as $TABLE ){
  667. // $sql="show full tables like '".$TABLE."' ;" ;
  668. DEBUG_S(-3,'SQL:'.$this->getDatabaseName(),$sql,__FILE__, __FUNCTION__, __LINE__) ;
  669. // $result=$this->query($sql) or die('\nProblem z '.$sql);
  670. $result=$this->show_tables($TABLE);
  671. while($h=$this->fetch($result)) {
  672. $FIELDS_CHECKED['Table_type']=$h->{'Table_type'};
  673. }
  674. DEBUG_S(-3,'FIELDS_CHECKED:',$FIELDS_CHECKED,__FILE__, __FUNCTION__, __LINE__) ;
  675. if($this->count($result)==0) {
  676. // nie ma tabeli - trzeba zapisac
  677. if($ARR_TABLE['Table_type']=='BASE TABLE') {
  678. //DEBUG_S(-3,"\n BRAK TABELI dodajemy : ".$TABLE."!!!",null,__FILE__,__FUNCTION__,__LINE__);
  679. // $sql="create table ".$TABLE." ( ".$ARR_TABLE['FIELDS'][0]->Field." ".$ARR_TABLE['FIELDS'][0]->Type ; // ID int(11) NOT NULL AUTO_INCREMENT,
  680. if(trim($ARR_TABLE['FIELDS'][0]->Extra)=='auto_increment') {
  681. if(in_array('SKIP-PRIMARY-KEY', $options)) {
  682. $sql="create table \"".$TABLE."\" ( \"id_".$options['getDB']."\" serial
  683. , CONSTRAINT \"".$TABLE."_pkey\" PRIMARY KEY (\"id_".$options['getDB']."\")" ;
  684. } else $sql="create table \"".$TABLE."\" ( \"".$ARR_TABLE['FIELDS'][0]->Field."\" serial " ; // ID int(11) NOT NULL AUTO_INCREMENT,
  685. } else $sql="create table \"".$TABLE."\" ( \"".$ARR_TABLE['FIELDS'][0]->Field."\" ".$this->from_mysql_struct($ARR_TABLE['FIELDS'][0]->Type) ; // ID int(11) NOT NULL AUTO_INCREMENT,
  686. // if($ARR_TABLE['FIELDS'][0]->Null=='NO') $sql.=" not null "; else $sql.=" null ";
  687. //if($ARR_TABLE['FIELDS'][0]->Extra=='auto_increment') $sql.=" AUTO_INCREMENT "; else $sql.=" ";
  688. //$sql.=" ) DEFAULT CHARSET=latin2 ";
  689. $sql.=" ) ";
  690. DEBUG_S(-3,"Brak tabeli: ".$TABLE." dodajemy sql:",$sql,__FILE__,__FUNCTION__,__LINE__) ;
  691. //if(!empty($CONFIRM_SQL_UPDATE))
  692. $this->query($sql) or die('\nProblem z CREATE '.$sql);
  693. if($TABLE=='CRM_LISTA_ZASOBOW') {
  694. $sql=" alter table \"".$TABLE."\" AUTO_INCREMENT=1000 ";
  695. if(!empty($CONFIRM_SQL_UPDATE)) $this->query($sql) or die('\nProblem z AUTO INCREMENT '.$sql);
  696. }
  697. } else if($ARR_TABLE['Table_type']=='VIEW') {
  698. $sql=$ARR_TABLE['VIEW']->{'Create View'};
  699. DEBUG_S(-3,"Brak widoku: ".$TABLE." dodajemy sql:",$sql,__FILE__,__FUNCTION__,__LINE__) ;
  700. if(!empty($CONFIRM_SQL_UPDATE)) $this->query($sql) or die('\nProblem ze '.$sql);
  701. }
  702. } else {
  703. //try to detect if types are the same
  704. if($ARR_TABLE['Table_type']<>$FIELDS_CHECKED['Table_type']) die('Todo: ERROR VIEW/TABLE different types ');
  705. if($ARR_TABLE['Table_type']=='VIEW') {
  706. if(isset($ARR_TABLE['VIEW'])) {
  707. $sql_="show create view `{$TABLE}` ;" ;
  708. echo $sql_;
  709. $result_=$this->query($sql_) or die('\nProblem z '.$sql_);
  710. while($h_=self::fetch($result_)) {
  711. DEBUG_S(-3,"//! get current view info ".$TABLE." sql/res",array($sql_,$h_),__FILE__, __FUNCTION__, __LINE__);
  712. $FIELDS_CHECKED['VIEW']=$h_;
  713. }
  714. //ereg_replace(, , )
  715. if(strtolower($FIELDS_CHECKED['VIEW']->{'Create View'})<>strtolower($ARR_TABLE['VIEW']->{'Create View'})) {
  716. $sql="drop view `{$TABLE}`";
  717. if(!empty($CONFIRM_SQL_UPDATE)) $this->query($sql) or die('\nProblem ze '.$sql);
  718. $sql_=$ARR_TABLE['VIEW']->{'Create View'};
  719. DEBUG_S(-3,"//! Views are different for ".$TABLE." . Dropping old view and adding new (old/new/sql/sql):",array(strtolower($FIELDS_CHECKED['VIEW']->{'Create View'}),$ARR_TABLE['VIEW']->{'Create View'},$sql,$sql_,$h_),__FILE__, __FUNCTION__, __LINE__);
  720. if(!empty($CONFIRM_SQL_UPDATE)) $this->query($sql_) or die('\nProblem ze '.$sql_);
  721. }
  722. }
  723. }
  724. }
  725. //always create
  726. if($ARR_TABLE['Table_type']=='BASE TABLE') {
  727. set_time_limit(36000);
  728. //$sql=" describe `".$TABLE."` ;" ;
  729. //DEBUG_S(-3,'SQL:describe '.$TABLE,$sql,__FILE__, __FUNCTION__, __LINE__) ;
  730. //$result=$this->query($sql) or die('\nProblem z '.$sql);
  731. $result=$this->describe_table($TABLE) or die('\nProblem z '.$sql);
  732. $FIELDS_CHECKED=""; unset($FIELDS_CHECKED);
  733. foreach($ARR_TABLE['FIELDS'] as $TSTIND=>$TST_VAL) { //tu robie tabelke do odhaczania z niej zmiennych
  734. $FIELDS_CHECKED['FIELD_IN_CONFIG_TO_BE_PASSED'][$TST_VAL->Field]=1;
  735. $FIELDS_CHECKED['FIELD_IN_CONFIG_THAT_EXISTS'][$TST_VAL->Field]=1;
  736. }
  737. DEBUG_S(-3,'FIELDS_CHECKED',$FIELDS_CHECKED,__FILE__, __FUNCTION__, __LINE__) ;
  738. $var_passed=false;
  739. while($h=$this->fetch($result)) {
  740. //tu sprawdzamy czy sa wszystkie kolumny i maja takie same typy
  741. $FIELDS_CHECKED['FIELD_FROM_DB'][$h->Field]=1;
  742. if(!isset($FIELDS_CHECKED['FIELD_IN_CONFIG_THAT_EXISTS'][$h->Field])) {
  743. DEBUG_S(-3,'Za duzo o komorke '.$h->Field,$FIELDS_CHECKED,__FILE__, __FUNCTION__, __LINE__) ;
  744. $FIELDS_CHECKED['FIELD_IN_CONFIG_THAT_NOT_EXISTS'][$h->Field]=1;
  745. }
  746. foreach($ARR_TABLE['FIELDS'] as $TSTIND=>$TST_VAL) { //tu sprawdzam czy kolumna jest i jaka
  747. // echo "\n Tst ".$TST_VAL->Field." ==? ".$h->Field;
  748. if($TST_VAL->Field==$h->Field) {
  749. $FIELDS_CHECKED['FIELD_FOUND_IN_REMOTE_DB'][$h->Field]=1;
  750. if(isset($FIELDS_CHECKED['FIELD_IN_CONFIG_TO_BE_PASSED'][$h->Field])) //jezeli byla komorka ramowa
  751. unset($FIELDS_CHECKED['FIELD_IN_CONFIG_TO_BE_PASSED'][$h->Field]);
  752. }
  753. }
  754. //$TABLES_IMPORT[$TABLE]['FIELDS']=$h;
  755. }
  756. if(!empty($FIELDS_CHECKED['FIELD_IN_CONFIG_TO_BE_PASSED'])) DEBUG_S(-3,'Brakuje komorek dla '.$TABLE." ",array($FIELDS_CHECKED['FIELD_IN_CONFIG_TO_BE_PASSED']),__FILE__, __FUNCTION__, __LINE__);
  757. DEBUG_S(-3,'FIELDS_CHECKED',$FIELDS_CHECKED,__FILE__, __FUNCTION__, __LINE__) ;
  758. //dodajemy brakujace komorki
  759. if(count($FIELDS_CHECKED['FIELD_IN_CONFIG_TO_BE_PASSED'])>0) {
  760. foreach($FIELDS_CHECKED['FIELD_IN_CONFIG_TO_BE_PASSED'] as $FIELD_TO_ADD=>$VAL ){
  761. set_time_limit(36000);
  762. //echo "\n Trying to add column: ".$FIELD_TO_ADD;
  763. if(isset($INDEX_OF_CONFIG_TABLE)) unset($INDEX_OF_CONFIG_TABLE);
  764. foreach($ARR_TABLE['FIELDS'] as $TSTIND=>$TST_VAL) { //trzeba znalezc numer ID indeksu brakujacej komorki
  765. if($TST_VAL->Field==$FIELD_TO_ADD) $INDEX_OF_CONFIG_TABLE=$TSTIND;
  766. }
  767. // $sql="create table ".$TABLE." ( ".$ARR_TABLE['FIELDS'][0]->Field." ".$ARR_TABLE['FIELDS'][0]->Type ; // ID int(11) NOT NULL AUTO_INCREMENT,
  768. //if($ARR_TABLE['FIELDS'][0]->Extra=='auto_increment') $sql.=" AUTO_INCREMENT "; else $sql.=" ";
  769. //* $sql="alter table \"".$TABLE."\" add \"".$FIELD_TO_ADD."\" ".$this->from_mysql_struct($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type)." ";
  770. self::alter_add_struct($TABLE,$FIELD_TO_ADD,$this->from_mysql_struct($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type));
  771. //if(($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Default)) {
  772. /// if(($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Default=='NULL')||($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Default=='CURRENT_TIMESTAMP'))
  773. /// $sql.=" DEFAULT ".$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Default." ";// (".$INDEX_OF_CONFIG_TABLE.")";
  774. /// else $sql.=" DEFAULT '".$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Default."' ";// (".$INDEX_OF_CONFIG_TABLE.")";
  775. // }
  776. /// TODO !!! if($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Null=='NO') $sql.=" not null "; else $sql.=" null ";
  777. // $sql.=" null ";
  778. // $sql.=" ;";
  779. // echo "\n ".$sql;
  780. // $this->query($sql) or DEBUG_S(-3,'Problem z sql',$sql,__FILE__, __FUNCTION__, __LINE__) or die();
  781. }
  782. } //eof dodajemy brakujace komorki
  783. //Sprawdzamy czy sa zgodne typy komorek...
  784. //$sql=" describe `".$TABLE."` ;" ;
  785. //DEBUG_S(-3,'describe '.$TABLE,$sql,__FILE__, __FUNCTION__, __LINE__) ;
  786. $result=$this->describe_table($TABLE) or die('\nProblem z '.$sql);
  787. //$result=$this->query($sql) or die('\nProblem z '.$sql);
  788. while($h=self::fetch($result)) {
  789. set_time_limit(36000);
  790. $FIELDS_CHECKED['FIELD_FOUND_IN_REMOTE_DB_PROFILE'][$h->Field]=$h;
  791. }
  792. DEBUG_S(-3,'FIELDS_CHECKED',$FIELDS_CHECKED,__FILE__, __FUNCTION__, __LINE__) ;
  793. foreach($FIELDS_CHECKED['FIELD_FOUND_IN_REMOTE_DB_PROFILE'] as $FIELD_TO_CHK=>$VAL) {
  794. if(isset($INDEX_OF_CONFIG_TABLE)) unset($INDEX_OF_CONFIG_TABLE);
  795. foreach($ARR_TABLE['FIELDS'] as $TSTIND=>$TST_VAL) { //trzeba znalezc numer ID indeksu brakujacej komorki
  796. if(trim($TST_VAL->Field)==trim($FIELD_TO_CHK)) $INDEX_OF_CONFIG_TABLE=$TSTIND;
  797. }
  798. if(isset($FIELDS_CHECKED['FIELD_IN_CONFIG_THAT_NOT_EXISTS'][$FIELD_TO_CHK])) continue; //jezeli komorki nie ma i jest tylko lokalnie - ignorujemy!
  799. // to jakis glupi warunek ?
  800. if(!isset($INDEX_OF_CONFIG_TABLE)) die('Nie znaleziono indeksu w konfiguracji dla '.$TABLE.' i komorki '.$FIELD_TO_CHK);
  801. // echo "\nsprawdzamy wszystkie wlasciwosci dla db ".$TABLE." ".$FIELD_TO_CHK." col ".$INDEX_OF_CONFIG_TABLE;
  802. $CHK_TYPES_ARS=array('Type','Null','Default');
  803. $sql="";
  804. // echo "\n if ".var_dump($VAL->Type)." =? ".var_dump($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type) ;
  805. if(!strcmp(trim($VAL->Type),trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type))) {
  806. //! aktualizujemy typy
  807. $sql=" alter table \"".$TABLE."\" ALTER COLUMN \"".$FIELD_TO_CHK."\" ".$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type." ; ";
  808. if(strstr(trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type), 'char(')&& strstr(trim($VAL->Type), 'char(')){
  809. $src_char_len=ereg_replace('[^0-9]', '',trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type) );
  810. $dst_char_len=ereg_replace('[^0-9]', '',trim($VAL->Type) );
  811. if($src_char_len>$dst_char_len) {
  812. DEBUG_S(-3,'Aktualizacja rozszerzajaca zakres pola CHAR : CUR_CHAR_LEN ='.$src_char_len." and dest=".$dst_char_len ,$sql,__FILE__, __FUNCTION__, __LINE__);
  813. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die('\nProblem z '.$sql);
  814. } else {
  815. DEBUG_S(-3,'celowe pominiecie - aktualizacja moze skasowac dane w bazie!!! :',$sql,__FILE__, __FUNCTION__, __LINE__);
  816. // die();
  817. }
  818. } else if(strstr(trim($VAL->Type), 'enum(') && strstr(trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type), 'enum(' )) { //jezeli zmienia sie ENUM na inne ENUM
  819. preg_match('/^enum\((.*)\)$/', trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type), $src_char_len);
  820. preg_match('/^enum\((.*)\)$/', trim($VAL->Type), $dst_char_len);
  821. $src_char_len=explode(',', $src_char_len[1]);$dst_char_len=explode(',', $dst_char_len[1]);
  822. foreach($src_char_len as $var) {
  823. if( !in_array($var, $dst_char_len)) $dst_char_len[]=$var;
  824. }
  825. $dst_char_len="enum(".implode(",", $dst_char_len).")";
  826. $sql=" alter table \"".$TABLE."\" CHANGE \"".$FIELD_TO_CHK."\" \"".$FIELD_TO_CHK."\" ".$dst_char_len." ; ";
  827. DEBUG_S(-3,'Uzupelniamy strukture o ewentualnie brakujace elementy (sql,wynik polaczenia,import.strukt.,akt_strukt.)',array($sql,$dst_char_len,$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type,$VAL->Type),__FILE__, __FUNCTION__, __LINE__);
  828. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die('\nProblem z '.$sql);
  829. } else if(strstr(trim($VAL->Type), 'set(') && strstr(trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type), 'set(' )) { //jezeli zmienia sie ENUM na inne ENUM
  830. preg_match('/^set\((.*)\)$/', trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type), $src_char_len);
  831. preg_match('/^set\((.*)\)$/', trim($VAL->Type), $dst_char_len);
  832. $src_char_len=explode(',', $src_char_len[1]);$dst_char_len=explode(',', $dst_char_len[1]);
  833. foreach($src_char_len as $var) {
  834. if( !in_array($var, $dst_char_len)) $dst_char_len[]=$var;
  835. }
  836. $dst_char_len="set(".implode(",", $dst_char_len).")";
  837. $sql=" alter table \"".$TABLE."\" CHANGE \"".$FIELD_TO_CHK."\" \"".$FIELD_TO_CHK."\" ".$dst_char_len." ; ";
  838. DEBUG_S(-3,'Uzupelniamy strukture o ewentualnie brakujace elementy (sql,wynik polaczenia,import.strukt.,akt_strukt.)',array($sql,$dst_char_len,$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type,$VAL->Type),__FILE__, __FUNCTION__, __LINE__);
  839. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die('\nProblem z '.$sql);
  840. } else if(strstr(trim($VAL->Type), 'int(') && strstr(trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type), 'int(' )) {
  841. DEBUG_S(-3,'Te same typy INT',array($VAL->Type,$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type),__FILE__,__FUNCTION__,__LINE__);
  842. preg_match('/^int\((.*)\)$/', $ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type, $src_char_len);
  843. preg_match('/^int\((.*)\)$/', $VAL->Type, $dst_char_len);
  844. if($src_char_len[1]>$dst_char_len[1]) {
  845. $sql=" alter table \"".$TABLE."\" ALTER COLUMN \"".$FIELD_TO_CHK."\" type ".self::from_mysql_struct($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type)." ; ";
  846. DEBUG_S(-3,'Aktualizacja rozszerzajaca zakres pola INT ma byc ='.$src_char_len[1]." byla dest=".$dst_char_len[1] ,$sql,__FILE__, __FUNCTION__, __LINE__);
  847. // if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die('\nProblem z '.$sql);
  848. } else {
  849. DEBUG_S(-3,'Pominieta Aktualizacja zawiezajaca zakres pola INT ma byc ='.$src_char_len[1]." byla dest=".$dst_char_len[1] ,$sql,__FILE__, __FUNCTION__, __LINE__);
  850. }
  851. } else if( ( strstr(trim($VAL->Type), 'char(') || strstr(trim($VAL->Type), 'varchar(') ) && strstr(trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type), 'text' )
  852. || ( strstr(trim($VAL->Type), 'bigint(') ) && strstr(trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type), 'longblob' )
  853. || ( strstr(trim($VAL->Type), 'mediumtext') ) && strstr(trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type), 'longblob' )
  854. || ( strstr(trim($VAL->Type), 'decimal(42') ) && strstr(trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type), 'decimal(41' )
  855. || ( strstr(trim($VAL->Type), 'decimal(43') ) && strstr(trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type), 'decimal(41' )
  856. ) {
  857. $sql=" alter table \"".$TABLE."\" CHANGE \"".$FIELD_TO_CHK."\" \"".$FIELD_TO_CHK."\" ".$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type." ; ";
  858. DEBUG_S(-3,'Aktualizacja rozszerzajaca zakres pola varchar/char() do text()',$sql,__FILE__, __FUNCTION__, __LINE__);
  859. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die('\nProblem z '.$sql);
  860. // DEBUG_S(-3,'Pominieta Aktualizacja zawiezajaca zakres pola INT ma byc ='.$src_char_len[1]." byla dest=".$dst_char_len[1] ,$sql,__FILE__, __FUNCTION__, __LINE__);
  861. } else {
  862. DEBUG_S(-3,'Celowe zabicie z uwagi na niebezpieczenstwo zmiany typu: sql/old/new',array($sql,$VAL->Type,$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type),__FILE__, __FUNCTION__, __LINE__);
  863. echo "<font color=red> DO AKTAULIZACJI PHP BO TO JEST BLAD PHP!!!</font>";
  864. continue;
  865. die();
  866. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die('\nProblem z '.$sql);
  867. }
  868. }
  869. if($VAL->Null!=$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Null)
  870. if($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Null=='YES') {
  871. $sql=" alter table `".$TABLE."` CHANGE `".$FIELD_TO_CHK."` `".$FIELD_TO_CHK."` ".$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type." NULL ; ";
  872. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL ',$sql,__FILE__, __FUNCTION__, __LINE__) or DIE();
  873. } else {
  874. $sql=" alter table `".$TABLE."` CHANGE `".$FIELD_TO_CHK."` `".$FIELD_TO_CHK."` ".$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type." NOT NULL ; ";
  875. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL ',$sql,__FILE__, __FUNCTION__, __LINE__) or DIE();
  876. }
  877. if($VAL->Default!=$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Default) {
  878. if($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Default=='CURRENT_TIMESTAMP')
  879. $sql=" alter table `".$TABLE."` CHANGE `".$FIELD_TO_CHK."` `".$FIELD_TO_CHK."` ".$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type." DEFAULT ".str_replace("'","",$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Default)." ; ";
  880. else if(empty($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Default))
  881. $sql=" alter table `".$TABLE."` CHANGE `".$FIELD_TO_CHK."` `".$FIELD_TO_CHK."` ".$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type." ; ";
  882. else $sql=" alter table `".$TABLE."` CHANGE `".$FIELD_TO_CHK."` `".$FIELD_TO_CHK."` ".$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type." DEFAULT '".$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Default."' ; ";
  883. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL ',$sql,__FILE__, __FUNCTION__, __LINE__) or DIE();
  884. }
  885. //autoincrement:
  886. if(in_array('SKIP-PRIMARY-KEY', $options)) {
  887. DEBUG_S(4,'SKIP-PRIMARY-KEY option',null,__FILE__,__FUNCTION__,__LINE__);
  888. } else if((trim($VAL->Extra)!=trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Extra))&&trim($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Extra)=='auto_increment' ) {
  889. //sprawdzmy czy nie ma w tabeli klucza z PRIMARY z ID
  890. //$sql="show keys from `".$TABLE."`";
  891. //$result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL ',$sql,__FILE__, __FUNCTION__, __LINE__) or DIE();
  892. $result=self::show_index($TABLE);
  893. $TEST_IF_HAS_PRIMARY=false;
  894. while($tst=self::fetch($result)) { //dla kazdego klucza
  895. if(trim($tst->Column_name)==$FIELD_TO_CHK) //sprawdz czy jest klucz do tej kolumny
  896. if(trim($tst->Key_name)=='PRIMARY') $TEST_IF_HAS_PRIMARY=true; //jezeli jest primary, to flagujemy
  897. }
  898. if($TEST_IF_HAS_PRIMARY==false) { //bedziemy dodawac primary key
  899. $sql="ALTER TABLE \"".$TABLE."\" ADD PRIMARY KEY ( \"".$FIELD_TO_CHK."\" )";
  900. $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL ',$sql,__FILE__, __FUNCTION__, __LINE__) or DIE();
  901. }
  902. $sql=" alter table \"".$TABLE."\" ALTER COLUMN \"".$FIELD_TO_CHK."\" TYPE ".$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Type." ".$ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE]->Extra." ; ";
  903. echo "\n SQL auto_increment ".$sql ;
  904. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL ',$sql,__FILE__, __FUNCTION__, __LINE__) or DIE();
  905. }
  906. //foreach($ARR_TABLE['FIELDS'][$INDEX_OF_CONFIG_TABLE] as $TST_FIELD_IND=>$TST_FIELD_VAL) {
  907. // echo "\n TST2 ".$TST_FIELD_IND." ?= ".$FIELDS_CHECKED['FIELD_FOUND_IN_REMOTE_DB_PROFILE'][$TST_FIELD_IND]->$TST_FIELD_IND;
  908. //}
  909. }
  910. //print_r($FIELDS_CHECKED);
  911. /* TODO to implement to postgressql!!!
  912. $sql=" show index from `".$TABLE."` ;" ;
  913. echo "\n ".$sql;
  914. $result=$this->query($sql) or die('\nProblem z '.$sql);
  915. while($h=mysql_fetch_object($result)) {
  916. set_time_limit(36000);
  917. $FIELDS_CHECKED['INDEX_FOUND_IN_TABLES'][$h->Key_name]=$h;
  918. }
  919. foreach($ARR_TABLE['INDEX'] as $FOUND_INDEX_NAME=>$FOUND_INDEX_ARR){
  920. $FIELDS_CHECKED['INDEX_TO_BE_FOUND_IN_TABLES'][$FOUND_INDEX_NAME]=$FOUND_INDEX_ARR;
  921. }
  922. DEBUG_S(-3,'Znaleziono indeksy w tabeli '.$TABLE." FOUND/TO_BE_FOUND",array($FIELDS_CHECKED['INDEX_FOUND_IN_TABLES'],$FIELDS_CHECKED['INDEX_TO_BE_FOUND_IN_TABLES']),__FILE__, __FUNCTION__, __LINE__);
  923. //teraz wygaszam znalezione indeksy
  924. foreach($ARR_TABLE['INDEX'] as $FOUND_INDEX_NAME=>$FOUND_INDEX_ARR){
  925. echo "\n If jest ".$FOUND_INDEX_NAME;
  926. if(isset($FIELDS_CHECKED['INDEX_FOUND_IN_TABLES'][$FOUND_INDEX_NAME]))
  927. unset($FIELDS_CHECKED['INDEX_TO_BE_FOUND_IN_TABLES'][$FOUND_INDEX_NAME]);
  928. }
  929. //print_r($FIELDS_CHECKED['INDEX_TO_BE_FOUND_IN_TABLES']);
  930. //brakujace klucze dodajemy
  931. foreach($FIELDS_CHECKED['INDEX_TO_BE_FOUND_IN_TABLES'] as $FOUND_INDEX_NAME=>$FOUND_INDEX_ARR) {
  932. if($FOUND_INDEX_NAME=='PRIMARY') {
  933. $FOUND_INDEX_ARR->Column_name=str_replace('`','',$FOUND_INDEX_ARR->Column_name);
  934. $sql="ALTER TABLE `".$TABLE."` ADD PRIMARY KEY ( `".$FOUND_INDEX_ARR->Column_name."` ) ;";
  935. echo "\n 927: ".$sql;
  936. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or print_r($FIELDS_CHECKED) && die('\nProblem z '.$sql);
  937. $sql="ALTER TABLE `".$TABLE."` CHANGE `".$FOUND_INDEX_ARR->Column_name."` `".$FOUND_INDEX_ARR->Column_name."` ".$FIELDS_CHECKED['FIELD_FOUND_IN_REMOTE_DB_PROFILE'][$FOUND_INDEX_ARR->Column_name]->Type." AUTO_INCREMENT ; ";
  938. echo "\n ".$sql;
  939. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or print_r($FIELDS_CHECKED) && die('\nProblem z '.$sql);
  940. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or print_r($FIELDS_CHECKED) && die('\nProblem z '.$sql);
  941. } else if($FOUND_INDEX_ARR->Non_unique==1) {
  942. $sql="ALTER TABLE `".$TABLE."` ADD KEY `".$FOUND_INDEX_ARR->Key_name."` ( ".$FOUND_INDEX_ARR->Column_name." ) ;" ;
  943. echo "\n ".$sql;
  944. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die();
  945. } else {
  946. set_time_limit(36000);
  947. //@2013-01-17 poprawka do kluczy bledu w stylu ALTER TABLE `IN7_PRODUKTY_CECHY` ADD UNIQUE `UNIK_CECHY_PRODUKTU` ( CECHA_ID, PRODUKT_ID , DESC ) ;
  948. $CORRECT_INDEX_FOUNDKEY="";
  949. if(!strstr($FOUND_INDEX_ARR->Column_name,'`')) {
  950. $explode=explode(' ',$FOUND_INDEX_ARR->Column_name);
  951. foreach($explode as $exploded) {
  952. $exploded=str_replace(',','',$exploded); //wywalenie przecinkow
  953. if((!strstr($exploded,' '))&&(strlen($exploded)>1))
  954. if($CORRECT_INDEX_FOUNDKEY) $CORRECT_INDEX_FOUNDKEY.=" , `".$exploded."` ";
  955. else $CORRECT_INDEX_FOUNDKEY.=" `".$exploded."` ";
  956. }
  957. } else $CORRECT_INDEX_FOUNDKEY=$FOUND_INDEX_ARR->Column_name;
  958. // $CORRECT_INDEX_FOUNDKEY=$FOUND_INDEX_ARR->Column_name;
  959. $sql="ALTER TABLE `".$TABLE."` ADD UNIQUE `".$FOUND_INDEX_ARR->Key_name."` ( ".$CORRECT_INDEX_FOUNDKEY." ) ;" ;
  960. echo "\n ".$sql;
  961. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die();
  962. }
  963. }
  964. flush();
  965. //print_r($FIELDS_CHECKED);
  966. unset($FIELDS_CHECKED);
  967. $sql=" show triggers like '".$TABLE."' ;" ; //listujemy nasze triggery z tej tabeli
  968. DEBUG_S(-3,'Looking for triggers in '.$TABLE,$sql,__FILE__,__FUNCTION__,__LINE__);
  969. $result=$this->query($sql) or die('\nProblem z '.$sql);
  970. while($h=mysql_fetch_object($result)) {
  971. set_time_limit(36000);
  972. $sql_="show create trigger {$h->Trigger} ;" ;
  973. //echo $sql_;
  974. $result_=$this->query($sql_) or die('\nProblem z '.$sql_);
  975. while($h_=mysql_fetch_object($result_)) {
  976. $FIELDS_CHECKED['TRIGGER_FOUNDS'][$h->Trigger]=$h_;
  977. if(!isset($ARR_TABLE['TRIGGERS'][$h->Trigger])) $FIELDS_CHECKED['TRIGGER_TO_DELETE'][$h->Trigger]=$h_;
  978. }
  979. }
  980. DEBUG_S(-3,'Try to unserialize trigger and install to db:',$ARR_TABLE['TRIGGERS'],__FILE__,__FUNCTION__,__LINE__);
  981. //! try to synchronize triggers $TABLE=>$ARR_TABLE
  982. foreach($ARR_TABLE['TRIGGERS'] as $TRIGGER_INDEX=>$TRIGGER_OBJECT) {
  983. if(!isset($FIELDS_CHECKED['TRIGGER_FOUNDS'][$TRIGGER_INDEX])) $FIELDS_CHECKED['TRIGGER_TO_CREATE'][$TRIGGER_INDEX]=$TRIGGER_OBJECT;
  984. }
  985. //staramy sie zaktualizowac stare triggery, pod warunkiem, ze sie roznia
  986. foreach($FIELDS_CHECKED['TRIGGER_FOUNDS'] as $TRIGGER_INDEX=>$TRIGGER_OBJECT) {
  987. DEBUG_S(-3,'TRIGGER_OBJECT/$TRIGGER_OBJECT for '.$TRIGGER_INDEX,array($TRIGGER_OBJECT,$ARR_TABLE['TRIGGERS'][$TRIGGER_INDEX]),__FILE__, __FUNCTION__, __LINE__);
  988. if(isset($ARR_TABLE['TRIGGERS'][$TRIGGER_INDEX])) //we first try to find if this trigger exists or delete it
  989. if($TRIGGER_OBJECT->{'SQL Original Statement'}<>$ARR_TABLE['TRIGGERS'][$TRIGGER_INDEX]->{'SQL Original Statement'} ) {
  990. DEBUG_S(-3,"Triggers are different ({$TRIGGER_INDEX}). We add object to be created as new.",__FILE__, __FUNCTION__, __LINE__);
  991. $FIELDS_CHECKED['TRIGGER_TO_CREATE'][$TRIGGER_INDEX]=$ARR_TABLE['TRIGGERS'][$TRIGGER_INDEX];
  992. $FIELDS_CHECKED['TRIGGER_TO_DELETE'][$TRIGGER_INDEX]=true;
  993. }
  994. }
  995. if(isset($FIELDS_CHECKED['TRIGGER_TO_DELETE'])) {
  996. DEBUG_S(-3,'We have some triggers to delete',$FIELDS_CHECKED['TRIGGER_TO_DELETE'],__FILE__,__FUNCTION__,__LINE__);
  997. foreach($FIELDS_CHECKED['TRIGGER_TO_DELETE'] as $TRIGGER_INDEX=>$TRIGGER_OBJECT ) {
  998. $sql="DROP TRIGGER IF EXISTS `{$TRIGGER_INDEX}`; ";
  999. DEBUG_S(-3,' sql to delete trigger '.$TRIGGER_INDEX,$sql,__FILE__,__FUNCTION__,__LINE__);
  1000. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die();
  1001. }
  1002. }
  1003. //tworzymy brakujace procedury
  1004. foreach ($FIELDS_CHECKED['TRIGGER_TO_CREATE'] as $TRIGGER_INDEX=>$TRIGGER_OBJECT) {
  1005. //$sql="DROP TRIGGER IF EXISTS `{$TRIGGER_INDEX}`; ";
  1006. //DEBUG_S(-3,'Delete old trigger '.$TRIGGER_INDEX,$sql,__FILE__,__FUNCTION__,__LINE__);
  1007. //if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',array($sql,mysql_error() ),__FILE__, __FUNCTION__, __LINE__) or die();
  1008. //if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query("show create trigger {$TRIGGER_INDEX}") or DEBUG_S(-3,'Problem ze SQL:'.mysql_error(),$sql,__FILE__, __FUNCTION__, __LINE__) or die();
  1009. $sql=$TRIGGER_OBJECT->{'SQL Original Statement'};
  1010. DEBUG_S(-3,'Try to add new trigger '.$TRIGGER_INDEX,$sql,__FILE__,__FUNCTION__,__LINE__);
  1011. if(!empty($CONFIRM_SQL_UPDATE)) $result=$this->query($sql) or DEBUG_S(-3,'Problem ze SQL:',$sql,__FILE__, __FUNCTION__, __LINE__) or die();
  1012. }
  1013. */
  1014. }
  1015. //tu bedziemy dodawac wartosci insert :
  1016. if(!strstr($TABLE, '__SCHEMA_FUNCTIONS__ARRAY__')) {
  1017. $sql="select count(*) as ilosc from \"".$TABLE."\" ;" ;
  1018. DEBUG_S(-3,'SQL: licze czy cos jest w tabeli ',$sql,__FILE__, __FUNCTION__, __LINE__) ;
  1019. $result=$this->query($sql) or die('\nProblem z '.$sql);
  1020. $ilosc=0;
  1021. //while($h=mysql_fetch_object($result)) {
  1022. // $ilosc=$h->ilosc;
  1023. //}
  1024. //if($ilosc>0) {
  1025. // DEBUG_S(-2,'Nie trzeba dodawac rekordow - juz jakies sa w tabeli: ilosc : ',$ilosc,__FILE__,__FUNCTION__,__LINE__);
  1026. // continue ;
  1027. //} else {
  1028. if(!empty($ARR_TABLE['VALUES']))
  1029. foreach($ARR_TABLE['VALUES'] as $ROW) {
  1030. $sql="insert ignore into `".$TABLE."` values ( ";
  1031. $vals="";
  1032. foreach($ROW as $FIELD=>$VAL) {
  1033. if(!$vals) $vals.="'".$VAL."'" ; else $vals.=" , '".$VAL."' ";
  1034. }
  1035. $sql.=$vals." ) ;";
  1036. if(!empty($CONFIRM_SQL_UPDATE)) $this->query($sql) or die('\nProblem z '.$sql);
  1037. DEBUG_S(-3,'Dodanie rekordu do tabeli ',$sql,__FILE__,__FUNCTION__,__LINE__);
  1038. }
  1039. //}
  1040. }
  1041. }
  1042. //}
  1043. DEBUG_S(-3,'function in devel',$array,__FILE__,__FUNCTION__,__LINE__);
  1044. }
  1045. function SHOW_TABLE_STATUS_LIKE($table) {
  1046. $return['engine']='default';
  1047. $res=$this->query("SELECT pg_class.relname, pg_attribute.attname
  1048. FROM pg_class, pg_attribute, pg_index
  1049. WHERE pg_class.oid = pg_attribute.attrelid AND
  1050. pg_class.oid = pg_index.indrelid AND
  1051. pg_index.indkey[0] = pg_attribute.attnum AND
  1052. pg_index.indisprimary = 't'
  1053. and pg_class.relname='".$table."';");
  1054. $record=$this->fetch_assoc($res);
  1055. $return['primary']=$record['attname'];
  1056. $sql='select max("'.$return['primary'].'")+1 as max from "'.$table.'";';
  1057. $res=$this->query($sql);
  1058. $record=$this->fetch_assoc($res);
  1059. $return['Auto_increment']=$record['max'];
  1060. return $return;
  1061. }
  1062. function affected_rows($res) {
  1063. return pg_affected_rows( $res );
  1064. }
  1065. function _( $str ) {
  1066. return pg_escape_string( $str);
  1067. }
  1068. function error() {
  1069. return "#".pg_result_error_field($this->_conn).": ".pg_result_error($this->_conn);
  1070. }
  1071. function get_by_id( $table, $id ) {
  1072. $primary=self::show_index_value($table); //TODO to optimalize cache
  1073. $null = null;
  1074. $sql = "select p.*
  1075. from \"".$table."\" as p
  1076. where p.\"".$primary."\"='".$id."'
  1077. ";
  1078. $res = $this->query( $sql );
  1079. if ($r = $this->fetch( $res )) {
  1080. return $r;
  1081. }
  1082. return $null;
  1083. }
  1084. /**
  1085. * @returns int
  1086. * 1 - changed but without add hist
  1087. * 2 - changed and add hist
  1088. * 0 - nothing to change
  1089. * -1 - sql errors
  1090. * -2 - error id not exists in DB
  1091. * -3 - error ID not set
  1092. *
  1093. * TODO: sprawdzac czy w hist mozna odczytac aktualny stan, jesli nie to dodac caly rekord do HIST, jako 'procesy-fix-hist-data'
  1094. */
  1095. public function UPDATE_OBJ($table, $sql_obj,$timestamp=null) {
  1096. $structure=self::describe_table_value($table);
  1097. $primary=self::show_index_value($table);
  1098. if (!isset($sql_obj->$primary) || $sql_obj->$primary <= 0) {
  1099. return -3;
  1100. }
  1101. $id = $sql_obj->$primary;
  1102. // check id record $id exists
  1103. if (($curr_obj = $this->get_by_id( $table, $sql_obj->$primary )) == null) {
  1104. return -2;
  1105. }
  1106. // check if enything changed
  1107. $changed = false;
  1108. $fields_to_change = get_object_vars($sql_obj);
  1109. //DEBUG_S(-3,'chk',array($fields_to_change),__FILE__,__FUNCTION__,__LINE__);
  1110. foreach ($fields_to_change as $k => $v) {
  1111. if ($k == $primary) continue;
  1112. if ($v == $curr_obj->$k) {// === ?
  1113. unset($sql_obj->$k);
  1114. } else {
  1115. $changed = true;
  1116. }
  1117. }
  1118. if ($changed == false) {
  1119. return 0;// record not changed
  1120. }
  1121. $sql_arr = array();
  1122. // TODO: add admin columns if exists in table - search in session
  1123. $admin_col = array();
  1124. $admin_col []= 'A_RECORD_CREATE_DATE';
  1125. $admin_col []= 'A_RECORD_CREATE_AUTHOR';
  1126. // ...
  1127. // $sql_obj->A_RECORD_UPDATE_DATE = date('Y-m-d H:i');
  1128. if(!empty($timestamp)) //fixed timestamp option TODO @2015-01-not working due to trigger?
  1129. $sql_obj->A_RECORD_UPDATE_DATE = $timestamp;
  1130. else
  1131. $sql_obj->A_RECORD_UPDATE_DATE = self::get_current_timestamp();
  1132. $sql_obj->A_RECORD_UPDATE_AUTHOR = User::getName();
  1133. foreach (get_object_vars($sql_obj) as $k => $v) {
  1134. if($k=='A_RECORD_CREATE_DATE'&& $v=='0000-00-00 00:00:00') {
  1135. unset($k);
  1136. unset($v);
  1137. continue;
  1138. } else if(strstr(trim($structure[$k]->Type),'date') && (strstr($v,'-00'))) {
  1139. $v="'".str_replace("-00","-01",$v)."'" ;
  1140. } else if(strstr(trim($structure[$k]->Type),'date') && (strstr($v,'0000'))) {
  1141. $v="'".str_replace("0000","1970",$v)."'" ;
  1142. } else if (substr($v, 0, strlen('ST_GeomFromText')) == 'ST_GeomFromText') {
  1143. } else if (strtoupper($v) == 'NOW()') {
  1144. $v = 'NOW()';
  1145. } else if (strtoupper($v) == 'NULL') {
  1146. $v = 'NULL';
  1147. } else {
  1148. $v = $this->_($v);
  1149. $v = "'{$v}'";
  1150. }
  1151. $sql_arr [] = '"'.$k.'"='.$v;
  1152. }
  1153. $sql = "update \"{$table}\" set ".implode(",", $sql_arr)." where \"".$primary."\"='{$id}' ; ";
  1154. // DEBUG_S(-3,'update',array($sql),__FILE__,__FUNCTION__,__LINE__);
  1155. // die();
  1156. $res=$this->query($sql);
  1157. if ($this->has_errors()) {
  1158. //DEBUG_S(-3,'errors',$this->has_errors,__FILE__,__FUNCTION__,__LINE__);
  1159. return -1;
  1160. }
  1161. $ret = $this->affected_rows($res);
  1162. // DEBUG_S(-3,'affected',$ret,__FILE__,__FUNCTION__,__LINE__);
  1163. if ($ret) {
  1164. $sql_obj->ID_USERS2 = $sql_obj->$primary;
  1165. unset($sql_obj->$primary);
  1166. $new_id = $this->ADD_NEW_OBJ("{$table}_HIST", $sql_obj);
  1167. if ($new_id) {
  1168. $ret += 1;
  1169. }
  1170. }
  1171. return $ret;
  1172. }
  1173. function ADD_NEW_OBJ( $table, $sql_obj,$dieonerror=null ) {
  1174. $structure=self::describe_table_value($table);
  1175. $primary=self::show_index_value($table);
  1176. $sql_arr = array();
  1177. // TODO: add admin columns if exists in table - search in session
  1178. $admin_col = array();
  1179. $admin_col []= 'A_RECORD_CREATE_DATE';
  1180. $admin_col []= 'A_RECORD_CREATE_AUTHOR';
  1181. $admin_col []= 'A_RECORD_UPDATE_DATE';
  1182. $admin_col []= 'A_RECORD_UPDATE_AUTHOR';
  1183. // ...
  1184. if (substr($table, 0, -5) == '_HIST') {
  1185. $sql_obj->A_RECORD_UPDATE_DATE = date('Y-m-d H:i');
  1186. $sql_obj->A_RECORD_UPDATE_AUTHOR = User::getName();
  1187. } else {
  1188. $sql_obj->A_RECORD_CREATE_DATE = date('Y-m-d H:i');
  1189. $sql_obj->A_RECORD_CREATE_AUTHOR = User::getName();
  1190. }
  1191. foreach (get_object_vars($sql_obj) as $k => $v) {
  1192. if($k==$primary) {
  1193. unset($k);
  1194. unset($v);
  1195. continue;
  1196. } else if (substr($v, 0, strlen('ST_GeomFromText')) == 'ST_GeomFromText') {
  1197. } else if(strstr(trim($structure[$k]->Type),'int')) {
  1198. if(strlen($v)>0) {
  1199. $v=$v;
  1200. } else if(empty($v)) $v='null';
  1201. else $v = $v;
  1202. } else if(trim($structure[$k]->Type)=='datetime') {
  1203. if(empty($v)) $v='null';
  1204. else if(strstr($v,'-00')) $v="'".str_replace("-00","-01",$v)."'" ;
  1205. else $v = "'".$v."'::timestamp";
  1206. } else if(trim($structure[$k]->Type)=='date') {
  1207. if($v=='0000-00-00') $v='null';
  1208. else if(strstr($v,'-00')) $v="'".str_replace("-00","-01",$v)."'" ;
  1209. else $v = "'".$v."'";
  1210. } else if (strtoupper($v) == 'NOW()') {
  1211. $v = 'NOW()';
  1212. } else if (strtoupper($v) == 'NULL' && substr($table, -5) != '_HIST') {
  1213. $v = 'NULL';
  1214. } else if(strstr($structure[$k]->Type,'int(')) {
  1215. $v = $v ;
  1216. } else {
  1217. $v = $this->_($v);
  1218. $v = "'{$v}'";
  1219. }
  1220. $sql_arr ['"'.$k.'"'] = $v;
  1221. }
  1222. $sql = "insert into \"{$table}\" (".implode(",", array_keys($sql_arr)).") values (".implode(",", array_values($sql_arr))."); ";
  1223. //DEBUG_S(-3,' insert sql ',$sql,__FILE__,__FUNCTION__,__LINE__);
  1224. $this->query($sql);
  1225. if ($this->has_errors()) {
  1226. if($dieonerror) {
  1227. DEBUG_S(-3,'Has errors died',$this->get_errors(),__FILE__,__FUNCTION__,__LINE__);
  1228. die();
  1229. }
  1230. // echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">db errors: (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($this->get_errors());print_r($sql);echo'</pre>';
  1231. }
  1232. $ret_id = $this->insert_id();
  1233. if (substr($table, -5) == '_HIST') {
  1234. return $ret_id;
  1235. }
  1236. if ($ret_id) {
  1237. $sql_obj->ID_USERS2 = $ret_id;
  1238. unset($sql_obj->ID);
  1239. $new_id_hist = $this->ADD_NEW_OBJ($table . '_HIST', $sql_obj);
  1240. // error jesli nie udalo sie dodac rekordu do tabeli _HIST
  1241. }
  1242. return $ret_id;
  1243. }
  1244. function MAKE_SE_AND_HIST_FIELDS_FOR_TABLE($table){
  1245. $primary=self::show_index_value($table);
  1246. //TODO @2014-10-01 zrobic tabele z autoincrement + hist
  1247. //die('function incomplete');
  1248. //$sql="show tables like '".$table."';";
  1249. DEBUG_S(-3,'primary detected ',array($sql,$primary),__FILE__,__FUNCTION__,__LINE__);
  1250. $USERS_COLUMN_INIT2['REQUEST_COLUMN']=array(
  1251. 'A_RECORD_CREATE_DATE'=>'datetime','A_RECORD_CREATE_AUTHOR'=>'varchar(100)','SYNC_SQIX_STATUS'=>'varchar(100) ',
  1252. 'A_RECORD_UPDATE_DATE'=>'datetime','A_RECORD_UPDATE_AUTHOR'=>'varchar(100) ',
  1253. 'L_APPOITMENT_DATE'=>'varchar(30) ',
  1254. 'L_APPOITMENT_USER'=>"varchar(100) ",
  1255. 'L_APPOITMENT_PERIOD'=>"varchar(4) ",
  1256. 'L_APPOITMENT_INFO'=>"varchar(255) ",
  1257. 'L_APPOITMENT_TYPE'=>"enum('', 'ARRANGED', 'TO_ARRANGE', 'CANCELLED', 'TO_CANCEL', 'RELATE', 'WAIT')",
  1258. 'A_STATUS'=>"enum('WAITING', 'NORMAL', 'MONITOR', 'WARNING', 'OFF_SOFT', 'OFF_HARD', 'DELETED')",
  1259. 'A_STATUS_INFO'=>"varchar(255) ",
  1260. 'A_ADM_COMPANY'=>'varchar(100) ','A_CLASSIFIED'=>'varchar(100) '
  1261. );
  1262. //DEBUG_S(-3,'zapytanie',$sql,__FILE__,__FUNCTION__,__LINE__);
  1263. //$result=self::query($sql) or die1(' Problem ze sql '.$sql);
  1264. $result=self::show_tables($table);
  1265. while($h=self::fetch_array($result)) {
  1266. $res=self::show_tables($h[0].'_HIST');
  1267. if(self::num_rows($res)==0) {
  1268. //$CONNLOCAL->query($sql)
  1269. $sql='create table IF NOT EXISTS "'.$h[0].'_HIST"(
  1270. "ID" SERIAL PRIMARY KEY,
  1271. "ID_USERS2" integer NOT NULL,
  1272. "_action_time" timestamp without time zone,
  1273. "_action_type" character varying(16)
  1274. )';
  1275. DEBUG_S(-3,'create table hist '.$h[0],array($sql),__FILE__,__FUNCTION__,__LINE__);
  1276. $rescr=self::query($sql) or die1(' Problem ze sql '.$sql);
  1277. $sql=' CREATE INDEX "'.$h[0].'_ID_USERS2_index" ON "'.$h[0].'_HIST" ("ID_USERS2")';
  1278. $rescr=self::query($sql) or die1(' Problem ze sql '.$sql);
  1279. } else DEBUG_S(-3,'Histable '.$h[0].'_HIST existied',null,__FILE__,__FUNCTION__,__LINE__);
  1280. //kolumny z bazy istniejace
  1281. // $sql_="describe `".$h[0]."`";
  1282. // $result_=self::query($sql_) or die1(' Problem ze sql '.$sql_);
  1283. $result_=self::describe_table($table);
  1284. $result__=self::describe_table($table."_HIST");
  1285. while($h__=self::fetch($result__)) {
  1286. $hist_exists[$h__->Field]=true;
  1287. }
  1288. while($h_=self::fetch($result_)) {
  1289. $table_exists[$h_->Field]=true;
  1290. if(empty($hist_exists[$h_->Field])) {
  1291. DEBUG_S(-3,'dane z tabeli',$h_,__FILE__,__FUNCTION__,__LINE__);
  1292. //$sql="\n alter table \"".$h[0]."_HIST\" add \"".$h_->Field."\" ; " ;
  1293. //self::query($sql) or DEBUG_S(-3,' Problem ze sql '.$sql,array($sql),__FILE__,__FUNCTION__,__LINE__);
  1294. self::alter_add_struct($table."_HIST",$h_->Field," text default 'N/S;'");
  1295. $hist_exists[$h_->Field]=true;
  1296. }
  1297. }
  1298. foreach($USERS_COLUMN_INIT2['REQUEST_COLUMN'] as $tst_column=>$tst_type) {
  1299. if(empty($table_exists[$tst_column])) {
  1300. //$sql="\n alter table \"".$h[0]."\" add \"".$tst_column."\" ".$tst_type." ; " ;
  1301. //self::query($sql) or DEBUG_S(-3,' Problem ze sql '.$sql,array($sql),__FILE__,__FUNCTION__,__LINE__);
  1302. self::alter_add_struct($table,$tst_column,$tst_type);
  1303. if(empty($hist_exists[$tst_column])) {
  1304. // $sql="\n alter table \"".$h[0]."_HIST\" add \"".$tst_column."\" char(255) default 'N/S;' ; " ;
  1305. // self::query($sql) or DEBUG_S(-3,' Problem ze sql '.$sql,array($sql),__FILE__,__FUNCTION__,__LINE__);
  1306. self::alter_add_struct($table."_HIST",$tst_column,'char(255) default \'N/S;\'');
  1307. $hist_exists[$tst_column]=true;
  1308. }
  1309. }
  1310. }
  1311. }
  1312. //Auto trigger funciton for history and edits
  1313. $sql = '
  1314. CREATE OR REPLACE FUNCTION "'.$table.'_HIST_func"() RETURNS TRIGGER AS $body$
  1315. DECLARE
  1316. v_old_data TEXT;
  1317. v_new_data TEXT;
  1318. v_currval INT;
  1319. BEGIN
  1320. /* If this actually for real auditing (where you need to log EVERY action),
  1321. then you would need to use something like dblink or plperl that could log outside the transaction,
  1322. regardless of whether the transaction committed or rolled back.
  1323. */
  1324. /* This dance with casting the NEW and OLD values to a ROW is not necessary in pg 9.0+ */
  1325. IF (TG_OP = \'UPDATE\') THEN
  1326. v_old_data := ROW(OLD.*);
  1327. v_new_data := ROW(NEW.*);
  1328. INSERT INTO "'.$table.'_HIST" ("ID_USERS2","_action_time","A_RECORD_UPDATE_AUTHOR","_action_type")
  1329. VALUES (NEW.'.$primary.',now(),session_user::TEXT,TG_OP);
  1330. v_currval := currval(\'"'.$table.'_HIST_ID_seq"\');
  1331. ';
  1332. foreach($hist_exists as $column=>$true) {
  1333. if($column=='ID') continue;
  1334. if($column=='ID_USERS2') continue;
  1335. if($column=='A_RECORD_UPDATE_AUTHOR') continue;
  1336. if($column=='A_RECORD_UPDATE_DATE') continue;
  1337. if($column=='A_RECORD_CREATE_DATE') continue;
  1338. if($column=='A_RECORD_CREATE_AUTHOR') continue;
  1339. if($column=='_action_time') continue;
  1340. if($column=='_action_type') continue;
  1341. $sql.='
  1342. IF cast(ROW(OLD."'.$column.'")as text)!=cast(ROW(NEW."'.$column.'")as text) THEN
  1343. UPDATE "'.$table.'_HIST" set "'.$column.'"=NEW."'.$column.'" where "ID"=v_currval;
  1344. -- ELSE
  1345. -- UPDATE "'.$table.'_HIST" set "'.$column.'"=\'N/S;\' where "ID"=v_currval;
  1346. END IF;
  1347. ';
  1348. }
  1349. $sql.='
  1350. -- UPDATE "'.$table.'" set "A_RECORD_UPDATE_DATE"=now(), "A_RECORD_UPDATE_AUTHOR"=session_user::TEXT where "'.$primary.'"=NEW."'.$primary.'";
  1351. RETURN NEW;
  1352. ELSIF (TG_OP = \'INSERT\') THEN
  1353. v_new_data := ROW(NEW.*);
  1354. END IF;
  1355. END;
  1356. $body$
  1357. LANGUAGE plpgsql
  1358. SECURITY DEFINER
  1359. ';
  1360. DEBUG_S(-3,'Definied autohistory function',array($sql),__FILE__,__FUNCTION__,__LINE__);
  1361. self::query($sql) or die1($sql);
  1362. $res=self::show_create_trigger($table,$table.'_HIST_trigger');
  1363. if(self::num_rows($res)==0) {
  1364. $sql='CREATE TRIGGER "'.$table.'_HIST_trigger"
  1365. AFTER UPDATE ON "'.$table.'"
  1366. FOR EACH ROW EXECUTE PROCEDURE "'.$table.'_HIST_func"();';
  1367. DEBUG_S(-3,'Definied autohistory triggers',array($sql),__FILE__,__FUNCTION__,__LINE__);
  1368. self::query($sql) or die1($sql);
  1369. }
  1370. self::query("CREATE OR REPLACE FUNCTION update_A_RECORD_UPDATE_DATE_column()
  1371. RETURNS TRIGGER AS $$
  1372. BEGIN
  1373. NEW.\"A_RECORD_UPDATE_DATE\" = now() at time zone 'utc';
  1374. NEW.\"A_RECORD_UPDATE_AUTHOR\" = session_user::TEXT;
  1375. RETURN NEW;
  1376. END;
  1377. $$ language 'plpgsql';");
  1378. $res=self::show_create_trigger($table,'update_A_RECORD_UPDATE_DATE');
  1379. if(self::num_rows($res)==0) {
  1380. self::query("CREATE TRIGGER \"update_A_RECORD_UPDATE_DATE\" BEFORE UPDATE
  1381. ON \"".$table."\" FOR EACH ROW EXECUTE PROCEDURE
  1382. update_A_RECORD_UPDATE_DATE_column();");
  1383. }
  1384. self::query("CREATE OR REPLACE FUNCTION create_A_RECORD_UPDATE_DATE_column()
  1385. RETURNS TRIGGER AS $$
  1386. BEGIN
  1387. NEW.\"A_RECORD_CREATE_DATE\" = now() at time zone 'utc';
  1388. NEW.\"A_RECORD_CREATE_AUTHOR\" = session_user::TEXT;
  1389. RETURN NEW;
  1390. END;
  1391. $$ language 'plpgsql';");
  1392. $res=self::show_create_trigger($table,'create_A_RECORD_UPDATE_DATE');
  1393. if(self::num_rows($res)==0) {
  1394. self::query("CREATE TRIGGER \"create_A_RECORD_UPDATE_DATE\" BEFORE INSERT
  1395. ON \"".$table."\" FOR EACH ROW EXECUTE PROCEDURE
  1396. create_A_RECORD_UPDATE_DATE_column();");
  1397. }
  1398. //! IMPORT_SORT_DESC_INFO
  1399. }
  1400. }