tiny ‘n’ smart
database layer

Odkazy: dibi | API reference

Oznámení

Omlouváme se, provoz fóra byl ukončen

Odlisna forma vracia datumov z MySQL databazy

před 7 lety

fliper333
Člen | 36

Dibi 2.0.1, PHP 5.3 (win)

Ahojte, chcem sa spytat, ci sa menilo nieco ohladom datumov v dibi verzii 2.0.1 (predtym som pouzival 1.5rc).

Niektore SQL prikazy co mi predtym fungovali zrazu prestali. Napriklad prikaz, ktory mi vytiahol pocet registracii pre konkretne dni za poslednych 7 dni. Tento prikaz mi vrati ako vysledok prazdne pole (pre fetchPairs, pre fetchAll vrati pole spravne, ale datum je tam rozvetveny na datum, casovu zonu…). Da sa toto chovanie nejak vypnut? Nerad by som sa koli tejto drobnosti vracal k starsej verzii dibi a ten projekt je dost velky nato aby som po vsetkych modeloch hladal kde pracujem s datumami a prepisoval to.

Problem je v tom, ze verzia 2.0.1 mi vracia datumy ako zlozene objekty, pricom verzia 1.5rc ho vracala ako string. Je to sice uzitocna vec, ale bolo by fajn keby sa dala vypnut. Ja datumy formatujem v templatovaci (smarty) cez {$date|format_date:‚d.m.Y‘}… Pride mi to spravnejsie formatovat datum vo view (template), pretoze ak ma stranka viacero jazykovych mutacii, tak moze mat aj viacero formatov datumov (napriklad SK d.m.YYYY, US – mm/dd/YYYY, atd…)

Za kazdu radu vopred dakujem

$registrations =
    dibi::query('
        SELECT
            DATE([user_registration_time]),
            COUNT(*)
        FROM
            [social_network_user]
        WHERE
            ADDDATE(DATE([user_registration_time]), INTERVAL 7 DAY) > DATE(NOW())
        GROUP BY
            DATE([user_registration_time])
        ORDER BY
            DATE(user_registration_time) DESC;
    ')->fetchPairs();

před 7 lety

Milo
Nette Core | 1119

V dibi verzi 2 se automaticky detekují typy. Nastav typ ručně

dibi::query('SELECT DATE([user_registration_time]) AS date')->setType('date', dibi::TEXT)->fetchPairs();

před 7 lety

fliper333
Člen | 36

Milo, ano diky, toto som sa docital, lenze tych query je tam vela a trvalo by velmi dlho zakial to prejdem kde vsade sa nieco robi s datumami. A to nehovorim o testovani… + do buducna neplanujem pouzivat datovy typ date ani pri dalsich projektoch, pokial to nebude nevyhnutne, string mi plne vyhovuje. Skor hladam sposob ako to nastavit globalne (v konfiguracii alebo pri pripajani do DB).

V com vlastne spociva myslienka dibi „datumoveho typu“? Resp ako by sa to malo pouzivat v praxi? Vo vacsine pripadov ked pouzivam databazu na vyhladavanie dat pouzivam query tak, ze do neho hodim values z nette formy, nastavim limit offset a fetchAll() vysledok zase posuvam priamo dalej do template kde si to pomocou foreach vylistujem. Spravne pouzitie je potom taketo?

...
{foreach $data as $row}
    <tr>
        <td>{$row->name}</td>
        <td>{$row->date->date}</td>
    </tr>
{/foreach}
...

Pretoze ak ano, aj tak musim pouzit templatovaciu funkciu na koverziu datumu. Keby to chcem robit v modeli, musel by tom vysledok fetchAll() prehnal foreachom kde by som ten datum upravil. Alebo mi nieco unika?

Diky

před 7 lety

Milo
Nette Core | 1119

Globálně se to nedá (můžeš vytvořit issue na githubu). Můžeš si také upravit zdrojáky dibi zakomentováním této řádky.

Formátovat datum až v šabloně je nejlepší řešení. Formátuj, až když je třeba.

<td>{$row->date|date}</td>

Nebo můžeš použít nepěkný hack hned po připojení do databáze. Není to pěkné a použij na vlastní nebezpečí ;)

