Merge branch gambas:master into master

This commit is contained in:
W. Raets 2023-07-16 11:39:18 +00:00
commit d8e8ffa922
30 changed files with 7860 additions and 7800 deletions

File diff suppressed because it is too large Load diff

View file

@ -95,6 +95,7 @@ Static Private Sub InitComponentNames()
$cName["gb.gui.opengl"] = ("OpenGL with QT/GTK+ switcher component") $cName["gb.gui.opengl"] = ("OpenGL with QT/GTK+ switcher component")
$cName["gb.gui.webview"] = ("QT/GTK+ web browser switcher component") $cName["gb.gui.webview"] = ("QT/GTK+ web browser switcher component")
$cName["gb.gui.qt"] = ("QT4/QT5 switcher component") $cName["gb.gui.qt"] = ("QT4/QT5 switcher component")
$cName["gb.gui.qt.ext"] = ("QT4/QT5 extension switcher component")
$cName["gb.gui.qt.opengl"] = ("QT4/QT5 OpenGL switcher component") $cName["gb.gui.qt.opengl"] = ("QT4/QT5 OpenGL switcher component")
$cName["gb.gui.qt.webkit"] = ("QT4/QT5 WebKit switcher component") $cName["gb.gui.qt.webkit"] = ("QT4/QT5 WebKit switcher component")
$cName["gb.gui.trayicon"] = ("System tray icon management component") $cName["gb.gui.trayicon"] = ("System tray icon management component")

View file

@ -348,8 +348,8 @@ Private Sub CreateProject() As Boolean
sTemplate = $hTemplate.Current.Path sTemplate = $hTemplate.Current.Path
Project.CopyProject(sTemplate, sDir) Project.CopyProject(sTemplate, sDir)
Shell "rm -rf " & Shell$(sDir &/ ".lang") Wait Shell "rm -rf " & Shell$(sDir &/ ".lang") Wait
Shell "rm -rf " & Shell$(sDir &/ ".hidden") Wait
Try Kill sDir &/ "icon.png" Try Kill sDir &/ "icon.png"
sTemp = Temp$() sTemp = Temp$()

View file

@ -214,3 +214,16 @@ Public Sub Find(Where As String, ...)
$hForm.DataView.Find(Where, ...) $hForm.DataView.Find(Where, ...)
End End
Public Sub FindNext(Where As String, ...)
$hForm.DataView.FindNext(Where, ...)
End
Public Sub MoveTo(Index As Integer)
$hForm.DataView.MoveTo(Index)
End

View file

@ -391,7 +391,7 @@ Public Sub _CreateCurrent() As Result
Dim hSrc As DataSource Dim hSrc As DataSource
Dim sKey As String Dim sKey As String
rData = _GetDB().Create($sTable) rData = _GetDB().Create($sTable, True)
hSrc = GetParent() hSrc = GetParent()
If hSrc Then If hSrc Then
@ -413,6 +413,7 @@ Public Function Save(Optional bMessage As Boolean = True) As Boolean
Dim iInd As Integer Dim iInd As Integer
Dim aVal As Variant[] Dim aVal As Variant[]
Dim bCancel As Boolean Dim bCancel As Boolean
Dim iIndex As Integer
If $bSaving Then Return True If $bSaving Then Return True
@ -454,16 +455,24 @@ Public Function Save(Optional bMessage As Boolean = True) As Boolean
Endif Endif
Next Next
aVal = New Variant[aKey.Count] iIndex = -1
For iInd = 0 To aKey.Max
aVal[iInd] = rData[aKey[iInd]]
Next
bCancel = Raise BeforeSave(rData) bCancel = Raise BeforeSave(rData)
If Not bCancel Then rData.Update If Not bCancel Then
rData.Update
aVal = New Variant[aKey.Count]
For iInd = 0 To aKey.Max
aVal[iInd] = rData[aKey[iInd]]
Next
iIndex = Find(Replace(Common.MakeWhere(aKey, aVal), "&", "&&"))
Endif
Redraw(True) Redraw(True)
If Not $bCheckModified Then Create(True) If Not $bCheckModified Then Create(True)
$iIndex = iIndex
Redraw
Else Else
@ -573,13 +582,13 @@ End
Public Function Find(Where As String, ...) As Integer Public Function Find(Where As String, ...) As Integer
Return $hTable.Find($DB.Subst(Where, ...)) Return $hTable.Find(_GetDB().Subst(Where, ...))
End End
Public Function FindNext(Index As Integer, Where As String, ...) As Integer Public Function FindNext(Index As Integer, Where As String, ...) As Integer
Return $hTable.Find($DB.Subst(Where, ...), Index) Return $hTable.Find(_GetDB().Subst(Where, ...), Index)
End End

