Giter Site home page Giter Site logo

dibi's Issues

BUG v substitucích, asi někde probíhá cache

Následující kód:

$connection = dibi::connect(Environment::getConfig('database'));

dibi::addSubst('id', 'A.id');
dump($connection->translate('[:id:]'));
dibi::removeSubst('id');

dibi::addSubst('id', 'B.id');
dump($connection->translate('[:id:]'));

vypíše:

"`A`.`id`" (8)
"`A`.`id`" (8)

očekávaný výstup je:

"`A`.`id`" (8)
"`B`.`id`" (8)

Verze: 1.3-dev 8dc164d released on 2010-08-05

Snad tohle pomůže: U toho translate dělají problém hranaté závorky, samotné ':id:' se překládá správně (tedy substituuje se za A i za B), problém je s identifikátorem, tj. '[:id:]'.

Bude to asi tím, že se cachují identifikátory jako třída DibiLazyStorage a identifikátor se substitucí tam přetrvá i když se substituce změní.

Mysql(i) getAffectedRows()

V souboru: https://github.com/dg/dibi/blob/master/dibi/drivers/mysqli.php#L198 (metoda getAffectedRows) je uvedeno v komentari, ze metoda vraci FALSE pri chybe, ale podle PHP dokumentace a zdrojoveho kodu to neni pravda:

http://www.php.net/manual/en/mysqli.affected-rows.php
https://github.com/php/php-src/blob/master/ext/mysqli/mysqli_api.c (doufam, ze odkazuju spravne)

Pri chybe se vraci -1.

Mohl by nekdo overit, ze se nemylim?
Diky


Narazil jsem na to, kdyz jsem cetl: http://stackoverflow.com/questions/7368225/how-do-i-tell-when-a-mysql-update-was-successful-versus-actually-updated-data

Class DibiNettePanel not loaded

Calling dibi::connect throws Fatal error in DibiConnection on line 123, stating that class DibiNettePanel does not exist. Possible solution is to simply require it:

require_once DIR."/../Nette/DibiNettePanel.php";

Autoloading třídy \DibiNettePanel

Hledal jsem důvod, proč se mi nezobrazuje Debug Panel v Nette při použití dibi bez použití statického dibi::__něco__. Přestože mám v konfiguraci Debug Panel zapnutý, nezobrazí se.

O vytvoření a napojení DibiNettePanelu se stará kontruktor ve tříde DibiConnection. Je nějaký důvod, proč je se kontrola na vytvoření panelu provádí právě takto?

<?
if (class_exists('DibiNettePanel', FALSE)) {
    $panel = new DibiNettePanel(isset($profilerCfg['explain']) ? $profilerCfg['explain'] : TRUE, $filter);
    $panel->register($this);
}
?>

Osobně bych uvítal například toto řešení:

<?
if (defined('NETTE') && class_exists('DibiNettePanel')) {
    $panel = new DibiNettePanel(isset($profilerCfg['explain']) ? $profilerCfg['explain'] : TRUE, $filter);
    $panel->register($this);
}
?>

Pokud mám projekt postavený na Nette, tak se použije pro DibiNettePanel autoloading a všechno krásně běží. Pokud Nette používám jen jako pomocnou knihovnu, tak mě to zajímat nemusí, protože konstanta NETTE je edfinována v loader.php, který v tomto případě nepoužiju. A pokud panel pro Dibi nechci vůbec, tak to jednoduše vypnu v konfiguraci.

Pokud mám poslat Pull Request, stačí komentář.

Mysql, BigInt a detekce typu

Pokud je v sloupeček typu BIGINT (vysledováno v MySQL databázi), dibi jej označí jako dibi::INTEGER (při automatickém přetypování). Pro 32b systémy je ale int v PHP jenom +/- 2 mld, tudíž se do něj hodnota bigintu z databáze nevejde a výsledek ve vrácených datech přeteče velikost intu (PHP_INT_SIZE). Pokud se provede přetypování na float, již je to v PHP v pořádku.

Privátní proměnné třídy DibiDataSource

Navrhuji některé privátní proměnné této třídy změnit na protected, aby se s nimi dalo dále pracovat ať už v extension metodách nebo v potomcích. Už jsem se dostal vícekrát do situace, kdy by se to hodilo. Momentálně by se to hodilo k implementaci metody reverse().

dibi won't connect to Nette's Debugbar

Problém je na řádku 28 v dibi.php, tato implementace háže:
Argument 1 passed to Nette\Debug::addPanel() must implement interface Nette\IDebugPanel, instance of DibiProfiler given

Opravou je z interface_exists('Nette\IDebugPanel', FALSE) vyhodit FALSE. Chyba se projevuje na Nette 2.0-dev z 24.9. v dibi balíku při aktivaci profileru pomocí config.ini.

