Prava ispravka: usluge/troskovi.datum_unosa promenjen na DATETIME u šemi
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.
This commit is contained in:
@@ -26,15 +26,11 @@ func skenirajTrosak(s interface {
|
|||||||
var t model.Trosak
|
var t model.Trosak
|
||||||
var sifra sql.NullString
|
var sifra sql.NullString
|
||||||
var arhiviran int
|
var arhiviran int
|
||||||
var datumUnosa string
|
if err := s.Scan(&t.ID, &sifra, &t.Naziv, &t.Cena, &t.Opis, &arhiviran, &t.DatumUnosa); err != nil {
|
||||||
if err := s.Scan(&t.ID, &sifra, &t.Naziv, &t.Cena, &t.Opis, &arhiviran, &datumUnosa); err != nil {
|
|
||||||
return t, err
|
return t, err
|
||||||
}
|
}
|
||||||
t.Sifra = sifra.String
|
t.Sifra = sifra.String
|
||||||
t.Arhiviran = arhiviran == 1
|
t.Arhiviran = arhiviran == 1
|
||||||
if parsed, err := parseDatumUnosa(datumUnosa); err == nil {
|
|
||||||
t.DatumUnosa = parsed
|
|
||||||
}
|
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,15 +26,11 @@ func skenirajUslugu(s interface {
|
|||||||
var u model.Usluga
|
var u model.Usluga
|
||||||
var sifra sql.NullString
|
var sifra sql.NullString
|
||||||
var arhiviran int
|
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, &u.DatumUnosa); err != nil {
|
||||||
if err := s.Scan(&u.ID, &sifra, &u.Naziv, &u.Kategorija, &u.JedinicaMere, &u.Cena, &u.PdvStopa, &u.Opis, &arhiviran, &datumUnosa); err != nil {
|
|
||||||
return u, err
|
return u, err
|
||||||
}
|
}
|
||||||
u.Sifra = sifra.String
|
u.Sifra = sifra.String
|
||||||
u.Arhiviran = arhiviran == 1
|
u.Arhiviran = arhiviran == 1
|
||||||
if t, err := parseDatumUnosa(datumUnosa); err == nil {
|
|
||||||
u.DatumUnosa = t
|
|
||||||
}
|
|
||||||
return u, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,11 +55,3 @@ func nullDateString(v *time.Time) sql.NullString {
|
|||||||
}
|
}
|
||||||
return sql.NullString{String: v.Format("2006-01-02"), Valid: true}
|
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)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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);
|
||||||
Reference in New Issue
Block a user