Database velden met prefix van tabelnaam

Naar aanleiding van een vroeger artikel over hergebruik van code, kwam ik op de kwestie van de standaardisering van de veldnamen in een databank. Algemeen zie ik twee systemen gebruikt worden:

1. Met prefix:

Meestal een korte prefix die de naam van de tabel aangeeft, zodat je altijd kan zien waar de veldnaam op slaat:

# Name Type Null Default Extra
1 emp_id bigint(20) No None AUTO_INCREMENT
2 emp_name int(11) No 0
3 emp_data2 int(11) No 0
8 emp_creat timestamp Yes CURRENT_TIMESTAMP
9 emp_creby char(24) Yes NULL
10 emp_updat datetime Yes NULL
11 emp_updby char(24) Yes NULL

Inderdaad de employee tabel, “emp” of beter “employee”.

2. Zonder prefix

Zonder tabelnaam (afkorting) in veldnamen:

# Name Type Null Default Extra
1 id bigint(20) No None AUTO_INCREMENT
2 name int(11) No 0
3 data2 int(11) No 0
8 creat timestamp Yes CURRENT_TIMESTAMP
9 creby char(24) Yes NULL
10 updat datetime Yes NULL
11 updby char(24) Yes NULL

In dit geval moet je de (afkorting voor) de veldnaam niet meegeven. Als de database vermeld wordt is het toch duidelijk:

emp.id
employee.name
employee.fieldname1
employee.creat
employee.creby
employee.updat
employee.updby

eventueel met korte alias

emp.id
emp.name
emp.fieldname1
emp.creat
emp.creby
emp.updat
emp.updby

Veel code blijft korter, maar een luie blik op de resultaten van een query kan iets meer aandacht gaan vragen (om de oorspronkelijke tabelnaam te zoeken), en misschien worden je aliassen langer e.veld wordt emp.veld voor table employee.

Vgl:

e.emp_id, e.emp_name
emp.id, emp.name

De prefix blijkt vooral een overblijfsel te zijn van vroeger, toen alle veldnamen uniek moesten zijn (ook buiten de tabel).

De algemene raadgeving is: geen prefix gebruiken:

  • korter
  • eenduidiger
  • goede tabelnamen en aliassen te gebruiken
  • betere standaardisatie

Pro prefix:

  • oude systemen waar het moet
  • geen probleem met gereserveerde woorden (commanodo’s in de query taal)*
  • gemakkelijk bij export want tabelnaam staat in veld.
  • soms beter leesbaar omdat velden altijd dezelfde vorm hebben.

* stel dat je een veld hebt waarin je aangeeft dat er een update gebeurd is of moet gebeuren:
employee.update
Helaas, UPDATE is een gereserveerd woord in de SQL taal (SELECT update FROM …), en zo zijn er nog woorden die door de syntax highlighting kunnen aangewezen worden als “gereserveerd”. Door prefixen te gebruiken moet je daar nooit op letten. Maar je kan ook ‘quotes’ gebruiken rond het gereserveerd woord als veldnaam.

Zie ook discussie op StockOverflow: (1) en (2)

Klasse met een “embedded array”

Bij het maken van de klasse, met verschillende types van eigenschappen, kan je op een punt komen dat je een array wil gebruiken, waarbij je niet op voorhand weet hoe lang die gaat worden. En je wil dat die bereikbaaar is van buitenaf, m.a.w. de array is public. (bv Objecten die een array bevatten)

Het object dat van de klasse afgeleid is, krijgt “data” te slikken die het in die array voert.

De nodige geheugenruimte voor een object ligt vast door het type van de eigenschappen van het object. Maar met deze array, waaraan steeds elementen kunnen toegevoegd worden dezearray.Add(iets), kan onvoorspelbaar groot worden, wat in tegenstelling is met de afgelijnde grootte van het object.


Ik vermoed dat dit het probleem is dat men aankaart met de vermelding van “embedded arrays”.
Je kan extern een array aanmaken, die je aan het object toespeelt. Het ruimtebeslag gebeurt dan buiten het object.
In een beschrijving van OOP voor Java zag ik dat een array altijd een object is. Dan is de plaats die het in beslag neemt die van de verwijzing naar een object, en is er toch geen probleem?

In een andere (Duitstalige) beschrijving blijkt dat de “embedded array” altijd op voorhand gedefinieerd is, bv