DibiProfiler a MAX_LENGTH

Dlzku SQL ovplyvnuje konstanta MAX_LENGTH. Je mi jasne, ze pokial profiler pouziva Firebug a FirePHP, je potrebne kontrolovat objem dat v hlavicke. Ale pri novom NetteBar-e uz take obmedzenie myslim nie je potrebne.

Samotny SQL profiler je potom zbytocny, kedze vacsinou prvych 500 znakov zo select-u je naprd, vacsinou to podstatne sa deje prave na konci :) Bolo by mozne dlzku SQL menit podla potreby ? Nieco ako Debug::$maxLen.

Komentáře v SQL dotazu

$result = dibi::query("-- ".__FILE__.":".__LINE__.": Hello world
                    SELECT 'hello world'
            ")->fetchSingle();

Výsledný SQL dotaz:

-- /var/www/index.php':83:' Hello world
SELECT 'hello world'

Ve výsledku jsou navíc apostrofy u dvojteček.

Přidáme-li otazník:

$result = dibi::query("-- ".__FILE__.":".__LINE__.": Hello world ?
                    SELECT 'hello world'
            ")->fetchSingle();

Výsledek: SQL translate error

-- /var/www/index.php':83:' Hello world **Extra
placeholder**
SELECT 'hello world'

Trošku větší SQL dotazy pak dokážou generovat i chyby jako "DateTime::__construct(): Failed to parse time string (AND start_time <= %d) at position 0 (A): The timezone could not be found in the database". Samozřejmě, SQL dotaz je zcela správně a po odstranění komentáře na prvním řádku funguje.

Ten komentář na začátku měl sloužit k identifikaci dotazu v logu a chybových hlášeních.

Navíc v tom ladicím toolbaru od Nette chybí "explain" u takto okomentovaného dotazu a komentáře nejsou správně zvýrazněny.

bad colon interpreting in sql in dibi::query($sql)

dibi::query('RENAME TABLE table TO table_2010-05-17_03:06:53;');
failed with "InvalidStateException - Missing substitution for '06' expression."

mysql do this command right, so this sql command is OK.

MSSQL reflector - jiná hodnota pro neexistující položku size než v ostatních driverech

Metoda getColumns() v mssql.reflector.php vrací v položce „size“ v případě chybějících dat FALSE, ostatní drivery (mysql.reflector.php a sqlite.reflector) vrací v tomto případě NULL – lze vyřešit nastavením defaultní hodnoty $size na NULL tedy :

  1. $size = false;
    nahradit za:
  2. $size = NULL;

pak bude chování metody stejné jako při použití ostatních driverů.

Incorrect table identifier quoting in PostgreSQL

This query:

WITH RECURSIVE user_privileges AS (
    SELECT
        ur1."id",
        ur1.id_user_parent,
        ur1.login,
        1 AS sort_order
    FROM
        "[user"] ur1
    WHERE
        ur1.login='guest'
    UNION
    SELECT
        ur2."id",
        ur2.id_user_parent,
        ur2.login,
        2 AS sort_order
    FROM
        "[user"] ur2
        JOIN
        user_privileges ups1
        ON(ur2.id_user_parent=ups1."id" OR ur2."id"=ups1.id_user_parent)
    WHERE
        ur2.login<>'guest'
)
SELECT
    *
FROM
    user_privileges
ORDER BY
    sort_order,
    "id",
    "id_user_parent"
;

which is the result of calling dibi::test($sql, UserModel::$user_login, UserModel::$user_login), where $sql is:

$sql = '
WITH RECURSIVE user_privileges AS (
    SELECT
        ur1.[id],
        ur1.id_user_parent,
        ur1.login,
        1 AS sort_order
    FROM
        [' . self::TABLE_USERS . '] ur1
    WHERE
        ur1.login=%s
    UNION
    SELECT
        ur2.[id],
        ur2.id_user_parent,
        ur2.login,
        2 AS sort_order
    FROM
        [' . self::TABLE_USERS . '] ur2
        JOIN
        user_privileges ups1
        ON(ur2.id_user_parent=ups1.[id] OR ur2.[id]=ups1.id_user_parent)
    WHERE
        ur2.login<>%s
)
SELECT
    *
FROM
    user_privileges
ORDER BY
    sort_order,
    [id],
    [id_user_parent]
';

and value of UserModel::$user_login is guest, fails, because Dibi doesn't rewrite [user] to "user" as it is necessary but it rewrites it to "[user"] instead.

If I use %n in $sql instead of [user], I get "[user]" instead of "user" (I call dibi::test($sql, self::TABLE_USERS, UserModel::$user_login, self::TABLE_USERS, UserModel::$user_login) in this case). This throws an SQL translate error exception.

Database: PostgreSQL.
Dibi: Dibi 1.3-dev (revision 550be3b released on 2010–04–06).

