Datums, databanken en Gambas

Ik heb een paar keer problemen gehad met datum/tijd in Gambas, meestal gecombineerd met het opslaan in een databank, of er terug uit ophalen (*).

Bug
Op een bepaald moment werd er een bug gemeld op de mailinglist:

[Gambas Bug Tracker] Bug #1321: Converting date to string behavior change between 3.10 and 3.11

Gebruikers hadden ontdekt dat bepaalde programma’s, bepaalde broncode, niet meer werkte na een update van Gambas3 (overgang 3.10 naar 3.11 of hoger).

De bug-melding werd verworpen.

Correctie
Maar die verandering werd bevestigd; het was echter geen bug; ze was het gevolg van het verbeteren van een bug; er zat een fout in vroeger Gambas-code, en die was met deze versie-wissel gecorrigeerd, waardoor Gambas inderdaad anders reageert in sommige situaties.

Str() Val() Format() en Date() maken gebruik van de “locale”, de instellingen van de “desktop” (taal/land/tijd/etc).

CStr() gebruikt de UTC tijd.

Dus je moet kijken naar de instelling van de database en die van je desktop, bv GMT+0200.

In één programma CDate() en Date() mengen zal waarschijnlijk problemen geven.

De interne manier om een datum of tijd bij te houden is een getal, relatief tov een denkbeeldig nulpunt.

Met Format(), Date() maak je een interpretatie waarin je tijdzone meegenomen wordt om het voor jou “aanschouwelijk juist” te maken.

Bv in Groot-Brittanië is een datum/tijd opgeslagen in een record.
Als jij die opvraagt en toont met Format() dan krijg je de tijd die het in jouw tijdszone was, niet wat letterlijk opgeslagen is in de database.

Je moet dus ook opletten (voor het verschil)
– of je de database een datum laat opslaan, bv automatisch (instelling db server) met de instelling timestamp.
– of je zelf een datum naar de database stuurt als tekst: .. values('2024-01-01 01:14:18')
– of je kan in je SQL statement de opdracht voor een datum geven

Database
De database (mysql/mariadb) heeft 5 tijdsgebonden opslagvormen (kolom):

  • DATE = aleen de datum (1000-01-01-9999-12-31)
  • DATETIME = datum + tijd (1000..:..- 9999...:..)
  • TIMESTAMP datum + tijd (1970-20238!!!!)
  • YEAR : alleen een jaartal (1901-2155)
  • TIME : alleen een tijd (getal -838.. tot + 838.. ong 35 dagen)

Het 2038 probleem

Het hangt er natuurlijk een beetje vanaf wat je met die datums wil doen, en daarom moet je rekening houden met hun bereik, meestal vooral met hun hoogst mogelijke waarde, die voor sommige formaten gevaarlijk dichtbij komt.

Als je de datum enkel opslaat als leesbare informatie voor de programmeur, is 2038 van timestamp geen probleem, maar als het een veld is waar je verder conclusies uit gaat trekken gebaseerd op vergelijkingen met andere datum/tijd, berekeningen maken, sorteren enz, dan zie je de problemen al opduiken nog voor je op pensioen* bent. En timestamp is ook zuiniger met opslagruimte.
(* bv als je geboren bent na de default pc BIOS datum van 04-01-1980)

DATETIME is dus het veiligere alternatief, maar let op met de tijdszone.
Timestamp probeert de “huidige” tijdszone om te zetten naar UTC om de waarde op te slaan in de database, en terug te zetten naar de tijdszone (van de server**) bij het opvragen.
** dus niet de zone van de client als je bv vanop afstand gegevens opvraagt

Tijdzone
Vanaf Gambas 3.18 kan de tijdzone meegegeven worden:
(Old date string representation) space [ UTC | GMT ] [ + | - ] HH [ :MM ]

Om de algehele verwarring rond datums, (interne) opslag en weergave, tijdzone en formaten aan te pakken werd deze wiki pagina gemaakt, met oa:

