Giter Site home page Giter Site logo

nette / database Goto Github PK

View Code? Open in Web Editor NEW
482.0 41.0 104.0 1.81 MB

💾 A database layer with a familiar PDO-like API but much more powerful. Building queries, advanced joins, drivers for MySQL, PostgreSQL, SQLite, MS SQL Server and Oracle.

Home Page: https://doc.nette.org/database

License: Other

PHP 99.20% HTML 0.80%
database-layer php orm nette nette-framework sql-query pdo

database's Introduction

Nette Framework is a popular tool for PHP web development. It is designed to be as usable and as friendly as possible. It focuses on security and performance and is definitely one of the safest PHP frameworks.

Nette Framework speaks your language and helps you to easily build better websites.

The Quick Start tutorial gives you a first introduction to the framework by creating a simple database driven application.

Over 10 Yrs of Development

We have been developing Nette for over 10 years- and counting! Libraries we provide are therefore highly mature, stable and widely used. They are trusted by a number of global corporations and many significant websites rely on us.

Catching Bronze

We aim to create Nette as a fun and easy to use framework, that programmers can fall in love with. And we seem to be doing it well! We were rated as the 3rd most popular framework in a survey Best PHP Framework for 2015 by a well-know magazine SitePoint.

Security Is a Priority

There is nothing we care about more than security. That is why we had built Nette as the safest PHP framework. It had passed many audits with flying colours, it eliminates safety traps like XSS, CSRF and brings out ground-breaking methods.

Libraries & Framework

Nette consists of a number of handy standalone libraries, which can be used in any codebase, for example combined with WordPress or another framework. Careful, some of them are highly addictive! These are the components that Nette Framework is built on:

  • Application – The kernel of web application
  • Bootstrap – Bootstrap of your application
  • Caching – Cache layer with set of storages
  • Component Model – Foundation for component systems
  • DI – Dependency Injection Container
  • Finder – Find files and directories with an intuitive API
  • Database – Database layer
  • Forms – Greatly facilitates secure web forms
  • Http – Layer for the HTTP request & response
  • Latte – Amazing template engine
  • Mail – Sending E-mails
  • Neon – Loads and dumps NEON format
  • Php Generator – PHP code generator
  • Robot Loader – The most comfortable autoloading
  • Routing – Routing
  • Safe Stream – Safe atomic operations with files
  • Security – Provides access control system
  • Schema – User data validation
  • Tester – Enjoyable unit testing in PHP
  • Tracy – Debugging tool you will love ♥
  • Tokenizer – Source code tokenizer
  • Utils – Utilities and Core Classes

database's People

Contributors

adaamz avatar audio avatar clovnrian avatar detrandix avatar dg avatar edacz avatar enumag avatar fabik avatar foxycode avatar fprochazka avatar h4kuna avatar hrach avatar insekticid avatar jantvrdik avatar josefdohnal avatar juzna avatar majkl578 avatar martinmystikjonas avatar matej21 avatar milo avatar mishak87 avatar norbe avatar paranoiq avatar remicollet avatar ricco24 avatar rikap avatar smuuf avatar tomaswindsor avatar unlink avatar vrana avatar

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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

database's Issues

Extending ActiveRow

Sometimes i need functions based on row data, for example if i have $user->first_name and $user->last_name, and i want to have function $user->full_name that just concat these two attributes.

I imagine something like extend ActiveRecord, then create factory and inject that factory into Nette\Database\Table\Selection. What do you think ?

wrong created sql query with group and min or max

My code:
$rows = $this->db->table('prices')->group('vehicle_id'); return $rows->min('price');

Returned query:
SELECT MIN(price) FROM prices

Right query:
SELECT MIN(price) FROM prices GROUP BY vehicle_id


Sorry, my mistake. ->min($column) return only int

Problem with table names

$this->database->table('update')->insert(array('id' => $id));

create mysql code

INSERT INTO update id='1411560628260'

Saving resources to database

During migration from Nette 2.0.18 to Nette 2.3.1 I found problem with saving resources to database as LOB.

Nette 2.0 used bindValue() with autodetected types before calling execute() on prepared query.
See here: https://github.com/nette/nette/blob/v2.0.18/Nette/Database/Statement.php#L83
Nette 2.3 passes parameters directly to execute.

