Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 07b0f63

Browse files
committed
[[ Bug 18670 ]] Fixed bug preventing all table names being retrieved for MySQL dbs
1 parent 51d6632 commit 07b0f63

File tree

7 files changed

+132
-64
lines changed

7 files changed

+132
-64
lines changed

docs/notes/bugfix-18670.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Fixed bug preventing all table names being retrieved in MySQL db's

revdb/src/dbmysql.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
1919
#endif
2020

2121
#include "dbdrivercommon.h"
22+
#include "large_buffer.h"
2223

2324
#include <mysql.h>
2425
#include <mysql_com.h>
@@ -66,6 +67,7 @@ class DBConnection_MYSQL: public CDBConnection
6667
void getTables(char *buffer, int *bufsize);
6768
int getConnectionType(void) { return -1; }
6869
int getVersion(void) { return 2; }
70+
large_buffer_t *m_internal_buffer;
6971
protected:
7072
bool BindVariables(MYSQL_STMT *p_statement, DBString *p_arguments, int p_argument_count, int *p_placeholders, int p_placeholder_count, MYSQL_BIND **p_bind);
7173
bool ExecuteQuery(char *p_query, DBString *p_arguments, int p_argument_count);

revdb/src/dbpostgresql.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
2626

2727
#include <libpq-fe.h>
2828
#include "dbdrivercommon.h"
29+
#include "large_buffer.h"
2930

3031
#define DB_POSTGRESQL_STRING "POSTGRESQL";
3132

@@ -139,5 +140,7 @@ class DBConnection_POSTGRESQL: public CDBConnection
139140
protected:
140141
PGconn *dbconn;
141142
PGresult *ExecuteQuery(char *p_query, DBString *p_arguments, int p_argument_count);
143+
private:
144+
large_buffer_t *m_internal_buffer;
142145
};
143146
#endif

revdb/src/large_buffer.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
1717
#ifndef __LARGE_BUFFER__
1818
#define __LARGE_BUFFER__
1919

20+
#include "stddef.h"
21+
2022
class large_buffer_t
2123
{
2224
public:
@@ -48,10 +50,20 @@ class large_buffer_t
4850
m_frontier = m_frontier + p_length;
4951
}
5052

