mirror of
https://gitlab.com/hashborgir/d2tools.git
synced 2025-05-02 09:15:37 +00:00
87 lines
2.6 KiB
PHP
87 lines
2.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Short Query Notation Library
|
|
*
|
|
* SQN is a small library that allows you to write
|
|
* convention based SQL queries using a short notation.
|
|
* SQL is a very flexible and powerful language. Since SQL
|
|
* does not rely on assumptions you have to specify a lot.
|
|
* The SQN-library uses some basic assumptions regarding
|
|
* naming conventions and in return it gives you a shorter notation.
|
|
*
|
|
* Usage:
|
|
*
|
|
* R::sqn('shop<product<price'); - left joins shop, product and price
|
|
* R::sqn('book<<tag'); - doubly left joins book, and tag using book_tag
|
|
*
|
|
* SQN assumes id fields follow the following conventions:
|
|
*
|
|
* Primary key: id
|
|
* Foreign key: {table}_id
|
|
* No table prefix.
|
|
*
|
|
* SQN can also generate additional aliases:
|
|
*
|
|
* R::sqn( ..., 'area/x,y;place/x,y' ) - area_x area_y place_x place_y
|
|
*
|
|
* @author Gabor de Mooij
|
|
* @license BSD/GPLv2
|
|
*
|
|
* @copyright
|
|
* copyright (c) G.J.G.T. (Gabor) de Mooij
|
|
* This source file is subject to the BSD License that is bundled
|
|
* with this source code in the file license.txt.
|
|
*/
|
|
R::ext('sqn', function( $query, $aliases = null, $q = '`' ) {
|
|
$map = [
|
|
'|' => 'INNER JOIN',
|
|
'||' => 'INNER JOIN',
|
|
'>' => 'RIGHT JOIN',
|
|
'>>' => 'RIGHT JOIN',
|
|
'<' => 'LEFT JOIN',
|
|
'<<' => 'LEFT JOIN',
|
|
];
|
|
$select = [];
|
|
$from = '';
|
|
$joins = [];
|
|
$prev = '';
|
|
$ents = preg_split( '/[^\w_]+/', $query );
|
|
$tokens = preg_split( '/[\w_]+/', $query );
|
|
array_pop($tokens);
|
|
foreach( $ents as $i => $ent ) {
|
|
$select[] = " {$q}{$ent}{$q}.* ";
|
|
if (!$i) {
|
|
$from = $ent;
|
|
$prev = $ent;
|
|
continue;
|
|
}
|
|
if ( $tokens[$i] == '<' || $tokens[$i] == '>' || $tokens[$i] == '|') {
|
|
$join[] = " {$map[$tokens[$i]]} {$q}{$ent}{$q} ON {$q}{$ent}{$q}.{$prev}_id = {$q}{$prev}{$q}.id ";
|
|
}
|
|
if ( $tokens[$i] == '<<' || $tokens[$i] == '>>' || $tokens[$i] == '||') {
|
|
$combi = [$prev, $ent];
|
|
sort( $combi );
|
|
$combi = implode( '_', $combi );
|
|
$select[] = " {$q}{$combi}{$q}.* ";
|
|
$join[] = " {$map[$tokens[$i]]} {$q}{$combi}{$q} ON {$q}{$combi}{$q}.{$prev}_id = {$q}{$prev}{$q}.id ";
|
|
$join[] = " {$map[$tokens[$i]]} {$q}{$ent}{$q} ON {$q}{$combi}{$q}.{$ent}_id = {$q}{$ent}{$q}.id ";
|
|
}
|
|
$prev = $ent;
|
|
}
|
|
if (!is_null($aliases)) {
|
|
$aliases = explode(';', $aliases);
|
|
foreach($aliases as $alias) {
|
|
list($table, $cols) = explode('/', $alias);
|
|
$cols = explode(',', $cols);
|
|
foreach($cols as $col) {
|
|
$select[] = " {$q}{$table}{$q}.{$q}{$col}{$q} AS {$q}{$table}_{$col}{$q} ";
|
|
}
|
|
}
|
|
}
|
|
$selectSQL = implode( ",\n", $select );
|
|
$joinSQL = implode( "\n", $join );
|
|
return "SELECT{$selectSQL}\n FROM {$q}{$from}{$q}\n{$joinSQL}";
|
|
});
|
|
|