PUBLIC embeddedArray[2, 2] As Integer

De dimensies liggen vast. Hij wordt niet geïnitialiseerd. Het gebruik ervan is uitzonderlijk.

De andere arrays zouden dan “objecten” zijn, en toch gewoon gebruikt kunnen worden.

Gambas 3 voorbeelden niet meer meegeleverd

Sedert een tijd zijn de Gambas voorbeeldprojecten niet meer meegeleverd met de Gambas 3 IDE. In de plaats daarvan is een downloadsysteem voorzien. Een lijst geeft weer welke voorbeeldprojecten beschikbaar zijn. Met een eenvoudige klik kan je ze afhalen. Dit zorgt ervoor dat de updates van de voorbeelden onafhankelijk kunnen gebeuren van de Gambas3 updates, en dat de Gambas3 installatie kleiner wordt (door de vb weg te laten).

Nadeel is wel dat als je ergens off-line zit te werken, je niet aan voorbeelden kan (behalve deze die je al gedownload had).

Bovendien zijn er nog niet zo veel voorbeelden voorradig online; misschien komt het voorbeeld dat je nodig hebt nooit online.

Door upgrades vanuit vorige systemen kan het zijn dat je de voorbeelden nog hebt, of als je alvorens te upgraden zeker wil zijn dat je de voorbeelden nog hebt:

/usr/share/gambas3/examples

Je kan ze gewoon naar je eigen map kopiëren.

Gambas 3 v 3.8.90.svn.7791

Om één of andere reden startte de gambas 3 IDE niet meer en na wat pogingen om een recentere versie af te halen en een de-installatie + installatie ging het nog steeds niet

Enkele van de foutmeldingen die ik zag:
~> gambas3
ERROR: #2: Cannot load class ‘Action!’: Unable to load class file
~> gambas3
gbx3: unable to find startup file
~> gambas3
bash: /usr/bin/gambas3: No such file or directory

Daarna gekeken in de repositories (via software.opensuse.org):

Education

3.8.4
32 Bit
64 Bit
Source

home:munix9

3.8.4
32 Bit
64 Bit
Source

home:munix9:unstable

3.8.90.svn.7791
32 Bit
64 Bit
Source

En dus de laatste versie gekozen, die heel wat Qt5 spullen afhaalt.

Nu draait 3.8.90!

Gambas3 voorbeelden, WaveGenerator 3.6.3

Op openSUSE 13.1 kan het WaveGenerator voorbeeld een foutmelding geven:

Unable to create media control

en dit op de lijn met “autoaudisink”:

$hOutput = New MediaControl($hPlayer, "autoaudiosink")

Dat heeft te maken met het openen van een audio-uitvoer. Er zijn nogal wat verschillende audiosystemen, in verschillende lagen, en meestal lukt het met die autoaudiosink; hier dus niet.

Ik heb* “autoaudiosink” vervangen door “alsasink”, en daarna loopt het voorbeeld normaal.

$hOutput = New MediaControl($hPlayer, "alsasink")

(*) Op basis van een bericht op de mailinglist waar alsasink wordt vervangen door autoaudiosink.
Ik vond enkele meldingen van het probleem, met verwijzingen naar het audiosysteem, maar nergens een lijst met mogelijke waarden om uit te proberen om het snel te doen werken voor mezelf.

Objecten die een array bevatten

Array in een Klasse

Een objectklasse kan gegevens en methoden bevatten, maar ook bv een array. Die array kan bestaan uit getallen of tekst, maar kan ook weer uit objecten bestaan.

Ik maak een object met twee arrays;

  • 1 met string elementen
  • 1 met ‘object2’ elementen.

Object2 bevat enkel twee eigenschappen ter demonstratie: een tekstveld en een getal.

Een testprogramma maakt eerst de objecten en vult de arrays.

Daarna kan elk van de arrays weergegeven worden in een tabel.

(upd) Code testprogramma zie verder, maar eerst een opmerkig:

embedded arrays
Er wordt op online Gambas documentatie gewezen op het probleem van “embedded arrays” (lees meer).

Het testprogramma ziet er zo uit; het aantal elementen wordt bepaald door het getal, de tekst die opgeslagen wordt door het tekst-invulveld:

ArraysInObjectsFMainEdit