53+
void *ptr(void)
54+
{
55+
return m_data;
56+
}
57+
58+
ptrdiff_t length(void)
59+
{
60+
return m_frontier - m_data;
61+
}
62+
5163
void grab(void*& r_data, unsigned int& r_length)
5264
{
5365
r_length = m_frontier - m_data;
54-
r_data = (void *)realloc(m_data, m_frontier - m_data);
66+
r_data = (void *)realloc(m_data, r_length);
5567

5668
m_data = NULL;
5769
m_frontier = NULL;

revdb/src/mysql_connection.cpp

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -379,38 +379,38 @@ bool DBConnection_MYSQL::BindVariables(MYSQL_STMT *p_statement, DBString *p_argu
379379

380380
void DBConnection_MYSQL::getTables(char *buffer, int *bufsize)
381381
{
382-
int rowseplen = 1;
383-
char rowsep[] = "\n";
384382
if (!buffer) {
385-
*bufsize = 2500;
383+
if (!m_internal_buffer)
384+
{
385+
m_internal_buffer = new large_buffer_t;
386+
387+
}
388+
long buffersize = 0;
389+
char tsql[] = "SHOW tables";
390+
DBCursor *newcursor = sqlQuery(tsql, NULL, 0, 0);
391+
if (newcursor) {
392+
if (!newcursor->getEOF()){
393+
while (True){
394+
unsigned int colsize;
395+
char *coldata = newcursor->getFieldDataBinary(1,colsize);
396+
colsize = strlen(coldata);
397+
m_internal_buffer->append(coldata, colsize);
398+
m_internal_buffer->append('\n');
399+
buffersize += colsize + 1;
400+
newcursor->next();
401+
if (newcursor->getEOF()) break;
402+
}
403+
}
404+
deleteCursor(newcursor->GetID());
405+
*bufsize = buffersize+1;
406+
m_internal_buffer->append('\0');
407+
fprintf(stderr, "\n%d\n", *bufsize);
408+
}
386409
return;
387410
}
388-
char tsql[] = "SHOW tables";
389-
DBCursor *newcursor = sqlQuery(tsql, NULL, 0, 0);
390-
if (newcursor) {
391-
char *result = buffer;
392-
char *resultptr = result;
393-
if (!newcursor->getEOF()){
394-
while (True){
395-
unsigned int colsize;
396-
char *coldata = newcursor->getFieldDataBinary(1,colsize);
397-
colsize = strlen(coldata);
398-
if (((resultptr-result) + colsize + rowseplen + 16 )
399-
> *bufsize)
400-
break;
401-
memcpy(resultptr,coldata,colsize);
402-
resultptr+=colsize;
403-
newcursor->next();
404-
if (newcursor->getEOF()) break;
405-
memcpy(resultptr,rowsep,rowseplen);
406-
resultptr+=rowseplen;
407-
}
408-
}
409-
deleteCursor(newcursor->GetID());
410-
*resultptr++ = '\0';
411-
*bufsize = resultptr-result;
412-
}
413-
newcursor = NULL;
411+
memcpy((void *) buffer, m_internal_buffer->ptr(), m_internal_buffer->length());
412+
delete m_internal_buffer;
413+
m_internal_buffer = nullptr;
414414
}
415415

416416
/*MYSQL doesn't support transactions so leave blank for now*/

revdb/src/postgresql_connection.cpp

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -439,40 +439,38 @@ char *DBConnection_POSTGRESQL::getErrorMessage(Bool p_last)
439439

440440
void DBConnection_POSTGRESQL::getTables(char *buffer, int *bufsize)
441441
{
442-
int rowseplen = 1;
443-
char rowsep[] = "\n";
444-
if (!buffer) {
445-
*bufsize = 2500;
446-
return;
447-
}
448-
char tsql[] = "SELECT tablename FROM pg_tables WHERE tablename NOT LIKE 'pg%'";
449-
DBCursor *newcursor = sqlQuery(tsql , NULL, 0, 0);
450-
if (newcursor)
451-
{
452-
char *result = buffer;
453-
char *resultptr = result;
454-
unsigned int colsize = 0;
455-
if (!newcursor->getEOF())
456-
{
457-
while (True){
458-
unsigned int colsize;
459-
char *coldata = newcursor->getFieldDataBinary(1,colsize);
460-
colsize = strlen(coldata);
461-
if (((resultptr-result) + (int)colsize + rowseplen + 16 ) > *bufsize)
462-
break;
463-
memcpy(resultptr,coldata,colsize);
464-
resultptr+=colsize;
465-
newcursor->next();
466-
if (newcursor->getEOF()) break;
467-
memcpy(resultptr,rowsep,rowseplen);
468-
resultptr+=rowseplen;
469-
}
470-
}
471-
deleteCursor(newcursor->GetID());
472-
*resultptr++ = '\0';
473-
*bufsize = resultptr-result;
474-
}
475-
newcursor = NULL;
442+
if (!buffer)
443+
{
444+
if (!m_internal_buffer)
445+
{
446+
m_internal_buffer = new large_buffer_t;
447+
}
448+
449+
long buffersize = 0;
450+
char tsql[] = "SELECT tablename FROM pg_tables WHERE tablename NOT LIKE 'pg%'";
451+
DBCursor *newcursor = sqlQuery(tsql, NULL, 0, 0);
452+
if (newcursor) {
453+
if (!newcursor->getEOF()){
454+
while (True){
455+
unsigned int colsize;
456+
char *coldata = newcursor->getFieldDataBinary(1,colsize);
457+
colsize = strlen(coldata);
458+
m_internal_buffer->append(coldata, colsize);
459+
m_internal_buffer->append('\n');
460+
buffersize += colsize + 1;
461+
newcursor->next();
462+
if (newcursor->getEOF()) break;
463+
}
464+
}
465+
deleteCursor(newcursor->GetID());
466+
*bufsize = buffersize+1;
467+
m_internal_buffer->append('\0');
468+
}
469+
return;
470+
}
471+
memcpy((void *) buffer, m_internal_buffer->ptr(), m_internal_buffer->length());
472+
delete m_internal_buffer;
473+
m_internal_buffer = nullptr;
476474
}
477475

478476
void DBConnection_POSTGRESQL::transBegin()
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
script "CoreDatabaseTest"
2+
3+
/*
4+
Copyright (C) 2017 LiveCode Ltd.
5+
6+
This file is part of LiveCode.
7+
8+
LiveCode is free software; you can redistribute it and/or modify it under
9+
the terms of the GNU General Public License v3 as published by the Free
10+
Software Foundation.
11+
12+
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
13+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15+
for more details.
16+
17+
You should have received a copy of the GNU General Public License
18+
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
19+
20+
function generateStrings
21+
local tArray, tBaseString, tCounter
22+
put 1 into tCounter
23+
put "Table%d" into tBaseString
24+
repeat 1800 times
25+
put format(tBaseString,tCounter) into tArray[tCounter]
26+
put tCounter+1 into tCounter
27+
end repeat
28+
return tArray
29+
end generateStrings
30+
31+
command createTables pConnection, pStrings
32+
local tBaseStmt, tCounter
33+
put "CREATE TABLE %s (id integer)" into tBaseStmt
34+
put 1 into tCounter
35+
repeat 1800 times
36+
revExecuteSQL pConnection, format(tBaseStmt, pStrings[tCounter])
37+
put tCounter+1 into tCounter
38+
end repeat
39+
end createTables
40+
41+
on TestDBTableGetters
42+
TestSkip "skipping DB test","cannot use revOpenDatabase"
43+
exit TestDBTableGetters
44+
local tArray
45+
put generateStrings() into tArray
46+
local tDatabaseID, tNames
47+
put revOpenDatabase("mysql","localhost","t2","root","test_password",false,"/tmp/mysql.sock",10,true) into tDatabaseID
48+
createNewSchema(tDatabaseID)
49+
createTables(tDatabaseID, tArray)
50+
put revDatabaseTableNames(tDatabaseID) into tNames
51+
TestAssert "check the correct things are returned", the number of lines in tNames is 1800
52+
end TestDBTableGetters

0 commit comments

Comments
 (0)