View file

@ -167,17 +167,10 @@ End
Public Sub Find(sWhere As String, Optional iFrom As Integer) As Integer Public Sub Find(sWhere As String, Optional iFrom As Integer) As Integer
Dim sReq As String Dim sReq As String
Dim aSort As String[]
Dim I As Integer
Dim sSelect As String Dim sSelect As String
Dim rFind As Result Dim rFind As Result
aSort = GetSortKeys().Copy() sSelect = "ROW_NUMBER() OVER (" & $DB.SQL.OrderBy(GetSortKeys())() & ") AS __index"
For I = 0 To aSort.Max
aSort[I] = $DB.Quote(aSort[I])
Next
sSelect = "ROW_NUMBER() OVER (ORDER BY " & aSort.Join() & ") AS __index"
sReq = $DB.SQL.Select([sSelect, "*"]).From($sTable).Where($sFilter)() sReq = $DB.SQL.Select([sSelect, "*"]).From($sTable).Where($sFilter)()
sReq = "SELECT * FROM (" & sReq & ") WHERE " & sWhere sReq = "SELECT * FROM (" & sReq & ") WHERE " & sWhere

View file

@ -275,7 +275,6 @@ Public Sub Update()
End End
Private Function Columns_Read() As String[] Private Function Columns_Read() As String[]
Return $aColumns.Copy() Return $aColumns.Copy()
@ -684,11 +683,12 @@ Public Sub TableView_Save(Row As Integer, Column As Integer, Value As String)
iRow = $hCtrl.Row iRow = $hCtrl.Row
iCol = $hCtrl.Column iCol = $hCtrl.Column
If hSrc.MoveTo(Row) Then Return
If Row <> $iRowNewRecord Then If Row <> $iRowNewRecord Then
If hSrc.MoveTo(Row) Then Return
rData = hSrc._EditCurrent() rData = hSrc._EditCurrent()
If Not rData.Available Then Return If Not rData.Available Then Return
Else
hSrc.MoveTo(-1)
Endif Endif
hField = $aType[Column] hField = $aType[Column]
@ -803,10 +803,7 @@ End
Public Sub MoveNext() Public Sub MoveNext()
If $bCreate Then If $bCreate Then Return
MoveFirst
Return
Endif
If $hCtrl.Row >= $hCtrl.Rows.Max Then Return If $hCtrl.Row >= $hCtrl.Rows.Max Then Return
If $hCtrl.Row < 0 Then Return If $hCtrl.Row < 0 Then Return
Inc $hCtrl.Row Inc $hCtrl.Row
@ -817,7 +814,7 @@ End
Public Sub MovePrevious() Public Sub MovePrevious()
If $bCreate Then If $bCreate Then
MoveFirst MoveLast
Return Return
Endif Endif
If $hCtrl.Row <= 0 Then Return If $hCtrl.Row <= 0 Then Return
@ -828,6 +825,8 @@ End
Public Sub MoveTo(Index As Integer) Public Sub MoveTo(Index As Integer)
If Index = Index_Read() Then Return
If $bCreate Then $hCtrl.Row = -1
SetCreate(False) SetCreate(False)
$hCtrl.Row = Index $hCtrl.Row = Index
$hCtrl.Rows[$hCtrl.Row].Selected = True $hCtrl.Rows[$hCtrl.Row].Selected = True
@ -1308,6 +1307,15 @@ Public Sub Find(Where As String, ...)
Dim iIndex As Integer Dim iIndex As Integer
iIndex = GetSource().Find(Where, ...)
MoveTo(iIndex)
End
Public Sub FindNext(Where As String, ...)
Dim iIndex As Integer
iIndex = GetSource().FindNext(Index_Read() + 1, Where, ...) iIndex = GetSource().FindNext(Index_Read() + 1, Where, ...)
MoveTo(iIndex) MoveTo(iIndex)

View file

@ -66,6 +66,7 @@ Public Sub btnSave_Click()
dvwBrowser.Save dvwBrowser.Save
$hSrc.Save $hSrc.Save
dvwBrowser.MoveTo($hSrc.Index)
End End

View file

@ -71,7 +71,7 @@ Public Sub DataSource1_BeforeDelete(Keys As Variant[])
Next Next
Print Print
Stop Event 'Stop Event
End End
@ -81,3 +81,22 @@ Public Sub DataSource1_Invalid(Field As String)
Stop Event Stop Event
End End
Public Sub Button2_Click()
DataBrowser1.MoveTo(2)
End
Public Sub btnFind_Click()
Dim iId As Integer
Try iId = CInt(txtId.Text)
If iId = 0 Then Return
iId = DataSource1.Find("id = &1", iId)
'DataSource1.MoveTo(iId)
DataBrowser1.MoveTo(iId)
End

