GithubHelp home page GithubHelp logo

yiisoft / db Goto Github PK

View Code? Open in Web Editor NEW
131.0 131.0 34.0 15.88 MB

Yii Database Library

Home Page: https://www.yiiframework.com/

License: BSD 3-Clause "New" or "Revised" License

PHP 100.00%
database dbal query-builder sql yii3

db's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

db's Issues

copyTable function for Command like renameTable

we should add one function copyTable($table,$newName,$onlyStructure = true)
I hope it could provide a function to copy table efficient

Funding

  • You can sponsor this specific effort via a Polar.sh pledge below
  • We receive the pledge once the issue is completed & verified
Fund with Polar

2.0.16 breaks certain select2 fields validation in active form

@licanulla commented on Tue Feb 19 2019

Just found that since upgrade 2.0.16 my select2 fields with ajax option are no longer validated. Those with preset data still are. No JS errors in console. Downgraded to 2.0.15.1 and got my forms working again.


@rob006 commented on Tue Feb 19 2019

Probably duplicate of yiisoft/yii2#17111

How do you generate AJAX response for select2 widget?


@licanulla commented on Tue Feb 19 2019

No AJAX calls in my case. The client-side validation is broken somehow so when the form is loaded and you hit "submit" button, those select2 fields (with ajax option) left empty aren't marked as required, while they are and the form is initialized with those fields as required.


@rob006 commented on Wed Feb 20 2019

You need to give some code to reproduce this issue.

Batchinsert and associative arrays

Clarification

There is more at play here than the "order of elements" argument:

  1. Associative arrays are conceptually like dictionaries. While they have an order in PHP, it is not intuitive to use to depend on it.
  2. In this bug specifically, if you use associative data rows then type casting will not working unless your columns array also uses the same indexes; this is even less intuitive.
    The columns parameter is the ordered list of columns, their indexes shouldn't matter.

Regardless of the argument that you can construct all kinds of arrays in PHP I propose documenting a preferred structure and actually checking if the code conforms...

What steps will reproduce the problem?

Create code like this:

$x->batchInsert('table1', ['a', 'b'], ['b' => 123, 'a' => 345]);

What is the expected result?

I expect it to work properly, ie create a query like this:

insert into `table1` (`a`, `b`) values (345, 123);

What do you get instead?

insert into `table1` (`a`, `b`) values (123, 345);

Solution

The thing that is wrong here is not so much the code as my assumption: batch insert does not support associative arrays; this means things like column order and also column type casting will go wrong when passing in associative arrays.

My proposal is to actively check each key in the row data and throw a hard exception if it's not numerical. Since we're already iterating we can do this without a significant performance cost; the only lines we'd add are something like this:

if (!is_int($i)) {
    throw new SomeKindOfException('Data rows must be numerically indexed');
}

Additional info

Q A
Yii version latest
PHP version N/A
Operating system N/A
Related issues #14608

How to set a PDO statement attribute?

I have to use the each method to select in batches. The problem is, that I have to delete some columns in this foreach, which generates a table lock. Now I have to set the cursor PDO::ATTR_CURSOR to forward only PDO::CURSOR_FWDONLY. Is this even possible by now?

$simpleQuery = SimpleObject::find();
// need something like: $simpleQuery->setPdoStmtAttr(\PDO::ATTR_CURSOR, \PDO::CURSOR_FWDONLY);
foreach ($simpleQuery->each() as $simpleObject) {
    // fancy things...
}

Funding

  • You can sponsor this specific effort via a Polar.sh pledge below
  • We receive the pledge once the issue is completed & verified
Fund with Polar

Class 'yii\base\Component' not found

What steps will reproduce the problem?

I just want only use yiisoft/db, after install composer require yiisoft/db:dev-master, The exception throwed.

What is the expected result?

can use db component normally.

What do you get instead?

Fatal error occured.

Additional info

Q A
Yii version 3.0.?
PHP version php7.1
Operating system Centos

BTW: Emmm... What's the time to use yii3.0 components individually ?

DB CASE WHEN in SELECT

New feature, adding the possibility to use CASE WHEN in yii\db\Query

DB support for CASE WHEN

  • MySQL
  • PostgreSQL
  • MSSQL
  • Oracle
  • SQLite
  • Cubrid

TODO

  • Choose syntax for it
  • Write tests
  • Implement

Use utf8mb4 by default in mysql, not utf8

@teo1978 commented on Jul 29, 2018, 3:42 PM UTC:

MySQL's "utf8" charset, which shouldn't even be called that since it is not actual utf8, was a disgrace that happened years ago because someone in the MySQL team was stupid. The real utf8-conforming character set in MySQL is utf8mb4. In 2018, we should be using that and encouraging to use that as a default for MySQL.
Any hypothetical compatibility issue with old MySQL versions, I don't think is any more stringent, and worth caring about, than current existing incompatibilities with obsolete php versions, for example.
And the disastrous effects of using MySQL's "utf8" charset are much worse.

  1. I installed the Advanced Application Project template, I created a database for it with utf8mb4 utf8mb4_unicode_ci as the default collation. Then I configured main_local.php with
            'dsn' => 'mysql:host=localhost;dbname=iframe2',
            //...
            'charset' => 'utf8mb4',

I followed the rest of instructions (including running the migration) and have the application up and running, and I notice that the user table that has been created has utf8_unicode_ci (i.e. "utf8" charset) as its default and for all its fields.

I'm not sure whether this is a specific choice for the User model table based on the belief that allowing 4-byte characters such as smilies in a username wouldn't be a good idea (which could be questionable but arguable) or if this comes from a general "we use utf8 everywhere by default" policy. If it's the latter, then I'm seriously worried.
I wouldn't like to see any more tables created by the framework with utf8 specifically forced as the charset despite the database default being utf8mb4. I can understand forcing a specific charset rather than using the database default for some things, but then that specific charset should be utf8mb4 (which again is true utf-8) for anything that doesn't have a specific reason to be something else.

  1. In the Getting Started guides both for the basic and advanced apps I see you suggest utf8 as the charset in the configuration for a MySQL database. Again, it should be utf8mb4

  2. the actual config file provided with the basic app also has utf8.

Hopefully it's just a matter of the default configuration files provided with the template application projects and the examples in the docs (and apparently something else in the Advanced app, because utf8 was assigned to the user model table despite the database default and the config), and not much more than that.

This issue was moved by samdark from yiisoft/yii2#16576.

Split yii\db\QueryBuilder into separate simpler classes

Its just an idea to make yii\db\QueryBuilder more SRP than it is now.
What if make separate classes for SelectBuilder, InsertBuilder, UpdateBuilder e.t.c
They can be much better to use and understand than the monster yii\db\QueryBuilder
Please say what you think about it

Split connection into master and slave

Currently both master and slave connections use the same class.

This violates the SRP.
We should have a class that only implements the slave connection part and one class that only implements the master connection.

Funding

  • You can sponsor this specific effort via a Polar.sh pledge below
  • We receive the pledge once the issue is completed & verified
Fund with Polar

Расширение QueryBuilder::buildSelect() для агрегирующих функций

What steps will reproduce the problem?

Нет гибкого конструктора для создания запросов с агрегирующими функциями.

What is the expected result?

Простой и гибкий конструктор в QueryBuilder::buildSelect() для формирования запросов, включая COUNT(DISTINCT ...) и CASE конструкции.

What do you get instead?

Ничего.

Additional info

Q A
Yii version 2.0.?
PHP version
Operating system

Add method batchUpdate in \yii\db\QueryBuilder

Very often in practice I have to do a bulk update of rows.

IN PostgreSQL:

UPDATE table AS t
SET
    col1 = c.col1,
    col2 = c.col2
FROM (VALUES (1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4) ) AS c (id, col1, col2)
WHERE c.id = t.id;

or

INSERT INTO table (id, col1, col2) 
      VALUES (1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4)
ON CONFLICT (id) DO UPDATE SET 
  col1 = EXCLUDED.col1,
  col2 = EXCLUDED.col2

IN MySQL:

INSERT INTO table (id, col1, col2)
     VALUES (1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4)
ON DUPLICATE KEY UPDATE
    col1 = VALUES(col1),
    col2 = VALUES(col2);

I'm sure other databases have similar capabilities.
For each DBMS will have its own specific implementation of the method batchUpdate in descendant classes.

Sorry for my bad english.

Retry DB transaction on deadlock in multi-master replication

Feature request for discussion.

When the DB server uses multi-master replication, conflict can occur when clients of different replication masters write to the same row.

In the case of Galera replication (Dealing with Multi-Master Conflicts):

When two transactions come into conflict, the later of the two is rolled back by the cluster. The client application registers this rollback as a deadlock error. Ideally, the client application should retry the deadlocked transaction, but not all client applications have this logic built in.

If this is implemented it should be above the PDO layer but below the APIs that the application uses to access the DB. Hence I wonder if Yii might usefully provide this feature. I guess yii\db\Command::queryInternal() is roughly where this might happen.

If this were implemented it would

  • be optional and turned off by default
  • catch deadlock error exceptions from PDO
  • retry a deadlocked transaction a configurable number of times, with the default number of times being, say, 2
  • throw the caught exception if the number of retries is exhausted
  • possibly wait a small time before retrying, I am not sure if this is useful

I imagine it would be fairly easy to implement but I it might be quite hard to properly test.