Datums zijn geen strings
– Interne voorstelling
– Functies die werken met U.T.C. en American date format
– Functies die werken met local time
– Impliciete omvorming
– Datums zijn getallen
Null datums en datums met alleen een tijdsdeel
– Datums bewaren
– Datums bewaren in een binair bestand
– Datums bewaren in een tekstbestand
– Datums en kalenders

Voor selectie van een datum, zie ook de wiki pagina over kalenders.

Bronnen
– mailinglist en bugtracker
https://lists.gambas-basic.org/pipermail/user/2018-May/064153.html
Datetimes versus timestamps in MySQL
https://gambaswiki.org/ wiki/doc/date, wiki/doc/calendar

Posted in Uncategorized | Comments Off on Datums, databanken en Gambas

Testen in Gambas met unittesting

Testen

Ik gebruikte al verschillende manieren om mijn programma’s te testen:
– ik dump allerlei waarden naar de output met print (die blijven ook werken in uitvoerbare programma’s)
– ik dump allerlei waarden naar de output met debug (die worden er uit gehaald bij compileren als je dat kiest)
– ik neem testcode op in mijn applicatie en stuur de uitvoer naar een optioneel zichtbaar te maken “log” (bestand of tekst op scherm).
– bij libraries schreef ik de testen in de main module, omdat die toch niet geëxporteerd wordt, dus niet zichtbaar wordt voor gebruikers. Wordt snel te veel.
– ik maak een aparte module “MTest” waar ik alle tests in steek. Ik moet die dan nog wel aanroepen uit bv de Main (library) of kan ze zelfs vanuit mijn draaiende applicatie aanroepen (bv via een testmenu in “hidden developer mode”).
– ik schreef een library MijnLib en maakte een testprogramma MijnLibTest en riep de testen aan vanuit Main, en zet ze aan of af door een commentaarteken voor de lijn te wissen/zetten. Wordt ook snel onoverzichtelijkt.
Maar dat is nog geen unittesten

Formeel geÏntegreerd
Zoals altijd bij Gambas (althans mijn ervaring): als je iets nodig hebt, blijkt het ofwel al te bestaan, ofwel wordt het bijgemaakt, en kan je je eigen methodes vervangen door de geïntegreerde methodes in Gambas zelf.

Bij gebruik van de Gambas3 IDE viel me op dat er bij creatie van een nieuw bestand onder “bronnen”, behalve de opties “map”, “klasse”, en “module”, ook een optie “Test module” bestaat. Die maakt standaarde de testmodule “Test1” aan (die als bestandsnaam “Test1.test” heeft).
Waarschijnlijk is het overzichtelijker om een map te maken voor je tests (zoals ze in het voorbeeld doen); dus maak je eerst submap “Test”, en daarin de “Test1.test”. De testbestanden worden gebruikt in volgorde van hun bestandsnaam, en binnenin op volgorde van de methodenamen.
Een testmodule is in de linkse kolom herkenbaar aan een iets ander icoontje: een optionbox (aanvinkbaar hokje), en bij conventie laat je de naam voorafgaan door een T: TNaam (vgl module MNaam, form FNaam, class CNaam)

In de programmeeromgeving van Gambas3 druk je op F4 om de testen te starten.
Onderaan krijg je een vensterdeel met de resultaten van de tests. Bij het uitvoeren van de tests wordt een teller bijgehouden en onderaan krijg je een resultaat, bv als alles goed ging “PASSED”, anders “FAILED”.

Om de testen op te stellen heb je “Assert” te hulp:

Assert.Equals(uitdrukking1, uitdrukking2, commentaar)
Assert.Ok(uitdrukkingIsTrueOrNot, commentaar)
Assert.Error(commentaarBijErrorInTry_Something)
enz, Assert heeft een heleboel nuttige tests.