DibiColumnInfo::getTypeCache()->setCallback(function ($type) {
    if (preg_match('/DATE|TIME/i', $type)) {
        return dibi::TEXT;
    }

    return DibiColumnInfo::detectType($type);
});

před 7 lety

fliper333
Člen | 36

Hh, no ten hack sa mi velmi nepaci :) To uz radsej fakt upravim ten zdrojak, aj ked ani take riesenia nemam rad, ale mam pocit ze z casoveho hladiska mi ine nezostava. Rozmyslal som aj ci by sa to nedalo upravit dedenim… No neviem ci by som sa v tom este viac nezamotal :) Alebo tam nahodim 1.5rc, ved ani neviem co je vo verzii 2 nove okrem tych datovych typov.

Len ma to prekvapilo, lebo u vacsiny kniznic funguje spatna kompatibilita a nove featury sa daju zapat (alebo vypat) v configu, aby nova kniznica fungovala aj so starymi projektami :(

David: Hod nejake upozornenie na download stranku ze taketo nieco sa menilo, lebo som si isty ze viacero ludom to bude robit neporiadok v modeloch ak nahraju novu verziu dibi do stareho projektu.

Milo: Diky za typy. Uz v tom mam jasno :)

před 7 lety

fliper333
Člen | 36

Este by som sa chcel spytat na jednu ved ohladom datumov. Do databazy ukladam datumy do stlpcov typu (mysql) date, t.z. YYYY-MM-DD.

Da sa nejak jednoducho vytiahnut datum v inom formate ako MySQL, aby som nemusel pole manualne spracovavat? Vacsinou to potrebujem, ak chcem naplnit nette formular pri editacii nejakej polozky a je v nom datepicker, ktory mam nastaveny na SK format (d.m.Y).

Priklad:

function getDefaults($id)
{
    $defaults = dibi::query('SELECT * FROM [demand] WHERE [demand_id] = %i', $id)->fetch();

    if ($defaults['demand_create_date']) $defaults['demand_create_date'] = date('d.m.Y', strtotime($defaults['demand_create_date']));
    if ($defaults['demand_realization_date']) $defaults['demand_realization_date'] = date('d.m.Y', strtotime($defaults['demand_realization_date']));
    if ($defaults['demand_end_date']) $defaults['demand_end_date'] = date('d.m.Y', strtotime($defaults['demand_end_date']));

    return $defaults;
}

Cital som ze by malo fungovat taketo nieco:

$res->setType('created', dibi::FIELD_DATETIME, 'd.m.Y');

Ale mne to nejako nefunguje.

před 7 lety

Milo
Nette Core | 1119
return dibi::query('....')
    ->setFormat(dibi::DATE, 'd.m.Y')
    ->fetch();

před 7 lety

fliper333
Člen | 36

Diky moc! Funguje to perfektne.

před 7 lety

fliper333
Člen | 36

Da sa ->setFormat(dibi::DATE, ‚d.m.Y‘) pouzit aj pri dibi fluent?

před 7 lety

Milo
Nette Core | 1119
$fluent->execute()->setFormat(...)->fetchAll();

před 7 lety

fliper333
Člen | 36

To som skusal, chybu to sice nevyhodi, ale datum nesformatuje. Pre istotu pripajam celu funkciu ci chyba nie je niekde inde.

function getSearchResult($values, $limit = NULL, $offset = NULL)
{
    $query =
        dibi::select('incident.*, user.user_id')
            ->from('incident')
            ->leftJoin('user')->on('incident.incident_id_user = user.user_id');

    if ($values) $query->where($values);
    if ($offset) $query->offset($offset);
    if ($limit) $query->limit($limit);

    return $query->execute()->setFormat(dibi::DATE, 'd.m.Y')->fetchAll();

    //$query->fetchAll();
}

Vrati mi to klasicky MySQL format. (datumy su v MySQL ulozene samozrejme ako typ DATE)