PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/core/src/main/php/rdbms/sqlite/SQLiteDialect.class.php

http://github.com/xp-framework/xp-framework
PHP | 243 lines | 160 code | 12 blank | 71 comment | 13 complexity | 7bcab7cb9273d3848446d3d57f687972 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /* This class is part of the XP framework
  3. *
  4. * $Id$
  5. */
  6. uses('rdbms.SQLDialect');
  7. /**
  8. * helps to build functions for different SQL servers
  9. *
  10. */
  11. class SQLiteDialect extends SQLDialect {
  12. public
  13. $escape = "'",
  14. $escapeRules = array("'" => "''"),
  15. $escapeT = "'",
  16. $escapeRulesT = array("'" => "''"),
  17. $dateFormat = 'Y-m-d H:i:s';
  18. private static
  19. $dateparts= array(
  20. 'day' => '"d"',
  21. 'dayofyear' => '"z"',
  22. 'hour' => '"H"',
  23. 'microsecond' => FALSE,
  24. 'millisecond' => FALSE,
  25. 'minute' => '"i"',
  26. 'month' => '"m"',
  27. 'quarter' => FALSE,
  28. 'second' => 's',
  29. 'week' => FALSE,
  30. 'weekday' => FALSE,
  31. 'year' => 'Y',
  32. ),
  33. // http://www.sqlite.org/lang_expr.html
  34. $implementations= array(
  35. 'abs_1' => 'php("abs", %d)',
  36. 'acos_1' => 'php("acos", %d)',
  37. 'ascii_1' => 'php("ord", %s)',
  38. 'asin_1' => 'php("asin", %d)',
  39. 'atan_1' => 'php("atan", %d)',
  40. 'atan_2' => 'php("atan2", %d, %d)',
  41. 'bit_length_1' => 'bit_length_not_implemented',
  42. 'cast_2' => 'cast(%s as %e)',
  43. 'ceil_1' => 'php("ceil", %d)',
  44. 'char_1' => 'php("chr", %d)',
  45. 'cos_1' => 'php("cos", %d)',
  46. 'cot_1' => 'php("tan", php("pi") / 2 - %d)',
  47. 'dateadd_3' => 'dateadd(%t, %d, %s)',
  48. 'datediff_3' => 'datediff_not_implemented',
  49. 'datename_2' => 'php("strval", php("idate", %t, php("strtotime", %s)))',
  50. 'datepart_2' => 'php("idate", %t, php("strtotime", %s))',
  51. 'day_1' => 'php("idate", "d", php("strtotime", %s))',
  52. 'degrees_1' => 'php("rad2deg", %d)',
  53. 'exp_1' => 'php("exp", %d)',
  54. 'floor_1' => 'php("floor", %d)',
  55. 'getdate_0' => 'php("date", "Y-m-d H:i:s", php("time"))',
  56. 'hour_1' => 'php("idate", "H", php("strtotime", %s))',
  57. 'len_1' => 'php("strlen", %s)',
  58. 'length_1' => 'php("strlen", %s)',
  59. 'locate_2' => 'locate(%s, %s, 0)',
  60. 'locate_3' => 'locate(%s, %s, %d)',
  61. 'log10_1' => 'php("log10", %d)',
  62. 'log_1' => 'php("log", %d)',
  63. 'lower_1' => 'php("strtolower, "%s)',
  64. 'ltrim_1' => 'php("ltrim", %s)',
  65. 'ltrim_2' => 'php("ltrim", %s, %s)',
  66. 'minute_1' => 'php("idate", "i", php("strtotime", %s))',
  67. 'month_1' => 'php("idate", "m", php("strtotime", %s))',
  68. 'nullif_2' => 'nullif(%s, %s)',
  69. 'pi_0' => 'php("pi")',
  70. 'power_2' => 'php("pow", %d, %d)',
  71. 'radians_1' => 'php("deg2rad", %d)',
  72. 'rand_0' => 'php("rand")',
  73. 'reverse_1' => 'php("strrev", %s)',
  74. 'round_2' => 'php("round", %d, %d)',
  75. 'rtrim_1' => 'php("rtrim", %s)',
  76. 'rtrim_2' => 'php("rtrim", %s, %s)',
  77. 'second_1' => 'php("idate", "s", php("strtotime", %s))',
  78. 'sign_1' => 'sign(%d)',
  79. 'sin_1' => 'php("sin", %d)',
  80. 'soundex_1' => 'php("soundex", %s)',
  81. 'space_1' => 'php("str_repeat", " ", %d)',
  82. 'sqrt_1' => 'php("sqrt", %d)',
  83. 'str_1' => 'php("strval", %s)',
  84. 'substring_3' => 'php("substr", %s, %d, %d)',
  85. 'substring_2' => 'php("substr", %s, %d)',
  86. 'tan_1' => 'php("tan", %d)',
  87. 'trim_2' => 'php("trim", %s)',
  88. 'trim_3' => 'php("trim", %s, %s)',
  89. 'upper_1' => 'php("strtoupper", %s)',
  90. 'year_1' => 'php("idate", "Y", php("strtotime", %s))',
  91. );
  92. /**
  93. * register sql standard functions for a connection
  94. *
  95. * @param db handel conn
  96. */
  97. public function registerCallbackFunctions($conn) {
  98. sqlite_create_function($conn, 'cast', array($this, '_cast'), 2);
  99. sqlite_create_function($conn, 'sign', array($this, '_sign'), 1);
  100. sqlite_create_function($conn, 'dateadd', array($this, '_dateadd'), 3);
  101. sqlite_create_function($conn, 'locate', array($this, '_locate'), 3);
  102. sqlite_create_function($conn, 'nullif', array($this, '_nullif'), 2);
  103. }
  104. /**
  105. * Callback function to cast data
  106. *
  107. * @param var s
  108. * @param var type
  109. * @return var
  110. */
  111. public function _cast($s, $type) {
  112. static $identifiers= array(
  113. 'bigint' => "\3",
  114. 'date' => "\2",
  115. 'datetime' => "\2",
  116. 'decimal' => "\4",
  117. 'double' => "\4",
  118. 'float' => "\4",
  119. 'int' => "\3",
  120. 'integer' => "\3",
  121. 'smallint' => "\3",
  122. );
  123. return is_null($s) ? NULL : $identifiers[strtolower($type)].$s;
  124. }
  125. /**
  126. * Callback function to compare to statements
  127. *
  128. * @param string arg1
  129. * @param string arg2
  130. * @return int
  131. */
  132. public function _nullif($arg1, $arg2) {
  133. if ($arg1 == $arg2) return NULL;
  134. return $arg1;
  135. }
  136. /**
  137. * Callback function to find a string in a string
  138. *
  139. * @param string haystack
  140. * @param string needle
  141. * @param int start
  142. * @return int
  143. */
  144. public function _locate($h, $n, $s) {
  145. if (is_null($h) or is_null($n)) return NULL;
  146. return intval(strpos($h, $n, $s));
  147. }
  148. /**
  149. * Callback function to find the signature of a float
  150. *
  151. * @param float dig
  152. * @return int
  153. */
  154. public function _sign($dig) {
  155. $dig= floatval($dig);
  156. if ($dig > 0) return 1;
  157. if ($dig < 0) return -1;
  158. return 0;
  159. }
  160. /**
  161. * Callback function add a datepart to a date
  162. *
  163. * @param sring datepart
  164. * @param int amount to add
  165. * @param string datestr
  166. * @return string
  167. */
  168. public function _dateadd($part, $amount, $datestr) {
  169. $part= current(array_keys(self::$dateparts, '"'.$part.'"'));
  170. $date= new DateTime($datestr);
  171. $date->modify($amount.' '.$part);
  172. return $date->format($this->dateFormat);
  173. }
  174. /**
  175. * get a function format string
  176. *
  177. * @param SQLFunction func
  178. * @return string
  179. * @throws lang.IllegalArgumentException
  180. */
  181. public function formatFunction(SQLFunction $func) {
  182. $func_i= $func->func.'_'.sizeof($func->args);
  183. switch ($func->func) {
  184. case 'concat':
  185. return implode(' || ', array_fill(0, sizeof($func->args), '%s'));
  186. default:
  187. if (isset(self::$implementations[$func_i])) return self::$implementations[$func_i];
  188. return parent::formatFunction($func);
  189. }
  190. }
  191. /**
  192. * get a dialect specific datepart
  193. *
  194. * @param string datepart
  195. * @return string
  196. * @throws lang.IllegalArgumentException
  197. */
  198. public function datepart($datepart) {
  199. $datepart= strToLower($datepart);
  200. if (!array_key_exists($datepart, self::$dateparts)) return parent::datepart($datepart);
  201. if (FALSE === self::$dateparts[$datepart]) throw new IllegalArgumentException('PostgreSQL does not support datepart '.$datepart);
  202. return self::$dateparts[$datepart];
  203. }
  204. /**
  205. * build join related part of an SQL query
  206. *
  207. * @param rdbms.join.JoinRelation[] conditions
  208. * @return string
  209. * @throws lang.IllegalArgumentException
  210. */
  211. public function makeJoinBy(Array $conditions) {
  212. if (0 == sizeof($conditions)) throw new IllegalArgumentException('conditions can not be empty');
  213. $querypart= '';
  214. $first= TRUE;
  215. foreach ($conditions as $link) {
  216. if ($first) {
  217. $first= FALSE;
  218. $querypart.= sprintf(
  219. '%s LEFT OUTER JOIN %s on (%s) ',
  220. $link->getSource()->toSqlString(),
  221. $link->getTarget()->toSqlString(),
  222. implode(' and ', $link->getConditions())
  223. );
  224. } else {
  225. $querypart.= sprintf('LEFT JOIN %s on (%s) ', $link->getTarget()->toSqlString(), implode(' and ', $link->getConditions()));
  226. }
  227. }
  228. return $querypart.'where ';
  229. }
  230. }
  231. ?>