├── .scrutinizer.yml
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── composer.json
├── rector.php
├── sql
├── mysql-down.sql
├── mysql-up.sql
├── oci-down.sql
├── oci-up.sql
├── pgsql-down.sql
├── pgsql-up.sql
├── sqlite-down.sql
├── sqlite-up.sql
├── sqlsrv-down.sql
└── sqlsrv-up.sql
└── src
├── DbSchemaManager.php
└── DbTarget.php
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | checks:
2 | php: true
3 |
4 | filter:
5 | paths:
6 | - src/*
7 |
8 | build:
9 | image: default-bionic
10 |
11 | environment:
12 | php:
13 | version: 8.1.18
14 | ini:
15 | xdebug.mode: coverage
16 |
17 | nodes:
18 | analysis:
19 | tests:
20 | override:
21 | - php-scrutinizer-run
22 |
23 | phpunit:
24 | services:
25 | db-mssql:
26 | image: mcr.microsoft.com/mssql/server:2017-latest
27 |
28 | # Define any additional environment variables that are needed by the service.
29 | env:
30 | SA_PASSWORD: YourStrong!Passw0rd
31 | ACCEPT_EULA: Y
32 | MSSQL_PID: Developer
33 |
34 | # We automatically forward these ports from your localhost to the service's port.
35 | # Alternatively, you can also access the service on the "$SERVICE_SOME_NAME_IP"
36 | # environment variable.
37 | ports:
38 | # Forward 127.0.0.1:12345 -> SERVICE_IP:12345
39 | - 1433
40 |
41 | # If your service writes data to disk like most databases do, you can significantly
42 | # speed up tests by mounting a ramdisk at those paths.
43 | ramdisks:
44 | - /var/lib/data
45 |
46 | db-mysql:
47 | image: mysql:8.0.29
48 |
49 | # Define any additional environment variables that are needed by the service.
50 | env:
51 | MYSQL_ALLOW_EMPTY_PASSWORD: 1
52 | MYSQL_ROOT_PASSWORD: ''
53 | MYSQL_DATABASE: yiitest
54 |
55 | # We automatically forward these ports from your localhost to the service's port.
56 | # Alternatively, you can also access the service on the "$SERVICE_SOME_NAME_IP"
57 | # environment variable.
58 | ports:
59 | # Forward 127.0.0.1:12345 -> SERVICE_IP:12345
60 | - 3306
61 |
62 | # If your service writes data to disk like most databases do, you can significantly
63 | # speed up tests by mounting a ramdisk at those paths.
64 | ramdisks:
65 | - /var/lib/data
66 |
67 | db-pgsql:
68 | image: postgres:14
69 |
70 | # Define any additional environment variables that are needed by the service.
71 | env:
72 | POSTGRES_USER: root
73 | POSTGRES_PASSWORD: root
74 | POSTGRES_DB: yiitest
75 |
76 | # We automatically forward these ports from your localhost to the service's port.
77 | # Alternatively, you can also access the service on the "$SERVICE_SOME_NAME_IP"
78 | # environment variable.
79 | ports:
80 | # Forward 127.0.0.1:12345 -> SERVICE_IP:12345
81 | - 5432
82 |
83 | # If your service writes data to disk like most databases do, you can significantly
84 | # speed up tests by mounting a ramdisk at those paths.
85 | ramdisks:
86 | - /var/lib/data
87 |
88 | db-oracle:
89 | image: gvenzl/oracle-xe:21
90 |
91 | # We automatically forward these ports from your localhost to the service's port.
92 | # Alternatively, you can also access the service on the "$SERVICE_SOME_NAME_IP"
93 | # environment variable.
94 | ports:
95 | # Forward 127.0.0.1:12345 -> SERVICE_IP:12345
96 | - 1521
97 |
98 | env:
99 | ORACLE_DATABASE : yiitest
100 | ORACLE_PASSWORD : root
101 |
102 | # If your service writes data to disk like most databases do, you can significantly
103 | # speed up tests by mounting a ramdisk at those paths.
104 | ramdisks:
105 | - /var/lib/data
106 |
107 | tests:
108 | before:
109 | - curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
110 | - curl https://packages.microsoft.com/config/ubuntu/18.04/prod.list | sudo tee /etc/apt/sources.list.d/msprod.list
111 | - sudo apt-get update -y
112 | - sudo ACCEPT_EULA=Y apt-get install mssql-tools unixodbc-dev -y
113 | - sudo ls /opt/mssql-tools/bin/sqlcmd*
114 | - /opt/mssql-tools/bin/sqlcmd -S 127.0.0.1 -U SA -P 'YourStrong!Passw0rd' -Q 'CREATE DATABASE yiitest'
115 | - pecl -q install pdo_sqlsrv
116 | - sudo mkdir -p /opt/oracle
117 | - sudo curl -k -L --output /opt/oracle/instantclient-basic-linux.x64-21.3.0.0.0.zip https://download.oracle.com/otn_software/linux/instantclient/213000/instantclient-basic-linux.x64-21.3.0.0.0.zip
118 | - sudo curl -k -L --output /opt/oracle/instantclient-sdk-linux.x64-21.3.0.0.0.zip https://download.oracle.com/otn_software/linux/instantclient/213000/instantclient-sdk-linux.x64-21.3.0.0.0.zip
119 | - sudo unzip /opt/oracle/instantclient-basic-linux.x64-21.3.0.0.0.zip -d /opt/oracle
120 | - sudo unzip /opt/oracle/instantclient-sdk-linux.x64-21.3.0.0.0.zip -d /opt/oracle
121 | - sudo apt-get install libaio1 -y
122 | - export ORACLE_HOME=/opt/oracle/instantclient_21_3
123 | - sudo sh -c "echo /opt/oracle/instantclient_21_3 > /etc/ld.so.conf.d/oracle-instantclient.conf"
124 | - sudo ldconfig
125 | - curl -k -L --output /home/scrutinizer/oci8-3.0.1.tgz https://pecl.php.net/get/oci8-3.0.1.tgz
126 | - cd /home/scrutinizer
127 | - tar -zxf oci8-3.0.1.tgz
128 | - cd oci8-3.0.1
129 | - phpize
130 | - ./configure --with-oci8=instantclient,/opt/oracle/instantclient_21_3
131 | - make
132 | - sudo make install
133 | - sudo ldconfig
134 | - curl -k -L --output /home/scrutinizer/php-8.1.18.tar.gz https://www.php.net/distributions/php-8.1.18.tar.gz
135 | - cd /home/scrutinizer
136 | - tar -zxf php-8.1.18.tar.gz
137 | - cd php-8.1.18/ext/pdo_oci
138 | - phpize
139 | - ./configure --with-pdo-oci=instantclient,/opt/oracle/instantclient_21_3
140 | - make
141 | - sudo make install
142 | - sudo ldconfig
143 | - cd /home/scrutinizer/build/
144 | - composer require yiisoft/db-mssql --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
145 | - composer require yiisoft/db-mysql --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
146 | - composer require yiisoft/db-oracle --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
147 | - composer require yiisoft/db-pgsql --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
148 | - composer require yiisoft/db-sqlite --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
149 | - echo 'extension=pdo_oci' >> /home/scrutinizer/.phpenv/versions/8.1.18/etc/php.ini
150 |
151 | override:
152 | - command: ./vendor/bin/phpunit --coverage-clover ./coverage.xml
153 | coverage:
154 | file: coverage.xml
155 | format: php-clover
156 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Yii Logging Library - DB Target Change Log
2 |
3 | ## 1.0.1 under development
4 |
5 | - no changes in this release.
6 |
7 | ## 1.0.0 May 09, 2023
8 |
9 | - Initial release.
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright © 2008 by Yii Software ()
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions
6 | are met:
7 |
8 | * Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | * Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in
12 | the documentation and/or other materials provided with the
13 | distribution.
14 | * Neither the name of Yii Software nor the names of its
15 | contributors may be used to endorse or promote products derived
16 | from this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Yii Logging Library - DB Target
6 |
7 |
8 |
9 | [](https://packagist.org/packages/yiisoft/log-target-db)
10 | [](https://packagist.org/packages/yiisoft/log-target-db)
11 | [](https://codecov.io/gh/yiisoft/log-target-db)
12 | [](https://dashboard.stryker-mutator.io/reports/github.com/yiisoft/log-target-db/master)
13 | [](https://github.com/yiisoft/log-target-db/actions?query=workflow%3A%22static+analysis%22)
14 | [](https://shepherd.dev/github/yiisoft/log-target-db)
15 |
16 | This package provides the Database target for the [yiisoft/log](https://github.com/yiisoft/log) library.
17 |
18 | ## Supported databases
19 |
20 | | Packages | PHP | Versions | CI-Actions |
21 | |----------|-----|----------|------------|
22 | | [[db-mssql]](https://github.com/yiisoft/db-mssql) | **8.0 - 8.2** | **2017 - 2022** | [](https://github.com/yiisoft/log-target-db/actions/workflows/mssql.yml) | |
23 | | [[db-mysql/mariadb]](https://github.com/yiisoft/db-mysql) | **8.0 - 8.2** | **5.7-8.0**/**10.4-10.10** | [](https://github.com/yiisoft/log-target-db/actions/workflows/mysql.yml) |
24 | | [[db-oracle]](https://github.com/yiisoft/db-oracle) | **8.0 - 8.2** | **11C - 21C** | [](https://github.com/yiisoft/log-target-db/actions/workflows/oracle.yml) |
25 | | [[db-pgsql]](https://github.com/yiisoft/db-pgsql) | **8.0 - 8.2** | **9.0 - 15.0** | [](https://github.com/yiisoft/log-target-db/actions/workflows/pgsql.yml) |
26 | | [[db-sqlite]](https://github.com/yiisoft/db-sqlite) | **8.0 - 8.2** | **3:latest** | [](https://github.com/yiisoft/log-target-db/actions/workflows/sqlite.yml) |
27 |
28 | ## Requirements
29 |
30 | - PHP 8.0 or higher.
31 | - `PDO` PHP extension.
32 |
33 | ## Installation
34 |
35 | The package could be installed with [Composer](https://getcomposer.org):
36 |
37 | ```shell
38 | composer require yiisoft/log-target-db
39 | ```
40 |
41 | ## Create database connection
42 |
43 | For more information see [yiisoft/db](https://github.com/yiisoft/db/tree/master/docs/guide/en#create-connection).
44 |
45 | ## Database Preparing
46 |
47 | Package provides two way for preparing database:
48 |
49 | 1. Raw SQL. You can use it with the migration package used in your application.
50 |
51 | - Ensure tables:
52 | - [MSSQL](sql/sqlsrv-up.sql),
53 | - [MySQL / MariaDB](sql/mysql-up.sql),
54 | - [Oracle](sql/oci-up.sql),
55 | - [PostgreSQL](sql/pgsql-up.sql)
56 | - [SQLite](sql/sqlite-up.sql)
57 |
58 | - Ensure no tables:
59 | - [MSSQL](sql/sqlsrv-down.sql),
60 | - [MySQL / MariaDB](sql/mysql-down.sql),
61 | - [Oracle](sql/oci-down.sql),
62 | - [PostgreSQL](sql/pgsql-down.sql)
63 | - [SQLite](sql/sqlite-down.sql)
64 |
65 | 2. `DbSchemaManager` for `ensureTable()`, `ensureNoTable()` methods for log table (by default `{{%yii_log}}`).
66 |
67 | ```php
68 | // Create db schema manager
69 | $dbSchemaManager = new DbSchemaManager($db);
70 |
71 | // Ensure table with default name
72 | $dbSchemaManager->ensureTable();
73 |
74 | // Ensure table with custom name
75 | $dbSchemaManager->ensureTable('{{%custom_log_table}}');
76 |
77 | // Ensure no table with default name
78 | $dbSchemaManager->ensureNoTable();
79 |
80 | // Ensure no table with custom name
81 | $dbSchemaManager->ensureNoTable('{{%custom_log_table}}');
82 | ```
83 |
84 | ## General usage
85 |
86 | When creating an instance of `\Yiisoft\Log\Logger`, you must pass an instance of the database connection.
87 |
88 | Creating a target:
89 |
90 | ```php
91 | $dbTarget = new \Yiisoft\Log\Target\Db\DbTarget($db, $table);
92 | ```
93 |
94 | - `$db (\Yiisoft\Db\Connection\ConnectionInterface)` - The database connection instance.
95 | - `$table (string)` - The name of the database table to store the log messages. Defaults to "log".
96 |
97 | Creating a logger:
98 |
99 | ```php
100 | $logger = new \Yiisoft\Log\Logger([$dbTarget]);
101 | ```
102 |
103 | You can use multiple databases to store log messages:
104 |
105 | ```php
106 | /**
107 | * @var \Yiisoft\Db\Connection\ConnectionInterface $mysqlDb
108 | * @var \Yiisoft\Db\Connection\ConnectionInterface $sqliteDb
109 | */
110 |
111 | $logger = new \Yiisoft\Log\Logger([
112 | new \Yiisoft\Log\Target\Db\DbTarget($mysqlDb),
113 | new \Yiisoft\Log\Target\Db\DbTarget($sqliteDb),
114 | ]);
115 | ```
116 |
117 | ## Documentation
118 |
119 | For a description of using the logger, see the [yiisoft/log](https://github.com/yiisoft/log) package.
120 |
121 | - [Yii guide to logging](https://github.com/yiisoft/docs/blob/master/guide/en/runtime/logging.md)
122 | - [Internals](docs/internals.md)
123 |
124 | If you need help or have a question, the [Yii Forum](https://forum.yiiframework.com/c/yii-3-0/63) is a good place for that.
125 | You may also check out other [Yii Community Resources](https://www.yiiframework.com/community).
126 |
127 | ## License
128 |
129 | The Yii Logging Library - DB Target is free software. It is released under the terms of the BSD License.
130 | Please see [`LICENSE`](./LICENSE.md) for more information.
131 |
132 | Maintained by [Yii Software](https://www.yiiframework.com/).
133 |
134 | ## Support the project
135 |
136 | [](https://opencollective.com/yiisoft)
137 |
138 | ## Follow updates
139 |
140 | [](https://www.yiiframework.com/)
141 | [](https://twitter.com/yiiframework)
142 | [](https://t.me/yii3en)
143 | [](https://www.facebook.com/groups/yiitalk)
144 | [](https://yiiframework.com/go/slack)
145 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yiisoft/log-target-db",
3 | "type": "library",
4 | "description": "Yii Logging Library - DB Target",
5 | "keywords": [
6 | "yii",
7 | "framework",
8 | "log",
9 | "logger"
10 | ],
11 | "homepage": "https://www.yiiframework.com/",
12 | "license": "BSD-3-Clause",
13 | "support": {
14 | "issues": "https://github.com/yiisoft/log-target-db/issues",
15 | "source": "https://github.com/yiisoft/log-target-db",
16 | "forum": "https://www.yiiframework.com/forum/",
17 | "wiki": "https://www.yiiframework.com/wiki/",
18 | "irc": "ircs://irc.libera.chat:6697/yii",
19 | "chat": "https://t.me/yii3en"
20 | },
21 | "funding": [
22 | {
23 | "type": "opencollective",
24 | "url": "https://opencollective.com/yiisoft"
25 | },
26 | {
27 | "type": "github",
28 | "url": "https://github.com/sponsors/yiisoft"
29 | }
30 | ],
31 | "require": {
32 | "php": "^8.0",
33 | "ext-pdo": "*",
34 | "psr/log": "^3.0",
35 | "yiisoft/db": "^1.0",
36 | "yiisoft/log": "^2.0"
37 | },
38 | "require-dev": {
39 | "maglnet/composer-require-checker": "^4.2",
40 | "phpunit/phpunit": "^9.6|^10.1",
41 | "rector/rector": "^2.0.3",
42 | "roave/infection-static-analysis-plugin": "^1.25|^1.29",
43 | "spatie/phpunit-watcher": "^1.23",
44 | "vimeo/psalm": "^4.8|^5.8",
45 | "yiisoft/cache": "^3.0"
46 | },
47 | "autoload": {
48 | "psr-4": {
49 | "Yiisoft\\Log\\Target\\Db\\": "src"
50 | }
51 | },
52 | "autoload-dev": {
53 | "psr-4": {
54 | "Yiisoft\\Log\\Target\\Db\\Tests\\": "tests"
55 | }
56 | },
57 | "config": {
58 | "sort-packages": true,
59 | "allow-plugins": {
60 | "infection/extension-installer": true,
61 | "composer/package-versions-deprecated": true
62 | }
63 | },
64 | "scripts": {
65 | "test": "phpunit --testdox --no-interaction",
66 | "test-watch": "phpunit-watcher watch"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/rector.php:
--------------------------------------------------------------------------------
1 | paths([
11 | __DIR__ . '/src',
12 | __DIR__ . '/tests',
13 | ]);
14 |
15 | // register a single rule
16 | $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
17 |
18 | // define sets of rules
19 | $rectorConfig->sets([
20 | LevelSetList::UP_TO_PHP_80,
21 | ]);
22 | };
23 |
--------------------------------------------------------------------------------
/sql/mysql-down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE `yii_log`;
2 |
--------------------------------------------------------------------------------
/sql/mysql-up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `yii_log` (
2 | `id` bigint(20) NOT NULL AUTO_INCREMENT,
3 | `level` varchar(16),
4 | `category` varchar(255),
5 | `log_time` timestamp(6) DEFAULT CURRENT_TIMESTAMP(6),
6 | `message` text,
7 | CONSTRAINT `PK_yii_log` PRIMARY KEY (`id`)
8 | );
9 | CREATE INDEX `IDX_yii_log-category` ON `yii_log` (`category`);
10 | CREATE INDEX `IDX_yii_log-level` ON `yii_log` (`level`);
11 | CREATE INDEX `IDX_yii_log-time` ON `yii_log` (`log_time`);
12 |
--------------------------------------------------------------------------------
/sql/oci-down.sql:
--------------------------------------------------------------------------------
1 | /* STATEMENTS */
2 | DROP TRIGGER "yii_log_TRG";
3 | DROP SEQUENCE "yii_log_SEQ";
4 | DROP TABLE "yii_log";
5 |
--------------------------------------------------------------------------------
/sql/oci-up.sql:
--------------------------------------------------------------------------------
1 | /* STATEMENTS */
2 | CREATE TABLE "yii_log" (
3 | "id" NUMBER(20) NOT NULL,
4 | "level" VARCHAR2(16),
5 | "category" VARCHAR2(255),
6 | "log_time" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
7 | "message" CLOB,
8 | CONSTRAINT "PK_yii_log" PRIMARY KEY ("id")
9 | );
10 | CREATE SEQUENCE "yii_log_SEQ" START WITH 1 INCREMENT BY 1 NOMAXVALUE;
11 | CREATE INDEX "IDX_yii_log-category" ON "yii_log" ("category");
12 | CREATE INDEX "IDX_yii_log-level" ON "yii_log" ("level");
13 | CREATE INDEX "IDX_yii_log-time" ON "yii_log" ("log_time");
14 |
15 | /* TRIGGERS */
16 | CREATE TRIGGER "yii_log_TRG" BEFORE INSERT ON "yii_log" FOR EACH ROW BEGIN <> BEGIN
17 | IF INSERTING AND :NEW."id" IS NULL THEN SELECT "yii_log_SEQ".NEXTVAL INTO :NEW."id" FROM SYS.DUAL; END IF;
18 | END COLUMN_SEQUENCES;
19 | END;
20 | /
21 |
--------------------------------------------------------------------------------
/sql/pgsql-down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE "yii_log";
2 |
--------------------------------------------------------------------------------
/sql/pgsql-up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "yii_log" (
2 | "id" BIGSERIAL NOT NULL,
3 | "level" varchar(16),
4 | "category" varchar(255),
5 | "log_time" timestamp(6) DEFAULT CURRENT_TIMESTAMP,
6 | "message" text,
7 | CONSTRAINT "PK_yii_log" PRIMARY KEY ("id")
8 | );
9 | CREATE INDEX "IDX_yii_log-category" ON "yii_log" ("category");
10 | CREATE INDEX "IDX_yii_log-level" ON "yii_log" ("level");
11 | CREATE INDEX "IDX_yii_log-time" ON "yii_log" ("log_time");
12 |
--------------------------------------------------------------------------------
/sql/sqlite-down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE `yii_log`;
2 |
--------------------------------------------------------------------------------
/sql/sqlite-up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `yii_log` (
2 | `id` integer,
3 | `level` varchar(16),
4 | `category` varchar(255),
5 | `log_time` timestamp DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'UTC')),
6 | `message` text,
7 | CONSTRAINT `PK_yii_log` PRIMARY KEY (`id`)
8 | );
9 | CREATE INDEX `IDX_yii_log-category` ON `yii_log` (`category`);
10 | CREATE INDEX `IDX_yii_log-level` ON `yii_log` (`level`);
11 | CREATE INDEX `IDX_yii_log-time` ON `yii_log` (`log_time`);
12 |
--------------------------------------------------------------------------------
/sql/sqlsrv-down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE [yii_log];
2 |
--------------------------------------------------------------------------------
/sql/sqlsrv-up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE [yii_log] (
2 | [id] bigint NOT NULL IDENTITY,
3 | [level] nvarchar(16),
4 | [category] nvarchar(255),
5 | [log_time] DATETIME2(6) DEFAULT CURRENT_TIMESTAMP,
6 | [message] nvarchar(max),
7 | CONSTRAINT [PK_yii_log] PRIMARY KEY ([id])
8 | );
9 | CREATE INDEX [IDX_yii_log-category] ON [yii_log] ([category]);
10 | CREATE INDEX [IDX_yii_log-level] ON [yii_log] ([level]);
11 | CREATE INDEX [IDX_yii_log-time] ON [yii_log] ([log_time]);
12 |
--------------------------------------------------------------------------------
/src/DbSchemaManager.php:
--------------------------------------------------------------------------------
1 | db->getDriverName();
39 | $schema = $this->db->getSchema();
40 | $tableRawName = $schema->getRawTableName($table);
41 |
42 | if ($this->hasTable($table)) {
43 | return;
44 | }
45 |
46 | // `log_Time` Default value custom for all dbms
47 | $defaultValue = match ($driverName) {
48 | 'mysql' => new Expression('CURRENT_TIMESTAMP(6)'),
49 | 'sqlite' => new Expression("(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'UTC'))"),
50 | default => new Expression('CURRENT_TIMESTAMP'),
51 | };
52 |
53 | // `log_Time` Type custom for all dbms
54 | $logTimeType = match ($driverName) {
55 | 'sqlsrv' => $schema->createColumn('DATETIME2(6)')->defaultValue($defaultValue),
56 | default => $schema->createColumn(SchemaInterface::TYPE_TIMESTAMP, 6)->defaultValue($defaultValue),
57 | };
58 |
59 | // `id` AutoIncrement custom for all dbms
60 | $id = match ($driverName) {
61 | 'mysql' => $schema->createColumn(SchemaInterface::TYPE_BIGINT)->notNull()->append('AUTO_INCREMENT'),
62 | 'pgsql' => $schema->createColumn('BIGSERIAL')->notNull(),
63 | 'sqlsrv' => $schema->createColumn(SchemaInterface::TYPE_BIGINT)->notNull()->append('IDENTITY'),
64 | default => $schema->createColumn(SchemaInterface::TYPE_INTEGER)->notNull(),
65 | };
66 |
67 | // create table
68 | $this->db->createCommand()->createTable(
69 | $table,
70 | [
71 | 'id' => $id,
72 | 'level' => $schema->createColumn(SchemaInterface::TYPE_STRING, 16),
73 | 'category' => $schema->createColumn(SchemaInterface::TYPE_STRING),
74 | 'log_time' => $logTimeType,
75 | 'message' => $schema->createColumn(SchemaInterface::TYPE_TEXT),
76 | "CONSTRAINT [[PK_$tableRawName]] PRIMARY KEY ([[id]])",
77 | ],
78 | )->execute();
79 |
80 | if ($driverName === 'oci') {
81 | $this->addSequenceAndTrigger($tableRawName);
82 | }
83 |
84 | $this->db->createCommand()->createIndex($table, "IDX_{$tableRawName}-category", 'category')->execute();
85 | $this->db->createCommand()->createIndex($table, "IDX_{$tableRawName}-level", 'level')->execute();
86 | $this->db->createCommand()->createIndex($table, "IDX_{$tableRawName}-time", 'log_time')->execute();
87 | }
88 |
89 | /**
90 | * Ensures that the log table does not exist in the database.
91 | *
92 | * @param string $table The name of the log table. Defaults to '{{%yii_log}}'.
93 | *
94 | * @throws Exception
95 | * @throws InvalidConfigException
96 | * @throws Throwable
97 | */
98 | public function ensureNoTable(string $table = '{{%yii_log}}'): void
99 | {
100 | $schema = $this->db->getSchema();
101 | $tableRawName = $schema->getRawTableName($table);
102 |
103 | // drop table
104 | if ($this->db->getTableSchema($table, true) !== null) {
105 | $this->db->createCommand()->dropTable($tableRawName)->execute();
106 |
107 | // drop sequence oracle
108 | if ($this->db->getDriverName() === 'oci') {
109 | $this->db
110 | ->createCommand()
111 | ->setSql(
112 | <<execute();
117 | }
118 | }
119 | }
120 |
121 | /**
122 | * @throws Exception
123 | * @throws Throwable
124 | */
125 | private function addSequenceAndTrigger(string $tableRawName): void
126 | {
127 | // create sequence oracle
128 | $this->db
129 | ->createCommand()
130 | ->setSql(
131 | <<execute();
139 |
140 | // create trigger oracle
141 | $this->db
142 | ->createCommand()
143 | ->setSql(
144 | <<> BEGIN
146 | IF INSERTING AND :NEW."id" IS NULL THEN SELECT {{{$tableRawName}_SEQ}}.NEXTVAL INTO :NEW."id" FROM SYS.DUAL; END IF;
147 | END COLUMN_SEQUENCES;
148 | END;
149 | SQL,
150 | )
151 | ->execute();
152 | }
153 |
154 | /**
155 | * Checks if the given table exists in the database.
156 | *
157 | * @param string $table The name of the table to check.
158 | *
159 | * @return bool Whether the table exists or not.
160 | */
161 | private function hasTable(string $table): bool
162 | {
163 | return $this->db->getTableSchema($table, true) !== null;
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/src/DbTarget.php:
--------------------------------------------------------------------------------
1 | db;
36 | }
37 |
38 | /**
39 | * Gets the name of the database table to store the log messages.
40 | */
41 | public function getTable(): string
42 | {
43 | return $this->table;
44 | }
45 |
46 | /**
47 | * Stores log messages to the database.
48 | *
49 | * @throws RuntimeException If the log can't be exported.
50 | */
51 | protected function export(): void
52 | {
53 | $formattedMessages = $this->getFormattedMessages();
54 | $table = $this->db->getQuoter()->quoteTableName($this->table);
55 |
56 | try {
57 | $command = $this->db->createCommand();
58 |
59 | foreach ($this->getMessages() as $key => $message) {
60 | /** @psalm-var mixed $logTime */
61 | $logTime = $message->context('time');
62 | $columns = [
63 | 'level' => $message->level(),
64 | 'category' => $message->context('category', ''),
65 | 'log_time' => $logTime,
66 | 'message' => $formattedMessages[$key],
67 | ];
68 |
69 | if ($logTime === null) {
70 | unset($columns['log_time']);
71 | }
72 |
73 | $command->insert($table, $columns)->execute();
74 | }
75 | } catch (Throwable $e) {
76 | throw new RuntimeException($e->getMessage(), (int) $e->getCode(), $e);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------