add into insert and batchisert new parameter

Hello.
Sometimes I need to insert or update rows. I can do it using 'ON DUPLICATE KEY UPDATE'.

what do you think?

Funding

  • You can sponsor this specific effort via a Polar.sh pledge below
  • We receive the pledge once the issue is completed & verified
Fund with Polar

Database connection charset

@SamMousa commented on Jul 18, 2018, 10:23 AM UTC:

Currently the yii\db\Connection class has DBMS specific code for setting the charset.
Instead this should be moved to the respective Schema classes.

    protected function initConnection()
    {
        ...
        if ($this->charset !== null && in_array($this->getDriverName(), ['pgsql', 'mysql', 'mysqli', 'cubrid'], true)) {
            $this->pdo->exec('SET NAMES ' . $this->pdo->quote($this->charset));
        }
        $this->trigger(self::EVENT_AFTER_OPEN);
    }

A better solution would be to have the Schema initiate the character set, or more generic the connection. This could be done by simply initiating it in initConnection():

protected function initConnection()
    {
        $this->getSchema();
        $this->trigger(self::EVENT_AFTER_OPEN);
    }
  • The schema can do any initialization needed.
  • Schema object construction is cheap.
  • fully BC compatible.

This issue was moved by samdark from yiisoft/yii2#16530.

Anonymus function on fixture config / anonymus class

Idea

    public function _fixtures(){
        return [
            'user' => [
                'class' => UserFixture::className(),
                'dataFile' => codecept_data_dir() . 'user.php'
            ],
            'user1' => [
                'class' => (new class extends \yii\test\ActiveFixture
                {
                    public $modelClass = 'dektrium\user\models\User';
                }),
                'dataFile' => codecept_data_dir() . 'user.php'
            ],
            'user2' => function(){
                return Yii::createObject(\yii\test\ActiveFixture::className(),[
                    'modelClass' => 'dektrium\user\models\User',
                    'dataFile' => codecept_data_dir() . 'user.php',
                ]);
            },
            'token' => [
                'class' => TokenFixture::className(),
                'dataFile' => codecept_data_dir() . 'token.php'
            ],
        ];
    }

expand createFixture like a createObject

Additional info

Q A
Yii version 2.0.?
PHP version 7
Operating system Debian

Add comment property to database classes

A database can contain comments on the columns and the table itself. The comment of the columns can be read out trough the ColumnSchema class, but the comment on the table itself isn't.

Is this something that is open for inclusion in Yii 2? This is a bit related to #6093, but that PR wasn't accepted, so I want to avoid to work on this if it won't be accepted.

This could be used to generate usefull phpdoc with Gii based on the database comments.

Create index in migration

@i-panov commented on Oct 23, 2018, 2:38 PM UTC:

What steps will reproduce the problem?

Create new migration and use function $this->createIndex().

What is the expected result?

I want the fourth parameter in this function not the $unique flag, but the type of the index, for example fulltext. Because there is no other possibility to create an index (except through the execute method).

Additional info

Q A
Yii version 2.0.14
PHP version 7.2
Operating system CentOS 7

This issue was moved by samdark from yiisoft/yii2#16815.

Command::update() - add ability to pass Query to UPDATE FROM