This difference is problem when I try to save resource - it is saved to database as string "Resource id #260", because PDO needs to have set correct binding to save conent of resource.
Is it possible to add binding of values into Database\Connection::query()?

Selection->getPrimary() is not sufficiently specific

Selection->getPrimary returns name of primary key (in my case id for all the tables).

This is also true when joining tables - e.g. with where table2.column = ?.

Unfortunatelly when joining very large tables (hundreads of thousands of rows, hundread columns) the order of returned columns is indeterminate in MySQL. Although observed here, this might not be the only case when this happens.

The resulting behaviour is the primary key from table2 is considered instead of table1. This has fatal results - not all the rows are returned and they might get damaged when being updated.

The easy way to fix this seemed to be:

  1. not using PKs in Statement->execute, unfortunatelly this breaks referencing (row->table2->table2row).
  2. just using <table name>.id instead of just id in Selection->getPrimary, but this breaks referencing as well

Bug: Nette\Database\Table\Selection generate wrong sql

Example code:

class Phone
{
    private $areaCode;
    private $number;

    public function __construct($areaCode, $number)
    {
        $this->areaCode = $areaCode;
        $this->number = $number;
    }

    public function __toString()
    {
        return $this->areaCode.' '.$this->number;
    }
}

$myPhone = new Phone('+420', '111222333');

$db->table('accounts')->where('phone LIKE', $myPhone)

GENERATES

SELECT `id` 
FROM `accounts` 
WHERE (`phone` LIKE +420 111222333)

CORRECTLY

$db->table('accounts')->where('phone LIKE', (string)$myPhone)

GENERATES

SELECT `id` 
FROM `accounts` 
WHERE (`phone` LIKE '+420 111222333')

Helpers::dumpSql() should parse named params

In PDO you can bind named params bindValue('something', 1, PDO::TYPE);

So you can use ResultSet like this

$query = 'SELECT * FROM table WHERE id = :something';
$params[':something'] = 1;
$resultSet = new ResultSet($connection, $query, $params);
$connection->onQuery($connection, $resultSet);// log binded param query to Tracy

Problem is in Nette\Bridges\DatabaseTracy\ConnectionPanel template which invoke Helpers::dumpSql()

This helper does not support named parameters. Tracy result is:

SELECT * FROM table WHERE id = :something

Weird exception message when table don't exists

Hello!

A friend of mine created simple application that use nette/database. In controller action he has this code:

$clients = $db->table('clients');
$client = $db->get($id);

At first time it worked fine. But later he started to want to rename 'clients' to 'users' . So he changed table name in database, and changed code:

$users = $db->table('users');
$user = $db->get($id);

Seems fine, but.. He got exception:

LogicException
Table 'users' does not have a primary key.

What?!? He looked at database structure, and said "but i have primary key in this table!".

Then he looked at Nette.Database.Structure cache and found real problem - there is no any data about table named 'users'. So he removed this cache to rebuild it, and after this application started to work fine again.

I tried to use table that really don't exists in database:

$db->table('foobar')->get(1);

and got same exception:

Table 'foobar' does not have a primary key.

This is very strange behavior to show this exception message, isn't? I think if table actually exists in database but not present in cache, then nette/database should rebuild cache. Or, if not, then it should throw more meaningful exception like "Table don't exists".

toArray() on deleted ActiveRow creates infinite loophole

I have noticed some buggy behavior when I was attempting to delete row from database, but also preserve the ActiveRow with data, for logging purpose. While this operation is incorrect, some exception would be more suited then current behavior.

First case - produces infinite loophole.

function delete( ActiveRow $note )
{   
    $note->getTable()->createSelectionInstance()
        ->wherePrimary( $note->id )
        ->delete();

    dump( $note->toArray() ); // <-- isded
}

Second case - produces undefined offset notice.

function delete( ActiveRow $note )
{
    $note->delete();

    dump( $note->toArray() ); // <-- isded
}

Versions
Nette: 2.3.0
Nette/Database: 2.3.0
PHP: 5.5.9

Wrong join generating

Hello,
I have these primitive tables:

