Mssql.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. Lib::loadClass('Core_DataSource');
  3. class Core_DataSource_Mssql extends Core_DataSource {
  4. function __construct($host, $user, $password, $database, $names = '', $params = array()) {
  5. if ($names != '') {
  6. if (strtolower($names) == 'utf8') {
  7. $names = 'UTF-8';// @see http://stackoverflow.com/questions/1322421/php-sql-server-how-to-set-charset-for-connection
  8. }
  9. ini_set('mssql.charset', $names);
  10. }
  11. if (!empty($params['tdsver'])) {
  12. $tdsver = V::get('tdsver', '', $params);
  13. putenv("TDSVER={$tdsver}");
  14. }
  15. $this->_database_name = $database;
  16. $this->_conn = @mssql_connect($host, $user, $password);
  17. if (!is_resource($this->_conn)) {
  18. $this->_set_error('CREATE CONNECTION FAILED');
  19. return;
  20. }
  21. if (false === mssql_select_db($database, $this->_conn)) {
  22. $this->_set_error('SELECT DATABASE FAILED');
  23. return;
  24. }
  25. if ($names != '') {
  26. //$this->query(" SET NAMES '$names' ");
  27. }
  28. }
  29. function getConnection() {
  30. return $this->_conn;
  31. }
  32. function getVersion($version) {
  33. if (!$this->_version) {
  34. // TODO: get version sql
  35. }
  36. return $this->_version;
  37. }
  38. /**
  39. * Wykonuje podane zapytanie i zwraca wynik mssql_query().
  40. */
  41. function query($query, $msg = 'Query ERROR.') {
  42. $null = null;
  43. if (!$this->_conn) { return $null; }
  44. $res = mssql_query($query, $this->_conn);
  45. if (!$res) {
  46. $this->_set_error('SQL QUERY FAILED: ' . mssql_get_last_message());
  47. return $null;
  48. }
  49. return $res;
  50. }
  51. function fetch($res) {
  52. if (!is_resource($res)) return null;
  53. return mssql_fetch_object($res);
  54. }
  55. function fetch_row($res) {
  56. if (!is_resource($res)) return null;
  57. return mssql_fetch_row($res);
  58. }
  59. /**
  60. * Returns an associative array that corresponds to the fetched row and moves
  61. * the internal data pointer ahead. mysql_fetch_assoc() is equivalent to calling
  62. * mysql_fetch_array() with MYSQL_ASSOC for the optional second parameter.
  63. * It only returns an associative array.
  64. */
  65. function fetch_assoc($res) {
  66. $ret = null;
  67. if (!is_resource($res)) {
  68. return null;
  69. } else {
  70. $ret = mssql_fetch_assoc($res);
  71. }
  72. return $ret;
  73. }
  74. function fetch_array($res, $result_type = null) {
  75. if (!is_resource($res)) return null;
  76. return ($result_type)? mssql_fetch_array($res, $result_type) : mssql_fetch_array($res);
  77. }
  78. function count($res) {
  79. if (!is_resource($res)) return null;
  80. return mssql_num_rows($res);
  81. }
  82. function num_rows($res) {
  83. if (!is_resource($res)) return null;
  84. return mssql_num_rows($res);
  85. }
  86. function insert_id() {
  87. $id = 0;
  88. $res = $this->query("SELECT @@identity AS id");
  89. if ($row = $this->fetch_assoc($res)) {
  90. $id = $row["id"];
  91. }
  92. return $id;
  93. }
  94. function affected_rows() {
  95. return mssql_rows_affected($this->_conn);
  96. }
  97. function _($str) {
  98. //TODO: return mssql_real_escape_string($str, $this->_conn);
  99. return $str;
  100. }
  101. function error() {
  102. return "#".mssql_errno($this->_conn).": ".mssql_error($this->_conn);
  103. }
  104. function get_by_id( $table, $id ) {
  105. $null = null;
  106. $sql = "select p.*
  107. from `".$table."` as p
  108. where p.`ID`='".$id."'
  109. ";
  110. $res = $this->query( $sql );
  111. if ($r = $this->fetch( $res )) {
  112. return $r;
  113. }
  114. return $null;
  115. }
  116. /**
  117. * @returns int
  118. * 1 - changed but without add hist
  119. * 2 - changed and add hist
  120. * 0 - nothing to change
  121. * -1 - error ID not set
  122. * -2 - error id not exists in DB
  123. *
  124. * TODO: sprawdzac czy w hist mozna odczytac aktualny stan, jesli nie to dodac caly rekord do HIST, jako 'procesy-fix-hist-data'
  125. */
  126. function UPDATE_OBJ( $table, &$sql_obj ) {
  127. if (!isset($sql_obj->ID) || $sql_obj->ID <= 0) {
  128. return -1;
  129. }
  130. $id = $sql_obj->ID;
  131. // check id record $id exists
  132. if (($curr_obj = $this->get_by_id( $table, $sql_obj->ID )) == null) {
  133. return -2;
  134. }
  135. // check if enything changed
  136. $changed = false;
  137. $fields_to_change = get_object_vars($sql_obj);
  138. foreach ($fields_to_change as $k => $v) {
  139. if ($k == 'ID') continue;
  140. if ($v == $curr_obj->$k) {// === ?
  141. unset($sql_obj->$k);
  142. } else {
  143. $changed = true;
  144. }
  145. }
  146. if ($changed == false) {
  147. return 0;// record not changed
  148. }
  149. $sql_arr = array();
  150. // TODO: add admin columns if exists in table - search in session
  151. $admin_col = array();
  152. $admin_col []= 'A_RECORD_CREATE_DATE';
  153. $admin_col []= 'A_RECORD_CREATE_AUTHOR';
  154. // ...
  155. $sql_obj->A_RECORD_UPDATE_DATE = date('Y-m-d-H:i');
  156. $sql_obj->A_RECORD_UPDATE_AUTHOR = User::getName();
  157. foreach (get_object_vars($sql_obj) as $k => $v) {
  158. if (strtoupper($v) == 'NOW()') {
  159. $v = 'NOW()';
  160. } else if (strtoupper($v) == 'NULL') {
  161. $v = 'NULL';
  162. } else {
  163. $v = $this->_($v);
  164. $v = "'{$v}'";
  165. }
  166. $sql_arr [] = "`{$k}`={$v}";
  167. }
  168. $sql = "update `{$table}` set ".implode(",", $sql_arr)." where `ID`='{$id}' limit 1; ";
  169. $this->query($sql);
  170. if ($this->has_errors()) {
  171. //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());echo'</pre>';
  172. }
  173. $ret = $this->affected_rows();
  174. if ($ret) {
  175. $sql_obj->ID_USERS2 = $sql_obj->ID;
  176. unset($sql_obj->ID);
  177. $new_id = $this->ADD_NEW_OBJ("{$table}_HIST", $sql_obj);
  178. if ($new_id) {
  179. $ret += 1;
  180. }
  181. }
  182. return $ret;
  183. }
  184. function ADD_NEW_OBJ( $table, $sql_obj ) {
  185. $sql_arr = array();
  186. // TODO: add admin columns if exists in table - search in session
  187. $admin_col = array();
  188. $admin_col []= 'ID';
  189. $admin_col []= 'A_RECORD_CREATE_DATE';
  190. $admin_col []= 'A_RECORD_CREATE_AUTHOR';
  191. $admin_col []= 'A_RECORD_UPDATE_DATE';
  192. $admin_col []= 'A_RECORD_UPDATE_AUTHOR';
  193. // ...
  194. $sql_arr["`ID`"] = "NULL";// add default value for ID, NULL in all inserts
  195. if (substr($table, 0, -5) == '_HIST') {
  196. $sql_obj->A_RECORD_UPDATE_DATE = date('Y-m-d-H:i');
  197. $sql_obj->A_RECORD_UPDATE_AUTHOR = User::getName();
  198. } else {
  199. $sql_obj->A_RECORD_CREATE_DATE = date('Y-m-d-H:i');
  200. $sql_obj->A_RECORD_CREATE_AUTHOR = User::getName();
  201. }
  202. foreach (get_object_vars($sql_obj) as $k => $v) {
  203. if (strtoupper($v) == 'NOW()') {
  204. $v = 'NOW()';
  205. } else if (strtoupper($v) == 'NULL' && substr($table, -5) != '_HIST') {
  206. $v = 'NULL';
  207. } else {
  208. $v = $this->_($v);
  209. $v = "'{$v}'";
  210. }
  211. $sql_arr ["`{$k}`"] = $v;
  212. }
  213. $sql = "insert into `{$table}` (".implode(",", array_keys($sql_arr)).") values (".implode(",", array_values($sql_arr))."); ";
  214. $this->query($sql);
  215. if ($this->has_errors()) {
  216. //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());echo'</pre>';
  217. }
  218. $ret_id = $this->insert_id();
  219. if (substr($table, -5) == '_HIST') {
  220. return $ret_id;
  221. }
  222. if ($ret_id) {
  223. $sql_obj->ID_USERS2 = $ret_id;
  224. unset($sql_obj->ID);
  225. $new_id_hist = $this->ADD_NEW_OBJ($table . '_HIST', $sql_obj);
  226. // error jesli nie udalo sie dodac rekordu do tabeli _HIST
  227. }
  228. return $ret_id;
  229. }
  230. }