View file

@ -6,10 +6,25 @@
Arrangement = Arrange.Vertical Arrangement = Arrange.Vertical
Spacing = True Spacing = True
Margin = True Margin = True
{ Button1 Button { Panel2 HBox
MoveScaled(1,0,16,4) MoveScaled(1,0,72,4)
Visible = False Spacing = True
Text = ("Refresh") { Button1 Button
MoveScaled(0,0,16,4)
Visible = False
Text = ("Refresh")
}
{ Button2 Button
MoveScaled(17,0,16,4)
Text = ("Move")
}
{ txtId TextBox
MoveScaled(34,0,15,4)
}
{ btnFind Button
MoveScaled(51,0,16,4)
Text = ("Find")
}
} }
{ DataSource2 DataSource { DataSource2 DataSource
MoveScaled(3,5,69,87) MoveScaled(3,5,69,87)
@ -30,6 +45,7 @@
Arrangement = Arrange.Fill Arrangement = Arrange.Fill
Spacing = True Spacing = True
Table = "test" Table = "test"
Sort = "color"
{ Panel1 VSplit { Panel1 VSplit
MoveScaled(1,2,62,64) MoveScaled(1,2,62,64)
Spacing = True Spacing = True
@ -115,7 +131,6 @@
} }
{ DataCheckBox1 DataCheckBox { DataCheckBox1 DataCheckBox
MoveScaled(1,23,34,4) MoveScaled(1,23,34,4)
Text = ("Active")
Field = "active" Field = "active"
} }
{ DataControl7 DataControl { DataControl7 DataControl

View file

@ -3,7 +3,7 @@
Public Sub Main() Public Sub Main()
Dim hConn As Connection Dim hConn As Connection
'Dim rResult As Result Dim rResult As Result
' hConn = New Connection("mysql://root@localhost/test") ' hConn = New Connection("mysql://root@localhost/test")
' hConn.Password = "mysql" ' hConn.Password = "mysql"
@ -12,8 +12,12 @@ Public Sub Main()
hConn.Open hConn.Open
Print DB.Version
Print DB.FullVersion
Print DB.FormatBlob("'gambas' is not a blob\n") Print DB.FormatBlob("'gambas' is not a blob\n")
rResult = DB.Create("Test", True)
' rResult = hConn.Find("test") ' rResult = hConn.Find("test")
' For Each rResult ' For Each rResult
' Print rResult["image"].Length;; Len(rResult["image"].Data) ' Print rResult["image"].Length;; Len(rResult["image"].Data)

View file

@ -591,25 +591,26 @@ static int do_query_cached(DB_DATABASE *db, const char *error, MYSQL_RES **pres,
} }
/* Internal function to return database version number as a XXYYZZ integer number*/ // Internal function to get database version
static int db_version(DB_DATABASE *db) static void init_version(DB_DATABASE *db)
{ {
//Check db version const char *query = "select version()";
const char *vquery = "select left(version(),6)"; char *version;
long dbversion =0; uint verMain, verMajor, verMinor;
MYSQL_RES *res; MYSQL_RES *res;
MYSQL_ROW row;
if (!do_query(db, NULL, &res, vquery, 0)) if (!do_query(db, NULL, &res, query, 0))
{ {
unsigned int verMain, verMajor, verMinor; version = mysql_fetch_row(res)[0];
row = mysql_fetch_row(res);
sscanf(row[0],"%2u.%2u.%2u", &verMain, &verMajor, &verMinor); db->full_version = GB.NewZeroString(version);
dbversion = ((verMain * 10000) + (verMajor * 100) + verMinor);
sscanf(version, "%2u.%2u.%2u", &verMain, &verMajor, &verMinor);
db->version = ((verMain * 10000) + (verMajor * 100) + verMinor);
mysql_free_result(res); mysql_free_result(res);
} }
return dbversion;
} }
/* Search in the first column a result for a specific name */ /* Search in the first column a result for a specific name */
@ -975,7 +976,7 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db)
} }
db->handle = conn; db->handle = conn;
db->version = db_version(db); init_version(db);
set_character_set(db); set_character_set(db);

View file

@ -858,7 +858,9 @@ fflush(stderr);
odbc->user_name = malloc(sizeof(char) * strlen(user)); odbc->user_name = malloc(sizeof(char) * strlen(user));
strcpy(odbc->user_name, user); strcpy(odbc->user_name, user);
// TODO: Use SQLGetInfo() to retrieve the DBMS version string
db->version = 3; db->version = 3;
db->full_version = GB.NewZeroString("3");
retcode = SQLGetFunctions(odbc->odbcHandle, SQL_API_SQLFETCHSCROLL, &odbc->drvrCanFetchScroll); retcode = SQLGetFunctions(odbc->odbcHandle, SQL_API_SQLFETCHSCROLL, &odbc->drvrCanFetchScroll);
if (!SQL_SUCCEEDED(retcode)) if (!SQL_SUCCEEDED(retcode))