DROP TABLE IF EXISTS firstTable;
CREATE TABLE firstTable (
id int(11) NOT NULL AUTO_INCREMENT,
firstFk int(11) NOT NULL,
PRIMARY KEY (id),
KEY firstFk (firstFk),
CONSTRAINT firstTable_ibfk_1 FOREIGN KEY (firstFk) REFERENCES secondTable (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

DROP TABLE IF EXISTS `secondTable`;
CREATE TABLE `secondTable` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

and trying to do following:

$result = $this->db->table("firstTable")->select("firstTable.id, secondTable.id");
dump($result->getSql());

Result is exception No reference found for $firstTable->secondTable. I've found, that it works only if I name column with FK with the same name as target table (used stripos in DiscoveredConventions). I think that it is not correct behavior because we can also use foreign keys. When I dumped variables in getBelongsToReference method, then I've found that for correct join should be line if (stripos($column, $key) !== FALSE) { changed to if (stripos($targetTable, $key) !== FALSE) {, because $tableColumns contains eg. firstFk => "secondTable".

I'm not sure if this is real bug, or just my mistake and if is potencial solution ok. I've created for this example sandbox - http://pastebin.com/bm1HHCut

Microsoft SQL Server 2012 SYNTAX ERROR

Firstly, I would like to send many, many thanks to Davit to implement support of MSSQL. I found one important bug.

$this->context->table(...)->limit(100,10) generate bad syntaxt.

SELECT *
FROM [table]
OFFSET 10 ROWS FETCH NEXT 100 ROWS ONLY

This syntax works only, if I use order clausule, for example:
SELECT *
FROM [table]
ORDER BY [id] DESC
OFFSET 10 ROWS FETCH NEXT 100 ROWS ONLY

Nette 2.3 problem with Nette\Database\Structure for huge database

After upgrade nette from 2.0.7 to 2.3.5 in my app i detected masive grow execution time and memory consuption at \Nette\Database\Structure after unserialize cached data.
I have huge database with 6k tables and cached data in serialize structure string have 23MB. (by profiler - +180MB memory, extra 1000ms execution time)
Before updating nette this not problem. Why?

Undefined offset while retrieving data from cache

In production environment with dozens of simultaneous requests, retrieving data from cache sometimes fails (this is true for newest version of Nette Database as well as older ones).

A long time ago a thread started at: https://forum.nette.org/cs/13466-undefined-offset-pri-dotazu-z-databaze-po-vymazani-cache

The issue is not consistent, sometimes the notice appears sometimes it does not (I was unable to test the conditions when this fails - they still seem magical to me). Moreover this is not the issue only when using count(), but any query.

The best approximation to errorneus conditions I could achieve is:

  1. You need to access quite large database
  2. Multiple accesses to the same table over the same data set with different queries is a plus stronly supporting the error appearing
  3. You need to have cache enabled
    4) You need to use the same ResultSet in different conditions, e.g. once to read couple of rows and other time to get count(); or use limit() multiple times to get rows; or probably any duplicate access to the same data

I strongly feel, the 4) is the real approximation to the mistake. Although I was unable to locate it directly in the code, it seems you need to access the data multiple times and cache only stores one case. The other case should logically be there, therefore you get a notice.

Allow specifying ON clause filtering condition.

Would be very useful to allow specify conidtion, which would be add to ON clause. The question is the syntax. The main usecase are condition with OR. Other usecases are against NDB principle to select only from one table at once.

Usecase:
Select all photos, which "current user" is author or has allowed acces in access table.

SELECT photos.*
FROM photos
    LEFT JOIN access ON (photo.id = access.photoId AND access.userId = ?)
WHERE
    photo.authorId = ?
OR acess.userId IS NOT  NULL

Need api suggestions:

$books = $context->table('photos');
$books->whereSoft('access.userId = ?', $userId);
$books->where('photo.authorId = ? OR access.userId IS NOT NULL');

Things to discuss:

  • whereSoft method name
  • support for OR in where SOFT?
  • some bigger overhaul for SqlBuilder (alias supporting, etc?)

cc @milo @norbe @dg nette/nette#1436


Edit: it is possible to rewrite it without the condition included in join, but then is needed some either grouping by or distinct, which would give much worse EXPLAIN, some temporary table needed for mysql.

PostgreSQL reflection across the schemas

In dibi issue, @JanRossler pointed out, that comparing table by its name may fail with multiple schemas. Imagine two tables with the same name in different schemas:

CREATE TABLE "one"."tab" ("id_one" integer NULL);
CREATE TABLE "two"."tab" ("id_two" integer NULL);

If you set SET search_path TO one, two you get by reflection:

Issue 1

dump($driver->getTables());
[
    0 => ['name' => 'tab', 'view' => FALSE],
    1 => ['name' => 'tab', 'view' => FALSE],  # duplicit
]

Issue 2

dump($driver->getColumns('tab'));
[
    0 => ['name' => 'id_one', 'table' => 'tab'],
    1 => ['name' => 'id_two', 'table' => 'tab'],  # should not be there
]

One of the solutions is to use table_name::regclass (you get OID of the first table relatively to search_path) instead of schema name + table name comparision. It has side effect, using ::regclass on undefined table leads to SQL error. It is BC break because now you get empty result silently.

I am prepared to update PostgreSQL driver reflection part, but:

  • how to solve Issue 1? Filter out the duplicits?
  • how to handle undefined::regclass error exception? Is it OK?

Table '$name' does not exist.

Zdravím,

myslím, že úpravy v issue #79 omylem způsobily, že se vyhazuje výjimka tam kde dřív ne.

Metoda resolveFQTableName v Nette\Database\Strucure se volá z metody getPrimaryKey téže třídy. Problém nastane ve chvíli, když je argumentem pohled.

Pohledy se v metodě loadStructure přeskakují:

foreach ($structure['tables'] as $tablePair) {
    if ($tablePair['view']) {
        continue;
    }
    ....

a díky tomu v $this->structure['columns'] ani $this->structure['primary'] nikdy nebude a vyskočí ona vyjímka.

SqlBuilder: delete doesn't parse joins

Hi,
example:

$db->table('table')
    ->where(':another_table.column', 5)
    ->delete();

Makes SQL like

DELETE FROM table WHERE :´another_table´.´column´ = 5.

Selection - refetch

Sometimes it would be useful to have method to force Selection to refetch data from database.

Use case: I have component displaying datagrid. It gets Selection as parameter (somehow prefiltered) which describes data I want in this grid. Some actions in datagrid calls methods for other parts of application which affects displayed data. I would want to refetch data after I call such method.

Create new Selection and replace it is not an option - In grid I do not know haw the selection I got was created.

Currently I use trick with $selection->limit(null); which triggers refetch, but it is not nice.

I think some method like reload(), refetch(), invalidate() or so should be part of Selection interface.

What do you think?

ActiveRow __isset return FALSE

V sablone mam 2 radky za sebou:
{dump $row->price}
{dump empty($row->price)}

a vraci hodnotu a TRUE (http://icqlister.123hosting.cz/test.png)

chvili jsem koukal jak se chova empty a ono vola __isset() u objectu a to vraci false i presto, ze promenna existuje a dokonce ma hodnotu

empty(($row->price)) uz vraci spravne FALSE pochopitelne

MSSQL Nette driver does not support UC2 for UTF-8 characters

MSSQL Nette driver does not support UC2 for UTF-8 characters, for example "č" is inserted to the database as "c".

Solution is us N before the string, which needs to be converted to UC2. My solution is following:

$this->context->table(self::LR_TABLE_NAME)->where(self::LR_TABLE_ID, $formData->id)->update(array(
self::LR_COLUMN_NUMBER => $formData->number,
self::LR_COLUMN_DESCRIPTION => '@@uc2@@' . $formData->description,
....
));

In the database driver: If string is started with @@uc2@@, remove @@uc2@@ and add "N" before slash.

ActiveRow: Trying to get property of non-object & Selection: Invalid argument supplied for foreach()

In some cases (delete of cache files, access to one page and then access to another page) Nette\Database\Table\ActiveRow::accessColumn generates Notice.

I can't write test case because bug is unpredictable.

My temporary solution is edit Nette\Database\Table\Selection::offsetGet, but it's only a hack IMHO (and is applied only to ::offsetGet).

public function offsetGet($key)
{
    $this->execute();

    // solves strange cache bug
    $rows = ($this->rows) ? : $this->data;

    return $rows[$key];
}

Another hack is edit Nette\Database\Table\ActiveRow::accessColumn like this:

protected function accessColumn($key, $selectColumn = TRUE)
{
    $this->table->accessColumn($key, $selectColumn);
    if ($this->table->getDataRefreshed() && !$this->dataRefreshed) {
        $row = ($this->table[$this->getSignature()]) ? : $this->table->get($this->getSignature());
        $this->data = $row->data;
        $this->dataRefreshed = TRUE;
    }
}

Related topic in forum:


I can't reproduce issue artifically so I can't write tests and create full pull-request at the moment :(
Codes above are only my "hacks" until we found right cause of the issue.

SqlsrvDriver poorly composed TOP n if used SELECT DISTINCT

SELECT - SQL Command - SELECT Clause

SELECT [ALL | DISTINCT] [TOP nExpr [PERCENT]] Select_List_Item [, ...] ...

If used $dbsel->select("DISTINCT column") SQL is "SELECT TOP 10 DISTINCT" column but must be "SELECT DISTINCT TOP 10 column".

In the file database/src/Database/Drivers/SqlsrvDriver.php on line 92:

$sql = preg_replace('#^\s*(SELECT|UPDATE|DELETE)#i', '$0 TOP ' . (int) $limit, $sql, 1, $count);

change regular expression:

'#^\s*(SELECT|UPDATE|DELETE)#i'

to

'#^\s*(SELECT\s*DISTINCT|SELECT\s*ALL|SELECT|UPDATE|DELETE)#i'

mysql: insert when primary key is not auto_increment

When inserting record to table with primary key column without auto_increment, the result of operation is false. The reason is that it is not able to refetch data. It is because the current solution is relying on LAST_INSERT_ID() sql query, which is working only for auto_increment columns (docs).

Proposed solution
When table has not primary key with auto_increment, it has to be in data passed to insert method. So the solution should be that when the primary key is already set, no getLastInsertId method is needed to be called and refetch can use the primary id from data.

PostgreSQL: insert() fails when sequence have upper case letter in the name

$conn->table("Orders")->insert(...); // exception here
image
(notice that getPrimarySequence() detected sequence correctly)

Not sure if it is PHP or nette/database bug. However fix is very simple.
change line 737 in Selection.php to:
$primaryKey = $this->connection->getInsertId('"'.$this->getPrimarySequence().'"');

Can not add multiple selections as condition on the same column

Example code:

    $q = $db->table('users');
    foreach(array('admin','user') as $role) {
       $q->where('id',
                         $db->table('user_role')
                               ->select('user_id')
                               ->where('role_id',$role));
    }

Example code adds only first selection, because of hash check in SqlBuilder.php line 200. It's because Selection does not have any unique public property and so it's always translated as empty object {} in JSON.

PostgreSQL: select() fails when column name has all big letters

$context->query('DROP SCHEMA IF EXISTS public CASCADE');
$context->query('CREATE SCHEMA public');
$context->query('
    CREATE TABLE "public"."bug12" (
        "id" serial,
        "PSC" varchar(5),
        PRIMARY KEY ("id")
    )
');

$context->table("bug12")->insert(array(
    'PSC' => "61600"
));

$row = $context->table("bug12")->select("PSC")->fetch();

Throws:
PDOException: SQLSTATE[42703]: Undefined column: 7 ERROR: column "psc" does not exist

Problem with \DateInterval object on insert/update

Hi,
I'm reacting on BC break in the issue nette/nette#1213.

The thing is, that it's really nice, that database layout returns the \DateInterval object (instead of \DateTime object) on select from time column, but in that case I'll expect, that database layout will also be able to work with \DateInterval object on insert/update or everywhere else, e.g.:

// Database layout can't process object \DateInterval so it tries to convert it into string
// An Exception in throw due to \DateInterval doesn't have implemented __toString method
$database->table("scheduler")->insert(array(..., "interval" => new \DateInterval("PT1H"), ...));

Or another example:

$activeRow = $database->table("scheduler")->where("id", 5)->fetch();
$interval = clone $activeRow->interval;
$interval->h++;
$activeRow->update(array("interval" => $interval)); // Same problem as above

There are two ways how to deal with this problem:

  1. Extend ISupplementalDriver interface by method formatInterval & fix method formatValue in class SqlPreprocessor to use it if value is instance of \DateInterval
  2. Create \Nette\Utils\DateInterval class (like \Nette\Utils\DateTime) which will extend class \DateInterval by function __toString & fix method normalizeRow in class ResultSet to use this new object instead of php \DateInterval

I prefer the first option, but it's up to you guys :)

If you don't have anything against this, I'd like to resolve this issue & create pull request. (Because this term at school I have a subject called Open-Source Programming in which I have to join some running open source project & resolve some issues.) :D

Thanks for your attention,
and I'll look forward to your reply.

SqlBuilder: SELECT DISTINCT isn't first

Hi,
the syntax of SELECT DISTINCT (for MySQL) is
SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] select_expr [, select_expr ...]
Consider this code:

$selection = $db->table('table');
$selection->select('col2');
$selection->select('DISTINCT col1');

then the DISTINCT col2 is on 2nd place.

Bug in SqlBuilder

Code

$this->datatabase->table('TABLE 30');

Generate:

SELECT * FROM TABLE 30

ResultSet->normalizeRow ignores timezones

$row[$key] = new Nette\Utils\DateTime($value);

Tested for PostgreSQL's timestamp with time zone data type. This line seems to throw out timezone, when it is present. 2014-10-27 18:05:00 +0100 gets converted to 2014-10-27 18:05:00 with timezone specified in config date.timezone.

Something like $row[$key] = Nette\Utils\DateTime::from(strtotime($value)); works, but is not very nice. I would like to know if a) this is a bug or I am doing something wrong, and b) possible solutions?

PgSql driver - delimite() doesn't work correctly with FQN

We encountered problem, during upgrade to newest version.
INSERTs suddenly stopped working., after some digging, we found following:

  1. INSERTs on their own work correctly
  2. problem is when trying to get lastInsertId()
    Nette\Database\Selection::764
$primaryKey = $this->context->getInsertId(
    !empty($primarySequenceName)
        ? $this->context->getConnection()->getSupplementalDriver()->delimite($primarySequenceName)
        : $primarySequenceName
);
  1. This throws following error: SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "web.product_id_seq" does not exist
  2. When I modified delimite function to work same way as delimiteFQN function in PgSqlDriver, all problems disappeared.

Solution
In identifier names should'nt be any . characters. Move delimiteFQN logic into delimite function.
When asking for delimition of not FQN identifier, it won't cause any problem.

ActiveRow::related::fetch on 1:1 relation does not produce an error

Given there is a 1:1(optional) relationship in the database.

For example in there are 2 tables member and add_info.
member has PK id and add_info has FK member_id.
However not every member has a add_info ,
and every add_info belongs to one and only one member.

When iterating over the Selection of member, i.e. ActiveRow.

ActiveRow::related()::fetch() to get to add_info, seemingly works if cache is disabled (or set to DevNullStorage). Should produce an error. Under DiscoveredReflection

If cache is enabled, than ActiveRow::related()::fetch() crashes apache server with error.log message: 'Parent: child process exited with status 255 -- Restarting.' Might be related to this issue: http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error. Again should produce an error insead.

I am aware that ActiveRow::related()::fetch() is the wrong costruct to use, and ActiveRow::ref() should be used instead. However incorrect and non-sensible construc should produce an error. More inportantly since it seemingly works in development (with DevNullStorage) and suddenly crashes in production.

undefined method validateConfig

V souboru src/Bridges/DatabaseDI/DatabaseExtension.php na řádku 56 se volá metoda validateConfig, která neexistuje. Nebo alespoň já dostávám tuto výjimku

Nette\MemberAccessException
Call to undefined method Nette\Bridges\DatabaseDI\DatabaseExtension::validateConfig().

Stane se to když v config.local.neon odstraním sekci nette: a podsekci database: co byla předtím uvnitř přesunu na její úroveň. Což tedy je pravděpodobně špatně, ovšem i přesto by nette nemělo volat neexistující metodu, nebo pokud jsem to rozbil tou konfigurací, tak by mělo předložit hezčí výjimku, která by říkala co jsem rozbil a jak to opravit.

Configuring row normalization

Would be nice to have confirugable normalization of database row result.
Currently, it's impossible to add own new normalization (like pgarray?). On the other hand, it's impossible to disable some normalization (like all transforms to datetime/dateinterval, ...)

ActiveRow problem with update of primary key

Hi,
recently, I've been exploring source code of some database entities and I've noticed, that in method update of object ActiveRow is one small bug. Well to be precise, it's not a bug, but I think It's not a valid behavior of method too.

The code of method looks like this:

public function update($data) {
    $selection = $this->table->createSelectionInstance()->wherePrimary($this->getPrimary());
    if ($selection->update($data)) {
        selection->select('*');
        if (($row = $selection->fetch()) === FALSE) {
            throw new Nette\InvalidStateException('Database refetch failed; row does not exist!');
        }
        $this->data = $row->data;
        return TRUE;
    else {
        return FALSE;
    }
}

How you can see, if I’ll be updating primary key of ActiveRow, the primary key will be in database updated (if I don’t have defined any references on it), but I’ll end up with an exception “Database fetch failed;…” because in the query is used an old value of the primary key.

I think that a better behavior this method will be the one from below:

  1. To disable update of a primary column(s), and throw an exception before update in DB
  2. Or to fetch updated row for from DB on updated key (my option)

If you don't have anything against this, I'd like to resolve this issue & create pull request. (Because this term at school I have a subject called Open-Source Programming in which I have to join some running open source project & resolve some issues.) :D

Thanks for your attention,
and I'll look forward to your reply.

Netta database generate massive memleaks from version 2.3

Starting from Nette Database 2.3 there are present memleaks with Nette database.

When I run this method 1000x it consumes hundreds of MB:
$context->table('table_name')->insert(['col1' => $val1])->getPrimary();

When I run these two methods 1000x it consumes tens of MB:
$context->query('INSERT INTO table_name (col1) VALUES (?)', $val1);
$context->getInsertId();

When I run these three methods 1000x it consumes a few MB:
$prep = $context->getConnection()->getPdo()->query('INSERT INTO table_name (col1) VALUES (?)');
$prep->execute($val1);
$context->getConnection()->getPdo()->lastInsertId();

Tested on PHP 5.6.5 and 5.6.1 on two different computers

Fetch fatals if column has empty name (fetchField)

This line assumes too much.
It could be solved by mapping empty key to something else. It is called normalizeRow after all.

Example query: SELECT CAST(NEWID() AS VARCHAR(50)) (SQLSRV)

It worked with old version and fetchSingle. Deleted some bullshits what we should do. hrach Apologies was expecting heating OT debate. mishak

Bug: Return value in Database::table()->insert() without autoincrement on PK

https://github.com/nette/database/blob/master/src/Database/Table/Selection.php#L742

$primaryKey = $this->context->getInsertId() aka PDO::lastInsertId()

you have table:
id int(10) unsigned NOT NULL
value varchar(255) COLLATE utf8_czech_ci DEFAULT NULL
PRIMARY KEY (id),

Database::table()->insert(array('id'=>2, 'value'=> 'text'));
will result in
PDO::lastInsertId() return 0 because we have not autoincrement on the table
https://github.com/nette/database/blob/master/src/Database/Table/Selection.php#L769

$row = $this->createSelectionInstance()
            ->select('*')
            ->wherePrimary(0)
            ->fetch();

solution?
check no autoincrement on PK and then iterate over data to insert and get primary key value from this array?

Broken sqlite

In php 5.5 and 5.6 is broken sqlite implementation (detection) of primary keys.
Pragma returns primary keys now indexed, not "(int) bool" as earlier.

Nette\Database\Row #ca39
cid => 0
name => "book_id" (7)
type => "INTEGER" (7)
notnull => 1
dflt_value => NULL
pk => 1

Nette\Database\Row #ccdc
cid => 1
name => "tag_id" (6)
type => "INTEGER" (7)
notnull => 1
dflt_value => NULL
pk => 2 

Would be nice to detect the change which caused this :) (php bug, version of sqlite...)

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.