[DEVELOPMENT ENVIRONMENT]
* NEW: The structure of databases is now stored in the *.connection files. It will be used for an automatic database initialization feature. [WEBSITE MAKER] * NEW: Update for 3.6.2. [WIKI CGI SCRIPT] * BUG: Fix the display of page without headers. * NEW: Indexes are now displayed on two or more columns. [INTERPRETER] * NEW: New GB.AllocZero() API for allocating memory and filling it with zeros. [GB.DB.MYSQL] * OPT: Cache metadata queries during 30 secondes to speed up things. [GB.FORM] * NEW: MenuButton displays a focus rectangle now. [GB.GUI.BASE] * BUG: ProgressBar now raises native control events. git-svn-id: svn://localhost/gambas/trunk@6652 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
parent
cda2eda390
commit
dd41b47ef3
17 changed files with 649 additions and 497 deletions
|
@ -14,7 +14,7 @@ Sub InitVar()
|
|||
'DIM aDev AS String[] = ["92", "91", "90", "51"]
|
||||
|
||||
$cVar["OLD_VERSION"] = "2.24.0"
|
||||
$cVar["DEV_VERSION"] = "3.6.1"
|
||||
$cVar["DEV_VERSION"] = "3.6.2"
|
||||
|
||||
InitAuthor
|
||||
|
||||
|
|
|
@ -41,10 +41,10 @@
|
|||
<div align="center"><img id="logo" src="logo.png"/></div>
|
||||
|
||||
<div>
|
||||
<a class="download-orange" target="_blank" href="http://sourceforge.net/projects/gambas/files/gambas3/gambas3-3.6.1.tar.bz2/download">
|
||||
{Download} <b>Gambas 3.6.1</b>
|
||||
<a class="download-orange" target="_blank" href="http://sourceforge.net/projects/gambas/files/gambas3/gambas3-3.6.2.tar.bz2/download">
|
||||
{Download} <b>Gambas 3.6.2</b>
|
||||
</a>
|
||||
<div class="release-notes" align="center"><a href="http://gambaswiki.org/wiki/doc/release/3.6.1?w&l=$(LANG)">{Release Notes}</a></div>
|
||||
<div class="release-notes" align="center"><a href="http://gambaswiki.org/wiki/doc/release/3.6.2?w&l=$(LANG)">{Release Notes}</a></div>
|
||||
</div>
|
||||
|
||||
<div style="display:inline-table;">
|
||||
|
|
|
@ -158,7 +158,6 @@ TABLE.example TH {
|
|||
}*/
|
||||
|
||||
.header {
|
||||
background: white; /*#DFC1A7; /*#CF6706;*/
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
|
@ -166,17 +165,6 @@ TABLE.example TH {
|
|||
z-index: 10;
|
||||
}
|
||||
|
||||
.header-v {
|
||||
background: white;
|
||||
/*padding: 2px 0px;*/
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
height: 1.2em;
|
||||
}
|
||||
|
||||
.header-inside {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
|
@ -184,6 +172,17 @@ TABLE.example TH {
|
|||
border-bottom-left-radius: 32px;
|
||||
border-bottom-right-radius: 32px;
|
||||
padding: 2px 16px 4px;
|
||||
box-shadow: 0 0 8px gray;
|
||||
}
|
||||
|
||||
.header-inside-v {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
background: #E8E8E8;
|
||||
border-bottom-left-radius: 32px;
|
||||
border-bottom-right-radius: 32px;
|
||||
padding: 2px 16px 4px;
|
||||
box-shadow: 0 0 8px gray;
|
||||
}
|
||||
|
||||
.header-bar {
|
||||
|
@ -204,11 +203,6 @@ TABLE.example TH {
|
|||
color: gray;
|
||||
}
|
||||
|
||||
.label-login {
|
||||
display: inline-block;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.page {
|
||||
padding: 4px 8px;
|
||||
max-width: 800px;
|
||||
|
@ -364,7 +358,7 @@ TABLE.index TD {
|
|||
DIV.index {
|
||||
display: inline-block;
|
||||
font-size: 85%;
|
||||
padding: 8px 32px 8px 0;
|
||||
padding: 0;
|
||||
margin-top: 0.75em;
|
||||
}
|
||||
|
||||
|
@ -470,19 +464,25 @@ DIV.syntax > P:first-child {
|
|||
position: static;
|
||||
background: white; /*#DFC1A7;*/
|
||||
color: gray;
|
||||
border: #D8D8D8 solid 8px;
|
||||
border: #DF6B00 solid 8px;
|
||||
border-radius: 32px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 0 8px #D8D8D8;
|
||||
box-shadow: 0 0 8px gray;
|
||||
width: 20em;
|
||||
margin: 16px;
|
||||
}
|
||||
|
||||
.label-login {
|
||||
display: inline-block;
|
||||
margin-left: 0.5em;
|
||||
width: 8em;
|
||||
height: 1.5em;
|
||||
}
|
||||
|
||||
#user {
|
||||
width: 12em;
|
||||
}
|
||||
|
||||
#ok {
|
||||
margin-top: 8px;
|
||||
width: 8em;
|
||||
|
@ -503,8 +503,7 @@ DIV.syntax > P:first-child {
|
|||
.login {
|
||||
position: fixed;
|
||||
top: 32px;
|
||||
right: 32px;
|
||||
z-index: 100;
|
||||
left: 32px;
|
||||
margin: 0px;
|
||||
}
|
||||
.hide-if-compact {
|
||||
|
|
|
@ -21,14 +21,13 @@ TABLE.table>TBODY>TR>TH,TABLE.error>TBODY>TR>TH{border-top:solid #D8D8D8 1px;bor
|
|||
TABLE.desc{border:solid #D8D8D8 2px;border-collapse:collapse;padding:0px;margin-top:0.75em;border-spacing:0;empty-cells:show;}
|
||||
TABLE.desc>TBODY>TR>TD{border:none;padding:6px 12px;}
|
||||
TABLE.desc>TBODY>TR>TH{text-align:left;border:none;padding:6px 12px;}
|
||||
.header{background:white;left:0;top:0;width:100%;position:fixed;z-index:10;}
|
||||
.header-v{background:white;left:0;top:0;width:100%;position:fixed;z-index:10;height:1.2em;}
|
||||
.header-inside{max-width:800px;margin:0 auto;background:#E8E8E8;border-bottom-left-radius:32px;border-bottom-right-radius:32px;padding:2px 16px 4px;}
|
||||
.header{left:0;top:0;width:100%;position:fixed;z-index:10;}
|
||||
.header-inside{max-width:800px;margin:0 auto;background:#E8E8E8;border-bottom-left-radius:32px;border-bottom-right-radius:32px;padding:2px 16px 4px;box-shadow:0 0 8px gray;}
|
||||
.header-inside-v{max-width:800px;margin:0 auto;background:#E8E8E8;border-bottom-left-radius:32px;border-bottom-right-radius:32px;padding:2px 16px 4px;box-shadow:0 0 8px gray;}
|
||||
.header-bar{}
|
||||
.title{display:inline-block;color:gray;}
|
||||
.title A:hover{color:black;}
|
||||
.title-v{font-size:75%;color:gray;}
|
||||
.label-login{display:inline-block;margin-left:0.5em;}
|
||||
.page{padding:4px 8px;max-width:800px;margin:0 auto;position:relative;top:2.5em;}
|
||||
.page-edit{position:absolute;top:2.5em;bottom:0;left:0;right:0;}
|
||||
.unknown{color:red;margin-top:8px;}
|
||||
|
@ -50,7 +49,7 @@ DIV.example,DIV.seealso{display:inline-block;border:none;padding:0px;}
|
|||
TEXTAREA{font-family:monospace;}
|
||||
TABLE.index{border:none;padding:0px;margin-top:0.75em;}
|
||||
TABLE.index TD{border:none;padding:1px 6px;vertical-align:baseline;}
|
||||
DIV.index{display:inline-block;font-size:85%;padding:8px 32px 8px 0;margin-top:0.75em;}
|
||||
DIV.index{display:inline-block;font-size:85%;padding:0;margin-top:0.75em;}
|
||||
DIV.syntax{display:inline-block;border:solid #D8D8D8 2px;padding:4px 8px;font-family:monospace;white-space:pre-wrap;}
|
||||
DIV.syntax>P:last-child{margin-bottom:-0.75em;}
|
||||
DIV.since{display:inline-block;background:#FF8080;color:white;font-weight:bold;border:solid 1px red;padding:1px 6px;text-transform:uppercase;font-size:80%;}
|
||||
|
@ -68,13 +67,14 @@ P:first-child,UL:first-child,OL:first-child,TABLE:first-child{margin-top:0;}
|
|||
H1:first-child{margin-top:0;}
|
||||
DIV.table:first-child{margin-top:0;}
|
||||
DIV.syntax>P:first-child{margin-top:-0.75em;}
|
||||
.login{position:static;background:white;color:gray;border:#D8D8D8 solid 8px;border-radius:32px;padding:16px;box-shadow:0 0 8px #D8D8D8;width:20em;margin:16px;}
|
||||
.label-login{width:8em;height:1.5em;}
|
||||
.login{position:static;background:white;color:gray;border:#DF6B00 solid 8px;border-radius:32px;padding:16px;box-shadow:0 0 8px gray;width:20em;margin:16px;}
|
||||
.label-login{display:inline-block;margin-left:0.5em;width:8em;height:1.5em;}
|
||||
#user{width:12em;}
|
||||
#ok{margin-top:8px;width:8em;}
|
||||
#register{width:8em;}
|
||||
.hide-if-compact{display:none;}
|
||||
.show-if-compact{display:inherit;}
|
||||
@media(min-width:120em){.login{position:fixed;top:32px;right:32px;z-index:100;margin:0px;}
|
||||
@media(min-width:120em){.login{position:fixed;top:32px;left:32px;margin:0px;}
|
||||
.hide-if-compact{display:inherit;}
|
||||
.show-if-compact{display:none;}
|
||||
}
|
||||
|
|
|
@ -29,20 +29,22 @@ H1 { display: none; }
|
|||
|
||||
<%If Not Request.Exist("nh") Then%>
|
||||
|
||||
<div class="header-v">
|
||||
<div class="header-inside">
|
||||
<table border="0" cellpadding="0" cellspacing="0" style="position:fixed;">
|
||||
<tr valign="top"><td><a href="<%_PrintParent()%>"><img src="<%/%>/up-gray.png" style="vertical-align:top;"></a> </td>
|
||||
<td><div class="title-v"><%_PrintLink%></div></td></tr>
|
||||
</table>
|
||||
<div class="header">
|
||||
<div class="header-inside-v">
|
||||
<div class="header-bar">
|
||||
<table border="0" cellpadding="0" cellspacing="0">
|
||||
<tr valign="top"><td><a href="<%_PrintParent()%>"><img src="<%/%>/up-gray.png" style="vertical-align:top;"></a> </td>
|
||||
<td><div class="title-v"><%_PrintLink%></div></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page" style="padding-top:4px;top:1.2em;">
|
||||
<div class="page" style="top:1.5em;">
|
||||
|
||||
<%Else%>
|
||||
|
||||
<div class="page" style="padding-top:4px;top:0;">
|
||||
<div class="page" style="top:0;">
|
||||
|
||||
<%Endif%>
|
||||
|
||||
|
@ -159,12 +161,12 @@ H1 { display: none; }
|
|||
<div align="center">
|
||||
<div class="login"><div>
|
||||
<%If Session.Id Then%>
|
||||
<div class="label-login" align="left"><%= Main.UserName%></div>
|
||||
<div id="user" class="label-login" align="left"><%= Main.UserName%></div>
|
||||
<div class="command"><input type="submit" name="logout" value="<%= ("Logout")%>"></div>
|
||||
<%Else%>
|
||||
<div class="label-login" align="left"><%= ("Login")%> </div>
|
||||
<div class="label-login" align="left"><%=("Login")%> </div>
|
||||
<input type="text" name="login" id="login" maxlength="16">
|
||||
<div class="label-login" align="left"><%= ("Password")%> </div>
|
||||
<div class="label-login" align="left"><%=("Password")%> </div>
|
||||
<input type="password" name="password" id="password" maxlength="16">
|
||||
<div class="command"><input type="submit" id="ok" value="OK"></div>
|
||||
<div class="command"><input type="submit" id="register" name="register" value="<%= ("Register")%>"></div>
|
||||
|
|
|
@ -62,7 +62,6 @@ Public Sub Command(sCommand As String) As String[]
|
|||
Dim aArg As String[]
|
||||
Dim sDir As String
|
||||
Dim aResult As String[]
|
||||
Dim I As Integer
|
||||
Dim iPos As Integer
|
||||
Dim sPath As String
|
||||
Dim sLetter, sLast As String
|
||||
|
@ -72,6 +71,8 @@ Public Sub Command(sCommand As String) As String[]
|
|||
Dim hSym As CSymbolInfo
|
||||
Dim sTitle As String
|
||||
Dim sClass As String
|
||||
Dim iStart As Integer
|
||||
Dim I, J, K, N, NC As Integer
|
||||
|
||||
aArg = Split(sCommand, " ", Chr$(34))
|
||||
sCommand = aArg[0]
|
||||
|
@ -84,6 +85,13 @@ Public Sub Command(sCommand As String) As String[]
|
|||
aResult = New String[]
|
||||
aDir = New String[]
|
||||
|
||||
NC = 2
|
||||
For I = 1 To aArg.Max
|
||||
If aArg[I] Begins "col=" Then
|
||||
Try NC = CInt(Mid$(aArg[I], 5))
|
||||
Endif
|
||||
Next
|
||||
|
||||
If IsDir(sDir) Then
|
||||
|
||||
For Each sDir In Dir(sDir, "*", gb.Directory)
|
||||
|
@ -91,29 +99,38 @@ Public Sub Command(sCommand As String) As String[]
|
|||
If Not Main.ExistPage(sPath) Then Continue
|
||||
sTitle = Main.GetPageTitle(sPath)
|
||||
If aArg.Count > 2 And If Comp(Left(sTitle, Len(aArg[2])), aArg[2], gb.Language + gb.IgnoreCase) = 0 Then sTitle = LTrim(Mid$(sTitle, Len(aArg[2]) + 1))
|
||||
|
||||
Do
|
||||
sLetter = String.Left(sTitle)
|
||||
If Len(sLetter) > 1 Then Break
|
||||
If Not IsPunct(sLetter) Then Break
|
||||
If Not sTitle Then Break
|
||||
sTitle = String.Mid$(sTitle, 2)
|
||||
Loop
|
||||
|
||||
If Not sTitle Then sTitle = " "
|
||||
|
||||
aDir.Add(sTitle & "\n[" & sPath & "]")
|
||||
Next
|
||||
|
||||
If aDir.Count Then
|
||||
|
||||
aResult.Add("[[ index")
|
||||
aResult.Add("==")
|
||||
aResult.Add("<table class=\"no-border full\">")
|
||||
|
||||
aDir.Sort(gb.Natural + gb.IgnoreCase)
|
||||
|
||||
iStart = 0
|
||||
For I = 0 To aDir.Max
|
||||
If I Then aResult.Add("==")
|
||||
iPos = InStr(aDir[I], "\n")
|
||||
sLetter = String.UCase(String.Left(aDir[I]))
|
||||
If sLetter <> sLast Then
|
||||
aResult.Add("<div class=\"letter\">" & sLetter & "</div>")
|
||||
If I Then GoSub MAKE_INDEX_LETTER
|
||||
sLast = sLetter
|
||||
iStart = I
|
||||
Endif
|
||||
aResult.Add("--")
|
||||
aResult.Add(Mid$(aDir[I], iPos + 1) & "\\")
|
||||
Next
|
||||
GoSub MAKE_INDEX_LETTER
|
||||
|
||||
aResult.Add("]]")
|
||||
aResult.Add("</table>")
|
||||
|
||||
Endif
|
||||
|
||||
|
@ -183,6 +200,31 @@ Public Sub Command(sCommand As String) As String[]
|
|||
|
||||
Endif
|
||||
|
||||
MAKE_INDEX_LETTER:
|
||||
|
||||
aResult.Add("<tr><td><div class=\"letter\">" & sLast & " </div></td>")
|
||||
|
||||
N = (I - iStart + NC - 1) \ NC
|
||||
J = iStart
|
||||
|
||||
For K = 1 To NC
|
||||
|
||||
aResult.Add("<td width=\"" & CStr(100 \ NC) & "%\">")
|
||||
|
||||
For J = J To J + N - 1
|
||||
If J >= I Then Break
|
||||
iPos = InStr(aDir[J], "\n")
|
||||
aResult.Add(Mid$(aDir[J], iPos + 1) & "\\")
|
||||
Next
|
||||
|
||||
aResult.Add("</td>")
|
||||
|
||||
Next
|
||||
|
||||
aResult.Add("</tr>")
|
||||
|
||||
Return
|
||||
|
||||
End
|
||||
|
||||
Public Sub Enter(sClass As String) As String[]
|
||||
|
|
|
@ -230,6 +230,8 @@ Public Sub Reload() As Boolean
|
|||
|
||||
Inc Application.Busy
|
||||
|
||||
DB.Debug = True
|
||||
|
||||
$hConn.Open
|
||||
|
||||
$aCollations = Null
|
||||
|
@ -291,7 +293,8 @@ Public Sub Reload() As Boolean
|
|||
UpdateRequest
|
||||
|
||||
LoadList($sTable)
|
||||
|
||||
UpdateDefinition
|
||||
|
||||
DrawTitle
|
||||
Me.Enabled = True
|
||||
|
||||
|
@ -439,6 +442,8 @@ Private Sub ReloadTable()
|
|||
Dim cDescField As Collection
|
||||
Dim cDescIndex As Collection
|
||||
|
||||
UpdateDefinition($sTable)
|
||||
|
||||
$aField.Clear
|
||||
$cFieldName.Clear
|
||||
$aIndexField.Clear
|
||||
|
@ -1289,7 +1294,7 @@ Private Sub RemoveIndexFromTable(sTable As String)
|
|||
|
||||
End
|
||||
|
||||
Private Sub WriteTableDef(sName As String, sType As String, aPrimaryKey As String[], Optional bKill As Boolean)
|
||||
Private Sub WriteTableInDatabase(sName As String, sType As String, aPrimaryKey As String[], Optional bKill As Boolean)
|
||||
|
||||
Dim hTable As Table
|
||||
Dim hCField As CField
|
||||
|
@ -1384,9 +1389,9 @@ Private Sub WriteTable(Optional sOldTable As String) As Boolean
|
|||
sTemp = sOldTable 'MConnection.CopyTableData($hConn, sOldName)
|
||||
Endif
|
||||
|
||||
'WriteTableDef(MConnection.GetTempTableName($hConn), $sType, aPrimaryKey, True)
|
||||
'WriteTableInDatabase(MConnection.GetTempTableName($hConn), $sType, aPrimaryKey, True)
|
||||
RemoveIndexFromTable(sOldTable)
|
||||
WriteTableDef($sTable, $sType, aPrimaryKey)
|
||||
WriteTableInDatabase($sTable, $sType, aPrimaryKey)
|
||||
|
||||
Else
|
||||
|
||||
|
@ -1394,8 +1399,8 @@ Private Sub WriteTable(Optional sOldTable As String) As Boolean
|
|||
sTemp = MConnection.CopyTableData($hConn, $sTable)
|
||||
Endif
|
||||
|
||||
WriteTableDef(MConnection.GetTempTableName($hConn), $sType, aPrimaryKey, True)
|
||||
WriteTableDef($sTable, $sType, aPrimaryKey)
|
||||
WriteTableInDatabase(MConnection.GetTempTableName($hConn), $sType, aPrimaryKey, True)
|
||||
WriteTableInDatabase($sTable, $sType, aPrimaryKey)
|
||||
|
||||
Endif
|
||||
|
||||
|
@ -1615,6 +1620,7 @@ Public Sub btnKill_Click()
|
|||
If CheckCurrent() Then Return
|
||||
|
||||
$hConn.Tables.Remove($sTable)
|
||||
UpdateDefinition($sTable)
|
||||
lvwTable.Remove("T" & $sTable)
|
||||
datData.Reset
|
||||
btnRequest_Click
|
||||
|
@ -1872,21 +1878,62 @@ Public Sub btnAddQuery_Click()
|
|||
|
||||
End
|
||||
|
||||
Private Sub SaveTableDef()
|
||||
Private Sub UpdateDefinition(Optional sTable As String)
|
||||
|
||||
Dim hConfig As Settings
|
||||
Dim hSettings As Settings
|
||||
Dim aDesc As String[]
|
||||
Dim sDefaultValue As String
|
||||
Dim hTable As Table
|
||||
Dim hField As Field
|
||||
Dim hIndex As Index
|
||||
Dim sDesc As String
|
||||
Dim aTable As String[]
|
||||
|
||||
For Each hTable In $hConn.Tables
|
||||
hSettings = New Settings(Path, Trim(Mid$(Project.CONNECTION_MAGIC, 2)))
|
||||
|
||||
If Not sTable Then
|
||||
hSettings.Clear("Definition")
|
||||
aTable = New String[]
|
||||
For Each hTable In $hConn.Tables
|
||||
If hTable.System Then Continue
|
||||
If hTable.Name Begins MConnection.METADATA_TABLE_PREFIX Then Continue
|
||||
If sTable And If hTable.Name <> sTable Then Continue
|
||||
aTable.Add(hTable.Name)
|
||||
Next
|
||||
Else
|
||||
aTable = [sTable]
|
||||
hSettings["Definition" &/ sTable] = ""
|
||||
Endif
|
||||
|
||||
For Each sTable In aTable
|
||||
|
||||
If hTable.System Then Continue
|
||||
If hTable.Name Begins MConnection.METADATA_TABLE_PREFIX Then Continue
|
||||
hTable = $hConn.Tables[sTable]
|
||||
|
||||
aDesc = New String[]
|
||||
aDesc.Add(hTable.Type)
|
||||
aDesc.Add(hTable.PrimaryKey.Join())
|
||||
|
||||
For Each hField In hTable.Fields
|
||||
sDefaultValue = hField.Default
|
||||
If sDefaultValue Then sDefaultValue = Quote(sDefaultValue)
|
||||
sDesc = hField.Name & "," & CStr(hField.Type) & "," & hField.Length
|
||||
If sDefaultValue Or If hField.Collation Then
|
||||
sDesc &= "," & sDefaultValue & "," & hField.Collation
|
||||
Endif
|
||||
aDesc.Add(sDesc)
|
||||
Next
|
||||
|
||||
For Each hIndex In hTable.Indexes
|
||||
If hIndex.Primary Then Continue
|
||||
sDesc = "@" & hIndex.Name
|
||||
If hIndex.Unique Then sDesc &= "!"
|
||||
aDesc.Add(sDesc & "," & hIndex.Fields.Join())
|
||||
Next
|
||||
|
||||
hSettings["Definition" &/ sTable] = aDesc.Join(";")
|
||||
|
||||
Next
|
||||
|
||||
hConfig = New Settings(Path, Trim(Mid$(Project.CONNECTION_MAGIC, 2)))
|
||||
|
||||
hSettings.Save
|
||||
|
||||
End
|
||||
|
|
|
@ -83,7 +83,7 @@ SearchString=True
|
|||
|
||||
[OpenFile]
|
||||
Active=1
|
||||
File[1]=".src/MMain.module:110.55"
|
||||
File[1]=".src/MMain.module:336.45"
|
||||
File[2]=".src/MServerPage.module:3.0"
|
||||
File[3]=".src/CComponent.class:38.0"
|
||||
File[4]="usage-gbs:12.0"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Gambas Project File 3.0
|
||||
# Compiled with Gambas 3.6.0
|
||||
# Compiled with Gambas 3.6.90
|
||||
Title=More controls for graphical components
|
||||
Startup=FDocumentView
|
||||
Version=3.6.90
|
||||
|
|
|
@ -370,7 +370,15 @@ Public Sub DrawingArea_Draw()
|
|||
Else
|
||||
Style.PaintButton(0, 0, Me.W, Me.H, $bPressed, iFlag, bFlat)
|
||||
Endif
|
||||
|
||||
|
||||
If bFlat And If Not $bPressed And If $hDrawingArea.HasFocus Then
|
||||
Paint.AntiAlias = False
|
||||
Paint.Rectangle(2, 2, Me.W - 4, Me.H - 4)
|
||||
Paint.Background = Color.SelectedBackground
|
||||
Paint.Stroke
|
||||
Paint.AntiAlias = True
|
||||
Endif
|
||||
|
||||
X = Desktop.Scale
|
||||
|
||||
If $hPicture Then
|
||||
|
|
|
@ -23,6 +23,7 @@ Private $hTimerPulse As Timer
|
|||
Public Sub _new()
|
||||
|
||||
$hDrawingArea = New DrawingArea(Me) As "DrawingArea"
|
||||
Me.Proxy = $hDrawingArea
|
||||
|
||||
End
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <mysql.h>
|
||||
|
||||
|
@ -48,7 +49,15 @@ static char _buffer[125];
|
|||
static DB_DRIVER _driver;
|
||||
/*static int _print_query = FALSE;*/
|
||||
|
||||
// Cached queries
|
||||
#define CACHE(_db) ((GB_HASHTABLE)(_db)->data)
|
||||
|
||||
typedef
|
||||
struct {
|
||||
MYSQL_RES *res;
|
||||
time_t timestamp;
|
||||
}
|
||||
CACHE_ENTRY;
|
||||
|
||||
/* internal function to quote a value stored as a string */
|
||||
|
||||
|
@ -460,8 +469,7 @@ static void check_connection(MYSQL *conn)
|
|||
|
||||
/* Internal function to run a query */
|
||||
|
||||
static int do_query(DB_DATABASE *db, const char *error, MYSQL_RES **pres,
|
||||
const char *qtemp, int nsubst, ...)
|
||||
static int do_query(DB_DATABASE *db, const char *error, MYSQL_RES **pres, const char *qtemp, int nsubst, ...)
|
||||
{
|
||||
MYSQL *conn = (MYSQL *)db->handle;
|
||||
va_list args;
|
||||
|
@ -508,6 +516,62 @@ static int do_query(DB_DATABASE *db, const char *error, MYSQL_RES **pres,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int do_query_cached(DB_DATABASE *db, const char *error, MYSQL_RES **pres, char *key, const char *qtemp, int nsubst, ...)
|
||||
{
|
||||
CACHE_ENTRY *entry;
|
||||
int len_key;
|
||||
bool added;
|
||||
time_t t;
|
||||
va_list args;
|
||||
int i;
|
||||
const char *query;
|
||||
int ret;
|
||||
|
||||
if (nsubst)
|
||||
{
|
||||
va_start(args, nsubst);
|
||||
if (nsubst > 3)
|
||||
nsubst = 3;
|
||||
for (i = 0; i < nsubst; i++)
|
||||
query_param[i] = va_arg(args, char *);
|
||||
|
||||
query = DB.SubstString(qtemp, 0, query_get_param);
|
||||
key = DB.SubstString(key, 0, query_get_param);
|
||||
}
|
||||
else
|
||||
query = qtemp;
|
||||
|
||||
len_key = strlen(key);
|
||||
added = GB.HashTable.Get(CACHE(db), key, len_key, POINTER(&entry));
|
||||
if (added)
|
||||
{
|
||||
GB.AllocZero(POINTER(&entry), sizeof(CACHE_ENTRY));
|
||||
GB.HashTable.Add(CACHE(db), key, len_key, entry);
|
||||
}
|
||||
|
||||
t = time(NULL);
|
||||
|
||||
//fprintf(stderr, "-- do_query_cached: %s [ %p %ld ]\n", key, entry->res, entry->timestamp);
|
||||
|
||||
if (entry->res && (t - entry->timestamp) < 30)
|
||||
{
|
||||
mysql_data_seek(entry->res, 0);
|
||||
*pres = entry->res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
entry->timestamp = t;
|
||||
|
||||
if (entry->res)
|
||||
mysql_free_result(entry->res);
|
||||
|
||||
ret = do_query(db, error, &entry->res, query, 0);
|
||||
if (ret == 0)
|
||||
*pres = entry->res;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Internal function to return database version number as a XXYYZZ integer number*/
|
||||
|
||||
static int db_version(DB_DATABASE *db)
|
||||
|
@ -551,6 +615,41 @@ static bool search_result(MYSQL_RES *res, const char *name, MYSQL_ROW *row)
|
|||
return (i >= mysql_num_rows(res));
|
||||
}
|
||||
|
||||
// Clear the query cache
|
||||
|
||||
static void free_cache(void *data)
|
||||
{
|
||||
GB.Free(&data);
|
||||
}
|
||||
|
||||
static void clear_cache(DB_DATABASE *db)
|
||||
{
|
||||
GB.HashTable.Enum(CACHE(db), free_cache);
|
||||
GB.HashTable.Free((GB_HASHTABLE *)&db->data);
|
||||
}
|
||||
|
||||
static void remove_cache_entry(DB_DATABASE *db, char *key)
|
||||
{
|
||||
CACHE_ENTRY *entry;
|
||||
|
||||
if (GB.HashTable.Get(CACHE(db), key, -1, POINTER(&entry)))
|
||||
return;
|
||||
|
||||
mysql_free_result(entry->res);
|
||||
GB.Free(POINTER(&entry));
|
||||
GB.HashTable.Remove((GB_HASHTABLE *)&db->data, key, -1);
|
||||
}
|
||||
|
||||
static void clear_table_cache(DB_DATABASE *db, const char *table)
|
||||
{
|
||||
char key[strlen(table) + 5];
|
||||
|
||||
strcpy(key, "sts:"); strcat(key, table); remove_cache_entry(db, key);
|
||||
strcpy(key, "sc:"); strcat(key, table); remove_cache_entry(db, key);
|
||||
strcpy(key, "sfc:"); strcat(key, table); remove_cache_entry(db, key);
|
||||
strcpy(key, "si:"); strcat(key, table); remove_cache_entry(db, key);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
||||
get_quote()
|
||||
|
@ -660,12 +759,12 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* set dbversion */
|
||||
db->handle = conn;
|
||||
db->version = db_version(db);
|
||||
|
||||
set_character_set(db);
|
||||
|
||||
GB.HashTable.New(POINTER(&db->data), GB_COMP_BINARY);
|
||||
/* flags: none at the moment */
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -685,6 +784,8 @@ static void close_database(DB_DATABASE *db)
|
|||
{
|
||||
MYSQL *conn = (MYSQL *)db->handle;
|
||||
|
||||
clear_cache(db);
|
||||
|
||||
if (conn)
|
||||
mysql_close(conn);
|
||||
}
|
||||
|
@ -1282,8 +1383,7 @@ static int table_init(DB_DATABASE *db, const char *table, DB_INFO *info)
|
|||
|
||||
static int table_index(DB_DATABASE *db, const char *table, DB_INFO *info)
|
||||
{
|
||||
char *qindex =
|
||||
"show index from `&1`";
|
||||
char *qindex = "show index from `&1`";
|
||||
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
|
@ -1291,7 +1391,7 @@ static int table_index(DB_DATABASE *db, const char *table, DB_INFO *info)
|
|||
|
||||
/* Index primaire */
|
||||
|
||||
if (do_query(db, "Unable to get primary index: &1", &res, qindex, 1, table))
|
||||
if (do_query_cached(db, "Unable to get primary index: &1", &res, "si:&1", qindex, 1, table))
|
||||
return TRUE;
|
||||
|
||||
for ( i = 0, n = 0; i < mysql_num_rows(res); i++ )
|
||||
|
@ -1329,7 +1429,6 @@ static int table_index(DB_DATABASE *db, const char *table, DB_INFO *info)
|
|||
}
|
||||
}
|
||||
|
||||
mysql_free_result(res);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1367,17 +1466,11 @@ static void table_release(DB_DATABASE *db, DB_INFO *info)
|
|||
static int table_exist(DB_DATABASE *db, const char *table)
|
||||
{
|
||||
MYSQL_RES *res;
|
||||
int exist;
|
||||
|
||||
const char *query =
|
||||
"show tables like '&1'";
|
||||
|
||||
if (do_query(db, "Unable to check table: &1", &res, query, 1, table))
|
||||
if (do_query_cached(db, "Unable to check table: &1", &res, "st", "show tables", 0))
|
||||
return FALSE;
|
||||
|
||||
exist = !search_result(res, table, NULL);
|
||||
mysql_free_result(res);
|
||||
return exist;
|
||||
return !search_result(res, table, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1401,25 +1494,21 @@ static int table_list(DB_DATABASE *db, char ***tables)
|
|||
{
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
long i;
|
||||
long rows;
|
||||
int i;
|
||||
int rows;
|
||||
|
||||
const char *query =
|
||||
"show tables";
|
||||
|
||||
if (do_query(db, "Unable to get tables", &res, query, 0))
|
||||
if (do_query_cached(db, "Unable to get tables", &res, "st", "show tables", 0))
|
||||
return -1;
|
||||
|
||||
rows = mysql_num_rows(res);
|
||||
GB.NewArray(tables, sizeof(char *), rows);
|
||||
|
||||
for (i = 0; i < rows; i++){
|
||||
for (i = 0; i < rows; i++)
|
||||
{
|
||||
row = mysql_fetch_row(res);
|
||||
(*tables)[i] = GB.NewZeroString(row[0]);
|
||||
}
|
||||
|
||||
mysql_free_result(res);
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
|
@ -1440,14 +1529,13 @@ static int table_list(DB_DATABASE *db, char ***tables)
|
|||
|
||||
static int table_primary_key(DB_DATABASE *db, const char *table, char ***primary)
|
||||
{
|
||||
const char *query =
|
||||
"show index from `&1`";
|
||||
const char *query = "show index from `&1`";
|
||||
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
int i;
|
||||
|
||||
if (do_query(db, "Unable to get primary key: &1", &res, query, 1, table))
|
||||
if (do_query_cached(db, "Unable to get primary key: &1", &res, "si:&1", query, 1, table))
|
||||
return TRUE;
|
||||
|
||||
GB.NewArray(primary, sizeof(char *), 0);
|
||||
|
@ -1459,8 +1547,6 @@ static int table_primary_key(DB_DATABASE *db, const char *table, char ***primary
|
|||
*(char **)GB.Add(primary) = GB.NewZeroString(row[4]);
|
||||
}
|
||||
|
||||
mysql_free_result(res);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1486,28 +1572,7 @@ static int database_is_system(DB_DATABASE *db, const char *name);
|
|||
|
||||
static int table_is_system(DB_DATABASE *db, const char *table)
|
||||
{
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
int system;
|
||||
|
||||
if (do_query(db, "Unable to check database: &1", &res, "select database()", 0))
|
||||
return FALSE;
|
||||
|
||||
if (mysql_num_rows(res) != 1 )
|
||||
{
|
||||
GB.Error("Unable to check database: More than one current database !?");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* (BM) Check that the current database is mysql */
|
||||
/* (BM) All tables of 'mysql' database are system */
|
||||
|
||||
row = mysql_fetch_row(res);
|
||||
system = database_is_system(db, row[0]);
|
||||
|
||||
mysql_free_result(res);
|
||||
|
||||
return system;
|
||||
return db->flags.system;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1528,8 +1593,7 @@ static char *table_type(DB_DATABASE *db, const char *table, const char *settype)
|
|||
{
|
||||
static char buffer[16];
|
||||
|
||||
const char *query =
|
||||
"show table status like '&1'";
|
||||
const char *query = "show table status like '&1'";
|
||||
|
||||
const char *update =
|
||||
"alter table `&1` type = &2";
|
||||
|
@ -1537,14 +1601,15 @@ static char *table_type(DB_DATABASE *db, const char *table, const char *settype)
|
|||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
|
||||
if (settype){
|
||||
if (do_query(db, "Cannot set table &1 to type &2", &res, update, 2, table, settype))
|
||||
if (settype)
|
||||
{
|
||||
clear_table_cache(db, table);
|
||||
if (do_query(db, "Cannot set table type: &1", &res, update, 2, table, settype))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (do_query(db, "Invalid table: &1", &res, query, 1, table)){
|
||||
if (do_query_cached(db, "Invalid table: &1", &res, "sts:&1", query, 1, table))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (search_result(res, table, &row))
|
||||
{
|
||||
|
@ -1555,7 +1620,6 @@ static char *table_type(DB_DATABASE *db, const char *table, const char *settype)
|
|||
if (!row[1]) return "VIEW"; // the table is a view
|
||||
|
||||
strcpy(buffer, row[1]);
|
||||
mysql_free_result(res);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -1576,6 +1640,8 @@ static char *table_type(DB_DATABASE *db, const char *table, const char *settype)
|
|||
|
||||
static int table_delete(DB_DATABASE *db, const char *table)
|
||||
{
|
||||
clear_table_cache(db, table);
|
||||
remove_cache_entry(db, "st");
|
||||
return do_query(db, "Unable to delete table: &1", NULL, "drop table `&1`", 1, table);
|
||||
}
|
||||
|
||||
|
@ -1684,7 +1750,6 @@ static int table_create(DB_DATABASE *db, const char *table, DB_FIELD *fields, ch
|
|||
DB.Query.Add(" NOT NULL");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (primary)
|
||||
|
@ -1726,6 +1791,7 @@ static int table_create(DB_DATABASE *db, const char *table, DB_FIELD *fields, ch
|
|||
DB.Query.Add(tabletype);
|
||||
}
|
||||
|
||||
remove_cache_entry(db, "st");
|
||||
/* printf("table_create syntax: %s\n", DB.Query.Get());*/
|
||||
return do_query(db, "Cannot create table: &1", NULL, DB.Query.Get(), 0);
|
||||
}
|
||||
|
@ -1746,19 +1812,14 @@ static int table_create(DB_DATABASE *db, const char *table, DB_FIELD *fields, ch
|
|||
|
||||
static int field_exist(DB_DATABASE *db, const char *table, const char *field)
|
||||
{
|
||||
const char *query =
|
||||
"show columns from `&1` like '&2'";
|
||||
const char *query = "show columns from `&1`";
|
||||
|
||||
MYSQL_RES *res;
|
||||
int exist;
|
||||
|
||||
if (do_query(db, "Unable to check field: &1", &res, query, 2, table, field))
|
||||
if (do_query_cached(db, "Unable to check field: &1", &res, "sc:&1", query, 1, table))
|
||||
return FALSE;
|
||||
|
||||
exist = !search_result(res, field, NULL);
|
||||
mysql_free_result(res);
|
||||
|
||||
return exist;
|
||||
return !search_result(res, field, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1782,14 +1843,13 @@ static int field_exist(DB_DATABASE *db, const char *table, const char *field)
|
|||
|
||||
static int field_list(DB_DATABASE *db, const char *table, char ***fields)
|
||||
{
|
||||
const char *query =
|
||||
"show columns from `&1`";
|
||||
const char *query = "show columns from `&1`";
|
||||
|
||||
long i, n;
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
|
||||
if (do_query(db, "Unable to get fields: &1", &res, query, 1, table))
|
||||
if (do_query_cached(db, "Unable to get field: &1", &res, "sc:&1", query, 1, table))
|
||||
return -1;
|
||||
|
||||
n = mysql_num_rows(res);
|
||||
|
@ -1804,7 +1864,6 @@ static int field_list(DB_DATABASE *db, const char *table, char ***fields)
|
|||
}
|
||||
}
|
||||
|
||||
mysql_free_result(res);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -1827,7 +1886,7 @@ static int field_list(DB_DATABASE *db, const char *table, char ***fields)
|
|||
|
||||
static int field_info(DB_DATABASE *db, const char *table, const char *field, DB_FIELD *info)
|
||||
{
|
||||
const char *query = "show full columns from `&1` like '&2'";
|
||||
const char *query = "show full columns from `&1`";
|
||||
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
|
@ -1836,7 +1895,7 @@ static int field_info(DB_DATABASE *db, const char *table, const char *field, DB_
|
|||
int type;
|
||||
long len = 0;
|
||||
|
||||
if (do_query(db, "Unable to get field info: &1", &res, query, 2, table, field))
|
||||
if (do_query_cached(db, "Unable to get field info: &1", &res, "sfc:&1", query, 1, table))
|
||||
return TRUE;
|
||||
|
||||
if (search_result(res, field, &row))
|
||||
|
@ -1889,7 +1948,6 @@ static int field_info(DB_DATABASE *db, const char *table, const char *field, DB_
|
|||
else
|
||||
info->collation = NULL;
|
||||
|
||||
mysql_free_result(res);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1909,14 +1967,13 @@ static int field_info(DB_DATABASE *db, const char *table, const char *field, DB_
|
|||
|
||||
static int index_exist(DB_DATABASE *db, const char *table, const char *index)
|
||||
{
|
||||
const char *query =
|
||||
"show index from `&1`";
|
||||
const char *query = "show index from `&1`";
|
||||
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
int i, n;
|
||||
|
||||
if (do_query(db, "Unable to check index: &1", &res, query, 1, table))
|
||||
if (do_query_cached(db, "Unable to check index: &1", &res, "si:&1", query, 1, table))
|
||||
return FALSE;
|
||||
|
||||
for ( i = 0, n = 0; i < mysql_num_rows(res); i++ )
|
||||
|
@ -1926,12 +1983,7 @@ static int index_exist(DB_DATABASE *db, const char *table, const char *index)
|
|||
n++;
|
||||
}
|
||||
|
||||
mysql_free_result(res);
|
||||
if (n <= 0){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return (n > 0);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -1959,30 +2011,29 @@ static int index_list(DB_DATABASE *db, const char *table, char ***indexes)
|
|||
MYSQL_ROW row;
|
||||
long i, n, no_indexes;
|
||||
|
||||
if (do_query(db, "Unable to get indexes: &1", &res, query, 1, table))
|
||||
if (do_query_cached(db, "Unable to get indexes: &1", &res, "si:&1", query, 1, table))
|
||||
return -1;
|
||||
|
||||
for ( i = 0, no_indexes = 0; i < mysql_num_rows(res); i++ )
|
||||
for (i = 0, no_indexes = 0; i < mysql_num_rows(res); i++ )
|
||||
{
|
||||
/* Count the number of 1st sequences in Seq_in_index to
|
||||
give nmber of indexes. row[3] */
|
||||
row = mysql_fetch_row(res);
|
||||
if ( atoi(row[3]) == 1)
|
||||
no_indexes++;
|
||||
if (atoi(row[3]) == 1)
|
||||
no_indexes++;
|
||||
}
|
||||
|
||||
|
||||
GB.NewArray(indexes, sizeof(char *), no_indexes);
|
||||
mysql_data_seek(res, 0); /* move back to first record */
|
||||
|
||||
for ( i = 0, n = 0; i < mysql_num_rows(res); i++ )
|
||||
for (i = 0, n = 0; i < mysql_num_rows(res); i++ )
|
||||
{
|
||||
row = mysql_fetch_row(res);
|
||||
if ( atoi(row[3]) == 1 /* Start of a new index */)
|
||||
if (atoi(row[3]) == 1 /* Start of a new index */)
|
||||
(*indexes)[n++] = GB.NewZeroString(row[2]); /* (BM) The name is row[2], not row[4] */
|
||||
}
|
||||
|
||||
mysql_free_result(res);
|
||||
return no_indexes;
|
||||
}
|
||||
|
||||
|
@ -2004,14 +2055,13 @@ static int index_list(DB_DATABASE *db, const char *table, char ***indexes)
|
|||
|
||||
static int index_info(DB_DATABASE *db, const char *table, const char *index, DB_INDEX *info)
|
||||
{
|
||||
const char *query =
|
||||
"show index from `&1`";
|
||||
const char *query = "show index from `&1`";
|
||||
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row = 0;
|
||||
int i, n;
|
||||
|
||||
if (do_query(db, "Unable to get index info: &1", &res, query, 2, table, index))
|
||||
if (do_query_cached(db, "Unable to get index info: &1", &res, "si:&1", query, 1, table))
|
||||
return TRUE;
|
||||
|
||||
n = mysql_num_rows(res);
|
||||
|
@ -2049,7 +2099,6 @@ static int index_info(DB_DATABASE *db, const char *table, const char *index, DB_
|
|||
i++; /* (BM) i must be incremented */
|
||||
}
|
||||
|
||||
mysql_free_result(res);
|
||||
info->fields = DB.Query.GetNew();
|
||||
|
||||
return FALSE;
|
||||
|
@ -2072,9 +2121,8 @@ static int index_info(DB_DATABASE *db, const char *table, const char *index, DB_
|
|||
|
||||
static int index_delete(DB_DATABASE *db, const char *table, const char *index)
|
||||
{
|
||||
return
|
||||
do_query(db, "Unable to delete index: &1", NULL,
|
||||
"drop index `&1` on `&2`", 1, index, table);
|
||||
clear_table_cache(db, table);
|
||||
return do_query(db, "Unable to delete index: &1", NULL, "drop index `&1` on `&2`", 1, index, table);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -2108,6 +2156,7 @@ static int index_create(DB_DATABASE *db, const char *table, const char *index, D
|
|||
DB.Query.Add(info->fields);
|
||||
DB.Query.Add(" )");
|
||||
|
||||
clear_table_cache(db, table);
|
||||
return do_query(db, "Cannot create index: &1", NULL, DB.Query.Get(), 0);
|
||||
}
|
||||
|
||||
|
@ -2231,9 +2280,7 @@ static int database_delete(DB_DATABASE *db, const char *name)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
return
|
||||
do_query(db, "Unable to delete database: &1", NULL,
|
||||
"drop database `&1`", 1, name);
|
||||
return do_query(db, "Unable to delete database: &1", NULL, "drop database `&1`", 1, name);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -2252,9 +2299,7 @@ static int database_delete(DB_DATABASE *db, const char *name)
|
|||
|
||||
static int database_create(DB_DATABASE *db, const char *name)
|
||||
{
|
||||
return
|
||||
do_query(db, "Unable to create database: &1", NULL,
|
||||
"create database `&1`", 1, name);
|
||||
return do_query(db, "Unable to create database: &1", NULL, "create database `&1`", 1, name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2298,8 +2343,8 @@ static int user_exist(DB_DATABASE *db, const char *name)
|
|||
|
||||
if (do_query(db, "Unable to check user: &1@&2", &res, query, 2, _name, _host))
|
||||
{
|
||||
free(_name);
|
||||
return FALSE;
|
||||
free(_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exist = mysql_num_rows(res) == 1;
|
||||
|
@ -2494,8 +2539,7 @@ static int user_delete(DB_DATABASE *db, const char *name)
|
|||
//Still need to look at the removal of privileges
|
||||
// _ret = do_query(db, "Unable to delete user: &1", NULL,
|
||||
// "revoke all on *.* from &1@&2", 2, _name, _host);
|
||||
_ret = do_query(db, "Unable to delete user: &1", NULL,
|
||||
_delete, 2, _name, _host);
|
||||
_ret = do_query(db, "Unable to delete user: &1", NULL, _delete, 2, _name, _host);
|
||||
free(_name);
|
||||
return _ret;
|
||||
}
|
||||
|
@ -2591,9 +2635,7 @@ static int user_set_password(DB_DATABASE *db, const char *name, const char *pass
|
|||
|
||||
free(_name);
|
||||
|
||||
return
|
||||
do_query(db, "Cannot change user password: &1",
|
||||
NULL, DB.Query.Get(), 0);
|
||||
return do_query(db, "Cannot change user password: &1", NULL, DB.Query.Get(), 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -221,6 +221,7 @@ const void *const GAMBAS_Api[] =
|
|||
(void *)GB_Eval,
|
||||
|
||||
(void *)GB_Alloc,
|
||||
(void *)GB_AllocZero,
|
||||
(void *)GB_Free,
|
||||
(void *)GB_Realloc,
|
||||
|
||||
|
@ -2024,6 +2025,11 @@ void GB_Alloc(void **addr, int len)
|
|||
ALLOC(addr, len);
|
||||
}
|
||||
|
||||
void GB_AllocZero(void **addr, int len)
|
||||
{
|
||||
ALLOC_ZERO(addr, len);
|
||||
}
|
||||
|
||||
void GB_Free(void **addr)
|
||||
{
|
||||
FREE(addr);
|
||||
|
|
|
@ -167,6 +167,7 @@ bool GB_CollectionGet(GB_COLLECTION col, const char *key, int len, GB_VARIANT *v
|
|||
bool GB_CollectionEnum(GB_COLLECTION col, GB_COLLECTION_ITER *iter, GB_VARIANT *value, char **key, int *len);
|
||||
|
||||
void GB_Alloc(void **addr, int len);
|
||||
void GB_AllocZero(void **addr, int len);
|
||||
void GB_Free(void **addr);
|
||||
void GB_Realloc(void **addr, int len);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -64,6 +64,7 @@ typedef
|
|||
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 no_collation : 1; /* No collation support at field level */
|
||||
unsigned system : 1; /* system database */
|
||||
}
|
||||
flags;
|
||||
struct {
|
||||
|
|
|
@ -1059,6 +1059,7 @@ typedef
|
|||
GB_VALUE *(*Eval)(void *, void *);
|
||||
|
||||
void (*Alloc)(void **, int);
|
||||
void (*AllocZero)(void **, int);
|
||||
void (*Free)(void **);
|
||||
void (*Realloc)(void **, int);
|
||||
|
||||
|
|
Loading…
Reference in a new issue