PageRenderTime 41ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/src/PHPCR/Util/QOM/Sql2Generator.php

https://github.com/lyrixx/phpcr-utils
PHP | 348 lines | 158 code | 39 blank | 151 comment | 17 complexity | 3dde95b63b3c7d9d5c35b5afae250376 MD5 | raw file
  1. <?php
  2. namespace PHPCR\Util\QOM;
  3. use PHPCR\Query\QOM;
  4. use PHPCR\Query\QOM\QueryObjectModelConstantsInterface as Constants;
  5. /**
  6. * Generate SQL2 statements
  7. *
  8. * TODO: is eval... the best name for the functions here?
  9. */
  10. class Sql2Generator extends BaseSqlGenerator
  11. {
  12. /**
  13. * Selector ::= nodeTypeName ['AS' selectorName]
  14. * nodeTypeName ::= Name
  15. *
  16. * @param string $nodeTypeName The node type of the selector. If it does not contain starting and ending brackets ([]) they will be added automatically
  17. * @param string $selectorName
  18. * @return string
  19. */
  20. public function evalSelector($nodeTypeName, $selectorName = null)
  21. {
  22. $sql2 = $nodeTypeName;
  23. if (substr($sql2, 0, 1) !== '[' && substr($sql2, -1) !== ']') {
  24. $sql2 = '[' . $sql2 . ']';
  25. }
  26. $name = $selectorName;
  27. if (! is_null($name)) {
  28. $sql2 .= ' AS ' . $name;
  29. }
  30. return $sql2;
  31. }
  32. /**
  33. * Join ::= left [JoinType] 'JOIN' right 'ON' JoinCondition
  34. * // If JoinType is omitted INNER is assumed.
  35. * left ::= Source
  36. * right ::= Source
  37. *
  38. * @param string $left
  39. * @param string $right
  40. * @param string $joinCondition
  41. * @param string $joinType
  42. * @return string
  43. */
  44. public function evalJoin($left, $right, $joinCondition, $joinType = '')
  45. {
  46. return "$left {$joinType}JOIN $right ON $joinCondition";
  47. }
  48. /**
  49. * JoinType ::= Inner | LeftOuter | RightOuter
  50. * Inner ::= 'INNER'
  51. * LeftOuter ::= 'LEFT OUTER'
  52. * RightOuter ::= 'RIGHT OUTER'
  53. *
  54. * @param string $joinType
  55. * @return string
  56. */
  57. public function evalJoinType($joinType)
  58. {
  59. switch ($joinType) {
  60. case Constants::JCR_JOIN_TYPE_INNER:
  61. return 'INNER ';
  62. case Constants::JCR_JOIN_TYPE_LEFT_OUTER:
  63. return 'LEFT OUTER ';
  64. case Constants::JCR_JOIN_TYPE_RIGHT_OUTER:
  65. return 'RIGHT OUTER ';
  66. }
  67. return $joinType;
  68. }
  69. /**
  70. * EquiJoinCondition ::= selector1Name'.'property1Name '='
  71. * selector2Name'.'property2Name
  72. * selector1Name ::= selectorName
  73. * selector2Name ::= selectorName
  74. * property1Name ::= propertyName
  75. * property2Name ::= propertyName
  76. *
  77. * @param string $sel1Name
  78. * @param string $prop1Name
  79. * @param string $sel2Name
  80. * @param string $prop2Name
  81. * @return string
  82. */
  83. public function evalEquiJoinCondition($sel1Name, $prop1Name, $sel2Name, $prop2Name)
  84. {
  85. return $this->evalPropertyValue($prop1Name, $sel1Name) . '=' .$this->evalPropertyValue($prop2Name, $sel2Name);
  86. }
  87. /**
  88. * SameNodeJoinCondition ::=
  89. * 'ISSAMENODE(' selector1Name ','
  90. * selector2Name
  91. * [',' selector2Path] ')'
  92. * selector2Path ::= Path
  93. *
  94. * @param string $sel1Name
  95. * @param string $sel2Name
  96. * @param string $sel2path
  97. * @return string
  98. */
  99. public function evalSameNodeJoinCondition($sel1Name, $sel2Name, $sel2Path = null)
  100. {
  101. $sql2 = "ISSAMENODE($sel1Name, $sel2Name";
  102. $sql2 .= ! is_null($sel2Path) ? ', ' . $sel2Path : '';
  103. $sql2 .= ')';
  104. return $sql2;
  105. }
  106. /**
  107. * ChildNodeJoinCondition ::=
  108. * 'ISCHILDNODE(' childSelectorName ','
  109. * parentSelectorName ')'
  110. * childSelectorName ::= selectorName
  111. * parentSelectorName ::= selectorName
  112. *
  113. * @param string $childSelectorName
  114. * @param string $parentSelectorName
  115. * @return string
  116. */
  117. public function evalChildNodeJoinCondition($childSelectorName, $parentSelectorName)
  118. {
  119. return "ISCHILDNODE($childSelectorName, $parentSelectorName)";
  120. }
  121. /**
  122. * DescendantNodeJoinCondition ::=
  123. * 'ISDESCENDANTNODE(' descendantSelectorName ','
  124. * ancestorSelectorName ')'
  125. * descendantSelectorName ::= selectorName
  126. * ancestorSelectorName ::= selectorName
  127. *
  128. * @param string $descendantSelectorName
  129. * @param string $ancestorselectorName
  130. * @return string
  131. */
  132. public function evalDescendantNodeJoinCondition($descendantSelectorName, $ancestorselectorName)
  133. {
  134. return "ISDESCENDANTNODE($descendantSelectorName, $ancestorselectorName)";
  135. }
  136. /**
  137. * SameNode ::= 'ISSAMENODE(' [selectorName ','] Path ')'
  138. *
  139. * @param string $path
  140. * @param string $selectorName
  141. */
  142. public function evalSameNode($path, $selectorName = null)
  143. {
  144. $sql2 = 'ISSAMENODE(';
  145. $sql2 .= is_null($selectorName) ? $path : $selectorName . ', ' . $path;
  146. $sql2 .= ')';
  147. return $sql2;
  148. }
  149. /**
  150. * SameNode ::= 'ISCHILDNODE(' [selectorName ','] Path ')'
  151. *
  152. * @param string $path
  153. * @param string $selectorName
  154. */
  155. public function evalChildNode($path, $selectorName = null)
  156. {
  157. $sql2 = 'ISCHILDNODE(';
  158. $sql2 .= is_null($selectorName) ? $path : $selectorName . ', ' . $path;
  159. $sql2 .= ')';
  160. return $sql2;
  161. }
  162. /**
  163. * SameNode ::= 'ISDESCENDANTNODE(' [selectorName ','] Path ')'
  164. *
  165. * @param string $path
  166. * @param string $selectorName
  167. */
  168. public function evalDescendantNode($path, $selectorName = null)
  169. {
  170. $sql2 = 'ISDESCENDANTNODE(';
  171. $sql2 .= is_null($selectorName) ? $path : $selectorName . ', ' . $path;
  172. $sql2 .= ')';
  173. return $sql2;
  174. }
  175. public function evalPropertyExistence($selectorName, $propertyName)
  176. {
  177. return $this->evalPropertyValue($propertyName, $selectorName) . " IS NOT NULL";
  178. }
  179. /**
  180. * FullTextSearch ::=
  181. * 'CONTAINS(' ([selectorName'.']propertyName |
  182. * selectorName'.*') ','
  183. * FullTextSearchExpression ')'
  184. * FullTextSearchExpression ::= BindVariable | ''' FullTextSearchLiteral '''
  185. * @param string $selectorName unusued
  186. * @param string $searchExpression
  187. * @param string $ropertyName
  188. * @return string
  189. */
  190. public function evalFullTextSearch($selectorName, $searchExpression, $propertyName = null)
  191. {
  192. $propertyName = $propertyName ?: '*';
  193. $sql2 = 'CONTAINS(';
  194. $sql2 .= $this->evalPropertyValue($propertyName, $selectorName);
  195. $sql2 .= ', ' . $searchExpression . ')';
  196. return $sql2;
  197. }
  198. /**
  199. * Length ::= 'LENGTH(' PropertyValue ')'
  200. *
  201. * @param string $propertyValue
  202. * @return string
  203. */
  204. public function evalLength($propertyValue)
  205. {
  206. return "LENGTH($propertyValue)";
  207. }
  208. /**
  209. * NodeName ::= 'NAME(' [selectorName] ')'
  210. *
  211. * @param string $selectorValue
  212. */
  213. public function evalNodeName($selectorValue = null)
  214. {
  215. return "NAME($selectorValue)";
  216. }
  217. /**
  218. * NodeLocalName ::= 'LOCALNAME(' [selectorName] ')'
  219. *
  220. * @param string $selectorValue
  221. */
  222. public function evalNodeLocalName($selectorValue = null)
  223. {
  224. return "LOCALNAME($selectorValue)";
  225. }
  226. /**
  227. * FullTextSearchScore ::= 'SCORE(' [selectorName] ')'
  228. *
  229. * @param string $selectorValue
  230. */
  231. public function evalFullTextSearchScore($selectorValue = null)
  232. {
  233. return "SCORE($selectorValue)";
  234. }
  235. /**
  236. * PropertyValue ::= [selectorName'.'] propertyName // If only one selector exists
  237. *
  238. * @param string $propertyName
  239. * @param string $selectorName
  240. */
  241. public function evalPropertyValue($propertyName, $selectorName = null)
  242. {
  243. if (false !== strpos($selectorName, ':')) {
  244. $selectorName = "[$selectorName]";
  245. }
  246. $sql2 = ! is_null($selectorName) ? $selectorName . '.' : '';
  247. if (false !== strpos($propertyName, ':')) {
  248. $propertyName = "[$propertyName]";
  249. }
  250. $sql2 .= $propertyName;
  251. return $sql2;
  252. }
  253. public function evalColumns($columns)
  254. {
  255. if (count($columns) === 0) {
  256. return '*';
  257. }
  258. $sql2 = '';
  259. foreach ($columns as $column) {
  260. if ($sql2 !== '') {
  261. $sql2 .= ', ';
  262. }
  263. $sql2 .= $column;
  264. }
  265. return $sql2;
  266. }
  267. public function evalColumn($selectorName, $propertyName = null, $colname = null)
  268. {
  269. $sql2 = '';
  270. if (! is_null($selectorName) && is_null($propertyName) && is_null($colname)) {
  271. $sql2 .= $selectorName . '.*';
  272. } else {
  273. $sql2 .= $this->evalPropertyValue($propertyName, $selectorName);
  274. $sql2 .= ! is_null($colname) ? ' AS ' . $colname : '';
  275. }
  276. return $sql2;
  277. }
  278. /**
  279. * Path ::= '[' quotedPath ']' | '[' simplePath ']' | simplePath
  280. * quotedPath ::= A JCR Path that contains non-SQL-legal characters
  281. * simplePath ::= A JCR Name that contains only SQL-legal characters
  282. *
  283. * @param string $path
  284. * @return string
  285. */
  286. public function evalPath($path)
  287. {
  288. if ($path) {
  289. $sql2 = $path;
  290. // only ensure proper quoting if the user did not quote himself, we trust him to get it right if he did.
  291. if (substr($path, 0,1) !== '[' && substr($path, -1) !== ']') {
  292. if (false !== strpos($sql2, ' ') || false !== strpos($sql2, '.')) {
  293. $sql2 = '"' . $sql2 . '"';
  294. }
  295. $sql2 = '[' . $sql2 . ']';
  296. }
  297. return $sql2;
  298. }
  299. return null;
  300. }
  301. /**
  302. * @param string $literal
  303. * @param string $type
  304. */
  305. public function evalCastLiteral($literal, $type)
  306. {
  307. return "CAST('$literal' AS $type)";
  308. }
  309. }