Als het draait:

ArraysInObjectsFMainRun

Hieronder de broncode … Continue reading

Klik en slepen beheren met een object? (Drag’n drop object)

In een bepaalde toepassing wilde ik meer controle krijgen over de klik en sleep akties in een form, omdat er verschillende mogelijke bronnen en bestemmingen waren. Ik weet niet of het een goed idee is, maar ik maakte er een apart object voor; zeg maar door een Class CDragDrop.

Daarin definieerde ik de nodige constanten.
Ik hield bij waar de klik en sleep vandaan kwam, en in geval van een tabel bv ook de coordinaten dmv rij en kolom in die tabel (row, col).

Ik definieerde een aantal mogelijke ontvangers in een array.
(deze zijn redelijk specifiek voor het scherm (Form) waarin ik werk)
bv:


' Gambas class file
' CDragDrop - to manage drag n drop
'
PUBLIC CONST Employee AS String = "employee"
PUBLIC CONST DestinationOne AS String = "destination1"
PUBLIC CONST DestinationTwo AS String = "destination2"
'
PRIVATE arrReceiver AS String[] = [Employee, DestinationOne, DestinationTwo]

Klik en sleep toestanden kan je bijhouden door methodes als:
Door procedures als

  • setOrigin
  • setReceiver
  • getOrigin
  • getReceiver

(deze zijn op zich redelijk universeel, invulling verschilt).
Ook kan je de bron en bestemmeling checken in de klasse.

Ik hergebruik het object van deze klasse:

PUBLIC SUB clear()

waarin ik alles leeg maak; maar je kan ook een nieuwe instantie maken en de gebruikte bijhouden als referentie (fifo lijstje?), als je nadien moet weten wat je vorige klik-en sleep aktie was.

English summary:
I created my own class to manage drag’n drop in my app. I can keep code away from my Form, and have all drag’n drop information at hand in one place. I could even keep the last action archived by keeping the previous instance(s) (in a FIFO array?).

Tekst van runtime knop onbereikbaar (button Text property)

In bepaalde omstandigheden kwam ik op een foutmelding bij het gebruiken van de tekst die ingesteld staat bij een knop. De foutmelding:

Unknown symbol ‘Text’ in class ‘Control’

Unknown Symbol Text In Class Control

De klasse van het object waarvan ik de tekst eigenschap wil gebruiken is niet “Control”, maar wel “Button”, maar dat ziet Gambas niet. Toch niet ‘at runtime’, maar… :

Unknown Symbol Text In Class Control Debugged

Bij het stilleggen van het programma, en het selecteren van de betreffende code, toont hij de juiste tekst in de tooltip.

Daarom gebruik ik nu deze kleine omweg:

In plaats van de children van hboxItems aan te spreken met een index, en daarvan ineens de tekst op te vragen, wijs ik nu eerst het i-de item van de children toe aan een voorgedefinieerde button, en gebruik ik daarvan de tekst eigenschap:

Unknown Symbol Text In Class Control Solved

ps: Dit is een stukje code uit een complexer stuk programma, en om de fout te isoleren heb ik me hier beperkt tot het weergeven met DEBUG van de Text eigenschap; in werkelijkheid gebeurt daar iets anders mee, meer bepaald een drag’n’drop bewerking.

De buttons werden niet gemaakt in de Form designer, maar vanuit het programma, met als parent de hboxItems container. Daarom kan ik ze enkel onrechtstreeks aanspreken.

English summaray:
To use the Text attribute of a button (in this case), you have to make a button object first, then allocate the child object (with index i) to this button object. Then you are able to use the button text property.
The buttons in the hBoxItems were made under program control (at runtime), that’s why I have to call them in this inderect way, as children of the parent container.

openSUSE Leap 42.1 en Gambas2, Gambas3

Update 03/2016:
Ondertussen draait Gambas2 IDE (2.24) perfect op LEap 42.1!

* Een update van openSUSE 13.1 naar openSUSE Leap:
– Gambas2 programma’s compileren en draaien via runtime ok.
– Gambas IDE’s opstarten: werkt niet (meer), te checken.

Opgelet; Trek geen andere conclusie; dit is dus geen “verse installatie” van Leap; kan een verschil maken!
(inderdaad, na nieuwe installatie of updates was het in orde, zie boven)