Gebruik
Als je helemaal nog geen code hebt, en gewooen een nieuwe test maakt “Test1”, en je probeert F4 krijg je:

1..0

# Ran ‘Test1’
#
# FAILED

En de voorbeeldcode (zie link onderaan) draait een succesvolle test en geeft:

1..5

Test THello.AHelloWorld
# I am the first test, because my name starts with A.
ok 1 – THello.AHelloWorld.7: HW strings should be equal
1..1
ok 1 – THello.AHelloWorld
(…enz 2, 3, 4 ..)
Test THello.Right
ok 1 – THello.Right.19: Hello.Right says Right
1..1
ok 5 – THello.Right

# Ran ‘Testsuite: A: Run all tests’
#
# PASSED

Verfijnen
Als je wil kunnen kiezen welke tests je wel of niet draait, kan je “test suites” maken. In het test scherm (F4) krijg je rechts onderaan de knop om “Test suites” te maken, -draaien, -beheren, enz.

Plannen
Het is lonend om bij het programmeren voor bepaalde methodes/procedures/functies eerst de test te programmeren, en dan pas de methode zelf: je kan dan tijdens het programmeren van de methode onmiddellijk testen met je test.
Als je later aanpassingen aan je programma maakt, bedenk je eerst of de test moet veranderen, en daarna kan je de wijzigingen dan ook testen met je oorspronkelijke of aangepaste test.
Vooral bij libraries zijn testmodules interressant, ook voor algemene code in modules in je project.

Links
https://gambaswiki.org/wiki/doc/unittesting
https://nl.wikipedia.org/wiki/Unittesten
https://gitlab.com/gambas/gambas/-/blob/master/main/lib/test/gb.test/unittesthelloworld-1.0.0.tar.gz

Posted in Gambas3 | Comments Off on Testen in Gambas met unittesting

Gambas compatibiliteit (backward compatibility): soms niet

Als je broncode schrijft in Gambas versie 3.(x) dan kan het zijn dat die niet werkt in versie 3.(x-1) https://gambaswiki.org/wiki/doc/compat
Als het een voorwaarde is dat die code daar wel werkt moet je weten wat niet gebruikt mag worden uit de mogelijkheden van je nieuwere Gambas versie.
Hieronder begin ik een lijstje met zelf ondervonden incompatibiliteit, als ik een officiële Gambas pagina vindt daarover komt die hier in de plaats…

Als je weet waar in je code het probleem ontstaat op de oude versie, kan je daar “TRY” gebruiken:
Use TRY and check for an ERROR to see if newer code will work on the current version of gambas or not.

Settings.Exist : code gemaakt in 3.18.4 – code werkt niet in: 3.9.1

with / end with : nesten van twee strukturen in elkaar werkt niet in oude Gambas versies.

with myClass
  with myObject
    ' code code..
  end with
end with

Form elementen : bepaalde eigenschap bestaat niet in oude versie/andere desktop (Gnome):
ScrollView.Autoresize

Posted in Uncategorized | Comments Off on Gambas compatibiliteit (backward compatibility): soms niet

Vriendelijk afsluiten van je programma

Een voorbeeldje van wat in mijn MMain zit bij een programma met meer vensters
(in de Gambas IDE zijn dat de Forms):

Public Sub doQuit()
  '
  Dim hWindow As Window
  '
  Settings.Save  ' other code 
  hRunCounter.appClose() ' other code
  For Each hWindow In Windows
    hWindow.Close
  Next
  '
End

Other code:
Settings.Save: omdat ik de component Settings gebruikt.
hRunCounter: ik hou een teller bij van het starten en sluiten van het programma

Posted in Hoe - in Gambas | Comments Off on Vriendelijk afsluiten van je programma

Gambas3 updates (OpenSUSE e.a.)

-ps voorheen zie ook Gambas2 updatesvanaf 2024 zie ..