View file

@ -544,14 +544,13 @@ static int do_query(DB_DATABASE *db, const char *error, PGresult **pres, const c
return ret; return ret;
} }
/* Internal function to check database version number */ // Internal function to get database version
static int db_version(DB_DATABASE *db) static void init_version(DB_DATABASE *db)
{ {
unsigned int verMain = 0, verMajor = 0, verMinor = 0; unsigned int verMain = 0, verMajor = 0, verMinor = 0;
const char *query = "select version()"; const char *query = "select version()";
const char *version; const char *version;
int dbversion = 0;
PGresult *res; PGresult *res;
if (!do_query(db, NULL, &res, query, 0)) if (!do_query(db, NULL, &res, query, 0))
@ -563,14 +562,14 @@ static int db_version(DB_DATABASE *db)
if (*version) if (*version)
{ {
db->full_version = GB.NewZeroString(version);
sscanf(version, "%2u.%2u.%2u", &verMain, &verMajor, &verMinor); sscanf(version, "%2u.%2u.%2u", &verMain, &verMajor, &verMinor);
dbversion = ((verMain * 10000) + (verMajor * 100) + verMinor); db->version = ((verMain * 10000) + (verMajor * 100) + verMinor);
} }
PQclear(res); PQclear(res);
} }
return dbversion;
} }
/* Internal function that fills field information from a schema request. /* Internal function that fills field information from a schema request.
@ -785,7 +784,9 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db)
/* get version */ /* get version */
db->handle = conn; db->handle = conn;
db->version = db_version(db);
init_version(db);
db->data = (void *)0; // transaction level db->data = (void *)0; // transaction level
if (db->version >= 90000) if (db->version >= 90000)
@ -817,6 +818,7 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db)
//db->flags.no_case = TRUE; //db->flags.no_case = TRUE;
db->flags.schema = TRUE; db->flags.schema = TRUE;
db->flags.no_collation = db->version < 90100; db->flags.no_collation = db->version < 90100;
db->flags.no_returning = db->version < 80200; // It seems that RETURNING has been introduced in PostgreSQL 8.2
/* encoding */ /* encoding */

View file

@ -484,17 +484,21 @@ static int WalkDirectory(const char *dir, char ***databases)
return GB.Count(databases); return GB.Count(databases);
} }
/* Internal function to check database version number */ // Internal function to get database version
int db_version()
static int init_version(DB_DATABASE *db)
{ {
//Check db version const char *version;
int dbversion =0;
unsigned int verMain, verMajor, verMinor; unsigned int verMain, verMajor, verMinor;
sscanf(sqlite_version,"%2u.%2u.%2u", &verMain, &verMajor, &verMinor);
dbversion = ((verMain * 10000) + (verMajor * 100) + verMinor); version = sqlite_libversion();
return dbversion; db->full_version = GB.NewZeroString(version);
sscanf(version, "%2u.%2u.%2u", &verMain, &verMajor, &verMinor);
db->version = ((verMain * 10000) + (verMajor * 100) + verMinor);
} }
/***************************************************************************** /*****************************************************************************
get_quote() get_quote()
@ -581,7 +585,7 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db)
db->charset = GB.NewZeroString(strcmp(sqlite_encoding, "iso8859") == 0 ? "ISO-8859-1" : "UTF-8"); db->charset = GB.NewZeroString(strcmp(sqlite_encoding, "iso8859") == 0 ? "ISO-8859-1" : "UTF-8");
/* set dbversion */ /* set dbversion */
db->version = db_version(); init_version(db);
/* flags */ /* flags */
db->flags.no_table_type = TRUE; db->flags.no_table_type = TRUE;
@ -589,6 +593,7 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db)
db->flags.no_blob = TRUE; db->flags.no_blob = TRUE;
db->flags.no_nest = TRUE; db->flags.no_nest = TRUE;
db->flags.no_collation = TRUE; db->flags.no_collation = TRUE;
db->flags.no_returning = TRUE;
db->db_name_char = "."; db->db_name_char = ".";

View file

