1: <?php
2: /**
3: * This file contains the implementation of the interface IRecordsetManager
4: * in the class RecordsetManager for working with record sets.
5: *
6: * @package Database
7: *
8: * @author Oleg Schildt
9: */
10:
11: namespace SmartFactory;
12:
13: use \SmartFactory\Interfaces\IRecordsetManager;
14:
15: use \SmartFactory\DatabaseWorkers\DBWorker;
16: use \SmartFactory\DatabaseWorkers\DBWorkerException;
17:
18: /**
19: * Class for working with record sets.
20: *
21: * @uses DatabaseWorkers\DBWorker
22: *
23: * @author Oleg Schildt
24: */
25: class RecordsetManager implements IRecordsetManager
26: {
27: /**
28: * Internal variable for storing the dbworker.
29: *
30: * @var ?DatabaseWorkers\DBWorker
31: *
32: * @author Oleg Schildt
33: */
34: protected ?DatabaseWorkers\DBWorker $dbworker = null;
35:
36: /**
37: * Internal variable for storing the target table name.
38: *
39: * @var ?string
40: *
41: * @author Oleg Schildt
42: */
43: protected ?string $table = null;
44:
45: /**
46: * Internal array for storing the target fields.
47: *
48: * @var array
49: *
50: * @author Oleg Schildt
51: */
52: protected array $fields = [];
53:
54: /**
55: * Internal array for storing the key fields. These are the fields that are used
56: * to uniquely identify a record.
57: *
58: * @var array
59: *
60: * @author Oleg Schildt
61: */
62: protected array $key_fields = [];
63:
64: /**
65: * This is internal auxiliary function for checking that the recordset manager
66: * is initialized correctly.
67: *
68: * @param string $type
69: * The type of validation - table or query.
70: *
71: * @return void
72: *
73: * @throws \Exception
74: * It might throw an exception in the case of any errors:
75: *
76: * - if some parameters are missing.
77: * - if dbworker does not extend {@see \SmartFactory\DatabaseWorkers\DBWorker}.
78: * - if some parameters are not of the proper type.
79: *
80: * @author Oleg Schildt
81: */
82: protected function validateParameters(string $type): void
83: {
84: if (empty($this->dbworker)) {
85: throw new \Exception("The 'dbworker' is not specified!");
86: }
87:
88: if (!$this->dbworker instanceof DBWorker) {
89: throw new \Exception(sprintf("The 'dbworker' does not extends the class '%s'!", DBWorker::class));
90: }
91:
92: if ($type == "table" && empty($this->table)) {
93: throw new \Exception("The target table is not specified!");
94: }
95:
96: if (empty($this->fields)) {
97: throw new \Exception("The target fields are not specified!");
98: }
99:
100: if (!is_array($this->fields)) {
101: throw new \Exception("Field definition must be an array - field => type!");
102: }
103:
104: if (!empty($this->key_fields) && !is_array($this->key_fields)) {
105: throw new \Exception("Key field definition must be an array!");
106: }
107: } // validateParameters
108:
109: /**
110: * This is internal auxiliary function for converting an array to a where clause.
111: *
112: * @param array|string &$where_clause
113: * The where clause that should be checked. If an array of keys is passed,
114: * the where clause is build based on it.
115: *
116: * @return void
117: *
118: * @throws \Exception
119: * It might throw an exception in the case if a field for the clause wad not described
120: * by the initialization.
121: *
122: * @author Oleg Schildt
123: */
124: protected function checkWhereClause(array|string &$where_clause): void
125: {
126: if (!is_array($where_clause)) {
127: return;
128: }
129:
130: $tmp = "";
131: foreach ($where_clause as $key_field => $value) {
132: if (empty($this->fields[$key_field])) {
133: throw new \Exception(sprintf("The field '%s' is not described!", $key_field));
134: }
135:
136: if (!empty($tmp)) {
137: $tmp .= " and ";
138: }
139:
140: $tmp .= $key_field . " = " . $this->dbworker->prepare_for_query($value, $this->fields[$key_field]);
141: }
142:
143: $where_clause = "where " . $tmp;
144: } // checkWhereClause
145:
146: /**
147: * This is internal auxiliary function for saving a record set from an array
148: * with key field values as array dimensions.
149: *
150: * It expands this multidimensional
151: * array into the set of flat records suitable for call {@see RecordsetManager::saveRecord()}.
152: *
153: * @param array $subarray
154: * The current subarray ro be processed.
155: *
156: * @param array $key_fields
157: * The array of the key fields. These are the fields that are used
158: * to uniquely identify a record.
159: *
160: * @param array &$parent_values
161: * The array of the values of the foreign keys
162: * in the form "field_name" => "value".
163: *
164: * @param array &$record
165: * The array where the resulting flat record is built.
166: *
167: * @param string $identity_field
168: * The name of the identity field if exists. If the identity field is specified
169: * and the record does not exist yet in the table, the source array is extended
170: * with a pair "identity field" => "identity value" issued by the database by this
171: * insert operation.
172: *
173: * @return void
174: *
175: * @throws \Exception
176: * It might throw an exception in the case of any errors:
177: *
178: * - if some parameters are missing.
179: * - if dbworker does not extend {@see \SmartFactory\DatabaseWorkers\DBWorker}.
180: * - if some parameters are not of the proper type.
181: * - if the query fails or if some object names are invalid.
182: *
183: * @author Oleg Schildt
184: */
185: protected function processSubarray(array $subarray, array $key_fields, array &$parent_values, array &$record, string $identity_field): void
186: {
187: $current_key = array_shift($key_fields);
188:
189: foreach ($subarray as $key => $value) {
190: if (!empty($current_key)) {
191: if (!empty($parent_values[$current_key])) {
192: $record[$current_key] = $parent_values[$current_key];
193: } else {
194: $record[$current_key] = $key;
195: }
196:
197: $this->processSubarray($value, $key_fields, $parent_values, $record, $identity_field);
198: } else {
199: $record[$key] = $value;
200: }
201: }
202:
203: if (empty($current_key)) {
204: $where_clause = [];
205:
206: foreach ($this->key_fields as $field) {
207: if (!empty($record[$field])) {
208: $where_clause[$field] = $record[$field];
209: }
210: }
211:
212: $this->saveRecord($record, $where_clause, $identity_field);
213: }
214: } // processSubarray
215:
216: /**
217: * Sets the dbworker to be used for working with the database.
218: *
219: * @param DBWorker $dbworker
220: * The dbworker to be used for working with the database.
221: *
222: * @return void
223: *
224: * @see RecordsetManager::getDBWorker()
225: *
226: * @author Oleg Schildt
227: */
228: public function setDBWorker(DBWorker $dbworker): void
229: {
230: $this->dbworker = $dbworker;
231: } // setDBWorker
232:
233: /**
234: * Returns the dbworker to be used for working with the database.
235: *
236: * @return ?\SmartFactory\DatabaseWorkers\DBWorker
237: * Returns the dbworker to be used for working with the database.
238: *
239: * @throws DBWorkerException
240: * It might throw exceptions in the case of any errors.
241: *
242: * @author Oleg Schildt
243: * @see RecordsetManager::getDBWorker()
244: *
245: */
246: public function getDBWorker(): ?\SmartFactory\DatabaseWorkers\DBWorker
247: {
248: $this->dbworker?->connect();
249:
250: return $this->dbworker;
251: } // getDBWorker
252:
253: /**
254: * Defines the field mappings for working with record sets based on a table.
255: *
256: * @param string $table
257: * The name of the table.
258: *
259: * @param array $fields
260: * The array of fields in the form "field name" => "field type".
261: *
262: * @param array $key_fields
263: * The array of key fields. These are the fields that are used
264: * to uniquely identify a record.
265: *
266: * @return void
267: *
268: * @throws \Exception
269: * It might throw an exception in the case of any errors:
270: *
271: * - if some parameters are missing.
272: * - if dbworker does not extend {@see \SmartFactory\DatabaseWorkers\DBWorker}.
273: * - if the query fails or if some object names are invalid.
274: *
275: * @see IRecordsetManager::describeTableFieldsQuery()
276: *
277: * @author Oleg Schildt
278: */
279: public function describeTableFields(string $table, array $fields, array $key_fields): void
280: {
281: $this->table = $table;
282: $this->fields = $fields;
283:
284: if (is_array($key_fields)) {
285: $this->key_fields = $key_fields;
286: } else {
287: $this->key_fields = [];
288: }
289:
290: $this->validateParameters("table");
291: } // describeTableFields
292:
293: /**
294: * Defines the field mappings for working with record sets based on a query.
295: *
296: * @param array $fields
297: * The array of fields in the form "field name" => "field type".
298: *
299: * @param array $key_fields
300: * The array of key fields. These are the fields that are used
301: * to uniquely identify a record.
302: *
303: * @return void
304: *
305: * @throws \Exception
306: * It might throw an exception in the case of any errors:
307: *
308: * - if some parameters are missing.
309: * - if dbworker does not extend {@see \SmartFactory\DatabaseWorkers\DBWorker}.
310: * - if the query fails or if some object names are invalid.
311: *
312: * @see IRecordsetManager::describeTableFields()
313: *
314: * @author Oleg Schildt
315: */
316: public function describeTableFieldsQuery(array $fields, array $key_fields): void
317: {
318: $this->fields = $fields;
319:
320: if (is_array($key_fields)) {
321: $this->key_fields = $key_fields;
322: } else {
323: $this->key_fields = [];
324: }
325:
326: $this->validateParameters("query");
327: } // describeTableFieldsQuery
328:
329: /**
330: * Deletes records by a given where clause.
331: *
332: * @param array|string $where_clause
333: * The where clause that should restrict the result. If an array of keys is passed,
334: * the where clause is build automatically based on it.
335: *
336: * @return void
337: *
338: * @throws \Exception
339: * It might throw an exception in the case of any errors:
340: *
341: * - if some parameters are missing.
342: * - if dbworker does not extend {@see \SmartFactory\DatabaseWorkers\DBWorker}.
343: * - if some parameters are not of the proper type.
344: * - if the query fails or if some object names are invalid.
345: *
346: * @see RecordsetManager::saveRecord()
347: * @see RecordsetManager::deleteRecordsQuery()
348: *
349: * @uses \SmartFactory\DatabaseWorkers\DBWorker
350: *
351: * @author Oleg Schildt
352: */
353: public function deleteRecords(array|string $where_clause): void
354: {
355: $this->validateParameters("table");
356:
357: $this->checkWhereClause($where_clause);
358:
359: $query = "delete from " . $this->table . "\n";
360:
361: $query .= $where_clause;
362:
363: $this->deleteRecordsQuery($query);
364: } // deleteRecords
365:
366: /**
367: * Deletes records by a given query.
368: *
369: * @param string $query
370: * The query to be used.
371: *
372: * @return void
373: *
374: * @throws \Exception
375: * It might throw an exception in the case of any errors:
376: *
377: * - if some parameters are missing.
378: * - if dbworker does not extend {@see \SmartFactory\DatabaseWorkers\DBWorker}.
379: * - if some parameters are not of the proper type.
380: * - if the query fails or if some object names are invalid.
381: *
382: * @see RecordsetManager::deleteRecords()
383: *
384: * @uses \SmartFactory\DatabaseWorkers\DBWorker
385: *
386: * @author Oleg Schildt
387: */
388: public function deleteRecordsQuery(string $query): void
389: {
390: $this->validateParameters("query");
391:
392: $this->dbworker->connect();
393:
394: $this->dbworker->execute_query($query);
395: } // deleteRecordsQuery
396:
397: /**
398: * Loads a record into an array in the form "field_name" => "value" based on a table.
399: *
400: * @param array &$record
401: * The target array where the data should be loaded.
402: *
403: * @param array|string $where_clause
404: * The where clause that should restrict the result to one record. If an array of keys is passed,
405: * the where clause is build automatically based on it.
406: *
407: * @return void
408: *
409: * @throws \Exception
410: * It might throw an exception in the case of any errors:
411: *
412: * - if some parameters are missing.
413: * - if dbworker does not extend {@see \SmartFactory\DatabaseWorkers\DBWorker}.
414: * - if some parameters are not of the proper type.
415: * - if the query fails or if some object names are invalid.
416: *
417: * @see RecordsetManager::saveRecord()
418: * @see RecordsetManager::loadRecordSet()
419: * @see RecordsetManager::loadRecordQuery()
420: *
421: * @uses \SmartFactory\DatabaseWorkers\DBWorker
422: *
423: * @author Oleg Schildt
424: */
425: public function loadRecord(array &$record, array|string $where_clause): void
426: {
427: $this->validateParameters("table");
428:
429: $this->checkWhereClause($where_clause);
430:
431: $query = "select\n";
432:
433: $query .= implode(", ", array_keys($this->fields)) . "\n";
434:
435: $query .= "from " . $this->table . "\n";
436:
437: $query .= $where_clause;
438:
439: $this->loadRecordQuery($record, $query);
440: } // loadRecord
441:
442: /**
443: * Loads a record into an array in the form "field_name" => "value".
444: *
445: * @param array &$record
446: * The target array where the data should be loaded.
447: *
448: * @param string $query
449: * The query to be used.
450: *
451: * @return void
452: *
453: * @throws \Exception
454: * It might throw an exception in the case of any errors:
455: *
456: * - if some parameters are missing.
457: * - if dbworker does not extend {@see \SmartFactory\DatabaseWorkers\DBWorker}.
458: * - if some parameters are not of the proper type.
459: * - if the query fails or if some object names are invalid.
460: *
461: * @see RecordsetManager::loadRecord()
462: * @see RecordsetManager::loadRecordSetQuery()
463: *
464: * @uses \SmartFactory\DatabaseWorkers\DBWorker
465: *
466: * @author Oleg Schildt
467: */
468: public function loadRecordQuery(array &$record, string $query): void
469: {
470: $this->validateParameters("query");
471:
472: $this->dbworker->connect();
473:
474: $this->dbworker->execute_query($query);
475:
476: if ($this->dbworker->fetch_row()) {
477: foreach ($this->fields as $field => $type) {
478: $record[$field] = $this->dbworker->field_by_name($field, $type);
479: }
480: }
481:
482: $this->dbworker->free_result();
483: } // loadRecordQuery
484:
485: /**
486: * Loads records into an array in the form
487: *
488: * $records["key_field1"]["key_field2"]["key_fieldN"]["field_name"] = "value".
489: *
490: * baed on a table.
491: *
492: * @param array &$records
493: * The target array where the data should be loaded.
494: *
495: * @param array|string $where_clause
496: * The where clause that should restrict the result. If an array of keys is passed,
497: * the where clause is build automatically based on it.
498: *
499: * @param string $order_clause
500: * The order clause to sort the results.
501: *
502: * @param int $limit
503: * The limit how many records should be loaded. 0 for unlimited.
504: *
505: * @return void
506: *
507: * @throws \Exception
508: * It might throw an exception in the case of any errors:
509: *
510: * - if some parameters are missing.
511: * - if dbworker does not extend {@see \SmartFactory\DatabaseWorkers\DBWorker}.
512: * - if some parameters are not of the proper type.
513: * - if the query fails or if some object names are invalid.
514: *
515: * @see RecordsetManager::loadRecord()
516: * @see RecordsetManager::saveRecordSet()
517: * @see RecordsetManager::loadRecordSetQuery()
518: *
519: * @uses \SmartFactory\DatabaseWorkers\DBWorker
520: *
521: * @author Oleg Schildt
522: */
523: public function loadRecordSet(array &$records, array|string $where_clause, string $order_clause = "", int $limit = 0): void
524: {
525: $this->validateParameters("table");
526:
527: $this->checkWhereClause($where_clause);
528:
529: $query = $this->dbworker->build_select_query($this->table, array_keys($this->fields), $where_clause, $order_clause, $limit);
530:
531: $this->loadRecordSetQuery($records, $query);
532: } // loadRecordSet
533:
534: /**
535: * Loads records into an array in the form
536: *
537: * $records["key_field1"]["key_field2"]["key_fieldN"]["field_name"] = "value".
538: *
539: * baed on a query.
540: *
541: * @param array &$records
542: * The target array where the data should be loaded.
543: *
544: * @param string $query
545: * The query to be used.
546: *
547: * @return void
548: *
549: * @throws \Exception
550: * It might throw an exception in the case of any errors:
551: *
552: * - if some parameters are missing.
553: * - if dbworker does not extend {@see \SmartFactory\DatabaseWorkers\DBWorker}.
554: * - if some parameters are not of the proper type.
555: * - if the query fails or if some object names are invalid.
556: *
557: * @see RecordsetManager::loadRecordSet()
558: * @see RecordsetManager::loadRecordQuery()
559: *
560: * @uses \SmartFactory\DatabaseWorkers\DBWorker
561: *
562: * @author Oleg Schildt
563: */
564: public function loadRecordSetQuery(array &$records, string $query): void
565: {
566: $this->validateParameters("query");
567:
568: $this->dbworker->connect();
569:
570: $this->dbworker->execute_query($query);
571:
572: while ($this->dbworker->fetch_row()) {
573: $dimensions = [];
574: $row = [];
575:
576: foreach ($this->fields as $field => $type) {
577: $val = $this->dbworker->field_by_name($field, $type);
578:
579: $row[$field] = $val;
580:
581: if (in_array($field, $this->key_fields)) {
582: $dimensions[$field] = $val;
583: }
584: }
585:
586: if (!empty($dimensions)) {
587: $reference = &$records;
588:
589: foreach ($dimensions as $dval) {
590: if (empty($reference[$dval])) {
591: $reference[$dval] = [];
592: }
593: $reference = &$reference[$dval];
594: }
595:
596: $reference = $row;
597:
598: unset($reference);
599: } else {
600: $records[] = $row;
601: }
602: }
603:
604: $this->dbworker->free_result();
605: } // loadRecordSetQuery
606:
607: /**
608: * Saves a record from an array in the form "field_name" => "value" into the table.
609: *
610: * @param array &$record
611: * The source array with the data to be saved.
612: *
613: * @param array|string $where_clause
614: * The where clause that should be used to define whether a record should be inserted or updated. If an array of keys is passed,
615: * the where clause is build automatically based on it.
616: *
617: * @param string $identity_field
618: * The name of the identity field if exists. If the identity field is specified
619: * and the record does not exist yet in the table, the source array is extended
620: * with a pair "identity field" => "identity value" issued by the database by this
621: * insert operation.
622: *
623: * @return void
624: *
625: * @throws \Exception
626: * It might throw an exception in the case of any errors:
627: *
628: * - if some parameters are missing.
629: * - if dbworker does not extend {@see \SmartFactory\DatabaseWorkers\DBWorker}.
630: * - if some parameters are not of the proper type.
631: * - if the query fails or if some object names are invalid.
632: *
633: * @see RecordsetManager::loadRecord()
634: * @see RecordsetManager::saveRecordSet()
635: *
636: * @uses DatabaseWorkers\DBWorker
637: *
638: * @author Oleg Schildt
639: */
640: public function saveRecord(array &$record, array|string $where_clause, string $identity_field = ""): void
641: {
642: $this->validateParameters("table");
643:
644: $this->dbworker->connect();
645:
646: $must_insert = false;
647:
648: // key_fields not specified - always insert
649: // identity firld exists but its value is not specified - always insert
650: if (empty($this->key_fields) || empty($where_clause)) {
651: $must_insert = true;
652: } else {
653: // check existence
654:
655: $query = "select\n";
656: $query .= "1\n";
657: $query .= "from " . $this->table . "\n";
658:
659: $this->checkWhereClause($where_clause);
660:
661: $query .= $where_clause;
662:
663: $this->dbworker->execute_query($query);
664:
665: if (!$this->dbworker->fetch_row()) {
666: $must_insert = true;
667: }
668:
669: $this->dbworker->free_result();
670: }
671:
672: // saving
673:
674: $update_string = "";
675: $insert_fields = "";
676: $insert_values = "";
677:
678: foreach ($this->fields as $field => $type) {
679: // if autoincrement
680: if ($must_insert && $field == $identity_field) {
681: continue;
682: }
683:
684: // The value for the field is not passed in the record,
685: // skip it
686: if (!array_key_exists($field, $record)) {
687: continue;
688: }
689:
690: $value = $this->dbworker->prepare_for_query($record[$field] ?? "", $this->fields[$field] ?? "");
691:
692: $update_string .= $field . " = " . $value . ",\n";
693: $insert_fields .= $field . ", ";
694: $insert_values .= $value . ", ";
695: }
696:
697: if ($must_insert) {
698: $query = "insert into " . $this->table . " (" . trim($insert_fields, ", ") . ")\n";
699: $query .= "values (" . trim($insert_values, ", ") . ")\n";
700:
701: $this->dbworker->execute_query($query);
702: } elseif (!empty($update_string)) {
703: $query = "update " . $this->table . " set\n";
704: $query .= trim($update_string, ",\n") . "\n";
705: $query .= $where_clause;
706:
707: $this->dbworker->execute_query($query);
708: }
709:
710: if ($must_insert && !empty($identity_field)) {
711: $record[$identity_field] = $this->dbworker->insert_id();
712: }
713: } // saveRecord
714:
715: /**
716: * Saves records from an array in the form
717: * $records["key_field1"]["key_field2"]["key_fieldN"]["field_name"] = "value" into the table.
718: *
719: * @param array $records
720: * The source array with the data to be saved.
721: *
722: * @param array $parent_values
723: * If this recordset is a child subset of data to be saved, you can set the values of the foreign keys
724: * in the form "field_name" => "value".
725: *
726: * @param string $identity_field
727: * The name of the identity field if exists. If the identity field is specified
728: * and the record does not exist yet in the table, the source array is extended
729: * with a pair "identity field" => "identity value" issued by the database by this
730: * insert operation.
731: *
732: * @return void
733: *
734: * @throws \Exception
735: * It might throw an exception in the case of any errors:
736: *
737: * - if some parameters are missing.
738: * - if dbworker does not extend {@see \SmartFactory\DatabaseWorkers\DBWorker}.
739: * - if some parameters are not of the proper type.
740: * - if the query fails or if some object names are invalid.
741: *
742: * @see RecordsetManager::loadRecordSet()
743: * @see RecordsetManager::saveRecord()
744: *
745: * @uses DatabaseWorkers\DBWorker
746: *
747: * @author Oleg Schildt
748: */
749: public function saveRecordSet(array $records, array $parent_values = [], string $identity_field = ""): void
750: {
751: $this->validateParameters("table");
752:
753: $this->dbworker->connect();
754:
755: $key_fields = $this->key_fields;
756: $current_key = array_shift($key_fields);
757:
758: foreach ($records as $key => $value) {
759: $record = [];
760:
761: if (!empty($parent_values[$current_key])) {
762: $record[$current_key] = $parent_values[$current_key];
763: } else {
764: $record[$current_key] = $key;
765: }
766:
767: $this->processSubarray($value, $key_fields, $parent_values, $record, $identity_field);
768: }
769: } // saveRecordSet
770:
771: /**
772: * Counts records based on the where clause.
773: *
774: * @param array|string $where_clause
775: * The where clause that should restrict the result. If an array of keys is passed,
776: * the where clause is build automatically based on it.
777: *
778: * @return int
779: * Returns the number of records.
780: *
781: * @throws \Exception
782: * It might throw exceptions in the case of any errors.
783: *
784: * @uses \SmartFactory\DatabaseWorkers\DBWorker
785: *
786: * @author Oleg Schildt
787: * @see IRecordsetManager::countRecordsQuery()
788: *
789: */
790: public function countRecords(array|string $where_clause): int
791: {
792: $this->validateParameters("table");
793:
794: $this->checkWhereClause($where_clause);
795:
796: $query = "select\n";
797:
798: $query .= "count(*)\n";
799:
800: $query .= "from " . $this->table . "\n";
801:
802: if (!empty($where_clause)) {
803: $query .= $where_clause . "\n";
804: }
805:
806: return $this->countRecordsQuery($query);
807: } // countRecords
808:
809: /**
810: * Counts records based on the query.
811: *
812: * @param string $query
813: * The query to be used.
814: *
815: * @return int
816: * Returns the number of records.
817: *
818: * @throws \Exception
819: * It might throw exceptions in the case of any errors.
820: *
821: * @see IRecordsetManager::countRecords()
822: *
823: * @uses \SmartFactory\DatabaseWorkers\DBWorker
824: *
825: * @author Oleg Schildt
826: */
827: public function countRecordsQuery(string $query): int
828: {
829: $this->validateParameters("query");
830:
831: $this->dbworker->connect();
832:
833: $cnt = 0;
834:
835: $this->dbworker->execute_query($query);
836:
837: if ($this->dbworker->fetch_row()) {
838: $cnt = $this->dbworker->field_by_num(0);
839: }
840:
841: $this->dbworker->free_result();
842:
843: return $cnt;
844: } // countRecordsQuery
845:
846: /**
847: * Starts the translation.
848: *
849: * @return void
850: *
851: * @throws DBWorkerException
852: * It might throw an exception in the case of any errors.
853: *
854: * @see RecordsetManager::commit_transaction()
855: * @see RecordsetManager::rollback_transaction()
856: *
857: * @author Oleg Schildt
858: */
859: public function start_transaction(): void
860: {
861: $this->dbworker->connect();
862:
863: $this->dbworker->start_transaction();
864: }
865:
866: /**
867: * Commits the translation.
868: *
869: * @return void
870: *
871: * @throws DBWorkerException
872: * It might throw an exception in the case of any errors.
873: *
874: * @see RecordsetManager::start_transaction()
875: * @see RecordsetManager::rollback_transaction()
876: *
877: * @author Oleg Schildt
878: */
879: public function commit_transaction(): void
880: {
881: $this->dbworker->connect();
882:
883: $this->dbworker->commit_transaction();
884: }
885:
886: /**
887: * Rolls back the translation.
888: *
889: * @return void
890: *
891: * @throws DBWorkerException
892: * It might throw an exception in the case of any errors.
893: *
894: * @see RecordsetManager::start_transaction()
895: * @see RecordsetManager::commit_transaction()
896: *
897: * @author Oleg Schildt
898: */
899: public function rollback_transaction(): void
900: {
901: $this->dbworker->connect();
902:
903: $this->dbworker->rollback_transaction();
904: }
905:
906: /**
907: * Escapes the string so that it can be used in the query without causing an error.
908: *
909: * @param string $str
910: * The string to be escaped.
911: *
912: * @return string
913: * Returns the escaped string.
914: *
915: * @see RecordsetManager::format_date()
916: * @see RecordsetManager::format_datetime()
917: * @see RecordsetManager::quotes_or_null()
918: * @see RecordsetManager::number_or_null()
919: *
920: * @author Oleg Schildt
921: */
922: public function escape(string $str): string
923: {
924: return $this->dbworker->escape($str);
925: }
926:
927: /**
928: * Escapes the string so that it can be used in the query without causing an error or returns the sstring NULL if the string is empty.
929: *
930: * @param string $str
931: * The string to be escaped.
932: *
933: * @return string
934: * Returns the escaped string.
935: *
936: * @see RecordsetManager::escape()
937: * @see RecordsetManager::format_date()
938: * @see RecordsetManager::format_datetime()
939: * @see RecordsetManager::number_or_null()
940: *
941: * @author Oleg Schildt
942: */
943: function quotes_or_null(string $str): string
944: {
945: return $this->dbworker->quotes_or_null($str);
946: }
947:
948: /**
949: * Checks that the value is a number and returns it, or returns the string NULL if the value is empty.
950: *
951: * @param string $str
952: * The string to be escaped.
953: *
954: * @return string
955: * Returns the escaped string.
956: *
957: * @throws DBWorkerException
958: * It might throw an exception in the case of any errors.
959: *
960: * @see RecordsetManager::escape()
961: * @see RecordsetManager::format_date()
962: * @see RecordsetManager::format_datetime()
963: * @see RecordsetManager::quotes_or_null()
964: *
965: * @author Oleg Schildt
966: */
967: function number_or_null(string $str): string
968: {
969: return $this->dbworker->number_or_null($str);
970: }
971:
972: /**
973: * Formats the date to a string compatible for the corresponding database.
974: *
975: * @param int $date
976: * The date value as timestamp.
977: *
978: * @return string
979: * Returns the string representation of the date compatible for the corresponding database.
980: *
981: * @see RecordsetManager::escape()
982: * @see RecordsetManager::format_datetime()
983: * @see RecordsetManager::quotes_or_null()
984: * @see RecordsetManager::number_or_null()
985: *
986: * @author Oleg Schildt
987: */
988: public function format_date(int $date): string
989: {
990: return $this->dbworker->format_date($date);
991: }
992:
993: /**
994: * Formats the date/time to a string compatible for the corresponding database.
995: *
996: * @param int $datetime
997: * The date/time value as timestamp.
998: *
999: * @return string
1000: * Returns the string representation of the date/time compatible for the corresponding database.
1001: *
1002: * @see RecordsetManager::escape()
1003: * @see RecordsetManager::format_date()
1004: * @see RecordsetManager::quotes_or_null()
1005: * @see RecordsetManager::number_or_null()
1006: *
1007: * @author Oleg Schildt
1008: */
1009: public function format_datetime(int $datetime): string
1010: {
1011: return $this->dbworker->format_datetime($datetime);
1012: }
1013: } // RecordsetManager