Pgsql.php 81 KB

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