Pgsql.php 82 KB

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