ProHoster > Blogs > AdministrÄcija > Vispirms patiesÄ«ba jeb kÄpÄc sistÄma ir jÄprojektÄ, pamatojoties uz datu bÄzes struktÅ«ru
Vispirms patiesÄ«ba jeb kÄpÄc sistÄma ir jÄprojektÄ, pamatojoties uz datu bÄzes struktÅ«ru
Äau Habr!
MÄs turpinÄm izpÄtÄ«t tÄmu Java Šø pavasaristostarp datu bÄzes lÄ«menÄ«. Å odien piedÄvÄjam lasÄ«t par to, kÄpÄc, veidojot lielas lietojumprogrammas, noteicoÅ”Ä nozÄ«me ir datu bÄzes struktÅ«rai, nevis Java kodam, kÄ tas tiek darÄ«ts un kÄdi ir Ŕī noteikuma izÅÄmumi.
Å ajÄ diezgan novÄlotajÄ rakstÄ es paskaidroÅ”u, kÄpÄc, manuprÄt, gandrÄ«z visos gadÄ«jumos datu modelis lietojumprogrammÄ ir jÄveido "no datu bÄzes", nevis "no Java iespÄjÄm" (vai neatkarÄ«gi no klienta valodas strÄdÄjot ar). IzvÄloties otro pieeju, jÅ«s ieejat garÄ sÄpju un cieÅ”anu ceļÄ, tiklÄ«dz jÅ«su projekts sÄk augt.
Raksts tika uzrakstÄ«ts, pamatojoties uz viens jautÄjums, kas norÄdÄ«ts Stack Overflow.
Cik es esmu pÄrsteigts, ka ir tik mazs lietotÄju slÄnis, kas, iepazinuÅ”ies ar jOOQ, aizvainojas par to, ka jOOQ nopietni paļaujas uz pirmkoda Ä£enerÄÅ”anu. Neviens neliedz jums izmantot jOOQ tÄ, kÄ jÅ«s uzskatÄt par pareizu, un neviens neliek jums izmantot kodu Ä£enerÄÅ”anu. Bet pÄc noklusÄjuma (kÄ aprakstÄ«ts rokasgrÄmatÄ) jOOQ darbojas Å”Ädi: jÅ«s sÄkat ar (mantoto) datu bÄzes shÄmu, apgriežat to ar jOOQ koda Ä£eneratoru, lai iegÅ«tu klaÅ”u kopu, kas attÄlo jÅ«su tabulas, un pÄc tam ierakstiet tipa- droÅ”i vaicÄjumi Å”ajÄs tabulÄs:
Ir dažÄdas filozofijas, priekÅ”rocÄ«bas un trÅ«kumi, kas saistÄ«ti ar Ŕīm pieejÄm koda Ä£enerÄÅ”anai - manuÄlai un automÄtiskai -, kuras es Å”ajÄ rakstÄ sÄ«kÄk neapspriedÄ«Å”u. Bet kopumÄ visa Ä£enerÄtÄ koda bÅ«tÄ«ba ir tÄda, ka tas ļauj Java reproducÄt āpatiesÄ«buā, ko mÄs uzskatÄm par paÅ”saprotamu gan mÅ«su sistÄmÄ, gan Ärpus tÄs. SavÄ ziÅÄ kompilatori, kas Ä£enerÄ baitkodu, maŔīnkodu vai cita veida kodu no pirmkoda, dara to paÅ”u ā mÄs iegÅ«stam savas "patiesÄ«bas" attÄlojumu citÄ valodÄ, neatkarÄ«gi no konkrÄtiem iemesliem.
Ir kÄda patiesÄ«ba (iekÅ”Äja vai ÄrÄja) - piemÄram, specifikÄcija, datu modelis utt.
Mums ir nepiecieÅ”ams vietÄjs Ŕīs patiesÄ«bas attÄlojums mÅ«su programmÄÅ”anas valodÄ.
TurklÄt gandrÄ«z vienmÄr ir ieteicams Ä£enerÄt Å”Ädu attÄlojumu, lai izvairÄ«tos no dublÄÅ”anas.
Tipa nodroÅ”inÄtÄji un anotÄciju apstrÄde
PiezÄ«me: Cita, modernÄka un specifiskÄka pieeja koda Ä£enerÄÅ”anai jOOQ ietver tipu nodroÅ”inÄtÄju izmantoÅ”anu, kÄ tie ir ieviesti F#. Å ajÄ gadÄ«jumÄ kodu Ä£enerÄ kompilators, faktiski kompilÄcijas stadijÄ. PrincipÄ Å”Äds kods neeksistÄ pirmkodu veidÄ. Java ir lÄ«dzÄ«gi, lai arÄ« ne tik eleganti rÄ«ki - tie ir, piemÄram, anotÄciju procesori, Lomboka.
ZinÄmÄ nozÄ«mÄ Å”eit notiek tÄs paÅ”as lietas, kas pirmajÄ gadÄ«jumÄ, izÅemot:
JÅ«s neredzat Ä£enerÄto kodu (varbÅ«t Ŕī situÄcija kÄdam neŔķiet tik riebÄ«ga?)
Jums ir jÄnodroÅ”ina, ka var norÄdÄ«t veidus, tas ir, vienmÄr ir jÄbÅ«t pieejamam ātrueā. Tas ir viegli Lombok gadÄ«jumÄ, kas anotÄ "patiesÄ«bu". Tas ir nedaudz sarežģītÄk ar datu bÄzes modeļiem, kas ir atkarÄ«gi no tieÅ”Ä savienojuma, kas vienmÄr ir pieejams.
KÄda ir koda Ä£enerÄÅ”anas problÄma?
Papildus kutelÄ«gajam jautÄjumam, kÄ labÄk sÄkt koda Ä£enerÄÅ”anu - manuÄli vai automÄtiski, jÄpiemin, ka ir cilvÄki, kas uzskata, ka koda Ä£enerÄÅ”ana nemaz nav vajadzÄ«ga. Pamatojums Å”im viedoklim, ar kuru es saskÄros visbiežÄk, ir tas, ka tad ir grÅ«ti izveidot bÅ«vniecÄ«bas cauruļvadu. JÄ, tas tieÅ”Äm ir grÅ«ti. Ir papildu infrastruktÅ«ras izmaksas. Ja jÅ«s tikko sÄkat darbu ar kÄdu konkrÄtu produktu (vai tas bÅ«tu jOOQ, JAXB, vai hibernate utt.), ir nepiecieÅ”ams laiks, lai iestatÄ«tu darbgaldu, ko vÄlaties pavadÄ«t, apgÅ«stot paÅ”u API, lai no tÄ gÅ«tu labumu. .
Ja izmaksas, kas saistÄ«tas ar Ä£eneratora ierÄ«ces izpratni, ir pÄrÄk augstas, tad API patieÅ”Äm slikti strÄdÄja pie koda Ä£eneratora lietojamÄ«bas (un nÄkotnÄ izrÄdÄ«sies, ka arÄ« pielÄgoÅ”ana tajÄ ir sarežģīta). Jebkurai Å”Ädai API augstÄkajai prioritÄtei ir jÄbÅ«t lietojamÄ«bai. Bet tas ir tikai viens arguments pret koda Ä£enerÄÅ”anu. PretÄjÄ gadÄ«jumÄ pilnÄ«bÄ ar roku uzrakstiet vietÄjÄs vai ÄrÄjÄs patiesÄ«bas attÄlojumu.
Daudzi teiks, ka viÅiem nav laika to visu darÄ«t. ViÅiem ir beidzies superprodukta termiÅÅ”. KÄdreiz vÄlÄk Ä·emmÄsim montÄžas konveijerus, bÅ«s laiks. Es viÅiem atbildÄÅ”u:
Bet Hibernate / JPA ir tik vienkÄrÅ”i rakstÄ«t kodu "Java".
TieÅ”Äm. Hibernate un tÄ lietotÄjiem tas ir gan svÄtÄ«gs, gan lÄsts. HibernÄcijas režīmÄ varat vienkÄrÅ”i ierakstÄ«t pÄris entÄ«tijas, piemÄram:
@Entity
class Book {
@Id
int id;
String title;
}
Un gandrÄ«z viss ir gatavs. Tagad Hibernate galvenais uzdevums ir Ä£enerÄt sarežģītas ādetaļasā par to, kÄ tieÅ”i Ŕī entÄ«tija tiks definÄta jÅ«su SQL ādialektaā DDL:
CREATE TABLE book (
id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
title VARCHAR(50),
CONSTRAINT pk_book PRIMARY KEY (id)
);
CREATE INDEX i_book_title ON book (title);
... un sÄciet palaist lietojumprogrammu. Ä»oti forÅ”a funkcija, lai Ätri sÄktu darbu un izmÄÄ£inÄtu dažÄdas lietas.
TomÄr ļaujiet man. Es meloju.
Vai Hibernate patieÅ”Äm ieviesÄ«s Ŕīs nosauktÄs primÄrÄs atslÄgas definÄ«ciju?
Vai Hibernate izveidos indeksu TITLE? Es noteikti zinu, ka mums tas ir vajadzīgs.
Vai Hibernate padarÄ«s Å”o atslÄgu par identitÄtes atslÄgu identitÄtes specifikÄcijÄ?
VisticamÄk ne. Ja jÅ«s izstrÄdÄjat savu projektu no nulles, vienmÄr ir Ärti vienkÄrÅ”i izmest veco datu bÄzi un izveidot jaunu, tiklÄ«dz esat pievienojis nepiecieÅ”amÄs anotÄcijas. TÄtad grÄmatas entÄ«tijai galu galÄ bÅ«s Å”Äda forma:
@Entity
@Table(name = "book", indexes = {
@Index(name = "i_book_title", columnList = "title")
})
class Book {
@Id
@GeneratedValue(strategy = IDENTITY)
int id;
String title;
}
ForÅ”i. Atjaunot. ArÄ« Å”ajÄ gadÄ«jumÄ sÄkumÄ tas bÅ«s ļoti viegli.
Bet vÄlÄk par to bÅ«s jÄmaksÄ.
AgrÄk vai vÄlÄk jums bÅ«s jÄiet uz ražoÅ”anu. TieÅ”i tad modelis pÄrstÄj darboties. Jo:
RažoÅ”anÄ vairs nebÅ«s iespÄjams nepiecieÅ”amÄ«bas gadÄ«jumÄ izmest veco datubÄzi un sÄkt visu no nulles. JÅ«su datu bÄze kļūs par mantotu.
No Ŕī brīža un uz visiem laikiem jums bÅ«s jÄraksta DDL migrÄcijas skripti, piemÄram, izmantojot Flyway. Un kas Å”ajÄ gadÄ«jumÄ notiks ar jÅ«su vienÄ«bÄm? Varat tos pielÄgot manuÄli (un dubultot darba slodzi), vai arÄ« Hibernate tos atjaunot (cik iespÄjams, ka Å”Ädi Ä£enerÄtais atbilst jÅ«su vÄlmÄm?) JÅ«s zaudÄjat jebkurÄ gadÄ«jumÄ.
TÄdÄjÄdi, tiklÄ«dz pÄriesit uz ražoÅ”anu, jums bÅ«s nepiecieÅ”ami karstie ielÄpi. Un tie ir ļoti Ätri jÄnogÄdÄ ražoÅ”anÄ. TÄ kÄ jÅ«s neesat sagatavojis un organizÄjis vienmÄrÄ«gu migrÄÅ”anu ražoÅ”anai, jÅ«s neprÄtÄ«gi veicat ielÄpu. Un tad jums nav laika darÄ«t visu pareizi. Un jÅ«s rÄjat Hibernate, jo tajÄ vienmÄr ir vainÄ«gs kÄds, bet ne jÅ«s ...
TÄ vietÄ jau no paÅ”a sÄkuma visu varÄja darÄ«t pavisam savÄdÄk. PiemÄram, uzvelciet velosipÄdam apaļus riteÅus.
Vispirms datu bÄze
ÄŖstÄ "patiesÄ«ba" jÅ«su datu bÄzes shÄmÄ un "suverenitÄte" pÄr to slÄpjas datu bÄzÄ. ShÄma ir definÄta tikai paÅ”Ä datu bÄzÄ un nekur citur, un katram klientam ir Ŕīs shÄmas kopija, tÄpÄc ir pilnÄ«gi saprÄtÄ«gi nodroÅ”inÄt shÄmas ievÄroÅ”anu un tÄs integritÄti, lai to izdarÄ«tu tieÅ”i datu bÄzÄ - kur informÄcija tiek glabÄta.
TÄ ir veca, pat sagrauta gudrÄ«ba. PrimÄrÄs un unikÄlÄs atslÄgas ir labas. Ar sveÅ”Äm atslÄgÄm viss kÄrtÄ«bÄ. Ierobežojumu pÄrbaude ir laba. Apgalvojumi - Labi.
Un tas vÄl nav viss. PiemÄram, izmantojot Oracle, iespÄjams, vÄlÄsities norÄdÄ«t:
KÄdÄ galda vietÄ atrodas jÅ«su galds
KÄda ir viÅas PCTFREE vÄrtÄ«ba
KÄds ir keÅ”atmiÅas lielums jÅ«su secÄ«bÄ (aiz id)
MazÄs sistÄmÄs tam visam var nebÅ«t nozÄ«mes, taÄu nav jÄgaida lÄ«dz pÄrejai uz "lielo datu" sfÄru ā jÅ«s varat sÄkt gÅ«t labumu no pÄrdevÄja nodroÅ”inÄtajÄm krÄtuves optimizÄcijÄm, piemÄram, iepriekÅ”minÄtajÄm, daudz agrÄk. Neviens no ORM, ko esmu redzÄjis (tostarp jOOQ), nenodroÅ”ina piekļuvi visam DDL opciju komplektam, ko jÅ«s varÄtu vÄlÄties izmantot savÄ datu bÄzÄ. ORM piedÄvÄ dažus rÄ«kus, kas palÄ«dz rakstÄ«t DDL.
Bet dienas beigÄs labi izstrÄdÄta shÄma tiek ar roku rakstÄ«ta DDL. JebkurÅ” Ä£enerÄtais DDL ir tikai tÄ aptuvens rÄdÄ«tÄjs.
KÄ ar klienta modeli?
KÄ minÄts iepriekÅ”, klientam bÅ«s nepiecieÅ”ama datu bÄzes shÄmas kopija, klienta skats. Lieki piebilst, ka Å”im klienta skatam ir jÄbÅ«t sinhronizÄtam ar reÄlo modeli. KÄds ir labÄkais veids, kÄ to panÄkt? Ar kodu Ä£eneratoru.
Visas datu bÄzes sniedz savu metainformÄciju, izmantojot SQL. TÄlÄk ir norÄdÄ«ts, kÄ no savas datu bÄzes iegÅ«t visas tabulas dažÄdos SQL dialektos.
-- H2, HSQLDB, MySQL, PostgreSQL, SQL Server
SELECT table_schema, table_name
FROM information_schema.tables
-- DB2
SELECT tabschema, tabname
FROM syscat.tables
-- Oracle
SELECT owner, table_name
FROM all_tables
-- SQLite
SELECT name
FROM sqlite_master
-- Teradata
SELECT databasename, tablename
FROM dbc.tables
Å ie vaicÄjumi (vai lÄ«dzÄ«gi, atkarÄ«bÄ no tÄ, vai jÄÅem vÄrÄ arÄ« skati, materializÄtie skati, tabulas vÄrtÄ«bas) tiek izpildÄ«ti arÄ« izsaucot DatabaseMetaData.getTables() no JDBC vai izmantojot jOOQ meta moduli.
No Å”Ädu vaicÄjumu rezultÄtiem ir samÄrÄ viegli Ä£enerÄt jebkuru jÅ«su datu bÄzes modeļa klienta puses attÄlojumu neatkarÄ«gi no klienta izmantotÄs tehnoloÄ£ijas.
Ja izmantojat JDBC vai Spring, varat izveidot virknes konstantu kopu
Ja izmantojat JPA, varat Ä£enerÄt paÅ”as entÄ«tijas
Ja izmantojat jOOQ, varat Ä£enerÄt jOOQ meta modeli
AtkarÄ«bÄ no tÄ, cik daudz iespÄju piedÄvÄ jÅ«su klienta API (piemÄram, jOOQ vai JPA), Ä£enerÄtais meta modelis var bÅ«t patieÅ”Äm bagÄts un pilnÄ«gs. Å emiet, piemÄram, netieÅ”as pievienoÅ”anÄs iespÄju, ieviests jOOQ 3.11, kas balstÄs uz Ä£enerÄtu metainformÄciju par ÄrÄjo atslÄgu attiecÄ«bÄm starp jÅ«su tabulÄm.
Tagad jebkurÅ” datu bÄzes pieaugums automÄtiski atjauninÄs klienta kodu. IedomÄjieties, piemÄram:
ALTER TABLE book RENAME COLUMN title TO book_title;
Vai tieÅ”Äm vÄlaties Å”o darbu darÄ«t divas reizes? NekÄdÄ gadÄ«jumÄ. MÄs vienkÄrÅ”i veicam DDL, palaižam to caur jÅ«su bÅ«vÄÅ”anas cauruļvadu un iegÅ«stam atjauninÄto entÄ«tiju:
Vai arÄ« atjauninÄtÄ jOOQ klase. LielÄkÄ daļa DDL izmaiÅu ietekmÄ arÄ« semantiku, ne tikai sintaksi. TÄpÄc var bÅ«t Ärti apkopotajÄ kodÄ redzÄt, kÄdu kodu ietekmÄs (vai varÄtu) ietekmÄt datu bÄzes palielinÄÅ”ana.
VienÄ«gÄ patiesÄ«ba
NeatkarÄ«gi no tÄ, kuru tehnoloÄ£iju izmantojat, vienmÄr ir viens modelis, kas ir vienÄ«gais patiesÄ«bas avots kÄdai apakÅ”sistÄmai ā vai vismaz mums vajadzÄtu uz to censties un izvairÄ«ties no uzÅÄmuma neskaidrÄ«bÄm, kur "patiesÄ«ba" ir visur un nekur uzreiz. Viss var bÅ«t daudz vieglÄk. Ja jÅ«s vienkÄrÅ”i apmainÄties ar XML failiem ar kÄdu citu sistÄmu, vienkÄrÅ”i izmantojiet XSD. Apskatiet jOOQ INFORMATION_SCHEMA metamodeli XML formÄtÄ: https://www.jooq.org/xsd/jooq-meta-3.10.0.xsd
XSD ir labi saprotams
XSD ļoti labi iezÄ«mÄ XML saturu un ļauj pÄrbaudÄ«t visÄs klientu valodÄs
XSD ir labi izstrÄdÄta versija un ļoti saderÄ«ga ar atpakaļejoÅ”u datumu
XSD var pÄrtulkot Java kodÄ, izmantojot XJC
PÄdÄjais punkts ir svarÄ«gs. Sazinoties ar ÄrÄju sistÄmu, izmantojot XML ziÅojumus, mÄs vÄlamies bÅ«t pÄrliecinÄti, ka mÅ«su ziÅojumi ir derÄ«gi. To ir ļoti viegli panÄkt ar JAXB, XJC un XSD. BÅ«tu ÄrprÄts domÄt, ka Java-first dizaina pieejÄ, kurÄ mÄs veidojam savus ziÅojumus kÄ Java objektus, tos kaut kÄdÄ veidÄ varÄtu atveidot saprotami XML formÄtÄ un nosÅ«tÄ«t patÄriÅam uz citu sistÄmu. Å ÄdÄ veidÄ Ä£enerÄtais XML bÅ«tu ļoti sliktas kvalitÄtes, nedokumentÄts un grÅ«ti izstrÄdÄjams. Ja bÅ«tu vienoÅ”anÄs par servisa kvalitÄtes lÄ«meni (SLA) par Å”Ädu interfeisu, mÄs to uzreiz saskrÅ«vÄtu.
GodÄ«gi sakot, tas ir tieÅ”i tas, kas visu laiku notiek ar JSON API, bet tas ir cits stÄsts, es strÄ«dÄÅ”os nÄkamreiz...
Datu bÄzes: tÄs ir vienÄdas
StrÄdÄjot ar datu bÄzÄm, jÅ«s saprotat, ka tÄs visas bÅ«tÄ«bÄ ir vienÄdas. Datu bÄzei pieder tÄs dati, un tai ir jÄpÄrvalda shÄma. Visas shÄmÄ veiktÄs modifikÄcijas ir jÄievieÅ” tieÅ”i DDL, lai tiktu atjauninÄts vienÄ«gais patiesÄ«bas avots.
Kad avota atjauninÄjums ir noticis, visiem klientiem ir jÄatjaunina arÄ« savas modeļa kopijas. Daži klienti var bÅ«t rakstÄ«ti Java, izmantojot jOOQ un Hibernate vai JDBC (vai abus). Citi klienti var bÅ«t rakstÄ«ti Perl valodÄ (vÄlÄsim viÅiem veiksmi), citi C#. Tas nav svarÄ«gi. Galvenais modelis ir datu bÄzÄ. ORM Ä£enerÄtie modeļi parasti ir sliktas kvalitÄtes, slikti dokumentÄti un grÅ«ti izstrÄdÄjami.
TÄpÄc nepieļaujiet kļūdas. Nepieļaujiet kļūdas no paÅ”a sÄkuma. Darbs no datu bÄzes. Izveidojiet izvietoÅ”anas cauruļvadu, ko var automatizÄt. IespÄjojiet kodu Ä£eneratorus, lai Ärti kopÄtu datu bÄzes modeli un izmestu to klientiem. Un beidziet uztraukties par kodu Ä£eneratoriem. ViÅi ir labi. Ar tiem jÅ«s kļūsit produktÄ«vÄks. Viss, kas jums jÄdara, ir jÄpavada nedaudz laika to iestatÄ«Å”anai jau no paÅ”a sÄkuma, un jÅ«s iegÅ«sit gadiem ilgi uzlabotu veiktspÄju, lai izveidotu sava projekta stÄstu.
VÄlÄk nesaki man paldies.
NoskaidroŔana
SkaidrÄ«bas labad: Å”is raksts nekÄdÄ veidÄ neatbalsta, ka visa sistÄma (t.i., domÄns, biznesa loÄ£ika utt. utt.) ir jÄpielÄgo, lai tÄ atbilstu jÅ«su datu bÄzes modelim. Å ajÄ rakstÄ es runÄju par to, ka klienta kodam, kas mijiedarbojas ar datu bÄzi, jÄdarbojas, pamatojoties uz datu bÄzes modeli, lai tas neatveidotu datu bÄzes modeli "pirmÄs klases" statusÄ. Å Äda loÄ£ika parasti atrodas jÅ«su klienta datu piekļuves slÄnÄ«.
DivlÄ«meÅu arhitektÅ«rÄs, kas vietÄm joprojÄm ir saglabÄjuÅ”Äs, Å”Äds sistÄmas modelis var bÅ«t vienÄ«gais iespÄjamais. TomÄr lielÄkajÄ daÄ¼Ä sistÄmu man Ŕķiet, ka datu piekļuves slÄnis ir "apakÅ”sistÄma", kas iekapsulÄ datu bÄzes modeli.
IzÅÄmumi
Katram noteikumam ir izÅÄmumi, un es jau iepriekÅ” teicu, ka datu bÄzes pirmÄ un avota koda Ä£enerÄÅ”anas pieeja dažreiz var bÅ«t nepiemÄrota. Å eit ir daži Å”Ädi izÅÄmumi (iespÄjams, ir arÄ« citi):
Ja shÄma nav zinÄma un ir jÄatver. PiemÄram, jÅ«s sniedzat rÄ«ku, kas palÄ«dz lietotÄjiem orientÄties jebkurÄ diagrammÄ. FÅ«. Å eit nav koda Ä£enerÄÅ”anas. Bet tomÄr - datubÄze pirmÄm kÄrtÄm.
Kad Ä·Äde ir jÄÄ£enerÄ lidojumÄ, lai atrisinÄtu kÄdu problÄmu. Å Ä·iet, ka Å”is piemÄrs ir nedaudz raiba modeļa versija entÄ«tijas atribÅ«ta vÄrtÄ«ba, t.i., jums nav Ä«sti definÄtas shÄmas. Å ajÄ gadÄ«jumÄ jÅ«s bieži pat nevarat bÅ«t pÄrliecinÄts, ka RDBMS jums bÅ«s piemÄrots.
IzÅÄmumi pÄc bÅ«tÄ«bas ir ÄrkÄrtÄji. VairumÄ gadÄ«jumu, kas saistÄ«ti ar RDBMS izmantoÅ”anu, shÄma ir iepriekÅ” zinÄma, tÄ atrodas RDBMS un ir vienÄ«gais "patiesÄ«bas" avots, un visiem klientiem ir jÄiegÄdÄjas no tÄs iegÅ«tÄs kopijas. IdeÄlÄ gadÄ«jumÄ tam vajadzÄtu bÅ«t koda Ä£eneratoram.