Kleine dynamische Datenbank im Interface-Stil

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

NicTheQuick hat geschrieben:Extremes Doppelposten hier! Naja... :mrgreen:
Dir sei verziehen ;-)

Super Arbeit, Nic :allright:


Irgendwie mag ich ja mit Blindheit geschlagen sein, aber ich vermisse die
DB_CreateFromDump() - Prozedur aus den ersten Versionen. Wäre schon
praktisch, wenn man sowas hätte, weil man sonst keine 'unbekannten'
Datenbanken laden kann.

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

@Kiffi:
Natürlich geht das:

Code: Alles auswählen

*DB.DB = DB_Create()
;Datei öffnen blablabla
*DB\ReadDB(FileID)
;Datei wieder schließen
@ts-soft:
Ja, ich zieh mir mal die neuste Version von jaPBe.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Update:

+ Added: Zusatzparameter bei AddRow() zum Einfügen mehr als einer neuen Zeile

Code: Alles auswählen

Interface DB
...
AddRow(Pos.l = -1, Rows.l = 1)
...
EndInterface
...
Procedure.l DB_AddRow(*DB.DB_Struc, Pos.l = -1, Rows.l = 1) ;Fügt (eine) neue Zeile(n) hinzu, die zur aktuellen wird
  Protected *Row.Long, *temp, a.l

  If *DB\Cols = 0 : ProcedureReturn #False : EndIf
  If Rows < 1 : ProcedureReturn #False : EndIf
  
  If *DB\Rows = 0
    *DB\tRows = (Rows / *DB\ChunkRows) * *DB\ChunkRows + *DB\ChunkRows
    *DB\pRows = AllocateMemory(*DB\tRows * 4)
    If *DB\pRows = 0 : ProcedureReturn #False : EndIf
    
    *Row = *DB\pRows
    For a = 1 To Rows
      *Row\l = AllocateMemory(4 + *DB\ColSize)
      PokeL(*Row\l, *DB\Cols)
      *Row + 4
    Next
    *DB\Rows = Rows
    *DB\ActRow = 1
  
  Else
    If (*DB\Rows + Rows) > *DB\tRows
      a = ((*DB\Rows + Rows) / *DB\ChunkRows) * *DB\ChunkRows + *DB\ChunkRows
      *temp = ReAllocateMemory(*DB\pRows, a * 4)
      If *temp = 0 : ProcedureReturn #False : EndIf
      *DB\tRows = a
      *DB\pRows = *temp
    EndIf
    *DB\Rows + Rows
    
    If Pos => 0 And Pos < *DB\Rows - 1 ; Neue Zeile hinter die mit Nummer 'Pos'
      CopyMemory(*DB\pRows + Pos * 4, *DB\pRows + (Pos + Rows) * 4, (*DB\Rows - Pos - 1) * 4)
      *Row = *DB\pRows + Pos * 4
      For a = 1 To Rows
        *Row\l = AllocateMemory(*DB\ColSize + 4)
        PokeL(*Row\l, *DB\Cols)
        *Row + 4
      Next
      *DB\ActRow = Pos + 1
    Else
      *Row = *DB\pRows + *DB\Rows * 4 - 4
      For a = 1 To Rows
        *Row\l = AllocateMemory(*DB\ColSize + 4)
        PokeL(*Row\l, *DB\Cols)
        *Row + 4
      Next
      *DB\ActRow = *DB\Rows
    EndIf
  EndIf
  
  ProcedureReturn #True
EndProcedure
Wenn man weiß, dass man jetzt 100000 Einträge eintragen will, ist das die
schnellste Methode: *DB\AddRow(-1, 100000)

Erklärung des ersten Parameters:
Alles kleiner 0 und größer gleich CountRows() hängt die neuen Zeilen hinter die letzte,
0 schiebt die neuen Zeilen vor die erste,
alle anderen gültigen Zeilenangaben hängen die neuen Zeilen hinter die Angegebene.

Der erste Parameter ist optional und standardmäßig -1. (immer anhängen)
Der zweite Parameter ist optional und standardmäßig 1. (eine neue Zeile)

Die neue aktuelle Zeile nach Aufruf der Funktion ist die erste der neu
eingefügten Zeilen, d.h. bei Pos >= 0 und Pos < CountRows() ist die neue
aktuelle Zeile = Pos + 1.



Jetzt versuche ich mich mal an den verschiebbaren, löschbaren und
mittendrin einfügbaren Spalten. :)
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Hast du diesen Beitrag von remi_meier bemerkt:

Hier ein kostenloser/s Bug/Feature für dich
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

@DarkDragon:
Ja, ist jetzt alles geregelt.

@all:
Man kann jetzt Spalten schon löschen, aber es gibt noch Fehler.
Beim Löschen einer Spalte wird es zwei Optionen geben:
Entweder ein entgültiges Löschen, bei dem bei jeder einzelnen Zeile der
Inhalt gelöscht und der Speicher freigegeben wird, oder ein schnelles
Löschen, bei dem jediglich alle Strings auf Null gesetzt und alle
Memoryblöcke freigegeben werden. So bleibt dann eine Lücke in jeder Zeile
übrig, die dann wiederbenutzt werden kann, wenn man wieder eine neue
Spalte einfügt.

Nach dem Speichern und Neuladen einer Datenbank ist auch alles wieder
geordnet im Speicher, womit auch Lücken nach einem Spaltenlöschen nicht
mehr existieren.

Bisher ist nur das schnelle Löschen voll funktionsfähig, aber beim
Neuanlegen einer Spalte wird eine Lücke noch nicht ausgenutzt. Daran
arbeite ich gerade.
Und obwohl das Löschen eine Spalte nicht so wichtig ist, macht es doch
Spaß nur alles noch komplizierter zu machen. Natürlich nur solange es
nachher noch funktioniert. Aber das kriege ich schon noch hin.

Bis das alles funktioniert ist also noch warten angesagt! <)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Momentan tut sich leider nicht viel. Bin noch bis 15. September in der
Zivildienstschule in Trier und komm nur an Wochenenden vorbei. Wer aus
der Gegend kommt, kann mich ja mal besuchen kommen. :lol:
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

> Momentan tut sich leider nicht viel.

Danke, dass Du Bescheid sagst!

Bei mir befindet sich Deine DB z.Zt. in einer halbproduktiven Umgebung in
der Testphase. Bisher habe ich noch keinen Fehler gefunden :allright:

Grüße ... Kiffi

P.S.: Freue mich schon auf die nächste Version mit den löschbaren Spalten.
Ich habe jetzt auch schon einen Anwendungszweck hierfür gefunden ;-)
a²+b²=mc²
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

So, Trier ist vorüber und ich weiß noch nicht, wann ich wieder richtig zum
Programmieren komme. Wenn ich dann auf meiner richtigen Zivi-Stelle
wieder Zeit habe, mache ich da mal hin und wieder weiter.

Ich meld mich dann wieder, wenn's was neues gibt.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

> So, Trier ist vorüber

war's sehr stressig für Deine Leber? ;-)

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

@Kiffi: So schlimm war's nicht. Aber die zahlreichen Schachpartien mit
meinen Zimmergenossen, haben mich motiviert an meinem alten
Schachcomputer wieder weiterzuarbeiten. Aber erstmal die Datenbank.

Also das mit den Spalten mache ich mal in ein paar ruhigen Stunden zu
Hause zu Ende.

Mittlerweile kann man aber noch CSV-Dateien lesen und schreiben. Optional
kann die erste Zeile als Spaltennamen benutzt werden.
Antworten