@ -500,19 +500,22 @@ static int walk_directory(const char *dir, char ***databases)
} }
/* Internal function to check database version number */ // Internal function to get database version
static int db_version()
static void init_version(DB_DATABASE *db)
{ {
//Check db version const char *version;
int dbversion = 0;
unsigned int verMain, verMajor, verMinor; unsigned int verMain, verMajor, verMinor;
sscanf(sqlite3_libversion(), "%2u.%2u.%2u", &verMain, &verMajor, &verMinor); version = sqlite3_libversion();
dbversion = ((verMain * 10000) + (verMajor * 100) + verMinor); db->full_version = GB.NewZeroString(version);
return dbversion;
sscanf(version, "%2u.%2u.%2u", &verMain, &verMajor, &verMinor);
db->version = ((verMain * 10000) + (verMajor * 100) + verMinor);
} }
/* Get the schema of a table */ // Get the schema of a table
static char *get_table_schema(DB_DATABASE *db, const char *table) static char *get_table_schema(DB_DATABASE *db, const char *table)
{ {
char *schema = NULL; char *schema = NULL;
@ -598,8 +601,8 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db)
} }
db->handle = conn; db->handle = conn;
/* set dbversion */
db->version = db_version(); init_version(db);
if (do_query(db, "Unable to initialize connection: &1", NULL, "PRAGMA empty_result_callbacks = ON", 0)) if (do_query(db, "Unable to initialize connection: &1", NULL, "PRAGMA empty_result_callbacks = ON", 0))
goto CANNOT_OPEN; goto CANNOT_OPEN;
@ -623,6 +626,7 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db)
/* flags */ /* flags */
db->flags.no_table_type = TRUE; db->flags.no_table_type = TRUE;
db->flags.no_nest = TRUE; db->flags.no_nest = TRUE;
db->flags.no_returning = db->version < 33500; // RETURNING keyword has been introduced in SQLite 3.35.0
db->db_name_char = "."; db->db_name_char = ".";

View file

@ -137,6 +137,7 @@ lib/gui.webview/Makefile \
lib/gui.qt/Makefile \ lib/gui.qt/Makefile \
lib/gui.qt.webkit/Makefile \ lib/gui.qt.webkit/Makefile \
lib/gui.qt.opengl/Makefile \ lib/gui.qt.opengl/Makefile \
lib/gui.qt.ext/Makefile \
lib/gui.trayicon/Makefile \ lib/gui.trayicon/Makefile \
lib/image/Makefile \ lib/image/Makefile \
lib/image.effect/Makefile \ lib/image.effect/Makefile \

View file

@ -1,2 +1,2 @@
SUBDIRS = debug eval db compress vb option geom draw image gui gui.opengl gui.qt gui.qt.webkit gui.qt.opengl image.effect signal term complex data clipper gui.trayicon gui.webview @INOTIFY_DIR@ jit test hash SUBDIRS = debug eval db compress vb option geom draw image gui gui.opengl gui.qt gui.qt.webkit gui.qt.opengl gui.qt.ext image.effect signal term complex data clipper gui.trayicon gui.webview @INOTIFY_DIR@ jit test hash
EXTRA_DIST = gb.component EXTRA_DIST = gb.component

View file

