Cortiveo i GEngine - prirucnik

↑ Nazad

Pročitano iz izvora (GEngine\src, GTehnobiro\src) i iz same baze, 23. septembra 2026.

Jednom rečenicom

Šema baze je napisana u Javi, ne u SQL-u. Jedna tabela = jedna Java klasa. Iz istog opisa kolona nastaju: CREATE TABLE, SELECT, tabela na ekranu, forma za unos, validacija, štampa i Excel izvoz. Najbliža poznata stvar je Oracle Forms ili MS Access — samo napisan u kući.

1. Tabela je klasa

gjava/db/sys/SysTable.java — „tabela tabela":

public class SysTable extends DbtObject
{
    public static GColumnString  TABLE = new GColumnString("Tabela", 50, GColumnHeader.CAN_BE_NULL_NO);
    public static GColumnString  NAZIV = new GColumnString("Opis", 40);
    public static GColumnInteger LEVEL = new GColumnInteger("Level", 2, EDITABLE_NO, CAN_BE_NEGATIVE_NO);
    public static GColumnString  ID    = new GColumnString("Id", 50 + 80, GFKey.PRIMARY,
                                                           CAN_BE_NULL_NO, SHOWABLE_NEVER);

    public SysTable()
    {
        super("SysTable");
        setTitle("Табела");
        getInfo().setVersion(1, 1, 15);
        addColumn(TABLE); addColumn(NAZIV); addColumn(PACKAGE); addColumn(LEVEL); addColumn(ID);
        setRDCItem(NAZIV);
    }
}

Kolona nije string u upitu nego objekat sa tipom, dužinom i pravilima (CAN_BE_NULL_NO, EDITABLE_NO, PRIMARY, SHOWABLE_NEVER).

Dokaz da baza nastaje iz koda: u MySQL-u je systable.Id tipa char(130), a u Javi stoji 50 + 80 (TABLENAMESIZE + PACKAGENAMESIZE). Baza je doslovno otisak klase.

2. Ko pravi tabelu

gjava/data/GMySqlDatabase.java:119:

String createString = "CREATE TABLE " + pDataSource.getName();
for (int i = 0; i < pDataSource.getColumnCount(); i++) {
    GColumnHeader ch = pDataSource.getColumn(i);
    if (ch.getDataType().equals(GDataType.INTEGER)) createString += " bigint(" + ch.getLength() + ")";
    if (ch.getDataType().equals(GDataType.STRING))  createString += " char("   + ch.getLength() + ")";
    if (ch.getDataType().equals(GDataType.TEXT))    createString += " text";
    if (ch.isIncrementalKey())                      createString += " serial";
}

Akcija u ekranu „(Ре)креирај табелу" radi Class.forName("paket.Tabela").newInstance() pa ovo.

⚠️ Zamka koja briše podatke. dbtCreate prvo zove dbtDelete, a to je DROP TABLE IF EXISTS (GMySqlDatabase.java:239). Na popunjenoj tabeli „(Ре)креирај" briše sve. Kolona se dodaje ručnim ALTER TABLE ... ADD COLUMN. Engine i sam tako radi kad dodaje polje (GMySqlDatabase.java:435). Migracije šeme ne postoji — postoji samo „napravi iz nule".

3. Tri sloja istine o tabeli

slojgde živiprimer
strukturaJava klasaSysTable.java
registarekran „Табела", puni se iz klasaGDbtPool.refreshSysTable
podešavanjau baziSysTableEditableColumn(L) — koje su kolone vidljive/editabilne

Zato dve instalacije mogu imati isti kod, a različite ekrane. Otuda i upit SHOW KEYS FROM systableeditablecolumn koji se vidi u tragu svakog otvaranja ekrana (GDataSource2d.java:993).

4. Kičma nasleđivanja (7 nivoa)

GDataSourceLevel00  (155 linija)  implements GInfoable
   └ Level05 → Level10
        └ Level20  (587 linija)   redovi i kolone; GRowDataSource, GColumnProvider, GExcelDataSource
             └ Level30
                  └ Level40/50    implements GMenuCallable  ← poziv bez GUI-ja
                       └ GDataSource
                            ├ GDataSource1d   jedan zapis
                            └ GDataSource2d   tabela (redovi)

GDataSourceLevel20.getColumn, GDataSource2d.getRowCount i columnExists su najčešći pozivi u celom programu — svaka ćelija prolazi kroz metapodatke. To je cena ovog dizajna (vidi Cortiveo tracer).

5. Podaci ne moraju da budu u bazi

public class Data extends MemDbtObject      // db.tehnobiro.Data
public class MemDbtObject extends DbtObject // gjava.db — razlika je samo GDataServer.Type.MEMORY

MemDbtObject je ista tabela, samo u memoriji. Zato paketna štampa (OTPsoft) čita .txt fajl u ObrazacH/ObrazacL i nad tim radi isti kod za štampu, filtriranje i prikaz kao da je baza. To je isti razlog zbog kog postoje GEngineAccess i GEngineExcel.

6. Filteri — tri nezavisna sloja

GDataSource2d.java:364-425:

dbt.setPermanentFilter(...)   // trajno ogranicenje (engine/program)
dbt.setFilter(...)            // programski filter  ← koristi ovaj iz koda
dbt.setUserFilter(...)        // ono sto korisnik ukuca u ekranu

Sva tri se AND-uju, pa programski filter ne gazi korisnikov. Upotreba:

dbt.setFilter(new GFilterItem("ClientStranaCount", GRelation.GE, 6));
dbt.addFilter(new GFilterItem("ClientStranaCount", GRelation.LE, 10));
dbt.loadData();

GRelation: EQ NE GT GE LT LE SW (počinje) EW (završava) $$ (sadrži) EQ$ (broj znakova).

Filter radi i nad memorijskim podacima — GDataDriverMemory.java:42-55 skuplja sva tri sloja i primenjuje mData.rowInFilter(i, mFilter).

7. Šta je stvarno u bazi

definition            718 redova    definitioninputh   696     definitioninputl  36153
definitionprinth      673           definitionprintl  6874     obrazacprinth       32
systable               44           syslog          22492      entitet              0  ← prazna

8. Štampa — dva paralelna puta

Engine (gjava/print/GPrintJob.java:432-505) već zna boju:

GColor lItemColorForeground = p.mColorForeground;
Color savedColor = mGraphics.getColor();
if (lItemColorForeground != null) mGraphics.setColor(lItemColorForeground);
...
mGraphics.setColor(savedColor);   // vrati staru boju

Aplikativni generator3 (DataHPrint, DataHPrintBaseUtilities) ima svoj PrintItem i radi mGraphics.setFont(textFont) — bez boje. Kolone elementa štampe (definitionprintl):

Tip, FieldName, Opis, StranaRb, RelativeY, PrnX, PrnY, PrnWidth, PrnHeight,
FontName, FontBold, FontItalic, FontSize, Umetanje, RowSpacing, Poravnanje, Ugao

Boje nema. Dodavanje boje u 4 koraka:

  1. kolona u generator3/DefinitionPrintL.java — npr. new GColumnString("Boja", 9) za #RRGGBB
  2. ALTER TABLE definitionprintl ADD COLUMN Boja char(9) ... AFTER FontSize — ne „(Ре)креирај"
  3. DataHPrintBaseUtilities.addPrintItem: dbt.getString("Boja") → poneti kroz PrintItem
  4. DataHPrint (oko linije 235): setColor pre crtanja, vratiti staru — prepisati iz GPrintJob

Obrazac već postoji u kući; ne izmišlja se ništa novo.

Izvor: 02-gengine-arhitektura.md