From e99dd5027347ee3072c109c54db58580cec243ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Markovi=C4=87?= Date: Sat, 4 Jul 2026 00:09:32 +0200 Subject: [PATCH] =?UTF-8?q?Prava=20ispravka:=20usluge/troskovi.datum=5Funo?= =?UTF-8?q?sa=20promenjen=20na=20DATETIME=20u=20=C5=A1emi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Umesto ručnog parsiranja (prethodni commit), migracija 103 rekreira obe tabele sa DATETIME kolonom (kao svuda drugde u šemi) — SQLite ne podržava ALTER COLUMN, pa je urađeno kreiraj-novu/prebaci-podatke/obriši-staru/ preimenuj. Fizički format podataka se ne menja (SQLite nema pravi numerički afinitet za DATETIME nad ovakvim stringom), menja se samo deklarisani tip kolone koji driver čita da odluči string vs time.Time pri Scan-u. Uklonjen parseDatumUnosa workaround iz utils.go — skenirajUslugu/skenirajTrosak sada rade identično kao svi ostali skenirajX helperi (direktan Scan u time.Time). Potvrđeno: migracija testirana na praznoj i na postojećoj bazi sa podacima (6 usluga, ID-jevi i datumi netaknuti), /usluge i /troskovi vraćaju 200. --- internal/db/sqlite/trosak.go | 6 +-- internal/db/sqlite/usluga.go | 6 +-- internal/db/sqlite/utils.go | 8 ---- ...3_usluge_troskovi_datum_unosa_datetime.sql | 39 +++++++++++++++++++ 4 files changed, 41 insertions(+), 18 deletions(-) create mode 100644 migrations/103_usluge_troskovi_datum_unosa_datetime.sql diff --git a/internal/db/sqlite/trosak.go b/internal/db/sqlite/trosak.go index 93cb340..cbed94f 100644 --- a/internal/db/sqlite/trosak.go +++ b/internal/db/sqlite/trosak.go @@ -26,15 +26,11 @@ func skenirajTrosak(s interface { var t model.Trosak var sifra sql.NullString var arhiviran int - var datumUnosa string - if err := s.Scan(&t.ID, &sifra, &t.Naziv, &t.Cena, &t.Opis, &arhiviran, &datumUnosa); err != nil { + if err := s.Scan(&t.ID, &sifra, &t.Naziv, &t.Cena, &t.Opis, &arhiviran, &t.DatumUnosa); err != nil { return t, err } t.Sifra = sifra.String t.Arhiviran = arhiviran == 1 - if parsed, err := parseDatumUnosa(datumUnosa); err == nil { - t.DatumUnosa = parsed - } return t, nil } diff --git a/internal/db/sqlite/usluga.go b/internal/db/sqlite/usluga.go index e421431..8db77c6 100644 --- a/internal/db/sqlite/usluga.go +++ b/internal/db/sqlite/usluga.go @@ -26,15 +26,11 @@ func skenirajUslugu(s interface { var u model.Usluga var sifra sql.NullString var arhiviran int - var datumUnosa string - if err := s.Scan(&u.ID, &sifra, &u.Naziv, &u.Kategorija, &u.JedinicaMere, &u.Cena, &u.PdvStopa, &u.Opis, &arhiviran, &datumUnosa); err != nil { + if err := s.Scan(&u.ID, &sifra, &u.Naziv, &u.Kategorija, &u.JedinicaMere, &u.Cena, &u.PdvStopa, &u.Opis, &arhiviran, &u.DatumUnosa); err != nil { return u, err } u.Sifra = sifra.String u.Arhiviran = arhiviran == 1 - if t, err := parseDatumUnosa(datumUnosa); err == nil { - u.DatumUnosa = t - } return u, nil } diff --git a/internal/db/sqlite/utils.go b/internal/db/sqlite/utils.go index 77ec141..4f058ab 100644 --- a/internal/db/sqlite/utils.go +++ b/internal/db/sqlite/utils.go @@ -55,11 +55,3 @@ func nullDateString(v *time.Time) sql.NullString { } return sql.NullString{String: v.Format("2006-01-02"), Valid: true} } - -// parseDatumUnosa parsira "YYYY-MM-DD HH:MM:SS" iz kolone deklarisane kao TEXT -// (npr. usluge/troskovi.datum_unosa, `DEFAULT (datetime('now'))`). Driver -// vraća string umesto time.Time za TEXT kolone (za razliku od DATETIME kolona -// koje driver sam parsira), pa Scan ne može direktno u *time.Time. -func parseDatumUnosa(s string) (time.Time, error) { - return time.ParseInLocation("2006-01-02 15:04:05", s, time.UTC) -} diff --git a/migrations/103_usluge_troskovi_datum_unosa_datetime.sql b/migrations/103_usluge_troskovi_datum_unosa_datetime.sql new file mode 100644 index 0000000..d478e9f --- /dev/null +++ b/migrations/103_usluge_troskovi_datum_unosa_datetime.sql @@ -0,0 +1,39 @@ +-- usluge.datum_unosa i troskovi.datum_unosa su bile deklarisane kao TEXT, za +-- razliku od svih ostalih tabela (DATETIME) — modernc.org/sqlite driver zato +-- vraća goli string umesto time.Time pri Scan-u. Fizički format podataka se ne +-- menja (SQLite nema stvarni numerički afinitet za DATETIME nad ovakvim +-- stringom), samo deklarisani tip kolone — pa je rekreacija tabele bezbedna +-- bez transformacije vrednosti. + +CREATE TABLE usluge_novo ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + sifra TEXT, + naziv TEXT NOT NULL, + kategorija TEXT NOT NULL DEFAULT '', + jedinica_mere TEXT NOT NULL DEFAULT 'usluga', + cena REAL NOT NULL DEFAULT 0, + pdv_stopa REAL NOT NULL DEFAULT 20, + opis TEXT NOT NULL DEFAULT '', + arhiviran INTEGER NOT NULL DEFAULT 0, + datum_unosa DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); +INSERT INTO usluge_novo (id, sifra, naziv, kategorija, jedinica_mere, cena, pdv_stopa, opis, arhiviran, datum_unosa) + SELECT id, sifra, naziv, kategorija, jedinica_mere, cena, pdv_stopa, opis, arhiviran, datum_unosa FROM usluge; +DROP TABLE usluge; +ALTER TABLE usluge_novo RENAME TO usluge; +CREATE INDEX IF NOT EXISTS idx_usluge_arhiviran ON usluge(arhiviran); + +CREATE TABLE troskovi_novo ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + sifra TEXT, + naziv TEXT NOT NULL, + cena REAL NOT NULL DEFAULT 0, + opis TEXT NOT NULL DEFAULT '', + arhiviran INTEGER NOT NULL DEFAULT 0, + datum_unosa DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); +INSERT INTO troskovi_novo (id, sifra, naziv, cena, opis, arhiviran, datum_unosa) + SELECT id, sifra, naziv, cena, opis, arhiviran, datum_unosa FROM troskovi; +DROP TABLE troskovi; +ALTER TABLE troskovi_novo RENAME TO troskovi; +CREATE INDEX IF NOT EXISTS idx_troskovi_arhiviran ON troskovi(arhiviran);