PostgreSQL native
Moderator: Moderatoren
- Jan
- Marvin
- Beiträge: 14658
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Re: PostgreSQL native
Es gibt da eine Klasse von DS-Datasoft.
Jan
Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
- AUGE_OHR
- Marvin
- Beiträge: 12910
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: PostgreSQL native
die baut vermutlich, wie meine oder Hectors, auf der CLASS von Phil Ide auf.
viewtopic.php?f=24&t=8564
wir hatten doch auch schon mal einen Vortrag von DS über PostgreSQL, oder
es geht mir aber um das Verständnis "wie" es funktioniert und welche "Fallen" es gibt wenn man es "selbst" machen möchte.
natürlich sind dann auch "Tricks" für Qwery vorgesehen z.b. wie ermittelt man die zugehörigen "echten" PostgreSQl Indexe zu einer Table.
das ganze soll als Thema im Forum zu Diskussionen führen und beim Einstieg helfen wie es z.b. Benz gehabt hat mit dem Original Source und NoiVar
gruss by OHR
Jimmy
Jimmy
- Jan
- Marvin
- Beiträge: 14658
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Re: PostgreSQL native
Das bezweifle ich. Aber Marcus kann da sicher mehr zu sagen. Und sonst: Weitere Infos gibt es unter https://www.ds-datasoft.de/g-pq.html
Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
- AUGE_OHR
- Marvin
- Beiträge: 12910
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: PostgreSQL native
hi,
die libpq.dll enthält nur wenige Function die für die "Kommunikation" notwendig sind.
der Wrapper für die 113 DLLFUNCTION sollte also gleich sein.
Unterschiede hatten sich bei Hector, Edgar und mir bei den verwendeten Daten Typen ergeben z.b. BLOB.
das sind dann so die Sachen wo sich unsere LIB unterscheiden. klar kommen dann weiter Methoden dazu ... je nachdem was man braucht.
ich möchte zunächst nur das man die Grundlagen hat und z.b. die Logik bei meiner Aussage "man braucht kein ISAM mit SQL" versteht.
die libpq.dll enthält nur wenige Function die für die "Kommunikation" notwendig sind.
der Wrapper für die 113 DLLFUNCTION sollte also gleich sein.
Unterschiede hatten sich bei Hector, Edgar und mir bei den verwendeten Daten Typen ergeben z.b. BLOB.
das sind dann so die Sachen wo sich unsere LIB unterscheiden. klar kommen dann weiter Methoden dazu ... je nachdem was man braucht.
ich möchte zunächst nur das man die Grundlagen hat und z.b. die Logik bei meiner Aussage "man braucht kein ISAM mit SQL" versteht.
gruss by OHR
Jimmy
Jimmy
- Jan
- Marvin
- Beiträge: 14658
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Re: PostgreSQL native
Also Daten in der PostgreSQL, und Zugriff per klassischer DB-Funktionen? Wenn Du das hinbekommst wäre das natürlich genial!
Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
- Marcus Herz
- 1000 working lines a day
- Beiträge: 853
- Registriert: Mo, 16. Jan 2006 8:13
- Wohnort: Allgäu
- Hat sich bedankt: 39 Mal
- Danksagung erhalten: 192 Mal
- Kontaktdaten:
Re: PostgreSQL native
Hallo
Ich habe vor einigen Jahren auch schon eine Klasse als Ersatz für die PGDBE geschrieben. Basiert ausschliesslich auf der C-API. Benötigt deswegen keine ISAM Emu. Aber ünterstützt auch keine Workarea oder klassische Xbase Datenbank Funktionen. Also nur für neue Anwendungen einsetzbar. Aber so schnell, wie PostgreSQL sein kann. Ohne den Overhead der ISAM Emu.Wir habe auch eine Anwendung, die darauf basiert, seit längerem im Einsatz. Im VDBU wird diese auch für PostgreSQL Daten verwendet. Hab ich auch schon mal im Forentreffen gezeigt.
Grundsätzlich muss einem folgendes klar sein:
DBF und auch ADS unterstützen das Konzept des Live Cursors. Ein Skip(0) liest somit immer den aktuellen Datensatz ein. Gilt auch für Live Sql Cursor bei ADS wie "select * from kunden where ort like 'M%';". In einen solchen SQL Cursor kann ich sogar schreiben. Und sehe sofort die neuen Daten, auch wenn ein Dritter diese verändert hat.
Bei PostgreSQL bekomme ich IMMER eine Kopie des Ergebnisses. Das heisst, nach jedem update muss dieses Resultset neu eingelesen werden. Deswegen ist auch die PGDBE langsamer, weil immer die Daten des PG Servers mit der lokalen Kopie synchronisert werden muss.
Das Problem liegt nicht in der technischen Anbindung an den PostgreSQL Server, sondern in einem neuen Programmierstil, weil die DBF Denke nicht mehr passt.
Grüße Marcus
Ich habe vor einigen Jahren auch schon eine Klasse als Ersatz für die PGDBE geschrieben. Basiert ausschliesslich auf der C-API. Benötigt deswegen keine ISAM Emu. Aber ünterstützt auch keine Workarea oder klassische Xbase Datenbank Funktionen. Also nur für neue Anwendungen einsetzbar. Aber so schnell, wie PostgreSQL sein kann. Ohne den Overhead der ISAM Emu.Wir habe auch eine Anwendung, die darauf basiert, seit längerem im Einsatz. Im VDBU wird diese auch für PostgreSQL Daten verwendet. Hab ich auch schon mal im Forentreffen gezeigt.
Grundsätzlich muss einem folgendes klar sein:
DBF und auch ADS unterstützen das Konzept des Live Cursors. Ein Skip(0) liest somit immer den aktuellen Datensatz ein. Gilt auch für Live Sql Cursor bei ADS wie "select * from kunden where ort like 'M%';". In einen solchen SQL Cursor kann ich sogar schreiben. Und sehe sofort die neuen Daten, auch wenn ein Dritter diese verändert hat.
Bei PostgreSQL bekomme ich IMMER eine Kopie des Ergebnisses. Das heisst, nach jedem update muss dieses Resultset neu eingelesen werden. Deswegen ist auch die PGDBE langsamer, weil immer die Daten des PG Servers mit der lokalen Kopie synchronisert werden muss.
Das Problem liegt nicht in der technischen Anbindung an den PostgreSQL Server, sondern in einem neuen Programmierstil, weil die DBF Denke nicht mehr passt.
Grüße Marcus
Gruß Marcus
Erkenne, was du findest, dann weißt du, wonach du gesucht hast
Erkenne, was du findest, dann weißt du, wonach du gesucht hast
- Marcus Herz
- 1000 working lines a day
- Beiträge: 853
- Registriert: Mo, 16. Jan 2006 8:13
- Wohnort: Allgäu
- Hat sich bedankt: 39 Mal
- Danksagung erhalten: 192 Mal
- Kontaktdaten:
Re: PostgreSQL native
Noch ne Anmerkung:
Da die Kopie des Resultset auf dem Server liegt, bekommt man nur Handles, mit denen man im Speicher auf dem Server navigieren kann. Da wir aber eine 32 bit Anwendung und demzufolge auch eine 32 bit API verwenden, liegt die maximale Größe des Speicher für eine Kopie bei 2**32-1 bit. Man kann sich leicht ausrechnen, wieviel Datensätze da enthalten sein dürfen, die Grenze ist schnell gesprengt:
z.B eine Satzänge von 50 Feldern * 25 Byte ergibt 1250 Byte oder um leichter zurechnen 2**10 bit, durchaus realistisches Szenario. Man kann also 2**22 Sätze im Speicher halten, wären ca 4.100.000 Sätze, offensichtlich werden aber ein paar bits intern noch benötigt. 2 bits weniger sind nur noch 1 Mio. Sätze. Meine Tests haben ergeben, dass diese Grenze viel niedriger liegt. Testtabellen haben schon bei über 200.000 Sätzen diese Grenze gesprengt (weiß aber nicht mehr die Feldlänge, war sicher länger). Diese Grenze gilt auch für PgAdmin und PGDBE. Auch die schmieren ab, wenn diese max. Puffergröße überschritten wird.
Diese Einschränkung betrifft nicht die Dateigrösse des PG Servers als solchen. Nur den Zugriff und Abfrage.
Da die Kopie des Resultset auf dem Server liegt, bekommt man nur Handles, mit denen man im Speicher auf dem Server navigieren kann. Da wir aber eine 32 bit Anwendung und demzufolge auch eine 32 bit API verwenden, liegt die maximale Größe des Speicher für eine Kopie bei 2**32-1 bit. Man kann sich leicht ausrechnen, wieviel Datensätze da enthalten sein dürfen, die Grenze ist schnell gesprengt:
z.B eine Satzänge von 50 Feldern * 25 Byte ergibt 1250 Byte oder um leichter zurechnen 2**10 bit, durchaus realistisches Szenario. Man kann also 2**22 Sätze im Speicher halten, wären ca 4.100.000 Sätze, offensichtlich werden aber ein paar bits intern noch benötigt. 2 bits weniger sind nur noch 1 Mio. Sätze. Meine Tests haben ergeben, dass diese Grenze viel niedriger liegt. Testtabellen haben schon bei über 200.000 Sätzen diese Grenze gesprengt (weiß aber nicht mehr die Feldlänge, war sicher länger). Diese Grenze gilt auch für PgAdmin und PGDBE. Auch die schmieren ab, wenn diese max. Puffergröße überschritten wird.
Diese Einschränkung betrifft nicht die Dateigrösse des PG Servers als solchen. Nur den Zugriff und Abfrage.
Gruß Marcus
Erkenne, was du findest, dann weißt du, wonach du gesucht hast
Erkenne, was du findest, dann weißt du, wonach du gesucht hast
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2517
- Registriert: Mi, 28. Jul 2010 17:16
- Hat sich bedankt: 12 Mal
- Danksagung erhalten: 77 Mal
Re: PostgreSQL native
Deshalb am besten von Beginn an nur mit Handles Arbeiten und gar keine Kopie des gesamten Resultats auf den lokalen Rechner ziehen. Bei bedarf dann nur die benötigten Felder abholen. So gibst gar keine Speicher-Probleme und ist erst noch viel viel schneller.liegt die maximale Größe des Speicher für eine Kopie bei 2**32-1 bit. Man kann sich leicht ausrechnen, wieviel Datensätze da enthalten sein dürfen, die Grenze ist schnell gesprengt:
Valar Morghulis
Gruss Carlo
Gruss Carlo
- Marcus Herz
- 1000 working lines a day
- Beiträge: 853
- Registriert: Mo, 16. Jan 2006 8:13
- Wohnort: Allgäu
- Hat sich bedankt: 39 Mal
- Danksagung erhalten: 192 Mal
- Kontaktdaten:
Re: PostgreSQL native
Damit ist ein Seek nicht möglich. Blieb nur sequentiell Satz für Satz durchskippen. Es gibt keinen Index auf dem Resultset, nur eine Order by, das macht dann doch einen Unterschied.
In meiner Klasse kopiere ich das Resultset in eine lokales Array, das kann ich sortieren, und durchsuchen. Aber hier sind wir schon bei der Auflistung der Erwartungen. Und einer anderen Maskenführung. Das lokale Array ist genauso statisch wie die Kopie auf dem Server. Um aber den aktuellen Satz zu lesen, geht dann nur über Primarykey: "select * from table where primarykey". Auch für ein Update ist dies dann nötig.
Also brauchts auch eine saubere Datenstruktur.
Hab ich die Bestellung, Auftrag, etc. kann man sich leicht die Childdaten, (Positionen, Termine, Lose, etc) in den lokalen Speicher ziehen. Ein solches Scenario deckt bei mir den Großteil der Anwendung ab. Anders sieht es bei Übersichtmasken zur Auswahl oder Abfrage aus.
Macht weinig Sinn, sich mal kurz zig-tausend Aufträge anzuzeigen, (oder ein Problem), da muss man eben vorher schon Eingrenzungen abfragen. Wie gesagt, das erfordert eine neue Sicht auf Masken Konzeption.
PS die Handles verweisen ja auch auf die Kopie des Satzes, es gibt keinen Recordzugriff wie in DBF!
In meiner Klasse kopiere ich das Resultset in eine lokales Array, das kann ich sortieren, und durchsuchen. Aber hier sind wir schon bei der Auflistung der Erwartungen. Und einer anderen Maskenführung. Das lokale Array ist genauso statisch wie die Kopie auf dem Server. Um aber den aktuellen Satz zu lesen, geht dann nur über Primarykey: "select * from table where primarykey". Auch für ein Update ist dies dann nötig.
Also brauchts auch eine saubere Datenstruktur.
Hab ich die Bestellung, Auftrag, etc. kann man sich leicht die Childdaten, (Positionen, Termine, Lose, etc) in den lokalen Speicher ziehen. Ein solches Scenario deckt bei mir den Großteil der Anwendung ab. Anders sieht es bei Übersichtmasken zur Auswahl oder Abfrage aus.
Macht weinig Sinn, sich mal kurz zig-tausend Aufträge anzuzeigen, (oder ein Problem), da muss man eben vorher schon Eingrenzungen abfragen. Wie gesagt, das erfordert eine neue Sicht auf Masken Konzeption.
PS die Handles verweisen ja auch auf die Kopie des Satzes, es gibt keinen Recordzugriff wie in DBF!
Gruß Marcus
Erkenne, was du findest, dann weißt du, wonach du gesucht hast
Erkenne, was du findest, dann weißt du, wonach du gesucht hast
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2517
- Registriert: Mi, 28. Jul 2010 17:16
- Hat sich bedankt: 12 Mal
- Danksagung erhalten: 77 Mal
Re: PostgreSQL native
Ich komme mit den Handles sehr gut zurecht. Wenn "order by" nicht ausreicht wäre noch die möglichkeit der TEMP TABLES da geht dann Index. SQL bietet so viele Möglichkeiten da sind Umwege über Arrays oder lokale Tabellen gar nicht nötig. Für Auftragsverwaltung usw. haben mir die möglichkeiten von SELECT und Arbeiten mit Handles eigentlich immer vollkommen gereicht. Auch beim Browse, ich weiss welche ID der erste und letzte Angezeigte Satz hat. Bewegt der User den Cursor über den Bildrand hinaus wird entsprechend genau die benötigten Sätze aus der Datenbank geholt. Lokales Speichern brauchts da gar nicht.
Das wichtigste ist dabei man muss umdenken, nicht mehr in DBF denken sondern in SQL dann erst dann wird vieles einfacher.
Einen Record Zugriff gibt es indirekt schon. Ein Datenfeld mit dem Datentyp Serial das ist innerhalb der Tabelle in jedem Datensatz ein Feld mit einer eindeutigen unveränderlichen fortlaufenden Nummer.
Das wichtigste ist dabei man muss umdenken, nicht mehr in DBF denken sondern in SQL dann erst dann wird vieles einfacher.
Einen Record Zugriff gibt es indirekt schon. Ein Datenfeld mit dem Datentyp Serial das ist innerhalb der Tabelle in jedem Datensatz ein Feld mit einer eindeutigen unveränderlichen fortlaufenden Nummer.
Valar Morghulis
Gruss Carlo
Gruss Carlo
- AUGE_OHR
- Marvin
- Beiträge: 12910
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: PostgreSQL native
hi,
---
Die Idee der PgDBE ist toll ... ohne grosse Änderungen soll bestehender Source laufen ... wenn das Konzept von Alaska performen würde
wer nicht mehr auf Alaska warten wollte hat dann zur SQLexpress++ oder der native Schnittstelle gegriffen.
auf dem Konzept von Phil Ide bauen wohl viele auf welche die native Schnittstelle nutzen.
---
kennt Ihr die CLASS DbServer wo man mit Method(en) "navigiert"
statt dem Befehl SKIP die Method SKIP()
wer das Demo von Phil Ide probiert hat dem ist sicherlich sein PGSQLBrowse und der DbSkipper aufgefallen.
das PGSQLBrowse Demo zeigt das man dass auch mit PostgreSQL machen kann
natürlich kann man die Method(en) zum "navigieren" auch ohne Browse nutzen ...
Die Idee ist nun die Kombination von beiden zu einer eigenen CLASS mit der man "navigieren" kann.
statt REPLACE / STORE nimmt man dann FieldGet() / FieldPut()
die CLASS wäre "Dual-fähig" für DBF und SQL wobei ich in diesem Thread von PostgreSQL sprechen möchte.
wenn man eine API Beschreibung von Alaska hätte wie man eine DBE für Xbase++ schreibt dann könnte man vielleicht ...
---
Die Idee der PgDBE ist toll ... ohne grosse Änderungen soll bestehender Source laufen ... wenn das Konzept von Alaska performen würde
wer nicht mehr auf Alaska warten wollte hat dann zur SQLexpress++ oder der native Schnittstelle gegriffen.
auf dem Konzept von Phil Ide bauen wohl viele auf welche die native Schnittstelle nutzen.
---
kennt Ihr die CLASS DbServer wo man mit Method(en) "navigiert"
statt dem Befehl SKIP die Method SKIP()
wer das Demo von Phil Ide probiert hat dem ist sicherlich sein PGSQLBrowse und der DbSkipper aufgefallen.
das PGSQLBrowse Demo zeigt das man dass auch mit PostgreSQL machen kann
natürlich kann man die Method(en) zum "navigieren" auch ohne Browse nutzen ...
Die Idee ist nun die Kombination von beiden zu einer eigenen CLASS mit der man "navigieren" kann.
statt REPLACE / STORE nimmt man dann FieldGet() / FieldPut()
die CLASS wäre "Dual-fähig" für DBF und SQL wobei ich in diesem Thread von PostgreSQL sprechen möchte.
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12910
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: PostgreSQL native
hi Marcus & Carlo,
zunächst mal Danke für eurer Interesse und Antworten.
nun seit Ihr schon am Ende der Geschichte während es bei vielen noch gar nicht "klick" gemacht hat wie man ohne ISAM Emu auskommen soll
mit dem Demo von Phil Ide hat man zwar den "Kernel" für die "Kommunikation" mit einem PostgreSQL Server aber auch nicht mehr. Das Demo von Hector ist da schon weiter aber nicht für grosse Datenmengen optimiert.
Ich möchte auf dem Level von Hector weitermachen aber mit eigenen grossen Daten Mengen.
Dazu ist zunächst die Übertragung von DBF nach Table gemeint natürlich native und nicht mit dem Upsize Tool.
Bei Import von DBF in eine Table tritt das erste Problem auf : was für ein Daten Type unter SQL wenn ich eine Table anlege
über DbStruct() bekomme man die Information einer DBF Structure.
Das muss nun in die SQL Syntax von PostgreSQL bei der Qwery umgesetzt werden.
den String für die Qwery kann man so erstellennachdem die Table angelegt ist kommt Satzweise der Import aus der DBF
die Function cBin2Hex() ist aus ot4xb. damit kann ich Bilder im HEX Format speichern / lesen.
OEM_ANSI() und DE_SQLdate() sind Workaround wenn die Darstellung nicht stimmt.
die Geschwindigkeit bei 39 Feldern und 500000 Record liegt deutlich > 2000 INSERT / Sec.
---
Anmerkung :
wenn man es mit einer Transaction macht wird nach einem INSERT kein COMMIT ausgeführt.
gewöhnlich wird ein Rollback ausgeführt wenn er nicht durchkommt.
ansonsten wird am Ende ein COMMIT gesendet.
damit haben können wir nun die DBF übertragen ... und die Xbase++ Index Datei
Fortsetzung folgt ...
zunächst mal Danke für eurer Interesse und Antworten.
nun seit Ihr schon am Ende der Geschichte während es bei vielen noch gar nicht "klick" gemacht hat wie man ohne ISAM Emu auskommen soll
mit dem Demo von Phil Ide hat man zwar den "Kernel" für die "Kommunikation" mit einem PostgreSQL Server aber auch nicht mehr. Das Demo von Hector ist da schon weiter aber nicht für grosse Datenmengen optimiert.
Ich möchte auf dem Level von Hector weitermachen aber mit eigenen grossen Daten Mengen.
Dazu ist zunächst die Übertragung von DBF nach Table gemeint natürlich native und nicht mit dem Upsize Tool.
Bei Import von DBF in eine Table tritt das erste Problem auf : was für ein Daten Type unter SQL wenn ich eine Table anlege
über DbStruct() bekomme man die Information einer DBF Structure.
Das muss nun in die SQL Syntax von PostgreSQL bei der Qwery umgesetzt werden.
den String für die Qwery kann man so erstellen
Code: Alles auswählen
cQuery := "CREATE TABLE " + xtab + " ( "
aStrut := DBSTRUCT()
FOR i = 1 TO LEN( aStrut )
cQuery += aStrut[ i, 1 ]
DO CASE
CASE aStrut[ i, 2 ] = "C"
cQuery += " character(" + ALLTRIM( STR( aStrut[ i, 3 ] ) ) + "), "
CASE aStrut[ i, 2 ] = "N"
cQuery += " numeric(" + ALLTRIM( STR( aStrut[ i, 3 ] ) ) + ',' + ALLTRIM( STR( aStrut[ i, 4 ] ) ) + "), "
CASE aStrut[ i, 2 ] = "D"
cQuery += " date, "
CASE aStrut[ i, 2 ] = "L"
cQuery += " boolean, "
CASE aStrut[ i, 2 ] = "M"
IF ::lBlob = .T.
cQuery += " bytea, "
ELSE
cQuery += " text, " // FTS
ENDIF
CASE aStrut[ i, 2 ] = "V" // store as HEX String
cQuery += " bytea, "
ENDCASE
NEXT
// add "internal" Fields
//
cQuery += " __deleted boolean NOT NULL DEFAULT false, "
cQuery += " __record serial NOT NULL, "
cQuery += " __rowversion integer NOT NULL DEFAULT 0, "
cQuery += " __keyversion integer NOT NULL DEFAULT 0, "
cQuery += " __lock_owner integer NOT NULL DEFAULT 0, "
// Alaska have this
//
// CONSTRAINT artikel_pkey PRIMARY KEY (__record)
//
cQuery += " CONSTRAINT " + xtab + "_pkey PRIMARY KEY (__record)"
cQuery += " )" // NEED
oPG:exec("BEGIN" ) // START Transaction
IF ResultStatus( oPG, oMain )
ELSE
oMain:OutMsg( "Error no BEGIN" )
ENDIF
Code: Alles auswählen
// for every Record
//
cPreText := "INSERT INTO " + xtab + " VALUES("
DO WHILE .NOT. EOF()
nCount ++
lUseBlob := .F.
cIns := cPreText
FOR i = 1 TO LEN( aStrut )
DO CASE
CASE aStrut[ i, 2 ] = "C"
IF ::lANSI
// convert German Umlaute OEM "„”Ž™šá"
//
cIns += " '" + STRTRAN( ::OEM_ANSI( FIELDGET( i ) ), "'", '"' ) + "',"
ELSE
cIns += " '" + STRTRAN( ALLTRIM( FIELDGET( i ) ), "'", '"' ) + "',"
ENDIF
CASE aStrut[ i, 2 ] = 'N'
cIns += " " + ALLTRIM( STR( FIELDGET( i ), aStrut[ i, 3 ], aStrut[ i, 4 ] ) ) + ","
CASE aStrut[ i, 2 ] = 'D'
IF EMPTY( FIELDGET( i ) )
cIns += " NULL,"
ELSE
cIns += " '" + DE_SQLdate( FIELDGET( i ) ) + "',"
ENDIF
CASE aStrut[ i, 2 ] = "L"
cIns += " " + IF( FIELDGET( i ) = .T., "true, ", "false, " )
CASE aStrut[ i, 2 ] = 'M'
// if you have Bitmap in Memo
//
IF ::lBlob = .T.
cIns += " '\x" + cBin2Hex( FIELDGET( i ) ) + "',"
lUseBlob := .T.
ELSE
IF ::lANSI = .T.
cIns += " '" + STRTRAN( ::OEM_ANSI( FIELDGET( i ) ), "'", '"' ) + "',"
ELSE
cIns += " '" + STRTRAN( FIELDGET( i ), "'", '"' ) + "',"
ENDIF
ENDIF
CASE aStrut[ i, 2 ] = "V"
// better use Type "V"
//
cIns += " '\x" + cBin2Hex( FIELDGET( i ) ) + "',"
lUseBlob := .T.
ENDCASE
NEXT
// add "__deleted" default
//
cIns += "false," // "__deleted"
// use nextval() for Sequence !
//
cIns += "nextval('" + xtab + "___record_seq')" + "," // use nextval()
cIns += "0," // "__rowversion"
cIns += "0," // "__keyversion"
cIns += "0 " // "__lock_owner"
cIns += ")"
cIns := STRTRAN( cIns, CHR( 0 ), " " ) // if any CHR(0)
oPG:exec( cIns ) // now send Query
IF ResultStatus( oPG, oMain ) // get Result Status
OEM_ANSI() und DE_SQLdate() sind Workaround wenn die Darstellung nicht stimmt.
die Geschwindigkeit bei 39 Feldern und 500000 Record liegt deutlich > 2000 INSERT / Sec.
---
Anmerkung :
Code: Alles auswählen
oPG:exec("BEGIN" ) // START Transaction
...
oPG:exec("COMMIT" ) // END Transaction
gewöhnlich wird ein Rollback ausgeführt wenn er nicht durchkommt.
ansonsten wird am Ende ein COMMIT gesendet.
damit haben können wir nun die DBF übertragen ... und die Xbase++ Index Datei
Fortsetzung folgt ...
Zuletzt geändert von AUGE_OHR am Fr, 05. Jul 2019 7:16, insgesamt 1-mal geändert.
gruss by OHR
Jimmy
Jimmy
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9371
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: PostgreSQL native
Daran arbeitet Alaska seit fast zehn Jahren, Jim. Aber Du wirst das sicher in ein paar Wochen viel besser hinkriegen.
Eine Klassenmethode wie :Skip() bei SQLexpress bewegt den Cursor in einem Resultset. Das hat mit dem ISAM-Skip technisch fast nichts zu tun. Es ähnelt eher der Veränderung eines Arraypointers.
Eine Klassenmethode wie :Skip() bei SQLexpress bewegt den Cursor in einem Resultset. Das hat mit dem ISAM-Skip technisch fast nichts zu tun. Es ähnelt eher der Veränderung eines Arraypointers.
Herzlich,
Tom
Tom
- AUGE_OHR
- Marvin
- Beiträge: 12910
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: PostgreSQL native
hat sich jetzt überschnitten mit meinem Beitrag.Tom hat geschrieben: ↑Fr, 05. Jul 2019 7:15 Daran arbeitet Alaska seit fast zehn Jahren, Jim. Aber Du wirst das sicher in ein paar Wochen viel besser hinkriegen.
Eine Klassenmethode wie :Skip() bei SQLexpress bewegt den Cursor in einem Resultset. Das hat mit dem ISAM-Skip technisch fast nichts zu tun. Es ähnelt eher der Veränderung eines Arraypointers.
für DBF hat ich das Beispiel DbServer genannt wo die Method Skip() ein DbSkip() ist.
unter SQLexpress++ oder native kann man die Method nachbauen und hätte dann "seine" CLASS zum "navigieren".
beim ISAM "Denken" sind auch "unwichtige" Dinge die man bei SQL nicht "so" benötigt.
bei einer Qwery wird schon eine Beschränkung vorgenommen und das "navigieren" im "Filter" ist mit dem Konzept möglich.
wenn ich auf den ersten "Treffer" will dann wäre "1" doch zutreffend ... was schert mich der "Rest" ausserhalb des "Filter".
Alaska hätte auch das interne FIELD "__Record". Die Lösung wäre also eine neue Qwery zu senden wenn "1" als "__Record" gemeint ist.
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12910
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: PostgreSQL native
eine Frage an die Zweifler : warum meint Ihr hat Alaska die interne Index Felder mit dem gewaltigen Overhead
mal sehen ob ihr den selben (xBase) "Denk" Fehler wie Alaska macht ...
mal sehen ob ihr den selben (xBase) "Denk" Fehler wie Alaska macht ...
gruss by OHR
Jimmy
Jimmy
- Jan
- Marvin
- Beiträge: 14658
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Re: PostgreSQL native
Jimmy,
Dir ist schon klar daß das jetzt ziemlich großkotzig und neunmalklug über kommt?
Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
- Martin Altmann
- Foren-Administrator
- Beiträge: 16517
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 111 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Re: PostgreSQL native
Jimmy,
mich würde ja mal interessieren, wie Du das __Record performant in sync hältst, wenn ein DbPack() abgesetzt wird.
Das bei dem Neuanlegen eines Datensatzes mittels APPEND BLANK das Feld __Record mit dem nächstgrößeren Wert belegt wird, ist ja noch recht einfach mit Bordmitteln abbildbar (oder kennt Postgres kein Max()?).
Viele Grüße,
Martin
mich würde ja mal interessieren, wie Du das __Record performant in sync hältst, wenn ein DbPack() abgesetzt wird.
Das bei dem Neuanlegen eines Datensatzes mittels APPEND BLANK das Feld __Record mit dem nächstgrößeren Wert belegt wird, ist ja noch recht einfach mit Bordmitteln abbildbar (oder kennt Postgres kein Max()?).
Viele Grüße,
Martin
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9371
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: PostgreSQL native
Mit Verlaub, Jimmy, aber ich halte das für Blödsinn, was Du hier erzählst, aber mir ist auch nicht klar, worauf Du hinauswillst. Wenn Du mit ISAM und physikalischen Daten arbeitest, befindest Du Dich in einem völlig anderen Verhältnis zu Deinen Daten als in einer Clientsituation mit einem echten Datenbankserver, der Resultsets zurückliefert, also Snapshots aus der Datenmenge, die übrigens nicht notwendigerweise eine Tabelle komplett oder nur eine Tabelle abbilden. Du hast in dieser Variante keine Verlässlichkeit in Bezug auf die Aktualität der Daten. Du hast keine Kontrolle über die Konsistenz und Integrität, das macht alles der Server. Und ob Du nun irgendein Serial verwendest, ein AutoIncrement oder ein selbstdefiniertes Feld für die Datensatznummer (nur als ein Beispiel) - Du müsstest hier dafür Sorge tragen, dass es das Feld nur ein einziges Mal gibt, dass der Zahlenraum bis zur Tabellengröße abgedeckt ist und sich bei physischen Löschungen auch anpasst. Sonst hast Du keine Datensatznummer, sondern nur irgendeinen Identifier. Wenn Du aber mit Indexen arbeiten willst und musst, die wiederum auf derlei referenzieren (nicht nur im direkten Zugriff, sondern auch in der erweiterten Logik etwa mit OrdKeyNo() und ähnlichen Funktionen), dann musst Du dafür irgendwie sorgen. Wenn, und darum geht es im Kern, Deine Programmlogik darauf abzielt, dass sich die Daten so verhalten. Also beispielsweise erwartet, dass es etwas wie Locking geben kann, das tatsächlich sicherstellt, dass außer Dir gerade niemand mit einem konkreten Datensatz oder gar einer ganzen Tabelle arbeitet. Und, und, und, und. Der irre Overhead, den die PGDBE etabliert, trägt (fast) all dem Rechnung. Wenn man das nicht verwenden will oder muss, ist direktes SQL das Mittel der Wahl. Dieser Hybrid, mit dem Du hier hantierst, hat m.E. keinen Wert. Und irgendwie Skip oder Seek oder sonstwas auf einem Resultset nachbilden, das ist Pillepalle - und das können die ganzen Tools schon seit Jahren.
Herzlich,
Tom
Tom
- AUGE_OHR
- Marvin
- Beiträge: 12910
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: PostgreSQL native
hi Tom,
ich verstehe deine Bedenken aber meine Intention geht nicht so weit wie du wohl denkst.
---
ich kann leider keine DBE schreiben wo man Theoretisch keine Änderungen am Code vornehmen muss wenn man die DBE austauscht.
Ich kann aber eine CLASS wie DbServer schreiben nur eben für PostgreSQL.
Natürlich ist eine CLASS ein völlig anderes Konzept das man nicht einfach in bestehenden Code übernehmen kann.
Es ist aber die Möglichkeit JETZT damit Xbase++ Apps zu schreiben mit gewohnter Xbase++ OOP Syntax um einen PostgreSQL Server zu nutzen.
wie du an den Code Beispielen erkennen kannst hab ich die Internen FIELD von Alaska übernommen und auch die beiden Trigger. wenn die PgDBE mal so performen sollte wie erhofft dann könnte man die DbServer CLASS verwenden und die vorhandenen Table müssten von PgDBE erkannt werden und mit dem Code arbeiten.
es sind also 2 "Technische" Schritte die ich plane aber der Hauptteil sind die Qwerys die man unabhängig vom Client verwenden könnte.
---
p.s. auf eure "Technischen" Fragen werde ich später noch eingehen.
ich verstehe deine Bedenken aber meine Intention geht nicht so weit wie du wohl denkst.
---
ich kann leider keine DBE schreiben wo man Theoretisch keine Änderungen am Code vornehmen muss wenn man die DBE austauscht.
Ich kann aber eine CLASS wie DbServer schreiben nur eben für PostgreSQL.
Natürlich ist eine CLASS ein völlig anderes Konzept das man nicht einfach in bestehenden Code übernehmen kann.
Es ist aber die Möglichkeit JETZT damit Xbase++ Apps zu schreiben mit gewohnter Xbase++ OOP Syntax um einen PostgreSQL Server zu nutzen.
wie du an den Code Beispielen erkennen kannst hab ich die Internen FIELD von Alaska übernommen und auch die beiden Trigger. wenn die PgDBE mal so performen sollte wie erhofft dann könnte man die DbServer CLASS verwenden und die vorhandenen Table müssten von PgDBE erkannt werden und mit dem Code arbeiten.
es sind also 2 "Technische" Schritte die ich plane aber der Hauptteil sind die Qwerys die man unabhängig vom Client verwenden könnte.
---
p.s. auf eure "Technischen" Fragen werde ich später noch eingehen.
gruss by OHR
Jimmy
Jimmy
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2829
- Registriert: Fr, 08. Feb 2008 21:29
- Hat sich bedankt: 97 Mal
- Danksagung erhalten: 13 Mal
Re: PostgreSQL native
Hallo,
kann mir mal jemand sagen, was "native" bedeuten soll? Und auf welchen Kontext sich dieses Wort dann bezieht?
Die PGDBE ist "native" Xbase++. Sorry, aber so isses.
Also, hat einer eine Definition, damit ich weiss, wofür ich abgestimmt habe?
kann mir mal jemand sagen, was "native" bedeuten soll? Und auf welchen Kontext sich dieses Wort dann bezieht?
Die PGDBE ist "native" Xbase++. Sorry, aber so isses.
Also, hat einer eine Definition, damit ich weiss, wofür ich abgestimmt habe?
Liebe Grüsse aus der Eifel,
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2517
- Registriert: Mi, 28. Jul 2010 17:16
- Hat sich bedankt: 12 Mal
- Danksagung erhalten: 77 Mal
Re: PostgreSQL native
Hallo
native PG soll bedeuten Postgres ohne die PGDBE sondern ausschliesslich mit den Mittel der pdlib.dll und in xbase++ geschriebenem Code, Klassen usw. zu verwenden.
im obigen Beispiel hat JImmy noch einen desaströsen Fehler:
Um Strings sicher zu machen muss die Funktion PQescapeStringConn() verwendet werden. Damit wird dann ein Charakterfeld auch wirklich sicher und kann in einem Query an den Server gesandt werden. Weitere Infos finden sich in der Documentation von pqlib.dll
Ich finde Alaska hat den Job mit dem ISAM-EMU nicht schlecht gemacht. Es ist einfach schlicht weg gar nicht möglich die Funktion der DBFDBE mit Postgres zu emulieren so dass der eigene für eine DBF geschriebener Code noch mit guter Performace abläuft.
Wer Postgres will muss beginnen in SQL zu denken und wohl oder übel seinen Code entsprechend komplett überarbeiten. Oder bei DBF bleiben. Selbst eine DBE (ISAM-EMU) zu schreiben das sich dann wie eine DBE verhält und funktionert, so dass vorhandener alter Code ohne Anpassung läuft ist meiner Meinung nach gar nicht möglich.
native PG soll bedeuten Postgres ohne die PGDBE sondern ausschliesslich mit den Mittel der pdlib.dll und in xbase++ geschriebenem Code, Klassen usw. zu verwenden.
im obigen Beispiel hat JImmy noch einen desaströsen Fehler:
Sollte so aus verschiedenenen Gründen niemals, NIEMALS benuzt werden!!! Es gibt auch noch andere Zeichenfolgen die in einem String entschärft werden müssen.cIns += " '" + STRTRAN( ALLTRIM( FIELDGET( i ) ), "'", '"' ) + "',"
Um Strings sicher zu machen muss die Funktion PQescapeStringConn() verwendet werden. Damit wird dann ein Charakterfeld auch wirklich sicher und kann in einem Query an den Server gesandt werden. Weitere Infos finden sich in der Documentation von pqlib.dll
Ich finde Alaska hat den Job mit dem ISAM-EMU nicht schlecht gemacht. Es ist einfach schlicht weg gar nicht möglich die Funktion der DBFDBE mit Postgres zu emulieren so dass der eigene für eine DBF geschriebener Code noch mit guter Performace abläuft.
Wer Postgres will muss beginnen in SQL zu denken und wohl oder übel seinen Code entsprechend komplett überarbeiten. Oder bei DBF bleiben. Selbst eine DBE (ISAM-EMU) zu schreiben das sich dann wie eine DBE verhält und funktionert, so dass vorhandener alter Code ohne Anpassung läuft ist meiner Meinung nach gar nicht möglich.
Valar Morghulis
Gruss Carlo
Gruss Carlo
- AUGE_OHR
- Marvin
- Beiträge: 12910
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: PostgreSQL native
technische Antworten :
@Tom : wenn du die NextVal() nicht kennst liegt es daran das du dich wohl noch nicht mit PostgreSQL beschäftigt hast
damit ist "__Record" auch ein eindeutiger Identifer der nicht mit "navigieren" und OrdKeyNo() zu tun hat.
"live" Daten sind in xBase auch nicht vorhanden wenn man kein Refresh in einem Browse macht. vielmehr wird mit dem DbSkipper neu eingelesen.
auch ein Webbrowse muss Daten nachladen wenn ein aktueller Stand gewünscht ist.
---
@Martin
die Frage nach dem DbPack() hatte ich erwartet aber die Gegenfrage lautet : wo zu ein PACK ?
wenn überhaupt die Methode die man für Memo Dateien benötigt und das heisst in eine neue Datei kopieren und dann löschen / umbenennen. dabei wird "__Record" neu erstellt aber würde die selbe sein wie bei xBase.
klar darf bei solchen Aktionen kein anderer damit arbeiten aber das gibt auch für PACK.
ich benötige die "__Record" nur dann als Identifyer wenn ich mit dem Satz arbeiten will.
@Tom : wenn du die NextVal() nicht kennst liegt es daran das du dich wohl noch nicht mit PostgreSQL beschäftigt hast
bei Type Serial mit der PostgreSQL (!) Function "nextval()" gibt es KEINE Duppletten ... aber eine Error-Meldung.9.11 Funktionen zur Bearbeitung von Sequenzen
nextval(text) bigint Sequenz erhöhen und neuen Wert zurückgeben
currval(text) bigint Wert, der zuletzt durch nextval erzeugt wurde
setval(text, bigint) bigint aktuellen Wert der Sequenz setzen
setval(text, bigint,boolean) bigint aktuellen Wert der Sequenz und den Parameter is_called setzen
damit ist "__Record" auch ein eindeutiger Identifer der nicht mit "navigieren" und OrdKeyNo() zu tun hat.
"live" Daten sind in xBase auch nicht vorhanden wenn man kein Refresh in einem Browse macht. vielmehr wird mit dem DbSkipper neu eingelesen.
auch ein Webbrowse muss Daten nachladen wenn ein aktueller Stand gewünscht ist.
---
@Martin
die Frage nach dem DbPack() hatte ich erwartet aber die Gegenfrage lautet : wo zu ein PACK ?
wenn überhaupt die Methode die man für Memo Dateien benötigt und das heisst in eine neue Datei kopieren und dann löschen / umbenennen. dabei wird "__Record" neu erstellt aber würde die selbe sein wie bei xBase.
klar darf bei solchen Aktionen kein anderer damit arbeiten aber das gibt auch für PACK.
ich benötige die "__Record" nur dann als Identifyer wenn ich mit dem Satz arbeiten will.
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12910
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: PostgreSQL native
du hast mit PQescapeStringConn() grundsätzlich Recht ... wenn man solche Zeichen hat.ramses hat geschrieben: ↑Sa, 06. Jul 2019 0:00 Sollte so aus verschiedenenen Gründen niemals, NIEMALS benuzt werden!!! Es gibt auch noch andere Zeichenfolgen die in einem String entschärft werden müssen.
Um Strings sicher zu machen muss die Funktion PQescapeStringConn() verwendet werden. Damit wird dann ein Charakterfeld auch wirklich sicher und kann in einem Query an den Server gesandt werden.
ich verwende auch NICHT UTF-8 sondern Win 1252 und arbeitet mit OEM also sollte keine Zeichen > 128 vorkommen wo ich das beachten müsste.
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12910
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: PostgreSQL native
hi,
bis Windows NT waren die Zugriffe über DLL immer "native" und man kann per API mit der DLL "sprechen"
alle "echten" XbParts bestehen aus Windows Control die uns Alaska "verpackt" als CLASS liefern.
ich habe das selbe mit den Controls in dex DXE LIB gemacht und un neue XbParts geschaffen
in der PgDBE ist auch der Source von libpq.dll "verpackt".
ich mache das selbe nur nicht als DBE sondern als CLASS
ich würde "native" als "zurück zu den Grundlagen" definieren da man am Anfang startete
um mit Windows zu "sprechen" kann man kein xBase verwenden.
bis Windows NT waren die Zugriffe über DLL immer "native" und man kann per API mit der DLL "sprechen"
alle "echten" XbParts bestehen aus Windows Control die uns Alaska "verpackt" als CLASS liefern.
ich habe das selbe mit den Controls in dex DXE LIB gemacht und un neue XbParts geschaffen
in der PgDBE ist auch der Source von libpq.dll "verpackt".
ich mache das selbe nur nicht als DBE sondern als CLASS
ich würde "native" als "zurück zu den Grundlagen" definieren da man am Anfang startete
gruss by OHR
Jimmy
Jimmy