@ -145,6 +145,7 @@ static void close_connection(CCONNECTION *_object)
THIS->driver->Close(&THIS->db); THIS->driver->Close(&THIS->db);
GB.FreeString(&THIS->db.charset); GB.FreeString(&THIS->db.charset);
GB.FreeString(&THIS->db.full_version);
THIS->db.handle = NULL; THIS->db.handle = NULL;
THIS->driver = NULL; THIS->driver = NULL;
@ -210,6 +211,16 @@ BEGIN_PROPERTY(Connection_Version)
END_PROPERTY END_PROPERTY
BEGIN_PROPERTY(Connection_FullVersion)
CHECK_DB();
CHECK_OPEN();
GB.ReturnString(THIS->db.full_version);
END_PROPERTY
BEGIN_PROPERTY(Connection_Timeout) BEGIN_PROPERTY(Connection_Timeout)
if (READ_PROPERTY) if (READ_PROPERTY)
@ -466,7 +477,7 @@ BEGIN_METHOD(Connection_Exec, GB_STRING query; GB_VALUE param[0])
END_METHOD END_METHOD
BEGIN_METHOD(Connection_Create, GB_STRING table) BEGIN_METHOD(Connection_Create, GB_STRING table; GB_BOOLEAN ret)
CRESULT *result; CRESULT *result;
char *table = GB.ToZeroString(ARG(table)); char *table = GB.ToZeroString(ARG(table));
@ -483,7 +494,14 @@ BEGIN_METHOD(Connection_Create, GB_STRING table)
result = DB_MakeResult(THIS, RESULT_CREATE, table, NULL); result = DB_MakeResult(THIS, RESULT_CREATE, table, NULL);
if (result) if (result)
{
if (THIS->db.flags.no_returning)
DB_Debug("gb.db", "'RETURNING' keyword is not supported by this '%s' connection", THIS->driver->name);
else
result->returning = VARGOPT(ret, FALSE);
GB.ReturnObject(result); GB.ReturnObject(result);
}
else else
GB.ReturnNull(); GB.ReturnNull();
@ -759,6 +777,7 @@ GB_DESC CConnectionDesc[] =
//GB_PROPERTY("Timezone", "i", Connection_Timezone), //GB_PROPERTY("Timezone", "i", Connection_Timezone),
GB_PROPERTY_READ("Charset", "s", Connection_Charset), GB_PROPERTY_READ("Charset", "s", Connection_Charset),
GB_PROPERTY_READ("Version", "i", Connection_Version), GB_PROPERTY_READ("Version", "i", Connection_Version),
GB_PROPERTY_READ("FullVersion", "s", Connection_FullVersion),
GB_PROPERTY_READ("Opened", "b", Connection_Opened), GB_PROPERTY_READ("Opened", "b", Connection_Opened),
GB_PROPERTY_READ("Error", "i", Connection_Error), GB_PROPERTY_READ("Error", "i", Connection_Error),
//GB_PROPERTY_READ("Transaction", "i", Connection_Transaction), //GB_PROPERTY_READ("Transaction", "i", Connection_Transaction),
@ -773,7 +792,7 @@ GB_DESC CConnectionDesc[] =
GB_METHOD("Limit", "Connection", Connection_Limit, "(Limit)i"), GB_METHOD("Limit", "Connection", Connection_Limit, "(Limit)i"),
GB_METHOD("Exec", "Result", Connection_Exec, "(Request)s(Arguments)."), GB_METHOD("Exec", "Result", Connection_Exec, "(Request)s(Arguments)."),
GB_METHOD("Create", "Result", Connection_Create, "(Table)s"), GB_METHOD("Create", "Result", Connection_Create, "(Table)s[(Return)b]"),
GB_METHOD("Find", "Result", Connection_Find, "(Table)s[(Request)s(Arguments).]"), GB_METHOD("Find", "Result", Connection_Find, "(Table)s[(Request)s(Arguments).]"),
GB_METHOD("Edit", "Result", Connection_Edit, "(Table)s[(Request)s(Arguments).]"), GB_METHOD("Edit", "Result", Connection_Edit, "(Table)s[(Request)s(Arguments).]"),
GB_METHOD("Delete", NULL, Connection_Delete, "(Table)s[(Request)s(Arguments).]"), GB_METHOD("Delete", NULL, Connection_Delete, "(Table)s[(Request)s(Arguments).]"),
@ -817,6 +836,7 @@ GB_DESC CDBDesc[] =
GB_STATIC_PROPERTY_READ("Charset", "s", Connection_Charset), GB_STATIC_PROPERTY_READ("Charset", "s", Connection_Charset),
GB_STATIC_PROPERTY_READ("Version", "i", Connection_Version), GB_STATIC_PROPERTY_READ("Version", "i", Connection_Version),
GB_STATIC_PROPERTY_READ("FullVersion", "s", Connection_FullVersion),
GB_STATIC_PROPERTY_READ("Opened", "b", Connection_Opened), GB_STATIC_PROPERTY_READ("Opened", "b", Connection_Opened),
GB_STATIC_PROPERTY_READ("Error", "i", Connection_Error), GB_STATIC_PROPERTY_READ("Error", "i", Connection_Error),
//GB_STATIC_PROPERTY_READ("Transaction", "i", Connection_Transaction), //GB_STATIC_PROPERTY_READ("Transaction", "i", Connection_Transaction),
@ -830,7 +850,7 @@ GB_DESC CDBDesc[] =
GB_STATIC_METHOD("Limit", "Connection", Connection_Limit, "(Limit)i"), GB_STATIC_METHOD("Limit", "Connection", Connection_Limit, "(Limit)i"),
GB_STATIC_METHOD("Exec", "Result", Connection_Exec, "(Request)s(Arguments)."), GB_STATIC_METHOD("Exec", "Result", Connection_Exec, "(Request)s(Arguments)."),
GB_STATIC_METHOD("Create", "Result", Connection_Create, "(Table)s"), GB_STATIC_METHOD("Create", "Result", Connection_Create, "(Table)s[(Return)b]"),
GB_STATIC_METHOD("Find", "Result", Connection_Find, "(Table)s[(Request)s(Arguments).]"), GB_STATIC_METHOD("Find", "Result", Connection_Find, "(Table)s[(Request)s(Arguments).]"),
GB_STATIC_METHOD("Edit", "Result", Connection_Edit, "(Table)s[(Request)s(Arguments).]"), GB_STATIC_METHOD("Edit", "Result", Connection_Edit, "(Table)s[(Request)s(Arguments).]"),
GB_STATIC_METHOD("Delete", NULL, Connection_Delete, "(Table)s[(Request)s(Arguments).]"), GB_STATIC_METHOD("Delete", NULL, Connection_Delete, "(Table)s[(Request)s(Arguments).]"),