Updates van Gambas3, meestal openSuse (v.a. 12-2018):
(datum opgemerkt, uitgavedatum kan je checken op gambas.sourceforge.net/en/main.html)

2023-12-10
openSUSE 15.4: gambas3 v. 3.18.4-lp154.9.1

2023-12-06 Sint-update
openSUSE 15.4: gambas3 v. 3.18.4-lp154.8.1

2023-11-21
openSUSE 15.4: gambas3 v. 3.18.4-lp154.7.1

2023-10-24
openSUSE 15.4: gambas3 v. 3.18.4-lp154.6.2

2023-10-15
openSUSE 15.4: gambas3 v. 3.18.4-lp154.6.1

2023-10-04
openSUSE 15.5: gambas3 v. 3.18.4-lp155.5.2

2023-09-28
openSUSE 15.4: gambas3 v. 3.18.4-lp154.5.2

2023-09-25
openSUSE 15.4: gambas3 v. 3.18.4-lp154.5.1

..(heb ik er gemist? Op sommige systemen spring ik van 1.1 naar 5.1, ergens zoals hieronder heb ik 2.1)

2023-09-22
openSUSE 15.4: gambas3 v. 3.18.4-lp154.2.1

2023-09-18
openSUSE 15.4: gambas3 v. 3.18.4-lp154.1.1

2023-07-27
openSUSE 15.4: gambas3 v. 3.18.3-lp154.3.1

2023-07-07
openSUSE 15.4: gambas3 v. 3.18.3-lp154.2.1

2023-06-25
openSUSE 15.4: gambas3 v. 3.18.3-lp154.1.1

2023-05-25
openSUSE 15.4: gambas3 v. 3.18.2-lp154.12.1

2023-05-22
openSUSE 15.4: gambas3 v. 3.18.2-lp154.11.1

2023-05-15
openSUSE 15.4: gambas3 v. 3.18.2-lp154.10.1

2023-05-12
openSUSE 15.4: gambas3 v. 3.18.2-lp154.9.1

(…)

2023-02-27
openSUSE 15.4: gambas3 v. 3.18.1-lp154.3.1

2023-02-13
openSUSE 15.4: gambas3 v. 3.18.0-lp154.11.1

2023-02-12
openSUSE 15.4: gambas3 v. 3.18.0-lp154.10.1

2023-02-07
openSUSE 15.4: gambas3 v. 3.18.0-lp154.9.1

2023-01-25
openSUSE 15.4: gambas3 v. 3.18.0-lp154.8.1

2023-01-15
openSUSE 15.4: gambas3 v. 3.18.0-lp154.6.1

2023-01-03
openSUSE 15.4: gambas3 v. 3.17.3-lp154.24.2

2022-12-28
openSUSE 15.4: gambas3 v. 3.17.3-lp154.24.1

2022-12-05
openSUSE 15.4: gambas3 v. 3.17.3-lp154.23.1

2022-12-03
openSUSE 15.4: gambas3 v. 3.17.3-lp154.22.1

2022-11-28
openSUSE 15.4: gambas3 v. 3.17.3-lp154.21.1

2022-11-21
openSUSE 15.4: gambas3 v. 3.17.3-lp154.16.3

2022-11-05
openSUSE 15.4: gambas3 v. 3.17.3-lp154.16.2

2022-10-27
openSUSE 15.4: gambas3 v. 3.17.3-lp154.16.1

2022-10-21
openSUSE 15.4: gambas3 v. 3.17.3-lp154.15.1

2022-10-04
openSUSE 15.4: gambas3 v. 3.17.3-lp154.13.1

2022-09-28
openSUSE 15.4: gambas3 v. 3.17.3-lp154.10.1

2022-09-23
openSUSE 15.4: gambas3 v. 3.17.3-lp154.9.1

2022-09-20
openSUSE 15.4: gambas3 v. 3.17.3-lp154.8.2

