libmysql

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

Jolinah

Betreff: libmysql

BeitragFr, Mai 26, 2006 20:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Update
Download des Source inklusive C-Libs + MySQL-DLL für Windows:

Edit: Ich hab mal die modifizierte / verbesserte Version von Vertex hochgeladen, da ich meine aus versehen gelöscht hatte Wink
http://zehr.de/downloads/mysql102.zip


Update
Das Modul funktioniert jetzt mit Windows und Linux! Für Linux wird jedoch mindestens glibc 2.3 benötigt, wer Version 2.2 hat, der kann mal versuchen ob es mit der libmysqlclient.a für glibc 2.2 läuft. Diese Datei kann auf der offiziellen MySQL-Seite heruntergeladen werden. In meiner ZIP ist aber wie gesagt die Lib für Version 2.3 drin.

Die libmysql.bmx importiert nur die Lib und definiert die externen Funktionen, so wie einige Konstanten. Wer will kann nur diese Datei importieren und mit den echten mysql-Befehlen arbeiten. Ich habe jedoch eine BlitzMax Lib geschrieben (MySql.bmx) um den Umgang etwas zu erleichtern. Dabei ist noch eine test.bmx von mir, die es aber nicht braucht:

Code: [AUSKLAPPEN]
SuperStrict

Import "MySQL.bmx"

'Verbindung herstellen
Local mysql:TMySql = TMySql.Create("host", "user", "pass", "database")
If mysql = Null Then End

'Query
Local r:TMySql_Res = mysql.Query("SELECT * FROM test")

If r <> Null
   Print "Zeilen: " + r.Rows

   Local buf:Byte[] = Null
   Local bank:TBank = Null

   'Alle Zeilen durchgehen
   For Local row:TMySql_Row = EachIn r
      Print row.GetString(0)
      Print row.GetString(1)
      buf = row.GetByteArray(2)
      bank = row.GetBank(2)
      Print row.GetFloat(3)
      Print row.GetString(4)
   Next
   
   'Datei von Byte Array schreiben
   Local f:TStream = WriteStream("byte.txt")
   For Local b:Byte = EachIn buf
      WriteByte(f, b)
   Next
   f.Close()
   buf = Null
   
   'Datei von Bank schreiben
   f = WriteStream("bank.txt")
   For Local i:Int = 1 To BankSize(bank)
      WriteByte(f, PeekByte(bank, i-1))
   Next
   f.Close()
   bank = Null
   
   
   r.Free()
EndIf

'Verbindung schliessen
mysql.Close()

End


Hier noch eine kleine Übersicht der wichtigsten Types und Methoden:

Type TMySql
- Funktion Create (zum direkten erstellen eines Objekts und verbinden)
- Connect (zum verbinden, nachdem ein Objekt erstellt wurde)
- Query (MySQL Abfrage, gibt ein TMySql_Res zurück, oder Null)
- Close (trennen der Verbindung)
- AffectedRows (gibt zurück, wie viele Zeilen von der letzten Abfrage betroffen sind)