View file

@ -653,9 +653,14 @@ END_METHOD
BEGIN_METHOD_VOID(Result_Update) BEGIN_METHOD_VOID(Result_Update)
int i; int i, j;
bool comma; bool comma;
DB_INFO *info = &THIS->info; DB_INFO *info = &THIS->info;
int ret_first = -1;
int ret_count = 0;
GB_VARIANT_VALUE *ret_buffer = NULL;
bool err;
DB_RESULT res;
if (check_available(THIS)) if (check_available(THIS))
return; return;
@ -717,8 +722,59 @@ BEGIN_METHOD_VOID(Result_Update)
q_add(" )"); q_add(" )");
if (!THIS->driver->Exec(&THIS->conn->db, q_get(), NULL, "Cannot create record: &1")) if (THIS->returning)
void_buffer(THIS); {
comma = FALSE;
for (i = 0; i < info->nfield; i++)
{
if (info->field[i].type == DB_T_SERIAL)
{
ret_count++;
if (comma)
q_add(", ");
else
{
q_add(" RETURNING ");
ret_first = i;
}
q_add(THIS->driver->GetQuote());
q_add(info->field[i].name);
q_add(THIS->driver->GetQuote());
comma = TRUE;
}
}
GB.Alloc(POINTER(&ret_buffer), sizeof(GB_VARIANT_VALUE) * ret_count);
for (i = 0; i < ret_count; i++)
ret_buffer[i].type = GB_T_NULL;
}
if (ret_count)
err = THIS->driver->Exec(&THIS->conn->db, q_get(), &res, "Cannot create record: &1");
else
err = THIS->driver->Exec(&THIS->conn->db, q_get(), NULL, "Cannot create record: &1");
if (!err)
{
if (!THIS->returning)
void_buffer(THIS);
else if (ret_count)
{
if (THIS->driver->Result.Fill(&THIS->conn->db, res, 0, ret_buffer, FALSE) == DB_OK)
{
THIS->buffer[ret_first] = ret_buffer[0];
for (i = ret_first + 1, j = 1; i < info->nfield; i++)
{
if (info->field[i].type == DB_T_SERIAL)
THIS->buffer[i] = ret_buffer[j++];
}
}
THIS->driver->Result.Release(res, NULL, FALSE);
}
}
GB.Free(POINTER(&ret_buffer));
break; break;

View file

@ -68,6 +68,7 @@ typedef
unsigned available : 1; unsigned available : 1;
unsigned no_seek : 1; unsigned no_seek : 1;
unsigned mode : 2; unsigned mode : 2;
unsigned returning : 1;
} }
CRESULT; CRESULT;

View file

@ -49,8 +49,9 @@ typedef
typedef typedef
struct { struct {
void *handle; /* Connection handle */ void *handle; /* Connection handle */
int version; /* Version of the database system */ int version; /* Version of the database server */
char *charset; /* Charset used by the database */ char *full_version; /* Full version of the database server */
char *charset; /* Charset used by the database server */
void *data; /* Can be used by the driver for storing its own private data */ void *data; /* Can be used by the driver for storing its own private data */
int error; /* Last SQL error code raise by a query */ int error; /* Last SQL error code raise by a query */
int timeout; /* Connection timeout */ int timeout; /* Connection timeout */
@ -65,6 +66,7 @@ typedef
//unsigned no_case : 1; /* table, field and index names must be converted to lower case */ //unsigned no_case : 1; /* table, field and index names must be converted to lower case */
unsigned schema : 1; /* If table names can be prefixed by a schema name and a dot */ unsigned schema : 1; /* If table names can be prefixed by a schema name and a dot */
unsigned no_collation : 1; /* No collation support at field level */ unsigned no_collation : 1; /* No collation support at field level */
unsigned no_returning : 1; /* Database does not support RETURNING keyword */
unsigned system : 1; /* system database */ unsigned system : 1; /* system database */
} }
flags; flags;

View file

@ -1,3 +1,3 @@
[Component] [Component]
Key=gb.db Key=gb.db
Version=3.18.0 Version=3.18.90

View file

@ -1,7 +1,7 @@
# Gambas Project File 3.0 # Gambas Project File 3.0
Title=gb.db Title=gb.db
Startup=Main Startup=Main
Version=3.18.0 Version=3.18.90
VersionFile=1 VersionFile=1
Component=gb.db Component=gb.db
TabSize=2 TabSize=2

