2008-06-04 23:18 UTC+0100 Viktor Szakats (harbour.01 syenar hu)
* contrib/hbsqlit2/hbsqlit2.c
* Removed commented debug code.
* Code cleanup, optimizations.
! GPFs fixed in many function, when no db was open.
! Automatically closing previous db when opening a new one.
! hb_sqlite2_db initialized with NULL.
This commit is contained in:
@@ -8,6 +8,14 @@
|
||||
2008-12-31 13:59 UTC+0100 Foo Bar <foo.bar@foobar.org>
|
||||
*/
|
||||
|
||||
2008-06-04 23:18 UTC+0100 Viktor Szakats (harbour.01 syenar hu)
|
||||
* contrib/hbsqlit2/hbsqlit2.c
|
||||
* Removed commented debug code.
|
||||
* Code cleanup, optimizations.
|
||||
! GPFs fixed in many function, when no db was open.
|
||||
! Automatically closing previous db when opening a new one.
|
||||
! hb_sqlite2_db initialized with NULL.
|
||||
|
||||
2008-06-04 22:13 UTC+0100 Viktor Szakats (harbour.01 syenar hu)
|
||||
* tests/rto_get.prg
|
||||
+ Added keypress emulator to aid automated testing.
|
||||
|
||||
@@ -6,17 +6,10 @@
|
||||
*------------------------------------------------------------------------
|
||||
* HARBOUR INTERFACE for SQLITE
|
||||
*------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2003 Alejandro de Gárate <alex_degarate@hotmail.com>
|
||||
*
|
||||
* License: General Public License (GNU)
|
||||
*
|
||||
* Developed using:
|
||||
* Harbour 0.42 or upper
|
||||
* Borland C++ BCC 5.5.1
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* Ver 0.40 30 December 2003 Fixed an opening error not detected
|
||||
* It seems is a problem with BCC compiler.
|
||||
* If "xxFile" database is not found, an empty file is
|
||||
@@ -24,13 +17,10 @@
|
||||
* to FILE() function. File is empty but exists (Oh man...)
|
||||
* I fix it from harbour code, when have more spare time
|
||||
* I will look in depth.
|
||||
*
|
||||
* Ver 0.30 28 December 2003 Pick tables, fields and DB structure,
|
||||
* you can import some dbf (not finish yet)
|
||||
*
|
||||
* you can import some dbf (not finish yet)
|
||||
* Ver 0.20 5 December 2003 changes in design, A front end is started
|
||||
* Shows database struc, table struct, field type
|
||||
*
|
||||
* Ver 0.10 26 November 2003 first intempts, open connection, list data
|
||||
* close connection
|
||||
*
|
||||
@@ -55,99 +45,58 @@
|
||||
#include "hbstack.h"
|
||||
#include "hbapiitm.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* need it for exit() and BCC55 */
|
||||
|
||||
#include "sqlite.h"
|
||||
#include "sqliteInt.h"
|
||||
|
||||
/* Public vars */
|
||||
sqlite * hb_sqlite2_db; /* public by ale */
|
||||
sqlite * hb_sqlite2_db = NULL; /* public by ale */
|
||||
char * hb_sqlite2_szErrMsg = NULL;
|
||||
int hb_sqlite2_iLastErrCode = 0; /* for use in foreign languages (translate msg) */
|
||||
/* Public temporary buffer till I can find a better approach */
|
||||
char * hb_sqlite2_aDataRows[ 1024 ];
|
||||
char * hb_sqlite2_aDataCols[ 255 ];
|
||||
int hb_sqlite2_iDataRows = 0; /* records */
|
||||
int hb_sqlite2_iDataCols = 0; /* fields */
|
||||
int hb_sqlite2_iDataRows = 0; /* records */
|
||||
int hb_sqlite2_iDataCols = 0; /* fields */
|
||||
|
||||
/* INTERNAL DO NOT TOUCH !!! */
|
||||
static int hb_sqlite2_callback( void * NotUsed, int argc, char ** argv, char ** azColName )
|
||||
/* Returns information about current SQLite package */
|
||||
HB_FUNC( SQLITE_INFO )
|
||||
{
|
||||
HB_SYMBOL_UNUSED( NotUsed );
|
||||
HB_SYMBOL_UNUSED( argc );
|
||||
HB_SYMBOL_UNUSED( argv );
|
||||
HB_SYMBOL_UNUSED( azColName );
|
||||
|
||||
#if 0
|
||||
{
|
||||
int i;
|
||||
|
||||
/* in arg is the number of data fields for each row */
|
||||
printf("argc =>%d\n", argc);
|
||||
|
||||
for( i = 0; i < argc; i++)
|
||||
{
|
||||
printf(">>> %s = %s\n", azColName[ i ], argv[ i ] ? argv[ i ] : "NULL" );
|
||||
hb_sqlite2_aDataCols[ i ] = azColName[ i ]; /* en realidad copiar cadena a cadena */
|
||||
hb_sqlite2_aDataRows[ i ] = argv[ i ];
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns a string explaining last error */
|
||||
HB_FUNC( SQLITE_ERROR )
|
||||
{
|
||||
if( hb_sqlite2_szErrMsg )
|
||||
hb_retc( hb_sqlite2_szErrMsg );
|
||||
hb_reta( 3 );
|
||||
hb_storc( ( char * ) SQLITE_VERSION , -1, 1 );
|
||||
hb_storc( ( char * ) sqlite_libversion() , -1, 2 );
|
||||
hb_storc( ( char * ) sqlite_libencoding(), -1, 3 );
|
||||
}
|
||||
|
||||
/* Open a database file (in SQLite format) and set a public structure */
|
||||
HB_FUNC( SQLITE_OPEN )
|
||||
{
|
||||
char * szDB = hb_parc( 1 );
|
||||
int iMode = 0; /* hb_parni( 2 ); */
|
||||
if( hb_sqlite2_db )
|
||||
sqlite_close( hb_sqlite2_db );
|
||||
|
||||
HB_SYMBOL_UNUSED( iMode );
|
||||
hb_sqlite2_db = ( sqlite * ) sqlite_open( hb_parcx( 1 ), 0, &hb_sqlite2_szErrMsg );
|
||||
|
||||
hb_sqlite2_db = ( sqlite * ) sqlite_open( szDB, 0, &hb_sqlite2_szErrMsg );
|
||||
hb_retni( hb_sqlite2_db == NULL ? 1 : 0 ); /* error: 1 */
|
||||
}
|
||||
|
||||
/* It seems Borland BCC55 do not return a correct pointer to a sqlite
|
||||
/ struc, thus I can't check if database was successfully open :( */
|
||||
/* Close currently open database */
|
||||
HB_FUNC( SQLITE_CLOSE )
|
||||
{
|
||||
if( hb_sqlite2_db )
|
||||
{
|
||||
sqlite_close( hb_sqlite2_db );
|
||||
hb_sqlite2_db = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
( sqlite * )
|
||||
printf("\n %lu ", hb_sqlite2_db->flags, );
|
||||
#endif
|
||||
|
||||
hb_retni( hb_sqlite2_db == 0 ? 1 : 0 ); // error: 1
|
||||
/* Execute a statment (not a query) over the database */
|
||||
HB_FUNC( SQLITE_EXECUTE )
|
||||
{
|
||||
if( hb_sqlite2_db )
|
||||
hb_retni( sqlite_exec( hb_sqlite2_db, hb_parcx( 1 ), NULL, NULL, &hb_sqlite2_szErrMsg ) );
|
||||
}
|
||||
|
||||
/* Execute a query over the passed table */
|
||||
HB_FUNC( SQLITE_QUERY )
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
char * szSQLcom = hb_parc( 1 );
|
||||
char * szSQLcom = hb_parcx( 1 );
|
||||
|
||||
hb_sqlite2_iDataRows = 0; // reset global records
|
||||
hb_sqlite2_iDataCols = 0; // reset global fields
|
||||
|
||||
/* reset temporary store */
|
||||
for( i = 0; i < 255; i++ )
|
||||
hb_sqlite2_aDataCols[ i ] = 0L;
|
||||
|
||||
for( i = 0; i < 1024; i++ )
|
||||
hb_sqlite2_aDataRows[ i ] = 0L;
|
||||
|
||||
rc = sqlite_exec( hb_sqlite2_db, szSQLcom, hb_sqlite2_callback, 0, &hb_sqlite2_szErrMsg );
|
||||
|
||||
/* Check the operation's result */
|
||||
if( rc == SQLITE_OK )
|
||||
if( hb_sqlite2_db && sqlite_exec( hb_sqlite2_db, szSQLcom, NULL, NULL, &hb_sqlite2_szErrMsg ) == SQLITE_OK )
|
||||
{
|
||||
int iResRows = 0;
|
||||
int iResCols = 0;
|
||||
@@ -156,7 +105,7 @@ HB_FUNC( SQLITE_QUERY )
|
||||
char * pErrmsg;
|
||||
char ** pResStr;
|
||||
PHB_ITEM paRows;
|
||||
PHB_ITEM paCols;
|
||||
int i;
|
||||
|
||||
/* put here a routine to process results */
|
||||
sqlite_get_table( hb_sqlite2_db, /* An open database */
|
||||
@@ -174,65 +123,115 @@ HB_FUNC( SQLITE_QUERY )
|
||||
/* quiero devolver un array bidimensional donde la cantidad de filas
|
||||
es rows +1 (ó reccords +1 ) y las columnas los campos
|
||||
la primer fila contiene los encabezados de los campos */
|
||||
#if 0
|
||||
for( iRec = 0, i = 0; iRec < iResRows + 1; iRec++ )
|
||||
{
|
||||
for( iField = 0; iField < iResCols; iField++, i++ )
|
||||
printf("%s\t", (pResStr)[ i ] );
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
/* dimension rows array */
|
||||
paRows = hb_itemArrayNew( iResRows + 1 );
|
||||
i = 0;
|
||||
|
||||
for( iRec = 0; iRec < iResRows + 1; iRec++ )
|
||||
for( iRec = 0, i = 0; iRec < iResRows + 1; iRec++ )
|
||||
{
|
||||
/* if it's a multidimensional array */
|
||||
if( iResCols > 1 )
|
||||
if( iResCols > 1 ) /* if it's a multidimensional array */
|
||||
{
|
||||
paCols = hb_itemArrayNew( iResCols );
|
||||
PHB_ITEM paCols = hb_itemArrayNew( iResCols );
|
||||
|
||||
/* for every field */
|
||||
for( iField = 0; iField < iResCols; iField++ )
|
||||
hb_arraySetC( paCols, iField + 1, pResStr[ i++ ] );
|
||||
|
||||
/* put data onto subarray of records */
|
||||
hb_itemArrayPut( paRows, iRec + 1, paCols);
|
||||
hb_itemArrayPut( paRows, iRec + 1, paCols );
|
||||
hb_itemRelease( paCols );
|
||||
}
|
||||
/* is an unidimensional array */
|
||||
else
|
||||
else /* is an unidimensional array */
|
||||
hb_arraySetC( paRows, iRec + 1, pResStr[ i++ ] );
|
||||
}
|
||||
|
||||
/* free memory allocated */
|
||||
sqlite_free_table( pResStr );
|
||||
|
||||
hb_itemReturn( paRows ); /* final, return to harbour & release */
|
||||
hb_itemRelease( paRows );
|
||||
hb_itemReturnRelease( paRows );
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_sqlite2_iLastErrCode = rc; /* set last error */
|
||||
hb_reta( 0 );
|
||||
}
|
||||
|
||||
/* Returns an unidimensional array with FIELD NAMES only */
|
||||
HB_FUNC( SQLITE_SYSCOLUMNS )
|
||||
{
|
||||
if( hb_sqlite2_db )
|
||||
{
|
||||
struct Table * pTable = ( struct Table * ) sqliteFindTable( hb_sqlite2_db, ( const char * ) hb_parcx( 1 ), NULL );
|
||||
|
||||
if( pTable )
|
||||
{
|
||||
/* dimension rows array:
|
||||
1 is table name
|
||||
2 is field number
|
||||
3 to n cols data */
|
||||
PHB_ITEM paRows = hb_itemArrayNew( 2 + pTable->nCol );
|
||||
int iField;
|
||||
|
||||
/* the Table structure itself */
|
||||
hb_arraySetC( paRows, 1, pTable->zName ); /* save name of table */
|
||||
hb_arraySetNL( paRows, 2, pTable->nCol ); /* save number of cols/fields */
|
||||
|
||||
for( iField = 0; iField < pTable->nCol; iField++ )
|
||||
{
|
||||
/* it's a multidimensional array */
|
||||
/* four data columns name, default, type, isprimarykey per field */
|
||||
PHB_ITEM paCols = hb_itemArrayNew( 4 );
|
||||
|
||||
hb_arraySetC( paCols, 1, pTable->aCol[ iField ].zName );
|
||||
hb_arraySetC( paCols, 2, pTable->aCol[ iField ].zDflt );
|
||||
hb_arraySetC( paCols, 3, pTable->aCol[ iField ].zType );
|
||||
hb_arraySetL( paCols, 4, pTable->aCol[ iField ].isPrimKey );
|
||||
|
||||
/* put data onto subarray of records */
|
||||
hb_itemArrayPut( paRows, 3 + iField, paCols );
|
||||
hb_itemRelease( paCols );
|
||||
}
|
||||
|
||||
hb_itemReturnRelease( paRows );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
hb_reta( 0 );
|
||||
}
|
||||
|
||||
/* Close currently open database */
|
||||
HB_FUNC( SQLITE_CLOSE )
|
||||
/* Returns an unidimensional array with field names only */
|
||||
HB_FUNC( SQLITE_FIELDS )
|
||||
{
|
||||
sqlite_close( hb_sqlite2_db );
|
||||
if( hb_sqlite2_db )
|
||||
{
|
||||
struct Table * pTable = ( struct Table * ) sqliteFindTable( hb_sqlite2_db, ( const char * ) hb_parcx( 1 ), NULL );
|
||||
|
||||
if( pTable )
|
||||
{
|
||||
int i;
|
||||
|
||||
/* the Table structure itself */
|
||||
hb_reta( pTable->nCol );
|
||||
|
||||
for( i = 0; i < pTable->nCol; i++ )
|
||||
hb_storc( pTable->aCol[ i ].zName, -1, 1 + i );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
hb_reta( 0 );
|
||||
}
|
||||
|
||||
/* Returns information about current SQLite package */
|
||||
HB_FUNC( SQLITE_INFO )
|
||||
/* Returns number of tables inside current open database (not table) */
|
||||
HB_FUNC( SQLITE_NUMOFTABLES )
|
||||
{
|
||||
hb_reta( 3 );
|
||||
hb_storc( ( char * ) SQLITE_VERSION , -1, 1 );
|
||||
hb_storc( ( char * ) sqlite_libversion() , -1, 2 );
|
||||
hb_storc( ( char * ) sqlite_libencoding(), -1, 3 );
|
||||
hb_retni( hb_sqlite2_db ? hb_sqlite2_db->nTable - 2 : 0 );
|
||||
}
|
||||
|
||||
/* Returns a string explaining last error */
|
||||
HB_FUNC( SQLITE_ERROR )
|
||||
{
|
||||
hb_retc( hb_sqlite2_szErrMsg );
|
||||
}
|
||||
|
||||
/* Returns the number of rows resulting from last operation */
|
||||
@@ -246,111 +245,3 @@ HB_FUNC( SQLITE_GETCOLS )
|
||||
{
|
||||
hb_retni( hb_sqlite2_iDataCols );
|
||||
}
|
||||
|
||||
/* Execute a statment (not a query) over the database */
|
||||
HB_FUNC( SQLITE_EXECUTE )
|
||||
{
|
||||
int rc, i; /* , iRec, iField; */
|
||||
char * szSQLcom = hb_parc( 1 );
|
||||
|
||||
hb_sqlite2_iDataRows = 0; /* reset global records */
|
||||
hb_sqlite2_iDataCols = 0; /* reset global fields */
|
||||
|
||||
/* reset temporary store */
|
||||
for( i = 0; i < 255; i++ )
|
||||
hb_sqlite2_aDataCols[ i ] = 0L;
|
||||
|
||||
for( i = 0; i < 1024; i++ )
|
||||
hb_sqlite2_aDataRows[ i ] = 0L;
|
||||
|
||||
rc = sqlite_exec( hb_sqlite2_db, szSQLcom, hb_sqlite2_callback, 0, &hb_sqlite2_szErrMsg );
|
||||
|
||||
/* Check the operation's result */
|
||||
if( rc != SQLITE_OK )
|
||||
{
|
||||
hb_sqlite2_iLastErrCode = rc; /* set last error */
|
||||
hb_retni( rc ); /* return last error also */
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns an unidimensional array with FIELD NAMES only */
|
||||
HB_FUNC( SQLITE_SYSCOLUMNS )
|
||||
{
|
||||
struct Table * pTable = ( struct Table * ) sqliteFindTable( hb_sqlite2_db, ( const char * ) hb_parc( 1 ), 0 );
|
||||
|
||||
if( pTable )
|
||||
{
|
||||
int iField;
|
||||
PHB_ITEM paRows;
|
||||
PHB_ITEM paCols;
|
||||
|
||||
/* dimension rows array:
|
||||
1 is table name
|
||||
2 is field number
|
||||
3 to n cols data */
|
||||
|
||||
paRows = hb_itemArrayNew( 2 + pTable->nCol );
|
||||
|
||||
/* the Table structure itself */
|
||||
hb_arraySetC( paRows, 1, pTable->zName ); /* save name of table */
|
||||
hb_arraySetNL( paRows, 2, pTable->nCol ); /* save number of cols/fields */
|
||||
|
||||
#if 0
|
||||
printf("\n\nName= %s", pTable->zName );
|
||||
printf("\n\nCols = %i", pTable->nCol );
|
||||
|
||||
for( i = 0; i < pTable->nCol; i++)
|
||||
{
|
||||
printf("\n Name= %s", pTable->aCol[ i ].zName );
|
||||
printf("\n Dflt= %s", pTable->aCol[ i ].zDflt );
|
||||
printf("\n Type= %s", pTable->aCol[ i ].zType );
|
||||
printf("\nPrimKey= %i", pTable->aCol[ i ].isPrimKey );
|
||||
}
|
||||
#endif
|
||||
|
||||
for( iField = 0; iField < pTable->nCol; iField++ )
|
||||
{
|
||||
/* it's a multidimensional array */
|
||||
/* four data columns name, default, type, isprimarykey per field */
|
||||
|
||||
paCols = hb_itemArrayNew( 4 );
|
||||
|
||||
hb_arraySetC( paCols, 1, pTable->aCol[ iField ].zName );
|
||||
hb_arraySetC( paCols, 2, pTable->aCol[ iField ].zDflt );
|
||||
hb_arraySetC( paCols, 3, pTable->aCol[ iField ].zType );
|
||||
hb_arraySetL( paCols, 4, pTable->aCol[ iField ].isPrimKey );
|
||||
|
||||
/* put data onto subarray of records */
|
||||
hb_itemArrayPut( paRows, 3 + iField, paCols );
|
||||
|
||||
hb_itemRelease( paCols );
|
||||
}
|
||||
|
||||
hb_itemReturnRelease( paRows );
|
||||
}
|
||||
else
|
||||
hb_reta( 0 );
|
||||
}
|
||||
|
||||
/* Returns an unidimensional array with field names only */
|
||||
HB_FUNC( SQLITE_FIELDS )
|
||||
{
|
||||
struct Table * pTable = ( struct Table * ) sqliteFindTable( hb_sqlite2_db, ( const char * ) hb_parc( 1 ), 0 );
|
||||
|
||||
if( pTable )
|
||||
{
|
||||
int i;
|
||||
|
||||
// the Table structure itself
|
||||
hb_reta( pTable->nCol );
|
||||
|
||||
for( i = 0; i < pTable->nCol; i++ )
|
||||
hb_storc( pTable->aCol[ i ].zName, -1, 1 + i );
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns number of tables inside current open database (not table) */
|
||||
HB_FUNC( SQLITE_NUMOFTABLES )
|
||||
{
|
||||
hb_retni( hb_sqlite2_db ? hb_sqlite2_db->nTable - 2 : 0 );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user