ChadoPrefixExtender.inc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <?php
  2. /**
  3. * ChadoPrefixExtender
  4. *
  5. * A query extender that for select queries. By extending the
  6. * SelectQueryExtender class, we can make sure that chado tables
  7. *
  8. * @see https://www.drupal.org/docs/7/api/database-api/dynamic-queries/extenders
  9. */
  10. class ChadoPrefixExtender extends SelectQueryExtender {
  11. /**
  12. * A static cache for Chado tables.
  13. *
  14. * @var array
  15. */
  16. protected static $chado_tables = [];
  17. /**
  18. * A replacement for db_select when querying Chado.
  19. *
  20. * Use this function instead of db_select when querying Chado tables.
  21. *
  22. * @param string|\SelectQuery $table
  23. * The base table for this query. May be a
  24. * string or another SelectQuery object. If a query object is passed, it
  25. * will be used as a subselect.
  26. * @param string $alias
  27. * The alias for the base table of this query.
  28. * @param array $options
  29. * An array of options to control how the query
  30. * operates.
  31. *
  32. * @return \SelectQuery
  33. * A new SelectQuery object for this connection.
  34. *
  35. * @ingroup tripal_chado_query_api
  36. */
  37. public static function select($table, $alias = NULL, array $options = []) {
  38. // Since the table could also be a SelectQuery object, we should verify that
  39. // it is a string first.
  40. if (is_string($table)) {
  41. $table = static::getTable($table);
  42. }
  43. // If the alias is null, determine a safe alias. db_select fails to generate
  44. // a safe alias when the table name is prefixed with "public.".
  45. if (is_null($alias)) {
  46. $alias = static::makeAlias($table);
  47. }
  48. // Create a select query
  49. $query = db_select($table, $alias, $options);
  50. return $query->extend('ChadoPrefixExtender');
  51. }
  52. /**
  53. * @param $type
  54. * @param $table
  55. * @param null $alias
  56. * @param null $condition
  57. * @param array $arguments
  58. *
  59. * @return $this
  60. *
  61. * @see SelectQueryInterface::addJoin()
  62. */
  63. public function addJoin($type, $table, $alias = NULL, $condition = NULL, $arguments = []) {
  64. $table = static::getTable($table);
  65. if (is_null($alias)) {
  66. $alias = static::makeAlias($table);
  67. }
  68. $this->query->addJoin($type, $table, $alias, $condition, $arguments);
  69. return $this;
  70. }
  71. /**
  72. * Overwrites the join to prefix table names.
  73. *
  74. * @param string $table
  75. * Table to join.
  76. * @param string $alias
  77. * Alias for joined table.
  78. * @param string $condition
  79. * Operation for joining.
  80. * @param array $arguments
  81. * Additional arguments.
  82. *
  83. * @return $this
  84. * The current object.
  85. *
  86. * @ingroup tripal_chado_query_api
  87. */
  88. public function join($table, $alias = NULL, $condition = NULL, $arguments = []) {
  89. $table = static::getTable($table);
  90. if (is_null($alias)) {
  91. $alias = static::makeAlias($table);
  92. }
  93. $this->query->join($table, $alias, $condition, $arguments);
  94. return $this;
  95. }
  96. /**
  97. * Overwrites the innerJoin to prefix table names.
  98. *
  99. * @param string $table
  100. * Table to join.
  101. * @param string $alias
  102. * Alias for joined table.
  103. * @param string $condition
  104. * Operation for joining.
  105. * @param array $arguments
  106. * Additional arguments.
  107. *
  108. * @return $this
  109. * The current object.
  110. *
  111. * @ingroup tripal_chado_query_api
  112. */
  113. public function innerJoin($table, $alias = NULL, $condition = NULL, $arguments = []) {
  114. $table = static::getTable($table);
  115. if (is_null($alias)) {
  116. $alias = static::makeAlias($table);
  117. }
  118. $this->query->innerJoin($table, $alias, $condition, $arguments);
  119. return $this;
  120. }
  121. public function leftJoin($table, $alias = NULL, $condition = NULL, $arguments = []) {
  122. $table = static::getTable($table);
  123. if (is_null($alias)) {
  124. $alias = static::makeAlias($table);
  125. }
  126. $this->query->leftJoin($table, $alias, $condition, $arguments);
  127. return $this;
  128. }
  129. /**
  130. * Overwrites the rightJoin to prefix table names.
  131. *
  132. * @param string $table
  133. * Table to join.
  134. * @param string $alias
  135. * Alias for joined table.
  136. * @param string $condition
  137. * Operation for joining.
  138. * @param array $arguments
  139. * Additional arguments.
  140. *
  141. * @return $this
  142. * The current object.
  143. *
  144. * @ingroup tripal_chado_query_api
  145. */
  146. public function rightJoin($table, $alias = NULL, $condition = NULL, $arguments = []) {
  147. $table = static::getTable($table);
  148. if (is_null($alias)) {
  149. $alias = static::makeAlias($table);
  150. }
  151. $this->query->rightJoin($table, $alias, $condition, $arguments);
  152. return $this;
  153. }
  154. /**
  155. * Checks if a table is a chado table.
  156. *
  157. * @param string $table The table name.
  158. *
  159. * @return bool
  160. */
  161. public static function isChadoTable($table) {
  162. if (empty(static::$chado_tables)) {
  163. static::$chado_tables = chado_get_table_names(TRUE);
  164. }
  165. return in_array($table, static::$chado_tables);
  166. }
  167. /**
  168. * If the table name has a schema name as a prefix, replace it with the
  169. * correct schema name.
  170. *
  171. * @param string $table
  172. * The table name.
  173. *
  174. * @return string
  175. * The table with the correct prefix.
  176. *
  177. */
  178. public static function getTable($table) {
  179. $chado_schema_name = chado_get_schema_name('chado');
  180. $drupal_schema_name = chado_get_schema_name('drupal');
  181. // No schema was provided.
  182. if (strpos($table, '.') === FALSE) {
  183. // If this is a chado table, add the chado prefix. Otherwise, add the
  184. // public prefix.
  185. if (static::isChadoTable($table)) {
  186. $table = $chado_schema_name . ".{$table}";
  187. }
  188. else {
  189. $table = $drupal_schema_name . ".{$table}";
  190. }
  191. }
  192. // Now that the schema has been set, we can replace it with the correct
  193. // name. Note that schema names can be altered by developers so we need to
  194. // to run the following function to obtain the final name.
  195. $table = static::getRealSchema($table);
  196. return $table;
  197. }
  198. /**
  199. * Allows altered schema names to be replaces correctly.
  200. *
  201. * @param string $table
  202. * The table name with a prefix such as "chado." or "public."
  203. *
  204. * @return mixed
  205. * The table name with the correct prefix.
  206. */
  207. public static function getRealSchema($table) {
  208. if (strpos($table, 'public.') === 0) {
  209. $replace = chado_get_schema_name('drupal') . '.';
  210. return str_replace('public.', $replace, $table);
  211. }
  212. if (strpos($table, 'chado.') === 0) {
  213. $replace = chado_get_schema_name('chado') . '.';
  214. return str_replace('chado.', $replace, $table);
  215. }
  216. return $table;
  217. }
  218. /**
  219. * Create a safe alias.
  220. *
  221. * @param string $table Table name.
  222. *
  223. * @return string
  224. * The safe alias.
  225. */
  226. public static function makeAlias($table) {
  227. return str_replace('.', '_', $table);
  228. }
  229. }