View file

@ -5,9 +5,10 @@ Public Sub Main()
Dim hConn As New Connection Dim hConn As New Connection
hConn.Type = "postgresql" hConn.Type = "postgresql"
hConn.Options["dbname"] = "omogen_benoit_kubuntu_sanef_fox2"
hConn.Open hConn.Open
Print hConn.SQL.From("$").OrderBy(["a DESC", "b"])()
Print hConn.Tables.Count Print hConn.Tables.Count
hConn.Close hConn.Close

View file

@ -122,33 +122,37 @@ Public Function _call() As String
Dim sField As String Dim sField As String
Dim bDesc As Boolean Dim bDesc As Boolean
If Not $sTable Then Error.Raise("No table specified") 'If Not $sTable Then Error.Raise("No table specified")
sReq = $sType If $sType Then
If $aField Then sReq = $sType
sReq &= " " If $aField Then
For I = 0 To $aField.Max sReq &= " "
If I Then sReq &= ","
aScan = Scan($aField[I], "* AS *") For I = 0 To $aField.Max
If aScan.Count = 2 And If InStr(aScan[1], " ") = 0 Then If I Then sReq &= ","
sReq &= $aField[I] aScan = Scan($aField[I], "* AS *")
Else If $aField[I] = "*" Then If aScan.Count = 2 And If InStr(aScan[1], " ") = 0 Then
sReq &= "*" sReq &= $aField[I]
Else Else If $aField[I] = "*" Then
sReq &= $hConn.Quote($aField[I]) sReq &= "*"
Endif Else
Next sReq &= $hConn.Quote($aField[I])
Endif
Else If $sType = "SELECT" Then Next
sReq &= " *" Else If $sType = "SELECT" Then
sReq &= " *"
Endif
Endif Endif
sReq &= " FROM " & $hConn.Quote($sTable, True) If $sTable Then sReq &= " FROM " & $hConn.Quote($sTable, True)
If $sWhere Then sReq &= " WHERE" & $sWhere If $sWhere Then sReq &= " WHERE" & $sWhere
@ -171,6 +175,6 @@ Public Function _call() As String
Endif Endif
Return sReq Return Trim(sReq)
End End

View file

@ -0,0 +1,12 @@
COMPONENT = gb.gui.qt.ext
include $(top_srcdir)/component.am
gblib_LTLIBRARIES = gb.gui.qt.ext.la
gb_gui_qt_ext_la_LIBADD =
gb_gui_qt_ext_la_LDFLAGS = -module @LD_FLAGS@
gb_gui_qt_ext_la_CFLAGS = -I$(top_srcdir)/share -I$(top_srcdir)/gbx @INCLTDL@ $(AM_CFLAGS)
gb_gui_qt_ext_la_SOURCES = \
main.h main.c

View file

@ -0,0 +1,4 @@
[Component]
Author=Benoît Minisini
Requires=gb.gui.qt
State=Finished

View file

@ -0,0 +1,71 @@
/***************************************************************************
main.c
(c) Benoît Minisini <benoit.minisini@gambas-basic.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
***************************************************************************/
#define __MAIN_C
#include "main.h"
GB_INTERFACE GB EXPORT;
GB_DESC *GB_CLASSES[] EXPORT =
{
NULL
};
char *GB_INCLUDE EXPORT = "gb.qt4.ext|gb.qt5.ext";
int EXPORT GB_INIT(void)
{
const char *comp = NULL;
char *env;
env = getenv("GB_GUI");
if (env)
{
if (strcmp(env, "gb.qt4") == 0)
comp = "gb.qt4.ext";
else if (strcmp(env, "gb.qt5") == 0)
comp = "gb.qt5.ext";
}
if (!comp)
{
// GB_GUI should be set by gb.gui
if (!env || !*env)
fprintf(stderr, "gb.gui.qt.ext: error: no component specified in GB_GUI environment variable");
else
fprintf(stderr, "gb.gui.qt.ext: error: unsupported component specified in GB_GUI environment variable");
exit(1);
}
if (GB.Component.Load(comp))
fprintf(stderr, "gb.gui.qt.ext: unable to load '%s' component\n", comp);
return 0;
}
void EXPORT GB_EXIT()
{
}

View file

@ -0,0 +1,34 @@
/***************************************************************************
main.h
(c) Benoît Minisini <benoit.minisini@gambas-basic.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
***************************************************************************/
#ifndef __MAIN_H
#define __MAIN_H
#include "gambas.h"
#include "gb_common.h"
#ifndef __MAIN_C
extern GB_INTERFACE GB;
#endif
#endif