Type TMySql_Res
- Field_Info:MYSQL_FIELD[] (Array mit Spalteninformationen für jede Spalte)
- GetRow (gibt eine Zeile anhand des Index' zurück, TMySql_Row)
- Free (Gibt den Speicher frei, wird auch automatisch aufgerufen wenn der GC den Speicher frei gibt, oder bei manuellem GCCollect())

Type TMySql_Row
- GetString (gibt den Wert von Spalte i als String zurück)
- GetByteArray (gibt den Wert von Spalte i als Byte Array zurück (BLOB etc.))
- GetBank (gibt den Wert von Spalte i als Bank zurück (BLOB etc.))
- GetByte
- GetShort
- GetInt
- GetFloat
- GetDouble

Type MYSQL_FIELD (enthält Informationen über eine Spalte)
- Name:String (Name im Select, wenn ein ALIAS benutzt wurde)
- Org_Name:String (Originaler Spaltenname)
- Table:String (Name der Tabelle im Select, wenn ein ALIAS benutzt wurde)
- Org_Table:String (Originaler Tabellenname)
- Db:String (Datenbankname)
- Def:String (Standardwert dieser Spalte, wenn bei INSERT leer)
- Length:Int (Grösse des Feldes)
- FieldType:Int (Datentyp des Feldes, dafür gibts Konstanten in der libmysql.bmx)


PS: Ist eigentlich kein Modul, einfach Importieren Wink
  • Zuletzt bearbeitet von Jolinah am Mi, Nov 29, 2006 19:28, insgesamt 2-mal bearbeitet

Blacal

BeitragSo, Mai 28, 2006 15:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Servus

Sehr schön. Gute Arbeit!
Wennst nix dagegen hast, bau ichs in mein BlitzDB Modul ein ( https://www.blitzforum.de/foru...hp?t=17700 )

Aber was anderes: Welche Version von mysql hast du denn da benutzt?
Oder is das ne Clientbibliothek, die mit jedem Mysql-Server zusammenarbeitet?

Jolinah

BeitragSo, Mai 28, 2006 15:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke Wink

Ich habe die aktuell stabile Version benutzt, MySQL 5.0. Da ich nur eine Interface-Lib gemacht habe, die die Funktionen aus der DLL heraus aufruft sollte man da eigentlich für ne neue Version nur die DLL austauschen können. Es sei den die Funktionen haben sich verändert, oder es sind neue dazu gekommen.

In dem Fall muss man wohl eine neue Interface-Lib generieren lassen (libmysql.a) und die neuen Funktionen im Extern Block von libmysql.bmx eintragen.

Zum generieren einer Interface-Lib gibts ein praktisches Tool namens Reimp.exe bzw. Dlltool.exe (Diese werden normalerweise mit MinGW mitgeliefert)

Dann lädt man sich einfach das neue MySQL runter, und generiert mit "Reimp libmysql.lib" eine libmysql.a. Dann einfach die .a und die DLL ersetzen.


Würde mich freuen wenn du das in deinem Modul einbaust, oder den Teil davon den du brauchst Wink Meines Wissens dürfte ich dir das auch gar nicht verbieten, weil MySQL unter GPL steht, somit ist dann mein Modul eigentlich auch gleich GPL. Und streng genommen müsstest auch du dann wieder GPL einhalten, d.h. SourceCode anbieten, und keine komerziellen Produkte damit machen, etc.. ^^

Vertex

BeitragFr, Jun 02, 2006 13:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Sagmal ist es immer nötig bei MySQL zu einem MySQL Server zu connecten? Bei einem Spiel z. B. mit lokaler Highscore wäre es doch unsinnig noch einen Server zu starten.
Also gibt es da Lösungen ohne Server lokal?

Code: [AUSKLAPPEN]
While r.CurrentRow <> Null

Ich glaube, man kann in seinen Types(siehe TList) auch eine Anwendung für For XYZ EachIn XYZ schreiben. Da wäre dann Sprachangepasster.
mfg olli
 

SlasHeR

BeitragFr, Jun 02, 2006 21:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn du MySQL benutzten willst, brauchst du immer einen Server, da MySQLClient ja über Sockets läuft.

Für die Speicherung von Spieldaten lokal (d.h. bei einem Client/Singleplayer-Spiel) würde ich keine MySQL DB verwenden!
Es sei denn, du hast einen bestimmten Grund dafür...


Bei einem Server macht es allerdings schon mehr Sinn! Smile


Programmier dir halt ne Datenbank auf dateibasis.
In php gibs solche Projekte wie tuple-tup.

http://www.internalscripts.de/tuple-tub/


Aber wenns nur ne highscore ist brauchst doch keine Datenbank, oder?

Jolinah

BeitragFr, Jun 02, 2006 21:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Vertex hat Folgendes geschrieben:
Code: [AUSKLAPPEN]
While r.CurrentRow <> Null

Ich glaube, man kann in seinen Types(siehe TList) auch eine Anwendung für For XYZ EachIn XYZ schreiben. Da wäre dann Sprachangepasster.
mfg olli


Das wollte ich zuerst so machen, ich glaube man muss dazu 'nen Type schreiben der die Methode Next:Object() und HasNext() besitzt. Aus irgend einem Grund (weiss nicht mehr warum ^^) habe ich das aber nicht so gemacht.

Mir sind noch ein paar Bugs aufgefallen bei GetInt() usw.. Anscheinend werden die Daten immer als CString zurückgegeben, daher liefern die ganzen Funktionen die Zahlen zurückgeben sollen falsche Werte. Das heisst ich werde das Modul nochmal überarbeiten wenn ich Zeit habe und evtl. noch ein paar neue Funktionen einbauen. Dann mach ich wahrscheinlich auch das mit dem For Eachin noch rein.

Beim aktuellen Code sollte man daher statt GetInt(SpaltenIndex) das benutzen (wenn man sicher ist, dass es eine Zahlenspalte ist):

Code: [AUSKLAPPEN]
Int(GetString(SpaltenIndex))

Vertex

BeitragSa, Jun 03, 2006 10:13
Antworten mit Zitat
Benutzer-Profile anzeigen
SlasHeR: Ja, das war nur das kleinste Beispiel. Nehmen wir mal ein Programm zum Verwalten von Mitarbeitern, Ausgaben, Einnahmen usw., also eine richtig große DB für eine Firma. Ich denke nicht, dass man da soetwas selber programmiert. Das muss doch irgendwie gehen. Der MySQL Syntax ist es doch egal, ob die DB lokal in einer Datei oder auf irgendein Server liegt.

Jolinah: Jo, dann kannst du es ja gleich beim nächsten Update mit einbauen Smile
mfg olli
 

SlasHeR

BeitragSa, Jun 03, 2006 10:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Was du meinst ist SQL (Structured Query Language). MySQL ist nur etwas erweitert/verändert.
Z.b. gibt es ja auch MS SQLServer, Postgre SQL usw...

Vielleicht hilft dir ja das stichwort mdb-file weiter. Das ist ne Datei-Datenbank von MS.
tuple-tubs ist halt nix anderes.

Blacal

BeitragSa, Jun 03, 2006 10:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Servus

nimm SQLite
da hast du keinen Datenbankserver.

siehe https://www.blitzforum.de/foru...hp?t=17700

Jolinah

BeitragFr, Jun 09, 2006 0:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

Habe den ersten Post ein wenig editiert. Auf Wunsch von Vertex hab ich das Modul auch unter Linux lauffähig gemacht, zumindest läuft es auf meinem Linux Server Wink

Zusätzlich sind einige Fehler behoben, und man kann jetzt durch die Zeilen einer Abfrage wie gewünscht mit For.. EachIn iterieren.

Vertex

BeitragFr, Jun 09, 2006 11:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, danke! Noch eine Frage: Unter welcher Lizens steht deine Lib?
mfg olli

Jolinah

BeitragFr, Jun 09, 2006 11:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Da MySQL unter GPL steht, wird mein Modul somit auch zu GPL. Das heisst komerzielle Produkte sind mit diesem Modul nicht möglich. MySQL bietet aber noch eine zweite Lizenz für proprietäre Software an, die man jedoch zuerst erwerben muss. Ich weiss nur nicht ob sich so eine Lizenz dann ebenfalls auf dieses Modul auswirken würde.

Streng genommen würde das auch heissen, alle Projekte die dieses Modul benutzen und öffentlich angeboten werden, müssten auch den Source dazu geben.

Um das zu ändern müsste wahrscheinlich ich die Lizenz für proprietäre Software kaufen, damit ich das Modul dann unter meinen Bestimmungen weitergeben könnte. Da ich das Modul aber eh nicht verkaufe ist mir das ehrlich gesagt zu teuer ^^

Vertex

BeitragFr, Jun 09, 2006 15:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist ja ein Dreck mit der GPL. Anscheinend machen die aber damit das meiste Geld Razz

Ich habe mich mal ran gesetzt, und habe daraus ein modul gemacht:
http://vertex.dreamfall.at/mysql/mysql101.zip
Habe dazu einiges an den Namen geändert(Ästhetik muss sein Razz )

Jedenfalls ist mir aufgefallen:
Code: [AUSKLAPPEN]
Query = "INSERT INTO `scores` "+ ..
        "(`name`, `points`) "+ ..
        "VALUES('test', '100')"
Result = MySQL.Query(Query)
If Not Result Then
   Print("Error: Query failed")
   MySQL.Close()
   End
EndIf
Result.Free()

Er gibt hier einen Fehler aus("Query failed" halt). Warum?
In deinem Code ist es:
Code: [AUSKLAPPEN]
      _res = mysql_query(_mysql, query)

      If _res = 0
         _res = mysql_store_result(_mysql)
         If _res = 0 Then Return Null

die letzte Zeile, die Null zurück gibt. Also mysql_query gibt Null zurück, genauso wie mysql_store_result.

Bei mir ist es:
Code: [AUSKLAPPEN]
      Self.Result = mysql_query(Self.MySQL, Query)

      If Not Self.Result Then
         Self.Result = mysql_store_result(Self.MySQL)
         If Not Self.Result Then Return Null


Mir ist schon klar, dass INSERT INTO eigentlich ein Query ohne Resultat ist, jedoch muss ich ja wissen, ob ein Fehler aufgetreten ist.

Schau mal bitte dafür in das Example von mir.
mfg olli

Vertex

BeitragFr, Jun 09, 2006 15:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Und da habe ich auch schon den Fehler gefunden:
Zitat:
Sie müssen mysql_store_result() oder mysql_use_result() für jede Anfrage aufrufen, die erfolgreich Daten abruft (SELECT, SHOW, DESCRIBE, EXPLAIN).

Für andere Anfragen müssen Sie mysql_store_result() oder mysql_use_result() nicht aufrufen, es schadet aber auch nicht, noch führt es zu wahrnehmbaren Performance-Störungen, wenn Sie mysql_store_result() in jedem Fall aufrufen. Sie können feststellen, ob die Anfrage keine Ergebnismenge hatte, wenn Sie prüfen, ob mysql_store_result() 0 zurückgibt (mehr darüber später).

Wenn Sie wissen wollen, ob die Anfrage eine Ergebnismenge zurückgeben sollte oder nicht, können Sie hierfür mysql_field_count() benutzen. See Abschnitt 9.4.3.20, „mysql_field_count()“.

mysql_store_result() liest das gesamte Ergebnis einer Anfrage zum Client ein, weist eine MYSQL_RES-Struktur zu und platziert das Ergebnis in diese Struktur.

mysql_store_results() gibt einen NULL-Zeiger zurück, wenn die Anfrage keine Ergebnismenge zurückgab (wenn die Anfrage zum Beispiel ein INSERT-Statement war).


Man muss als ersteinmal mit mysql_field_count prüfen, ob überhaupt eine Ergebnismenge vorliegt, um dann erst zu prüfen ob mit mysql_store_result ein Fehler auftrat.

Edit:
http://vertex.dreamfall.at/mysql/mysql102.zip hier gibt es das neue Modul. Habe mal noch GetError in TMySQL eingebaut als Methode, das Beispiel nochmal korrigiert sowie TMySQLResult.GetString(und damit GetByte, Short usw. ebenfalls) schneller gemacht.

An Jolinah:
Code: [AUSKLAPPEN]
If Result.Columns = 0 Then Return Null
statts
Code: [AUSKLAPPEN]
If Result.Columns = 0 Or Result.Rows = 0 Then Return Null

wäre auch für deine Lib wichtig. Bei einer Anfrage ohne Ergebniszeilen würde sonst Null zurückgegeben werden.

mfg olli

Jolinah

BeitragFr, Jun 09, 2006 17:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Das hatte ich Absichtlich so gemacht, aber das ist wahrscheinlich Geschmackssache Wink Bei Inserts prüfen ob es erfolgreich ist kann man soviel ich weiss auch mit mysql.AffectedRows(). Wenn es grösser als 0 zurück gibt dann hats auf jedenfall was eingefügt, aktualisiert oder gelöscht. Und ansonsten könnte man auch noch mit den mysql_error-Funktionen etwas machen.

Farbfinsternis

BeitragFr, Jun 09, 2006 19:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn diese Lib (ich habe sie mir weder genau angeschaut noch getestet) den normalen Syntax, wie ihn bspw. PHP bereit stellt, unterstützt, kann man mit mysql_insertid() das letzte INSERT Query überprüfen. Funktioniert selbstverständlich nur wenn es einen INTEGER AUTOINCREMENT gibt.

Ansonsten sollte man auf die Ausgabe Wert legen die MySQL_Error() liefert.

Im Allgemeinen ist es sinnvoll bei derartigen Dingen etablierte Vorgehensweisen zu implementieren die einem PHP+MySQL Programmierer nicht vor Probleme stellen, so stellt man sicher dass das Modul von jedem fähigen DB User verwendet werden kann.
SQLite versucht dies, schafft es leider nicht immer. Aber sie sind konsequent im Ignorieren von Standards Wink
Farbfinsternis.tv

Vertex

BeitragSa, Nov 25, 2006 17:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Hat keiner eine Ahnung, wie man das ganze unter Linux zum laufen bringt?
mfg olli
vertex.dreamfall.at | GitHub
 

Ticha

BeitragDo, Feb 15, 2007 18:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi
ich hab mir dein Modul mal runtergeladen. Allerdings gibt er mir beim compilen deines exampels folgenden fehler:

Code: [AUSKLAPPEN]
Building highscore
Compiling:highscore.bmx
Compile Error: Can't find interface for module 'pub.mysql'
[C:/BlitzMaxClient/mysql102/examples/highscore.bmx;7;1]
Build Error: failed to compile C:/BlitzMaxClient/mysql102/examples/highscore.bmx
Process complete


hab ich da irgendwas falsch gemacht? (unter windows)

Jolinah

BeitragDo, Feb 15, 2007 18:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Du musst wahrscheinlich zuerst das Modul kompilieren. Program -> Build Modules (dadurch werden aber alle Module kompiliert).
 

Ticha

BeitragDo, Feb 15, 2007 20:38
Antworten mit Zitat
Benutzer-Profile anzeigen
hmm... also ich habe die datei nun in die pub.mod im BlitzMax ordner kopiert, bzw den order mysql.mod

wenn ich aber versuche auf program-> build mpdul zu gehen, wird mir angezeigt, dass ich es nicht benutzen kann, bzw nich anklicken kann. sry bin noch reltiv frisch in BM, aber wie binde ich das Modul in BM an?

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group