TINYINT is detected as CHAR in MySQLi

DibiMySqliDriver::getColumnsMeta() detects TINYINT column as CHAR, because constants MYSQLI_TYPE_TINY and MYSQLI_TYPE_CHAR have same value.

(CHAR column is detected as MYSQLI_TYPE_STRING)

SQL injection přes limit v DibiFluent

Pokud do limitu v limitu v DibiFluent vložím SQL kód, tak se v klidu vykoná. Ono je to vlastně správně, protože v limit nemusí být jen číslo, ale může tam být výraz. Přesto ale v 99% případů tam bude jen číslo.

  $sql->limit(" 1; drop table inovice"); // projde a vykoná se

Správné použití by tedy nejspíš bylo

  $sql->limit("%i", " 1; drop table inovice");

Jenže to je dost psaní, když u všech limitů používám jen čísla. Ideální chování by tedy bylo, kdyby se limit validoval vždy jako int a jen přes modifikátor %sql by to šlo donutit k něčemu jinému. Samozřejmě je to ale BC break, takže by na to nejspíš musela být nějaká volba "strictLimits"

To samé pak platí pro offset. U jiných konstrukcí to problém není a pouze u limit/offset podvědomě očekávám automatickou validaci.

U sebe jsem to dočasně vyřešil následujícím kódem v DibiFulent->__call, ale určitě to není ideální řešení

if(($clause == "LIMIT" || $clause == "OFFSET") && is_array($args) && count($args) == 1 && $args[1] !== false) {
    $args = array((int)trim($args[0]));
}

EDIT: Konkrétně ten DROP TABLE v MySQL stejně neprojde, ale tohle už třeba ano:

  $sql->limit(" 1; union(select group_concat(user) from(mysql.user))"); 

detectTypes pro typ decimal vrací string

Pokud je sloupec typu decimal (8,3) a z databáze se čte celé číslo, mysql vrátí třeba "123.000". V dibi se detekuje jako decimal, takže se použije float. Na řádku 516 v DibiResult (metoda normalize) se ale provádí ještě jedna kontrola:

$row[$key] = (string) ($tmp = (float) $value) === $value ? $tmp : $value;

Pokud se pak vypisuje a ve sloupci decimal mám v jednom řádku hodnotu "123.001" a v druhém "123.000", tak první se převede správně na float, ale druhý se vrátí jako string.

Testováno na MySQL se stable dibi 2.0.1

Dibi Fluent a JOIN SELECT

Vypadá to na malý bug v Dibi fluent:

Pokud provedu

dibi::select('*')->from('jablka');

dostávám krásný výpis tabulky jablka.

Pokdu ale takovýto výpis chci joinnout:

echo dibi::select('*')->from('krabice_na_jablka', 'k')->join(
   dibi::select('*')->from('jablka'), 'j')->on('k.jablka_id = j.id');

Asi se to nějak zacyklí, protože to končí fatal errorem s vyčerpáním paměti.

Řešení problému je např. následující:

echo dibi::select('*')->from('krabice_na_jablka', 'k')->join(
   '('.dibi::select('*')->from('jablka').')', 'j')->on('k.jablka_id = j.id');

Tedy manuální dopsání závorek k joinovanému selectu - s ním vše funguje v pořádku.

inserting blank row

$dibiConnection->insert("table", array());

generates sql query

insert into `table` () values (null)

which fails. It should generate

insert into `table` () values ()

I need it for inserting rows where id is automatically generated and where I don't need anything else.

dibi.minified.com

There is not any dibi.minified.php file... Can it be added please?

DibiFluent cloning

Klonování DibiFluentu vůbec nefunguje.

$fluent = $dibiConnection->select("*")->from("table");
$f = clone $fluent;
echo $f;

nevypíše nic.

$fluent = $dibiConnection->select("*")->from("table");
$f = clone $fluent;
$f->removeClause("select")->select("count(*)");
echo $f;

pro změnu vypíše:

SELECT count(*) DISTINCT count(*) FROM count(*) WHERE count(*) GROUP BY count(*) HAVING count(*) ORDER BY count(*) LIMIT count(*) OFFSET count(*).

problem with dibi::getConnection()->getDatabaseInfo()->getTables() on empty db (postgre driver)

There is a problem getting array of tables if database is empty while using postgre driver.

Problem is in postgre.php in GetTables(). If there are no rows in resultSet, pg_fetch_all() returns FALSE . And this cause problems in DibiDatabaseInfo.php in init() method on line 115. Foreach expects it to be array instead and it throws warning 'Invalid argument supplied for foreach()'.

fix:


diff --git a/libs/dibi/drivers/postgre.php b/libs/dibi/drivers/postgre.php
index 6fbb560..f07d138 100644
--- a/libs/dibi/drivers/postgre.php
+++ b/libs/dibi/drivers/postgre.php
@@ -426,7 +426,7 @@ class DibiPostgreDriver extends DibiObject implements IDibiDriver
                ");
                $res = pg_fetch_all($this->resultSet);
                $this->free();
-               return $res;
+               return ($res === false ) ? array() : $res;
        }

DateTime & NULL

Hodila by se kontrola co vrací DateTime::format() (nebo jeho potomek),

protože pokud vrátí přesně typ NULL (možná to zní divně, ale je to v určitých případech potřeba) tak to poskládá chybný dotaz.

Přecejenom sloupec typu 'timestamp' v databázi může být taky NULL

příklad: http://gist.github.com/644588

DibiConnection::connect() není public.

Při rozšiřování DibiConnection (extensionMethod) je potřeba se připojit k databazi, protože může být nastaveno lazy připojení.

Bylo by dobré kdyby DibiConnection::connect() bylo public (DibiConnection::disconnect() public je)

Momentálně to řeším velmi ošklivým $connection->sql('');

Úprava je k dispozici zde: PetrP/dibi@9494061

lazy connection nefunguje s lazy disconnection

Připojuju se v nette 0.9.7 v bootstrap pomoci

$application->onStartup[] = 'BaseModel::connect';
$application->onShutdown[] = 'BaseModel::disconnect';

database.lazy = true

a kdyz se na databazi nedotazu vubec (kešuju), tak mi vyhodí disconnect warning:
mysqli_close() expects parameter 1 to be mysqli, null given in C:..\libs\dibi\drivers\mysqli.php on line 146

používám dibi 1.3 ale v latest to taky hází tohle

takže předpokládám, že connect je lazy, ale disconect s timhle vůbec nepočítá...

Mysql & Mysqli drivers: bug in detection unsigned columns

unsigned se špatně detekuje. Blbé pořadí parametrů ve funkci strstr viz
forum

Oprava zde: PetrP/dibi@9df5ec9

Zde je test:

/*
CREATE TABLE `test4` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `int` int(10) unsigned NOT NULL,
    `int2` int(10) unsigned zerofill NOT NULL,
    `int3` int(10) NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB;
*/

$connetion = new DibiConnection(array(
    'driver' => 'mysql',
    'username' => 'root',
    'database' => 'test',
));

T::note(get_class($connetion->getDriver()));
foreach ($connetion->getDriver()->getColumns('test4') as $column)
{
    T::dump($column['unsigned'], $column['name']);
}

$connetion = new DibiConnection(array(
    'driver' => 'mysqli',
    'username' => 'root',
    'database' => 'test',
));

T::note(get_class($connetion->getDriver()));
foreach ($connetion->getDriver()->getColumns('test4') as $column)
{
    T::dump($column['unsigned'], $column['name']);
}


__halt_compiler() ?>
------EXPECT------
DibiMySqlDriver

id: bool(TRUE)

int: bool(TRUE)

int2: bool(TRUE)

int3: bool(FALSE)

DibiMySqliDriver

id: bool(TRUE)

int: bool(TRUE)

int2: bool(TRUE)

int3: bool(FALSE)

Zalamování textu SQL dotazu rozdělí datum a čas

Dibi automaticky zalamuje text SQL dotazu, zřejmě podle mezer, pokud mám porovnávání data pomocí DATE_FORMAT se zadaným datem, rozlomí mi dibi např. 2010-11-18 10:00:00 na dva řádky (stává se pouze v případě příliš dlouhého řádku předpokládám):

2010-11-18
10:00:00

což způsobuje to, že porovnání následně nefunguje. Ozkoušeno pouze na MySQL.

chybny arg

DibiProfiler::__construct() L56
miesto call_user_func('Nette\Diagnostics\Debugger', $this);
ma byt call_user_func('Nette\Diagnostics\Debugger::addPanel', $this);

(SELECT ...) UNION (SELECT ...) není označen jako SELECT -> žádný explain

Mějme dotaz s UNIONem, který chceme třídit:

(SELECT a FROM t1 WHERE a=10 AND B=1)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2)
ORDER BY a LIMIT 10;

pak tento dotaz není označen jako IDibiProfiler::SELECT (viz DibiConnection.php 334) a tím pádem není nabídnuta možnost explainu dotazu v DibiProfileru.

DibiRow nededi od DibiObject

DibiRow v najnovsej verzii 1.3 nededi od DibiObjectu a iba implementuje potrebne rozhrania cim vsak obera o funkcionalitu objekty, ktore chce programator nastavit ako setRowClass objekty.

Bolo by lepsie ak by dedil od DibiObjectu aby aj classes, ktore budu v buducnu ako potencionalne entity mohli vyuzivat silu DibiObjectu.

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.