$db = db()->createCommand("
    UPDATE     bet 
    SET        status = subquery.winr
    FROM       (:subquery) AS subquery 
    WHERE      bet.id = subquery.id
", ['subquery' => new Expression($this->leadersQuery()->select(['id', 'winr'])->createCommand()->rawSql)])->execute();

//->update(/*the truth is out there*/); needed

Add `each()` to `QueryInterface`

In QueryInterface it seems some functions are missing:

public function each()
public function batch()

In Query, these functions return BatchQueryResult. Since from an API perspective BatchQueryResult is equal to Iterator, I propose changing the return type to iterable.

By doing this any QueryInterface implementation can simply implement these functions (we could even implement a basic trait) in an inefficient way:

public function each() {
    return $this->all(); // An array is already iterable.
}

// Taken from: https://github.com/nikic/iter/blob/master/src/iter.php#L802
public function batch($100) {
    $chunk = [];
    $count = 0;
    foreach ($this->each() as $key => $value) {
        $chunk[$key] = $value;
        $count++;
        if ($count === $size) {
            yield $chunk;
            $count = 0;
            $chunk = [];
        }
    }
    if ($count !== 0) {
        yield $chunk;
    }
}

Motivation

When creating objects that consume a QueryInterface, what matters not is implementation, but intended use. When I consume an implementation I want to let it know that I'll be iterating over the objects one by one (each), it should, if possible, do something smart with that information.

Currently I either type hint to a specific implementation or I call functions not on the interface, both are not satisfactory.
If I use Mongo for example, it has an implementation for each: https://github.com/yiisoft/yii2-mongodb/blob/master/Query.php#L302
However I cannot use this without explicitly adapting my code.

  • If I typehint the Query implemention in the framework the precondition will fail (Mongo extension Query does not extend yii\db\Query).
  • If I typehint QueryInterface I cannot call each() without making assumptions that might not be valid.

Backwards compatibility

This will break backwards compatibility for third party QueryInterface implementations, these will need to implement this functionality manually or use the trait containing the frameworks' implementations.

Interface should not have a constructor

Currently ServiceProviderInterface has 2 functions:

    public function __construct(ContainerInterface $container);
    public function register(): void;

Interfaces generally should not have constructors.
In this case I propose changing it to this:

public function register(ContainerInterface $container): void;

This has several advantages:

  • I could create the container after the service provider.
  • I could serialize my service provider.

I don't have any need for these advantages, but I think the code is cleaner and more correct this way.

yii\db\command execute() don't handle errors on multiple queries

What steps will reproduce the problem?

Try to import db schema (from mysqldump or PhpMyAdmin schema export) with some error on non-first query. In example, change "int" column type in some table to "intFOO" to cause mysql error.

Schema:

SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `auth_assignment`;
CREATE TABLE `auth_assignment` (
  `item_name` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
  `user_id` intFOO(10) UNSIGNED NOT NULL,
  `created_at` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Example code (console action):

public function actionReset()
{
    $schemaFile = 'some/path/schema.sql';
    try {
        $command = Yii::$app->db->createCommand(file_get_contents($schemaFile));
        $command->execute();

        Console::output('Schema imported.');
        return self::EXIT_CODE_NORMAL;
    } catch (\Exception $e) {
        Console::error($e->getMessage());
    }
    return self::EXIT_CODE_ERROR;
}

What is the expected result?

Execution ends with proper exception.

What do you get instead?

"Schema imported." on stdout - no exception thrown, or error reported.

Additional info

Read this question and approved answer: How to check if db execute sql fails?

I believe that Yii should handle this case?

Q A
Yii version 2.0.12
PHP version 7.1.x
Operating system Kubuntu 17.04

count() method is returning string not integer

If you use count() method to return the number of rows in your table, you will get the number but as string not integer. You can check that yourself, just var dump the result of your query. Documentation of count() says that it should return integer, and that is what I was hoping for, but got surprised with result. Is this (not)working as intended or I am missing something ?

Docs: http://www.yiiframework.com/doc-2.0/yii-db-query.html#count%28%29-detail

I was doing very simple query $numberOfUsers = User::find()->count();

I use the latest yii2, downloaded today.

Separate MariaDB schema

@SamMousa commented on Jul 5, 2018, 3:34 PM UTC:

MariaDB is diverging more and more from MySQL.

What steps will reproduce the problem?

Try to use JSON columns with Yii and MariaDB.

What is the expected result?

It should work.

What do you get instead?

It doesn't since MySQL and MariaDB have solved the problem in different ways.

Proposal

  • Create mariadb\Schema and related classes that extend from the MySQL version.
  • When creating a JSON column we must manually add the JSON validation constraint, see this.

Since in MariaDB creating a JSON column results in a LONGTEXT column we need to somehow identify which LONGTEXT columns contain JSON.

  • Create option to detect JSON columns in MariaDB via column comments or name pattern matching.
  • Create option to detect JSON column by parsing constraints via SHOW CREATE TABLE.

Backwards compatibility

Since the DSN remains exactly the same. No one will ever use the MariaDB schema / classes, so any additions to Yii are backwards compatible.
For now I propose not doing any detection and just forcing users to set $driverName = 'mariadb'; if they want to use the new classes.

I'm willing to implement this in 2.X, alternatively I'll implement this privately and will merge it into 3.0 when that gets released.

Any feedback is appreciated.

This issue was moved by samdark from yiisoft/yii2#16485.

Make a parameter $db to methods, those uses static::getDb() to make flexible

We have met that it is impossible to make full-duplex transaction (DB-Connection open and close per Query) when static methods using static::getDb() inside, So we propose to add optional parameter $db to such methods.
So this makes db-Connection more managable and easy transitable.
This patch adds to ActiveRecord $db property.

The main thing that this patch is providing - detach static function method ::getDb() when this method can response new Connection instance any new time and use one invocation result by transition gotten Connection. Sometimes it happens.
yii2-active-record-db-connection.patch.txt

This is ActiveRecord::getDb()

   /**
     * Returns the database connection used by this AR class.
     * By default, the "db" application component is used as the database connection.
     * You may override this method if you want to use a different database connection.
     * @return Connection the database connection used by this AR class.
     */
    public static function getDb()
    {
        return Yii::$app->getDb();
    }

Yes we owerread it because we have 100 of connections and every time connection can be new inside 1 launch. But this static function is invoking from multiple places directly, instead of invocation once transit through functions and finish request.

Add some id to SQL statements

Reviewing the executed SQL statements in the debug toolbar or SQL log file is difficult to identify where they created. It would be very convenient to add id to the beginning. For example:

        $sql = '
            -- ID::carsInWay --
        SELECT ...;

andHaving must be similar to andWhere. And are nested

What steps will reproduce the problem?

Try to add several addHavings to the query.

What is the expected result?

 [having] => [
        0 => 'and'
        1 => [
            0 => '<'
            1 => 'miles'
            2 => 100
        ]
        2 => [
            0 => '<='
            1 => 'finalPrice * ((100 - finalDiscount) / 100)'
            2 => 'test'
        ]
        3 => [
            0 => '<='
            1 => 'finalPrice * ((100 - finalDiscount) / 100)'
            2 => 'tests'
        ]
    ]

What do you get instead?

[having] => [
        0 => 'and'
        1 => [
            0 => 'and'
            1 => [
                0 => '<'
                1 => 'miles'
                2 => 100
            ]
            2 => [
                0 => '<='
                1 => 'finalPrice * ((100 - finalDiscount) / 100)'
                2 => 'test'
            ]
        ]
        2 => [
            0 => '<='
            1 => 'finalPrice * ((100 - finalDiscount) / 100)'
            2 => 'tests'
        ]
    ]

Additional info

Q A
Yii version 2.0.12

Solution?

andHaving must be same as andWhere. Instead of :

if ($this->having === null) {
            $this->having = $condition;
        } else {
            $this->having = ['and', $this->having, $condition];
        }
        $this->addParams($params);
        return $this;

It should be like this:

if ($this->having === null) {
            $this->having = $condition;
        } elseif (is_array($this->having) && isset($this->having[0]) && strcasecmp($this->having[0], 'and') === 0) {
            $this->having[] = $condition;
        } else {
            $this->having = ['and', $this->having, $condition];
        }
        $this->addParams($params);
        return $this;

Setting escapingReplacements property of the LikeCondition

Object Form in yii\db\Query conditions introduced in Yii 2.0.14 is really great and timely enhancement!

It would be nice although setting its escapingReplacements property in a more convenient way, than calling its setter method:

    $likeObject->setEscapingReplacements( false );

The property itself is not public but protected, so direct assignment raises exception:

    $likeObject->escapingReplacements = false;

In general, it would be nice to set escapingReplacements at object creation as fouth parameter passed to __construct method, e.g. like this:

    $data = ( new Query())
        ->select([ 'id', 'name' ])
        ->from( 'locality' )
        ->where( new LikeCondition( 'postal', 'LIKE', '12345_', false ))
        ->all();

This would eliminate the need in additional object holding var and code lines:

    $likeObject = new LikeCondition( 'postal', 'LIKE', '12345_' );
    $likeObject->setEscapingReplacements( false );
    $data = ( new Query())
        ->select([ 'id', 'name' ])
        ->from( 'locality' )
        ->where( $likeObject )
        ->all();

Additional info

Q A
Yii version 2.0.14
PHP version 5.6.12
Operating system Windows

Bug: Adding a comment on DB column fails when using MySQL with ANSI_QUOTES enabled

What steps will reproduce the problem?

Use MySQL database with sql_mode set to ANSI_QUOTES

What is the expected result?

QueryBuilder::addCommentOnColumn works as expected

What do you get instead?

QueryBuilder::addCommentOnColumn crashes with a MySQL syntax error, because QueryBuilder::getColumnDefinition returns null, because its regular expression pattern suddenly does not work.

I am already preparing a fix (a pull request)

error db (yii\db\Exception: SQLSTATE[HY000]: General error: 1096 No tables used)

Q A
Yii version 3.0
PHP version 7.1.17
Operating system Centos 7
Next yii\db\Exception: SQLSTATE[HY000]: General error: 1096 No tables used
The SQL being executed was: SELECT * in /home/example.com/public_html/vendor/yiisoft/db/src/Schema.php:664

Stack trace:
#0 /home/example.com/public_html/vendor/yiisoft/db/src/Command.php(1263): yii\db\Schema->convertException(Object(PDOException), 'SELECT *')
#1 /home/example.com/public_html/vendor/yiisoft/db/src/Command.php(1148): yii\db\Command->internalExecute('SELECT *')
#2 /home/example.com/public_html/vendor/yiisoft/db/src/Command.php(413): yii\db\Command->queryInternal('fetch', NULL)
#3 /home/example.com/public_html/vendor/yiisoft/db/src/Query.php(274): yii\db\Command->queryOne()
#4 /home/example.com/public_html/vendor/yiisoft/active-record/src/ActiveQuery.php(294): yii\db\Query->one(NULL)
#5 /home/example.com/public_html/vendor/yiisoft/active-record/src/BaseActiveRecord.php(111): yii\activerecord\ActiveQuery->one()
#6 /home/example.com/public_html/vendor/yiisoft/yii-base-web/src/models/User.php(83): yii\activerecord\BaseActiveRecord::findOne(Array)
#7 /home/example.com/public_html/vendor/yiisoft/yii-base-web/src/forms/LoginForm.php(77): yii\app\models\User::findByUsername('admin')
#8 /home/example.com/public_html/vendor/yiisoft/yii-base-web/src/forms/LoginForm.php(49): yii\app\forms\LoginForm->getUser()
#9 [internal function]: yii\app\forms\LoginForm->validatePassword('password', NULL, Object(yii\validators\InlineValidator))
#10 /home/example.com/public_html/vendor/yiisoft/core/src/validators/InlineValidator.php(72): call_user_func(Array, 'password', NULL, Object(yii\validators\InlineValidator))
#11 /home/example.com/public_html/vendor/yiisoft/core/src/validators/Validator.php(274): yii\validators\InlineValidator->validateAttribute(Object(yii\app\forms\LoginForm), 'password')
#12 /home/example.com/public_html/vendor/yiisoft/core/src/base/Model.php(364): yii\validators\Validator->validateAttributes(Object(yii\app\forms\LoginForm), Array)
#13 /home/example.com/public_html/vendor/yiisoft/yii-base-web/src/forms/LoginForm.php(63): yii\base\Model->validate()
#14 /home/example.com/public_html/vendor/yiisoft/yii-base-web/src/controllers/SiteController.php(78): yii\app\forms\LoginForm->login()
#15 /home/example.com/public_html/vendor/yiisoft/core/src/base/InlineAction.php(57): yii\app\controllers\SiteController->actionLogin()
#16 /home/example.com/public_html/vendor/yiisoft/core/src/base/Controller.php(160): yii\base\InlineAction->runWithParams(Array)
#17 /home/example.com/public_html/vendor/yiisoft/core/src/base/Module.php(542): yii\base\Controller->runAction('login', Array)
#18 /home/example.com/public_html/vendor/yiisoft/yii-web/src/Application.php(94): yii\base\Module->runAction('site/login', Array)
#19 /home/example.com/public_html/vendor/yiisoft/core/src/base/Application.php(525): yii\web\Application->handleRequest(Object(yii\web\Request))
#20 /home/example.com/public_html/public/index.php(14): yii\base\Application->run()
#21 /home/example.com/public_html/public/index.php(15): {closure}()
#22 {main}
Additional Information:
Array
(
    [0] => HY000
    [1] => 1096
    [2] => No tables used
)

2018-09-09 01:08:28 [999.999.999.999][-][e05d5532cdeea664670fa57b4ff9aec5][info][application] $_GET = []

$_POST = [
    '_csrf' => 'MuZl0hEYOz8SIZw_V_qcjAPKtCe29HHIo0h-i56owFYHhTqVXl5NVyVV31Y7nfrHcY_7YumBJKTqPgrZ9M32Ow=='
    'LoginForm' => [
        'username' => 'admin'
        'password' => 'admin'
        'rememberMe' => '1'
    ]
    'login-button' => ''
]

Query::one() should return null instead of false, when no results

yii\db\Query::one() returns false if there are no results. In a rare break from consistency, yii\db\ActiveQuery::one() returns null instead.

I can’t think of any reason why they would need to return different things, so this is probably just an oversight.

Of the two, null is probably the better option, as it’s more semantic and would allow the result could be used in conjunction with a ?? operator, e.g

$foo = $query->one() ?? 'default';

So Query::one() is the method that should change.

batchInsert support ignore

When I execute batch inserting into tables with unique index, I hope the batchInsert method of yii\db\Command Class have a argument to specify whether to execute INSERT IGNORE INTO or just INSERT INTO .

Add Hint Index in queries

I need force index in my project, so I've add the method addHintIndex to set the hints indexes associated to a table.
The param is an assoc array of the hintIndex(s) to be used on the query.
The key is the name of the table to be hinted.
The value is the hint settings or an array of hints settings to apply.
Each hint setting is compose by one to three string values defining the hint and one array defining the index(s) to hint.

Here are some examples:

$query = (new \yii\db\Query())->from(['t' => 'user'])->addHintIndex(['user' => [
    ['force', 'index', ['primary']],
    ['ignore', 'index', 'order by', ['i1']],
]])->leftJoin('profile as p', 'user.id = profile.user_id')->addHintIndex(['profile' => [
    'use', 'index', ['i2']
]]);

// sql -> SELECT * FROM `user` `t` FORCE INDEX (primary) IGNORE INDEX FOR ORDER BY (i1)
 LEFT JOIN `profile` `p` ON user.id = profile.user_id USE INDEX (i2)
$users = User::find()->addHintIndex(['user' => [['use', 'index', ['primary']]]])->one();

// sql -> SELECT * FROM {{%user}} USE INDEX (primary)

I have no experience enought with other drivers than mysql, so just write functionality for mysql and sqlite drivers (the former tested the last pending for testing).

Driver overwritting can be done on:

  • /yii2/framework/db/mysql/QueryBuilder.php
  • /yii2/framework/db/sqlite/QueryBuilder.php (require testing)*
  • /yii2/framework/db/cubrid/QueryBuilder.php (trace a message and ignore addHintIndex)*
  • /yii2/framework/db/mssql/QueryBuilder.php (trace a message and ignore addHintIndex)*
  • /yii2/framework/db/oci/QueryBuilder.php (trace a message and ignore addHintIndex)*
  • /yii2/framework/db/pgsql/QueryBuilder.php (trace a message and ignore addHintIndex)*

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • We receive the funding once the issue is completed & confirmed by you.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar

[2.1] Make all query properties protected

I'd like to make all query properties like $where, $limit and so on protected.

What steps will reproduce the problem?

I have a model (or multiple models) that support soft delete.
I'd like to limit how these are queried by implementing a custom ActiveQuery class.

Some things I do or would like to do:

  • Filter deleted records by default
  • Throw an exception on the ->where() function, for my models I want to enforce only using andWhere.
  • Disable direct modification of the query.

What is the expected result?

I expect to have control over my own query class.

What do you get instead?

Since most properties are public there is no control, anyone could be writing to them directly.
I think the design would be cleaner and more powerful if these properties would be protected.
Since these classes are subclasses of Component they have support for magic getters which would provide a backwards compatible upgrade path in most cases.

QueryBuilder: union and order by not works

I have:

$query1 = (new \yii\db\Query())
    ->select("id, category_id AS type, name")
    ->from('post')

$query2 = (new \yii\db\Query())
    ->select('id, type, name')
    ->from('user')
    ->orderBy('type');

$query1->union($query2);

This code generates the following SQL:

(SELECT `user`.`id`, `user`.`category_id` AS `type`, `user`.`name` FROM `post`) 
UNION
(SELECT `user`.`id`, `user`.`category_id`, `user`.`name`  FROM `post` ORDER BY `type`) 

The SQL above does not order correctly.
It's necessary remove the parentheses. Ex:

SELECT `user`.`id`, `user`.`category_id` AS `type`, `user`.`name` FROM `post`
UNION
SELECT `user`.`id`, `user`.`category_id`, `user`.`name`  FROM `post` ORDER BY `type`

Funding

  • You can sponsor this specific effort via a Polar.sh pledge below
  • We receive the pledge once the issue is completed & verified
Fund with Polar

Remove dependencies on yii-core

If we really want this to be useful independently of yii-core we should remove the application from the test suite.

We can't guarantee that it works properly without the core if we still initialize our singletons like Yii::$container and Yii::$app during testing.

refactor QueryBuilder::buildUnion

it should include the process of adding parenthesis to allow simpler override in sqlite\QueryBuilder.
Currently the complete build() method is overridden just to add two parenthesis.

Circular Reference to schema

On downloading the current master branch and installing everything, I get this following error on access of /public/:

[05-Sep-2018 07:41:16 UTC] An Error occurred while handling another error:
yii\di\exceptions\CircularReferenceException: Circular reference to "yii\db\mysql\Schema" detected while building: yii\db\mysql\Schema; dereferencing:  in /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/di/src/AbstractContainer.php:121
Stack trace:
#0 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/di/src/Factory.php(48): yii\di\AbstractContainer->build('yii\\db\\mysql\\Sc...', Array)
#1 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/helpers/BaseYii.php(69): yii\di\Factory->create(Array, Array)
#2 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/db/src/Connection.php(841): yii\helpers\BaseYii::createObject(Array)
#3 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/active-record/src/ActiveRecord.php(391): yii\db\Connection->getSchema()
#4 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/active-record/src/ActiveRecord.php(216): yii\activerecord\ActiveRecord::getTableSchema()
#5 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/active-record/src/ActiveRecord.php(195): yii\activerecord\ActiveRecord::filterCondition(Array)
#6 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/active-record/src/BaseActiveRecord.php(111): yii\activerecord\ActiveRecord::findByCondition(Array)
#7 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-base-web/src/models/User.php(64): yii\activerecord\BaseActiveRecord::findOne(Array)
#8 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-web/src/User.php(675): yii\app\models\User::findIdentity(1)
#9 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-web/src/User.php(195): yii\web\User->renewAuthStatus()
#10 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-web/src/User.php(363): yii\web\User->getIdentity()
#11 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/Component.php(142): yii\web\User->getIsGuest()
#12 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-base-web/src/views/layouts/main.php(44): yii\base\Component->__get('isGuest')
#13 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/view/src/view/View.php(324): require('/Applications/M...')
#14 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/view/src/view/View.php(246): yii\view\View->renderPhpFile('/Applications/M...', Array)
#15 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/Controller.php(397): yii\view\View->renderFile('/Applications/M...', Array, Object(yii\app\controllers\SiteController))
#16 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/Controller.php(383): yii\base\Controller->renderContent('<div class="sit...')
#17 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-web/src/ErrorAction.php(173): yii\base\Controller->render('error', Array)
#18 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-web/src/ErrorAction.php(152): yii\web\ErrorAction->renderHtmlResponse()
#19 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/Action.php(99): yii\web\ErrorAction->run()
#20 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/Controller.php(160): yii\base\Action->runWithParams(Array)
#21 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/Module.php(542): yii\base\Controller->runAction('error', Array)
#22 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-web/src/ErrorHandler.php(103): yii\base\Module->runAction('site/error')
#23 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/ErrorHandler.php(123): yii\web\ErrorHandler->renderException(Object(yii\di\exceptions\NotFoundException))
#24 [internal function]: yii\base\ErrorHandler->handleException(Object(yii\di\exceptions\NotFoundException))
#25 {main}
Previous exception:
yii\di\exceptions\NotFoundException: No definition for "yii\db\mysql\Schema" found in /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/di/src/AbstractContainer.php:161
Stack trace:
#0 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/di/src/AbstractContainer.php(134): yii\di\AbstractContainer->buildWithoutDefinition('yii\\db\\mysql\\Sc...', Array)
#1 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/di/src/AbstractContainer.php(155): yii\di\AbstractContainer->build('yii\\db\\mysql\\Sc...', Array)
#2 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/di/src/AbstractContainer.php(134): yii\di\AbstractContainer->buildWithoutDefinition('yii\\db\\mysql\\Sc...', Array)
#3 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/di/src/Factory.php(48): yii\di\AbstractContainer->build('yii\\db\\mysql\\Sc...', Array)
#4 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/helpers/BaseYii.php(69): yii\di\Factory->create(Array, Array)
#5 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/db/src/Connection.php(841): yii\helpers\BaseYii::createObject(Array)
#6 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/active-record/src/ActiveRecord.php(391): yii\db\Connection->getSchema()
#7 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/active-record/src/ActiveRecord.php(216): yii\activerecord\ActiveRecord::getTableSchema()
#8 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/active-record/src/ActiveRecord.php(195): yii\activerecord\ActiveRecord::filterCondition(Array)
#9 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/active-record/src/BaseActiveRecord.php(111): yii\activerecord\ActiveRecord::findByCondition(Array)
#10 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-base-web/src/models/User.php(64): yii\activerecord\BaseActiveRecord::findOne(Array)
#11 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-web/src/User.php(675): yii\app\models\User::findIdentity(1)
#12 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-web/src/User.php(195): yii\web\User->renewAuthStatus()
#13 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-web/src/User.php(363): yii\web\User->getIdentity()
#14 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/Component.php(142): yii\web\User->getIsGuest()
#15 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-base-web/src/views/layouts/main.php(44): yii\base\Component->__get('isGuest')
#16 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/view/src/view/View.php(324): require('/Applications/M...')
#17 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/view/src/view/View.php(246): yii\view\View->renderPhpFile('/Applications/M...', Array)
#18 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/Controller.php(397): yii\view\View->renderFile('/Applications/M...', Array, Object(yii\app\controllers\SiteController))
#19 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/Controller.php(383): yii\base\Controller->renderContent('<div class="sit...')
#20 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-base-web/src/controllers/SiteController.php(63): yii\base\Controller->render('index')
#21 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/InlineAction.php(57): yii\app\controllers\SiteController->actionIndex()
#22 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/Controller.php(160): yii\base\InlineAction->runWithParams(Array)
#23 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/Module.php(542): yii\base\Controller->runAction('', Array)
#24 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/yii-web/src/Application.php(94): yii\base\Module->runAction('', Array)
#25 /Applications/MAMP/htdocs/hack/y3/vendor/yiisoft/core/src/base/Application.php(525): yii\web\Application->handleRequest(Object(yii\web\Request))
#26 /Applications/MAMP/htdocs/hack/y3/public/index.php(14): yii\base\Application->run()
#27 /Applications/MAMP/htdocs/hack/y3/public/index.php(15): {closure}()
#28 {main}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.