2022-09-05
openSUSE 15.4: gambas3 v. 3.17.3-lp154.8.1

2022-08-26
openSUSE 15.4: gambas3 v. 3.17.3-lp154.6.1

2022-07-25
openSUSE 15.4: gambas3 v. 3.17.3-lp154.1.1
van:
openSUSE 15.4: gambas3 v. 3.17.2-lp154.4.1

vr 08 apr 2022 14:00:00
munix9@googlemail.com
- update to version 3.17.2 (ed8b8b69)

(2021…)
Continue reading

Posted in Gambas3 | Comments Off on Gambas3 updates (OpenSUSE e.a.)

Gambas op de TIOBE index

Alhoewel hij niet op de eerste pagina (top 50) van de TIOBE index staat, kan je gambas wel terugvinden in de volledige lijst van gekende programmeertalen op:

https://www.tiobe.com/tiobe-index/programminglanguages_definition/#instances.

Het is een alfabetische lijst, dus kijk bij de “g”:


Fortran
Fortress
FreeBASIC
Gambas
GAMS
GLSL
GML: GML, GameMaker Language
GNU Octave
Go: Go, Golang …

De vorige keer dat ik checkten (wanneer was dat ook alweer?) stond Gambas er nog niet in dacht ik.

De lijst wordt opgesteld op basis van het aantal keer zoeken op de taal:

+" programming"

Sommige talen vallen onder een grotere groep (zoals het meer algemene Basic), maar gambas heeft zijn eigen wikipedia pagina, en wordt dus apart genoteerd.

Echte cijfers over Gambas krijgen we niet te zien, ook niet het rangnummer dus.

Als je die wil, moet je de hele dataset van de TIOBE index kopen, en om hen “een beetje te compenseren” kost dat 5.000 dollar.

Maar het is zeer de vraag of het dat waard is, want de manier van rangschikken is redelijk omstreden (“Please stop citing TIOBE“), en anderen verkiezen RedMonk, StackOverflow developer survey bij 90.000 programmeurs,GitHub Octoverse, of andere methodes die voortgaan op andere gegevens, maar daar vind je Gambas helemaal niet terug.

Posted in Anderen over gambas | Comments Off on Gambas op de TIOBE index

Nieuw project: directory bestaat al

Gitlab project
Ik heb een nieuw project “nieuwproject” gemaakt op gitlab, leeg behalve de standaard aangemaakte README. Ik haal het af met git clone nieuwproject.

cd newproject
ls -A

.git  README.md

Ik open de Gambas3 IDE, en begin daar een nieuw programma met “New Project”, kies de map waar “nieuwproject” staat, geef als naam “newproject”:

The project directory already exists

Er is geen optie om de bestaande directory “newproject” te gebruiken in plaats van een nieuwe te laten maken door Gambas3.

Omgekeerd?
Ik verwijder de directory “newproject”.
Ik maak in Gambas3 “newproject” op die vorige locatie.

cd newproject
ls -A

.directory  .gitignore  .hidden  .icon.png  .lang  .lock  .project  .src

Dan ga ik in de hogere directory terug mijn git project afhalen met git clone:
git clone https://gitlab.com/groupname/newproject.git

fatal: destination path ‘newproject’ already exists and is not an empty directory.

Wat is de juiste manier?

Continue reading

Posted in vraag-me-af | Comments Off on Nieuw project: directory bestaat al

Kan project bestand niet openen

Bij het openen van een project krijg ik deze foutmelding:

Kan project bestand niet openen:
/home/cyb/Git/DbInfoCodePrj/dbinfocode

Void key
Project.ReadProject.3436 Project.Open.794 FWelcome.ProjectItem_Click.400 CProjectList.ProjectItem_Click.523 ProjectBox.DrawingArea_MouseUp.487 ?

Ik kan het bericht alleen wegklikken en blijf daarmee in het Gambas openingscherm om een project te kiezen.

Het project zit in een git repository.

