1: <?php
2: /**
3: * This file contains the declaration of the abstract base class DBWorker
4: * for all dbworkers for different databases.
5: *
6: * @package Database
7: *
8: * @author Oleg Schildt
9: */
10:
11: namespace SmartFactory\DatabaseWorkers;
12:
13: use \SmartFactory\Interfaces\IInitable;
14:
15: /**
16: * This is the abstract base class for all dbworkers for different databases.
17: *
18: * This is a wrapper around the database connectivity. It offers a universal
19: * common way for working with databases of different types. Currently, MySQL and
20: * MS SQL are supported. If in the future, there will be a better solution, or
21: * the current solution turns out to be inefficient in a new version of PHP,
22: * we can easily reimplement the DB wrapper without touching the business logic code.
23: * Adding support for new database types is also much easier with this wrapping approach.
24: *
25: * @author Oleg Schildt
26: */
27: abstract class DBWorker implements IInitable
28: {
29: /**
30: * The constant for the error: connection data is incomplete.
31: *
32: * @var string
33: *
34: * @author Oleg Schildt
35: */
36: const string ERR_CONNECTION_DATA_INCOMPLETE = "err_connection_data_incomplete";
37:
38: /**
39: * The constant for the error: connection to the server failed.
40: *
41: * @var string
42: *
43: * @author Oleg Schildt
44: */
45: const string ERR_CONNECTION_FAILED = "err_connection_failed";
46:
47: /**
48: * The constant for the error: host not reachable.
49: *
50: * @var string
51: *
52: * @author Oleg Schildt
53: */
54: const string ERR_HOST_UNREACHABLE = "err_host_unreachable";
55:
56: /**
57: * The constant for the error: wrong user credentials.
58: *
59: * @var string
60: *
61: * @author Oleg Schildt
62: */
63: const string ERR_WRONG_USER_CREDENTIALS = "err_wrong_user_credentials";
64:
65: /**
66: * The constant for the error: database not found.
67: *
68: * @var string
69: *
70: * @author Oleg Schildt
71: */
72: const string ERR_DATABASE_NOT_FOUND = "err_database_not_found";
73:
74: /**
75: * The constant for the error: query failed.
76: *
77: * @var string
78: *
79: * @author Oleg Schildt
80: */
81: const string ERR_QUERY_FAILED = "err_query_failed";
82:
83: /**
84: * The constant for the error: not connected.
85: *
86: * @var string
87: *
88: * @author Oleg Schildt
89: */
90: const string ERR_NOT_CONNECTED = "err_not_connected";
91:
92: /**
93: * The constant for the error: stream invalid.
94: *
95: * @var string
96: *
97: * @author Oleg Schildt
98: */
99: const string ERR_STREAM_ERROR = "err_stream_error";
100:
101: /**
102: * The constant for the error: wrong data format.
103: *
104: * @var string
105: *
106: * @author Oleg Schildt
107: */
108: const string ERR_WRONG_DATA_FORMAT = "err_data_format";
109:
110: /**
111: * The constant for the returning field value as is.
112: *
113: * @var int
114: *
115: * @author Oleg Schildt
116: */
117: const int DB_AS_IS = 0;
118:
119: /**
120: * The constant for the number type.
121: *
122: * @var int
123: *
124: * @author Oleg Schildt
125: */
126: const int DB_NUMBER = 1;
127:
128: /**
129: * The constant for the string type.
130: *
131: * @var int
132: *
133: * @author Oleg Schildt
134: */
135: const int DB_STRING = 2;
136:
137: /**
138: * The constant for the date type.
139: *
140: * @var int
141: *
142: * @author Oleg Schildt
143: */
144: const int DB_DATE = 3;
145:
146: /**
147: * The constant for the date/time type.
148: *
149: * @var int
150: *
151: * @author Oleg Schildt
152: */
153: const int DB_DATETIME = 4;
154:
155: /**
156: * The constant for the type geometry SRID 0.
157: *
158: * @var int
159: *
160: * @author Oleg Schildt
161: */
162: const int DB_GEOMETRY = 5;
163:
164: /**
165: * The constant for the type geometry SRID 4326 (latitude, longitude).
166: *
167: * @var int
168: *
169: * @author Oleg Schildt
170: */
171: const int DB_GEOMETRY_4326 = 6;
172:
173: /**
174: * The constant for the large objects.
175: *
176: * If a RDBMS supports stream reading, it is performed.
177: *
178: * @var int
179: *
180: * @author Oleg Schildt
181: */
182: const int DB_LARGE_OBJECT_STREAM = 7;
183:
184: /**
185: * Name or IP address of the server.
186: *
187: * @var string $db_server
188: *
189: * @author Oleg Schildt
190: */
191: protected string $db_server;
192:
193: /**
194: * Port of the server.
195: *
196: * @var string $db_port
197: *
198: * @author Oleg Schildt
199: */
200: protected string $db_port;
201:
202: /**
203: * Name of the database.
204: *
205: * @var string $db_name
206: *
207: * @author Oleg Schildt
208: */
209: protected string $db_name;
210:
211: /**
212: * Name of the database user.
213: *
214: * @var string $db_user
215: *
216: * @author Oleg Schildt
217: */
218: protected string $db_user;
219:
220: /**
221: * Password of the database user.
222: *
223: * @var string $db_password
224: *
225: * @author Oleg Schildt
226: */
227: protected string $db_password;
228:
229: /**
230: * This variable stores the last executed query.
231: *
232: * @var ?string $last_query
233: *
234: * @author Oleg Schildt
235: */
236: protected ?string $last_query = null;
237:
238: /**
239: * This variable stores the logging flag.
240: *
241: * @var bool $logging
242: *
243: * @author Oleg Schildt
244: */
245: protected bool $logging = false;
246: /**
247: * Flag property for storing the state whether it is clone or not.
248: *
249: * @var bool $is_clone
250: *
251: * @author Oleg Schildt
252: */
253: protected bool $is_clone = false;
254:
255: /**
256: * Initializes the dbworker with connection parameters.
257: *
258: * @param array $parameters
259: * The parameters may vary for each database.
260: *
261: * @return void
262: *
263: * @throws \Exception
264: * It might throw an exception in the case of any errors.
265: *
266: * @author Oleg Schildt
267: */
268: abstract public function init(array $parameters): void;
269:
270: /**
271: * Checks whether the extension is installed which is required for work with
272: * the corresponding database.
273: *
274: * @return bool
275: * The method should return true if the extension is installed, otherwise false.
276: *
277: * @see DBWorker::get_extension_name()
278: *
279: * @author Oleg Schildt
280: */
281: abstract public function is_extension_installed(): bool;
282:
283: /**
284: * Returns the name of the required PHP extension.
285: *
286: * @return string
287: * Returns the name of the required PHP extension.
288: *
289: * @see DBWorker::is_extension_installed()
290: *
291: * @author Oleg Schildt
292: */
293: abstract public function get_extension_name(): string;
294:
295: /**
296: * Returns the name of the supported database.
297: *
298: * @return string
299: * Returns the name of the supported database.
300: *
301: * @author Oleg Schildt
302: */
303: abstract public function get_rdbms_name(): string;
304:
305: /**
306: * Creates a clone of the dbworker that is using the same open
307: * connection.
308: *
309: * This might be useful if you want to execute some additional
310: * queries while iteration through the active results of a select query.
311: *
312: * @return DBWorker
313: * Returns the clone of this dbworker.
314: *
315: * @author Oleg Schildt
316: */
317: abstract public function create_clone(): DBWorker;
318:
319: /**
320: * Returns the connection state.
321: *
322: * @return bool
323: * Returns true if the connection is open, otherwise false.
324: *
325: * @see DBWorker::check_connection()
326: * @see DBWorker::connect()
327: * @see DBWorker::close_connection()
328: *
329: * @author Oleg Schildt
330: */
331: abstract public function is_connected(): bool;
332:
333: /**
334: * Check whether the connection exists and throws an exceptions if not.
335: *
336: * @return void
337: *
338: * @throws DBWorkerException
339: * It throws an exception if there is no connection.
340: *
341: * @see DBWorker::connect()
342: * @see DBWorker::is_connected()
343: * @see DBWorker::close_connection()
344: *
345: * @author Oleg Schildt
346: */
347: public function check_connection(): void
348: {
349: if (!$this->is_connected()) {
350: $err = "Database server not connected!";
351: trigger_error($err, E_USER_WARNING);
352: throw new DBWorkerException($err, DBWorker::ERR_NOT_CONNECTED);
353: }
354: } // check_connection
355:
356: /**
357: * Establishes the connection to the database using the connection
358: * settings parameters specified by the initialization.
359: *
360: * @return void
361: *
362: * @throws DBWorkerException
363: * It might throw an exception in the case of any errors.
364: *
365: * - if some parameters are missing.
366: *
367: * @see DBWorker::check_connection()
368: * @see DBWorker::is_connected()
369: * @see DBWorker::close_connection()
370: *
371: * @author Oleg Schildt
372: */
373: abstract public function connect(): void;
374:
375: /**
376: * Sets the database as working database.
377: *
378: * @param string $db_name
379: * The name of the database to be set as working database.
380: *
381: * @return void
382: *
383: * @throws DBWorkerException
384: * It might throw an exception in the case of any errors.
385: *
386: * @author Oleg Schildt
387: */
388: abstract public function use_database(string $db_name): void;
389:
390: /**
391: * Returns the name of the database schema if applicable.
392: *
393: * @return string
394: * Returns the name of the database schema if applicable, or an empty string.
395: *
396: * @see DBWorker::qualify_name_with_schema()
397: *
398: * @author Oleg Schildt
399: */
400: abstract public function get_schema(): string;
401:
402: /**
403: * Completes the name of a database object with the schema name if applicable.
404: *
405: * @param string $name
406: * The name of the database object to be completed with the schema name.
407: *
408: * @return string
409: * Returns the name of the database object with the schema name if applicable,
410: * otherwise the name of the database object remains unchanged.
411: *
412: * @see DBWorker::get_schema()
413: *
414: * @author Oleg Schildt
415: */
416: abstract public function qualify_name_with_schema(string $name): string;
417:
418: /**
419: * Executes the SQL query.
420: *
421: * @param string $query_string
422: * The SQL query to be executed.
423: *
424: * @return void
425: *
426: * @throws DBWorkerException
427: * It might throw an exception in the case of any errors.
428: *
429: * @author Oleg Schildt
430: */
431: abstract public function execute_query(string $query_string): void;
432:
433: /**
434: * Executes the SQL stored procedure.
435: *
436: * @param string $procedure
437: * The name of the SQL stored procedure.
438: *
439: * All subsequent parameters are the parameters of the SQL stored procedure.
440: *
441: * @return void
442: *
443: * @throws DBWorkerException
444: * It might throw an exception in the case of any errors.
445: *
446: * @author Oleg Schildt
447: */
448: abstract public function execute_procedure(string $procedure /* arg list */): void;
449:
450: /**
451: * Executes the prepared SQL query.
452: *
453: * @param mixed ...$args
454: * The number of parameters may vary and be zero. An array can also be passed.
455: * These are parameters of the prepared query.
456: *
457: * @return void
458: *
459: * @throws DBWorkerException
460: * It might throw an exception in the case of any errors.
461: *
462: * @see DBWorker::prepare_query()
463: * @see DBWorker::free_prepared_query()
464: *
465: * @author Oleg Schildt
466: */
467: abstract public function execute_prepared_query(...$args): void;
468:
469: /**
470: * Prepares the SQL query with bindable variables.
471: *
472: * @param string $query_string
473: * The SQL query to be prepared.
474: *
475: * @return void
476: *
477: * @throws DBWorkerException
478: * It might throw an exception in the case of any errors.
479: *
480: * @see DBWorker::execute_prepared_query()
481: * @see DBWorker::free_prepared_query()
482: *
483: * @author Oleg Schildt
484: */
485: abstract public function prepare_query(string $query_string): void;
486:
487: /**
488: * Stores long data from a stream.
489: *
490: * @param string $query_string
491: * The SQL query to be used for storing the long data.
492: *
493: * @param resource $stream
494: * The opened valid stream for reading the long data.
495: *
496: * Example:
497: * ```php
498: * $stream = fopen(".../large_binary.jpg", "rb");
499: *
500: * if(!$dbw->stream_long_data("UPDATE LARGE_DATA SET BLOB_DATA = ? WHERE ID = 1", $stream))
501: * {
502: * error reporting ...;
503: * }
504: * ```
505: *
506: * @return void
507: *
508: * @throws DBWorkerException
509: * It might throw an exception in the case of any errors.
510: *
511: * @author Oleg Schildt
512: */
513: abstract public function stream_long_data(string $query_string, $stream): void;
514:
515: /**
516: * Closes the currently opened connection.
517: *
518: * @return void
519: *
520: * @throws DBWorkerException
521: * It might throw an exception in the case of any errors.
522: *
523: * @see DBWorker::is_connected()
524: * @see DBWorker::check_connection()
525: * @see DBWorker::connect()
526: *
527: * @author Oleg Schildt
528: */
529: abstract public function close_connection(): void;
530:
531: /**
532: * Starts the translation.
533: *
534: * @return void
535: *
536: * @throws DBWorkerException
537: * It might throw an exception in the case of any errors.
538: *
539: * @see DBWorker::commit_transaction()
540: * @see DBWorker::rollback_transaction()
541: *
542: * @author Oleg Schildt
543: */
544: abstract public function start_transaction(): void;
545:
546: /**
547: * Commits the transation.
548: *
549: * @return void
550: *
551: * @throws DBWorkerException
552: * It might throw an exception in the case of any errors.
553: *
554: * @see DBWorker::start_transaction()
555: * @see DBWorker::rollback_transaction()
556: *
557: * @author Oleg Schildt
558: */
559: abstract public function commit_transaction(): void;
560:
561: /**
562: * Rolls back the translation.
563: *
564: * @throws DBWorkerException
565: * It might throw an exception in the case of any errors.
566: *
567: * @return void
568: *
569: * @see DBWorker::start_transaction()
570: * @see DBWorker::commit_transaction()
571: *
572: * @author Oleg Schildt
573: */
574: abstract public function rollback_transaction(): void;
575:
576: /**
577: * Frees the result of the previously executed retrieving query.
578: *
579: * It should be called only for the retrieving queries.
580: *
581: * @return void
582: *
583: * @throws DBWorkerException
584: * It might throw an exception in the case of any errors.
585: *
586: * @author Oleg Schildt
587: */
588: abstract public function free_result(): void;
589:
590: /**
591: * Frees the prepared query.
592: *
593: * It should be called after all executions of the prepared query.
594: *
595: * @return void
596: *
597: * @throws DBWorkerException
598: * It might throw an exception in the case of any errors.
599: *
600: * @see DBWorker::prepare_query()
601: * @see DBWorker::execute_prepared_query()
602: *
603: * @author Oleg Schildt
604: */
605: abstract public function free_prepared_query(): void;
606:
607: /**
608: * Fetches the next row of data from the result of the execution of the retrieving query.
609: *
610: * @return bool
611: * Returns true if the next row exists and has been successfully fetched, otherwise false.
612: *
613: * Example:
614: * ```php
615: * if(!$dbw->execute_query("SELECT FIRST_NAME, LAST_NAME FROM USERS"))
616: * {
617: * error reporting ...;
618: * }
619: *
620: * while($dbw->fetch_row())
621: * {
622: * echo $dbw->field_by_name("FIRST_NAME") . " " . $dbw->field_by_name("LAST_NAME") . "<br>";
623: * }
624: *
625: * $dbw->free_result();
626: * ```
627: *
628: * @throws DBWorkerException
629: * It might throw an exception in the case of any errors.
630: *
631: * @author Oleg Schildt
632: */
633: abstract public function fetch_row(): bool;
634:
635: /**
636: * Fetches all rows from the result into an array.
637: *
638: * @param array &$rows
639: * Target array for loading the results.
640: *
641: * @param array|null $dimension_keys
642: * Array of the column names that should be used as dimensions.
643: *
644: * Per default, the rows are fetched as two-dimensional array.
645: *
646: * Example:
647: * ```php
648: * $rows = [];
649: * $dbw->fetch_array($rows);
650: *
651: * rows[n] = ["col1" => "val1", "col2" => "val2", "col3" => "val3", ...]
652: * ```
653: * If the dimension columns are specified, their values are used for the dimensions.
654: *
655: * Example:
656: * ```php
657: * $rows = [];
658: * $dbw->fetch_array($rows, ["col1", "col2"]);
659: *
660: * rows["val1"]["val2"] = ["col3" => "val3", ...]
661: * ```
662: *
663: * @return int
664: * Returns the number of the fetched rows. It might be also 0. In the case of
665: * any error returns false.
666: *
667: * @throws DBWorkerException
668: * It might throw an exception in the case of any errors.
669: *
670: * @author Oleg Schildt
671: */
672: abstract public function fetch_array(array &$rows, ?array $dimension_keys = null): int;
673:
674: /**
675: * Returns the number of the rows fetched by the last retrieving query.
676: *
677: * @return int
678: * Returns the number of the rows fetched by the last retrieving query.
679: *
680: * @throws DBWorkerException
681: * It might throw an exception in the case of any errors.
682: *
683: * @author Oleg Schildt
684: */
685: abstract public function fetched_count(): int;
686:
687: /**
688: * Returns the number of the rows affected by the last modification query.
689: *
690: * @return int
691: * Returns the number of the rows affected by the last modification query.
692: *
693: * @throws DBWorkerException
694: * It might throw an exception in the case of any errors.
695: *
696: * @author Oleg Schildt
697: */
698: abstract public function affected_count(): int;
699:
700: /**
701: * Returns the number of the fields in the result of the last retrieving query.
702: *
703: * @return int
704: * Returns the number of the fields in the result of the last retrieving query.
705: *
706: * @throws DBWorkerException
707: * It might throw an exception in the case of any errors.
708: *
709: * @author Oleg Schildt
710: */
711: abstract public function field_count(): int;
712:
713: /**
714: * Returns the value of the auto increment field by the last insertion.
715: *
716: * @return ?int
717: * Returns the value of the auto increment field by the last insertion.
718: *
719: * @throws DBWorkerException
720: * It might throw an exception in the case of any errors.
721: *
722: * @author Oleg Schildt
723: */
724: abstract public function insert_id(): ?int;
725:
726: /**
727: * Returns the value of a field specified by name.
728: *
729: * @param string $name
730: * The name of the field.
731: *
732: * @param int $type
733: * The type of the field.
734: *
735: * @return mixed
736: * Returns the value of a field specified by name. In the case
737: * of any error returns null.
738: *
739: * @see DBWorker::field_by_num()
740: * @see DBWorker::field_name()
741: *
742: * @author Oleg Schildt
743: */
744: abstract public function field_by_name(string $name, int $type = self::DB_AS_IS): mixed;
745:
746: /**
747: * Returns the value of a field specified by number.
748: *
749: * @param int $num
750: * The number of the field.
751: *
752: * @param int $type
753: * The type of the field.
754: *
755: * @return mixed
756: * Returns the value of a field specified by number. In the case
757: * of any error returns null.
758: *
759: * @see DBWorker::field_by_name()
760: * @see DBWorker::field_info_by_num()
761: * @see DBWorker::field_name()
762: *
763: * @author Oleg Schildt
764: */
765: abstract public function field_by_num(int $num, int $type = self::DB_AS_IS): mixed;
766:
767: /**
768: * Returns the meta information about the field as an object with properties.
769: *
770: * @param int $num
771: * The number of the field.
772: *
773: * @return ?array
774: * Returns the associative array with properties. In the case
775: * of any error returns null.
776: *
777: * - $info["name"] - name of the field.
778: * - $info["type"] - type of the field.
779: * - $info["size"] - size of the field.
780: * - $info["binary"] - whether the filed is binary.
781: * - $info["numeric"] - whether the filed is numeric.
782: * - $info["datetime"] - whether the filed is datetime.
783: *
784: * @see DBWorker::field_by_num()
785: * @see DBWorker::field_name()
786: *
787: * @author Oleg Schildt
788: */
789: abstract public function field_info_by_num(int $num): ?array;
790:
791: /**
792: * Returns the name of the field by number.
793: *
794: * @param int $num
795: * The number of the field.
796: *
797: * @return ?string
798: * Returns the value of a field specified by number as an object with properties. In the case
799: * of any error returns null.
800: *
801: * @see DBWorker::field_by_num()
802: * @see DBWorker::field_info_by_num()
803: *
804: * @author Oleg Schildt
805: */
806: abstract public function field_name(int $num): ?string;
807:
808: /**
809: * Escapes the string so that it can be used in the query without causing an error.
810: *
811: * @param string $str
812: * The string to be escaped.
813: *
814: * @return string
815: * Returns the escaped string.
816: *
817: * @see DBWorker::format_date()
818: * @see DBWorker::format_datetime()
819: * @see DBWorker::quotes_or_null()
820: * @see DBWorker::number_or_null()
821: *
822: * @author Oleg Schildt
823: */
824: abstract public function escape(string $str): string;
825:
826: /**
827: * Escapes the string so that it can be used in the query without causing an error or returns the string NULL if the string is empty.
828: *
829: * @param string $str
830: * The string to be escaped.
831: *
832: * @return string
833: * Returns the escaped string.
834: *
835: * @see DBWorker::escape()
836: * @see DBWorker::format_date()
837: * @see DBWorker::format_datetime()
838: * @see DBWorker::number_or_null()
839: *
840: * @author Oleg Schildt
841: */
842: function quotes_or_null(string $str): string
843: {
844: return $str === "" ? "null" : "'" . $this->escape($str) . "'";
845: }
846:
847: /**
848: * Checks that the value is a number and returns it, or returns the string NULL if the value is empty.
849: *
850: * @param string $str
851: * The string to be escaped.
852: *
853: * @return float|int|string
854: * Returns the escaped string.
855: *
856: * @throws DBWorkerException
857: * It might throw an exception in the case of any errors.
858: *
859: * @see DBWorker::escape()
860: * @see DBWorker::format_date()
861: * @see DBWorker::format_datetime()
862: * @see DBWorker::quotes_or_null()
863: *
864: * @author Oleg Schildt
865: */
866: function number_or_null(string $str): float|int|string
867: {
868: if (empty($str) && $str != "0") {
869: return "null";
870: }
871:
872: if (!is_numeric($str)) {
873: throw new DBWorkerException("Value '$str' is not a number!", DBWorker::ERR_WRONG_DATA_FORMAT);
874: }
875:
876: return $str;
877: }
878:
879: /**
880: * Formats the date to a string compatible for the corresponding database.
881: *
882: * @param int $date
883: * The date value as timestamp.
884: *
885: * @return string
886: * Returns the string representation of the date compatible for the corresponding database.
887: *
888: * @see DBWorker::escape()
889: * @see DBWorker::format_datetime()
890: * @see DBWorker::quotes_or_null()
891: * @see DBWorker::number_or_null()
892: *
893: * @author Oleg Schildt
894: */
895: abstract public function format_date(int $date): string;
896:
897: /**
898: * Formats the date/time to a string compatible for the corresponding database.
899: *
900: * @param int $datetime
901: * The date/time value as timestamp.
902: *
903: * @return string
904: * Returns the string representation of the date/time compatible for the corresponding database.
905: *
906: * @see DBWorker::escape()
907: * @see DBWorker::format_date()
908: * @see DBWorker::quotes_or_null()
909: * @see DBWorker::number_or_null()
910: *
911: * @author Oleg Schildt
912: */
913: abstract public function format_datetime(int $datetime): string;
914:
915: /**
916: * Prepares the value for putting to a query depending on its type. It does escaping, formatting
917: * and quotation if necessary.
918: *
919: * @param mixed $value
920: * The value to be formatted.
921: *
922: * @param int $type
923: * The type of the value.
924: *
925: * @return string
926: * Returns the prepared value.
927: *
928: * @author Oleg Schildt
929: */
930: abstract function prepare_for_query(mixed $value, int $type): string;
931:
932: /**
933: * Builds simple select query based on parameters.
934: *
935: * It is used for building queries with limits.
936: *
937: * @param string $table
938: * The name of the table.
939: *
940: * @param array $fields
941: * The list of request fields.
942: *
943: * @param string $where_clause
944: * The where clause that should restrict the result.
945: *
946: * @param string $order_clause
947: * The order clause to sort the results.
948: *
949: * @param int $limit
950: * The limit how many records should be loaded. 0 for unlimited.
951: *
952: * @return string
953: * Returns the built query.
954: *
955: * @author Oleg Schildt
956: */
957: abstract function build_select_query(string $table, array $fields, string $where_clause, string $order_clause, int $limit): string;
958:
959: /**
960: * Returns the last executed query.
961: *
962: * @return string
963: * Returns the last executed query.
964: *
965: * @author Oleg Schildt
966: */
967: function get_last_query(): string
968: {
969: return trim($this->last_query);
970: } // get_last_query
971:
972: /**
973: * Sets the logging flag. If set, query is logged to a log file.
974: *
975: * @param bool $state
976: * The state of the logging.
977: *
978: * @return void
979: *
980: * @author Oleg Schildt
981: */
982: function enable_logging(bool $state): void
983: {
984: $this->logging = $state;
985: } // enable_logging
986: } // class DBWorker