6 use Drupal\Core\Config\ConfigFactory;
7 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
12 use Maquina\StateMachine\Machine;
13 use Maquina\StateMachine\MachineOfMachines;
14 use SqlParser\SqlParser;
15 use Symfony\Component\DependencyInjection\ContainerInterface;
20 class Service implements ContainerInjectionInterface {
26 private $configFactory;
33 private $datastoreService;
38 public static function create(ContainerInterface $container) {
40 $container->get(
'dkan.datastore.service'),
41 $container->get(
'config.factory')
55 $this->datastoreService = $datastoreService;
56 $this->configFactory = $configFactory;
71 public function runQuery(
string $queryString, $showDbColumns = FALSE): array {
72 $queryObject = $this->getQueryObject($queryString);
74 $identifier = NULL; $version = NULL;
77 $databaseTable = $this->getDatabaseTable($identifier, $version);
79 $result = $databaseTable->query($queryObject);
81 $schema = $databaseTable->getSchema();
82 $fields = $schema[
'fields'];
84 return array_map(
function ($row) use ($fields, $showDbColumns) {
85 if (!$showDbColumns) {
86 unset($row->record_number);
89 $arrayRow = (array) $row;
93 foreach ($arrayRow as $fieldName => $value) {
94 if (!$showDbColumns && isset($fields[$fieldName][
'description']) && !empty($fields[$fieldName][
'description'])) {
95 $newRow[$fields[$fieldName][
'description']] = $value;
98 $newRow[$fieldName] = $value;
102 return (
object) $newRow;
118 $stateMachine = $this->validate($sqlString);
119 $someIdentifier = $this->getTableNameFromSelect($stateMachine->gsm(
'select'));
126 private function getDatabaseTable($identifier, $version = NULL):
DatabaseTable {
127 return $this->datastoreService->getStorage($identifier, $version);
133 private function getTableNameFromSelect(MachineOfMachines $selectMachine): string {
134 $machine = $selectMachine->gsm(
'table_var');
135 $strings = $this->getStringsFromStringMachine($machine);
136 if (empty($strings)) {
137 throw new \Exception(
"No table name");
151 private function getQueryObject(
string $sqlString): Query {
152 return $this->getQueryObjectFromStateMachine($this->validate($sqlString));
158 private function validate(
string $sqlString): MachineOfMachines {
159 $parser =
new SqlParser();
160 if ($parser->validate($sqlString) === FALSE) {
161 throw new \Exception(
"Invalid query string.");
164 return $parser->getValidatingMachine();
176 private function getQueryObjectFromStateMachine(MachineOfMachines $state_machine): Query {
177 $object =
new Query();
178 $this->setQueryObjectSelect($object, $state_machine->gsm(
'select'));
179 $this->setQueryObjectWhere($object, $state_machine->gsm(
'where'));
180 $this->setQueryObjectOrderBy($object, $state_machine->gsm(
'order_by'));
181 $this->setQueryObjectLimit($object, $state_machine->gsm(
'limit'));
194 private function setQueryObjectSelect(Query $object, MachineOfMachines $state_machine) {
195 $strings = $this->getStringsFromStringMachine($state_machine->gsm(
'select_count_all'));
196 if (!empty($strings)) {
201 $strings = $this->getStringsFromStringMachine($state_machine->gsm(
'select_var_all'));
202 if (!empty($strings)) {
206 $strings = $this->getStringsFromStringMachine($state_machine->gsm(
'select_var'));
207 foreach ($strings as $property) {
208 $object->filterByProperty($property);
220 private function setQueryObjectWhere(Query $object, MachineOfMachines $state_machine) {
221 $properties = $this->getStringsFromStringMachine($state_machine->gsm(
'where_column'));
222 $quoted_string = $state_machine->gsm(
'quoted_string');
223 if (!($quoted_string instanceof MachineOfMachines)) {
224 throw new \Exception(
"State machine error.");
226 $values = $this->getStringsFromStringMachine($quoted_string->gsm(
'string'));
228 foreach ($properties as $index => $property) {
229 $value = $values[$index];
231 $object->conditionByIsEqualTo($property, $value);
244 private function setQueryObjectOrderBy(Query $object, MachineOfMachines $state_machine) {
245 $properties = $this->getStringsFromStringMachine($state_machine->gsm(
'order_var'));
247 $direction = $this->getStringsFromStringMachine($state_machine->gsm(
'order_asc'));
248 $sortMethod = (!empty($direction)) ?
"sortByAscending" :
"sortByDescending";
250 foreach ($properties as $property) {
251 $object->$sortMethod($property);
258 private function setQueryObjectLimit(Query $object, MachineOfMachines $state_machine) {
259 $limit = $this->getStringsFromStringMachine($state_machine->gsm(
'numeric1'));
267 $rows_limit = $this->configFactory->get(
'datastore.settings')->get(
'rows_limit');
268 if (!$object->count && isset($limit) && $limit > $rows_limit) {
269 $limit = $rows_limit;
272 $object->limitTo($limit);
274 $offset = $this->getStringsFromStringMachine($state_machine->gsm(
'numeric2'));
276 if (!empty($offset)) {
277 $object->offsetBy($offset[0]);
284 private function getStringsFromStringMachine(Machine $machine): array {
285 return (
new GetStringsFromStateMachineExecution($machine->execution))->get();
292 $stateMachine = $this->validate($sqlString);
293 $identifier = $this->getTableNameFromSelect($stateMachine->gsm(
'select'));
296 if (substr_count($identifier,
'__') == 0) {