Ik schakel over naar een andere branch (die kort daarvoor gemerged is met deze branch).

Nu gaat het project wel open. Ik schakel terug naar de “defecte” branch, en bekijk de foutmelding.
Die verwijst naar het project-bestand, dus ik open in een externe editor de .project file.

Daar vind ik stukken van een mislukte merge terug:

mcedit .project

# Gambas Project File 3.0
Title=DbInfoCode
Startup=MMain
Icon=img/DbInfoCode.png
<<<<<<< HEAD Version=3.2.11 ======= Version=3.2.12 >>>>>>> main
Component=gb.image
Component=gb.gui.qt
Component=gb.form

Ik verwijder de git lijnen en laat de juiste versie staan..

# Gambas Project File 3.0
Title=DbInfoCode
Startup=MMain
Icon=img/DbInfoCode.png
Version=3.2.12
Component=gb.image
Component=gb.gui.qt
Component=gb.form

Ok! Het project opent weer normaal.

Posted in Gambas3 | Comments Off on Kan project bestand niet openen

Dataconnection vanuit lib of app?

Ik vraag me af of ik de verbinding met de databank vanuit de applicatie moet doen of vanuit de lib die de data-classes bevat.

Nodig:

1 project als lib (zie properties bij maken nieuw gambas project)
1 project als gewone gambas3 applicatie.

Ik gebruik ook:
gb.db (Database toegang) en “Settings” in project properties, componenten (voorzien in Gambas).
– bibliotheek “DataContext” in project properties, libraries (deze moet je zelf afhalen)

In de lib zitten
– de classes bv CEmployee beschrijft de employee (properties voor velden enz).
– de Module MEmplData: bevat procedures voor het aanmaken van records, opvragen vanuit de classe voor het laden van de variabelen in de properties, bewaren vanuit de classe van het “object/record”.
– de Module MEmpData bezit ook hConData AS Connection

– de applicatie gaat de lib.hCondata initialiseren met de toegangsgegevens van de databank met behulp van DataContext.makeConnection.
(gegevens die gelezen worden uit een settings file – dat gebeurt in de DataContext class CDataContext; je kan er context naar settings mee maken, aktieve context zetten wat ook bewaard wordt in settings, nieuwe settings file maken, lijst alle contexten in settings opvragen, enz)

– in de applicatie ga je gewoon de “current” datacontext gebruiken, en je kan “switchen” van context door de “current” aan te passen via DataContext, en te “herladen”, maw de connectie terug te maken.

Posted in Databank, Gambas3, vraag-me-af | Comments Off on Dataconnection vanuit lib of app?

Git vanuit gambas

Voor een eigen programma waar de inhoud wordt bijgehouden in een git repository, zou ik die willen kunnen updaten vanuit mijn Gambas app. Sinds een tijdje is in de IDE een voorziening ingebouwd om de git branch om te schakelen enz vanuit de IDE, dus daar zit mogelijk een aanknooppunt.

Algemeen: een commando kan je vanuit Gambas lanceren met shell of exec.

In de broncode van gambas 3.18.0 vind je een map VersionControl met een Class CVersionControl, met een subclass CVersionControlGit.

Daarin:
Private Sub RunShell(sCmd As String, Optional bSilent As Boolean) As String
'
Return VersionControl.Shell("cd " & Shell(Project.Dir) & " && " & sCmd, bSilent)
'
End

In de Module (naam zonder M) “VersionControl” vind je:

Public Sub Shell(sCmd As String, Optional bSilent As Boolean, Optional aEnv As String[]) As String
'
Dim sResult As String
'
If Not bSilent Then Insert(sCmd & "\n")
Shell sCmd With aEnv To sResult
If Process.LastValue Then
$sLastResult = sResult
Insert(sResult)
Endif
Return sResult
'
End

Posted in Gambas3, Hoe - in Gambas | Comments Off on Git vanuit gambas