5 use Contracts\RemoverInterface;
6 use Contracts\RetrieverInterface;
7 use Contracts\StorerInterface;
8 use Dkan\Datastore\Storage\StorageInterface;
9 use Dkan\Datastore\Storage\Database\SqlStorageTrait;
10 use Drupal\Core\Database\Connection;
16 abstract class AbstractDatabaseTable implements StorageInterface, StorerInterface, RetrieverInterface, RemoverInterface {
18 use QueryToQueryHelperTrait;
36 abstract protected function prepareData(
string $data,
string $id = NULL): array;
53 $this->setSchemaFromTable();
66 $statement = $this->connection->select($this->
getTableName(),
't')
67 ->fields(
't', array_keys($this->getSchema()[
'fields']))
72 $return = (isset($statement)) ? $statement->fetch() : NULL;
74 return ($return === FALSE) ? NULL : $return;
86 $result = $this->connection->select($tableName,
't')
91 if ($result === FALSE) {
95 $result = array_map(
function ($item) {
105 public function store($data,
string $id = NULL): string {
108 $existing = (isset($id)) ? $this->retrieve($id) : NULL;
110 $data = $this->prepareData($data, $id);
114 if ($existing === NULL) {
115 $fields = $this->getNonSerialFields();
117 if (count($fields) != count($data)) {
118 throw new \Exception(
"The number of fields and data given do not match: fields - " .
119 json_encode($fields) .
" data - " . json_encode($data));
122 $q = $this->connection->insert($this->getTableName());
125 $returned_id = $q->execute();
128 $q = $this->connection->update($this->getTableName());
130 ->condition($this->primaryKey(), $id)
134 return ($returned_id) ?
"$returned_id" :
"{$id}";
149 $fields = $this->getNonSerialFields();
151 $q = $this->connection->insert($this->getTableName());
153 foreach ($data as $datum) {
154 $datum = $this->prepareData($datum);
155 if (count($fields) != count($datum)) {
156 throw new \Exception(
"The number of fields and data given do not match: fields - " .
157 json_encode($fields) .
" data - " . json_encode($datum));
161 return $q->execute();
169 foreach ($this->schema[
'fields'] as $field => $info) {
170 if ($info[
'type'] !=
'serial') {
182 public function remove(
string $id) {
183 $tableName = $this->getTableName();
184 $this->connection->delete($tableName)
185 ->condition($this->primaryKey(), $id)
194 $query = $this->connection->select($this->getTableName());
195 return $query->countQuery()->execute()->fetchField();
206 $db_query = $this->connection->select($this->getTableName(),
't')
207 ->fields(
't', $query->properties);
209 $this->setQueryConditions($db_query, $query);
210 $this->setQueryOrderBy($db_query, $query);
211 $this->setQueryLimitAndOffset($db_query, $query);
214 $db_query = $db_query->countQuery();
217 $result = $db_query->execute()->fetchAll();
225 private function setTable() {
226 if (!$this->tableExist($this->getTableName())) {
228 $this->tableCreate($this->getTableName(), $this->schema);
231 throw new \Exception(
"Could not instantiate the table due to a lack of schema.");
242 if ($this->tableExist($this->getTableName())) {
243 $this->connection->schema()->dropTable($this->getTableName());
250 private function tableExist($table_name) {
251 $exists = $this->connection->schema()->tableExists($table_name);
258 private function tableCreate($table_name, $schema) {
259 $this->connection->schema()->createTable($table_name, $schema);
265 private function setSchemaFromTable() {
266 $fields_info = $this->connection->query(
"DESCRIBE `{$this->getTableName()}`")->fetchAll();
267 if (!empty($fields_info)) {
268 $fields = $this->getFieldsFromFieldsInfo($fields_info);
269 $this->setSchema($this->getTableSchema($fields));
279 private function getFieldsFromFieldsInfo(array $fieldsInfo) {
281 foreach ($fieldsInfo as $info) {
282 $fields[] = $info->Field;
290 private function getTableSchema($fields) {
293 foreach ($header as $field) {
294 $schema[
'fields'][$field] = [