2002-07-03 14:48:48 +00:00
# define __ISAM_CPP
1994-11-24 14:01:20 +00:00
1994-09-27 10:19:36 +00:00
# include <config.h>
2002-07-03 14:48:48 +00:00
# include <execp.h>
# include <expr.h>
1994-08-12 10:52:49 +00:00
# include <extcdecl.h>
2007-03-06 16:37:44 +00:00
# include <diction.h>
2009-10-28 10:19:18 +00:00
# include <dongle.h>
2002-12-18 10:56:10 +00:00
# include <mailbox.h>
2000-05-05 15:25:49 +00:00
# include <postman.h>
1994-11-24 14:01:20 +00:00
# include <prefix.h>
2002-07-03 14:48:48 +00:00
# include <progind.h>
2003-10-21 11:10:01 +00:00
# include <recarray.h>
1994-11-24 14:01:20 +00:00
# include <relation.h>
1994-09-27 10:19:36 +00:00
# include <scanner.h>
2008-08-29 10:35:54 +00:00
# include <tabmod.h>
2008-04-04 16:04:15 +00:00
# include <utility.h>
2002-12-18 10:56:10 +00:00
# include <tabutil.h>
1996-09-02 14:20:24 +00:00
# include <varrec.h>
1995-04-10 15:28:03 +00:00
2007-03-06 16:37:44 +00:00
# ifdef WIN32
# include <io.h>
# include <share.h>
# include <stdio.h>
# endif
# include <fcntl.h>
# include <stdlib.h>
# include <sys/stat.h>
# include <codeb.h>
2008-04-04 16:04:15 +00:00
# include <nditte.h>
1998-10-01 13:59:39 +00:00
1995-07-03 07:49:30 +00:00
# define RECLOCKTYPES 0xFF00
# define READTYPES 0x00FF
1996-09-26 15:26:47 +00:00
# define INVFLD 255
1995-07-03 07:49:30 +00:00
1998-11-10 10:07:12 +00:00
bool __field_changed = FALSE ;
1995-07-03 07:49:30 +00:00
1994-08-12 10:52:49 +00:00
# define NOALLOC (char **) -1
1996-09-26 15:26:47 +00:00
HIDDEN bool __autoload = TRUE ;
// @doc INTERNAL
////////////////////////////////////////////////////////////////////////////////////////////////////
// Funzioni C
////////////////////////////////////////////////////////////////////////////////////////////////////
int hashfun ( const char * s )
{
1998-11-10 10:07:12 +00:00
int l = strlen ( s ) ;
1996-09-26 15:26:47 +00:00
unsigned short temp = 0 , * pw = ( unsigned short * ) s ;
const unsigned short * end = ( unsigned short * ) ( s + ( l - 1 ) ) ;
while ( ( char * ) pw < ( char * ) end )
{
temp ^ = * pw ;
pw + + ;
}
2010-02-09 10:11:25 +00:00
if ( l & 1 )
1996-09-26 15:26:47 +00:00
temp ^ = ( unsigned short ) ( 8192 + s [ l - 1 ] ) ;
l = ( short ) ( temp % ( MaxFields - 3 ) ) ;
CHECKS ( l > = 0 , " Negative remainder on " , s ) ;
return ( l ) ;
}
int findfld ( const RecDes * recd , const char * s )
{
1996-11-12 09:09:43 +00:00
short stp = hashfun ( s ) ;
1996-09-26 15:26:47 +00:00
for ( byte i = 0 ; i < MaxFields ; i + + )
{
if ( stp + i > = MaxFields )
stp - = MaxFields ;
byte p = stp + i ;
const int fp = recd - > SortFd [ p ] ;
1998-11-10 10:07:12 +00:00
if ( fp = = INVFLD )
return ( FIELDERR ) ;
1996-09-26 15:26:47 +00:00
const int cmp = strcmp ( recd - > Fd [ fp ] . Name , s ) ;
1998-11-10 10:07:12 +00:00
if ( cmp = = 0 )
1996-09-26 15:26:47 +00:00
return ( int ) fp ;
else
1998-11-10 10:07:12 +00:00
if ( cmp > 0 )
return ( FIELDERR ) ;
1996-09-26 15:26:47 +00:00
}
return ( FIELDERR ) ;
}
2012-05-23 14:36:59 +00:00
void __getfieldbuff ( byte l , byte t , const char * recin , TString & s )
1996-09-26 15:26:47 +00:00
{
CHECK ( recin , " Can't read from a Null record " ) ;
if ( t ! = _alfafld & & t ! = _datefld )
{
if ( t = = _intzerofld | | t = = _longzerofld )
{
byte i = 0 ;
for ( char * c = ( char * ) recin ; * c = = ' ' & & i < l ; c + + , i + + )
* c = ' 0 ' ;
if ( i = = l )
l = 0 ;
}
else
{
while ( ( * recin = = ' ' ) & & ( l ) )
{
recin + + ;
l - - ;
}
if ( ( t ! = _realfld ) & & ( t ! = _charfld ) )
{
while ( ( * recin = = ' 0 ' ) & & ( l ) )
{
recin + + ;
l - - ;
}
}
}
}
if ( l )
{
while ( l > 0 & & recin [ l - 1 ] = = ' ' ) l - - ;
if ( l )
2007-02-16 13:48:27 +00:00
s . strncpy ( recin , l ) ;
1996-09-26 15:26:47 +00:00
}
2007-02-16 13:48:27 +00:00
s . cut ( l ) ;
1996-09-26 15:26:47 +00:00
if ( l )
{
if ( t = = _datefld )
{
2007-02-16 13:48:27 +00:00
const TDate dt ( s ) ;
s = dt . string ( full ) ;
1996-09-26 15:26:47 +00:00
}
else
2007-02-16 13:48:27 +00:00
{
1996-09-26 15:26:47 +00:00
if ( t = = _boolfld )
{
const char ok = toupper ( * s ) ;
if ( ok = = ' T ' | | ok = = ' Y ' | | ok = = ' S ' | | ok = = ' X ' )
2007-02-16 13:48:27 +00:00
s = " X " ;
1996-09-26 15:26:47 +00:00
else
2007-02-16 13:48:27 +00:00
s . spaces ( 1 ) ;
1996-09-26 15:26:47 +00:00
}
2007-02-16 13:48:27 +00:00
}
1996-09-26 15:26:47 +00:00
}
}
2012-05-23 14:36:59 +00:00
void __putfieldbuff ( byte l , byte d , byte t , const char * s , char * recout )
1996-09-26 15:26:47 +00:00
{
CHECK ( recout , " Can't write null record " ) ;
2007-02-16 13:48:27 +00:00
TString80 s2 ;
1996-09-26 15:26:47 +00:00
if ( t = = _datefld )
{
2005-07-07 17:07:13 +00:00
if ( s & & * s & & strlen ( s ) ! = 8 )
1996-09-26 15:26:47 +00:00
{
const TDate dt ( s ) ;
2007-02-16 13:48:27 +00:00
s2 < < dt . date2ansi ( ) ;
s = s2 . get_buffer ( ) ;
1996-09-26 15:26:47 +00:00
}
}
else
if ( t = = _boolfld )
{
2007-02-16 13:48:27 +00:00
s2 = ( * s & & strchr ( " 1STXY " , toupper ( * s ) ) ! = NULL ) ? " T " : " F " ;
s = s2 . get_buffer ( ) ;
1996-09-26 15:26:47 +00:00
}
else
if ( t = = _realfld )
{
real r ( s ) ;
2007-02-16 13:48:27 +00:00
s2 = r . string ( l , d ) ;
s = s2 . get_buffer ( ) ;
1996-09-26 15:26:47 +00:00
}
2005-07-07 17:07:13 +00:00
int len = strlen ( s ) ;
1997-10-16 14:06:40 +00:00
const bool exceeded = len > l ;
1996-09-26 15:26:47 +00:00
if ( ( t = = _intfld ) | |
( t = = _longfld ) | |
( t = = _wordfld ) | |
( t = = _realfld ) | |
( t = = _intzerofld ) | |
( t = = _longzerofld )
)
{
1997-10-16 14:06:40 +00:00
if ( len = = 0 | | exceeded )
1996-09-26 15:26:47 +00:00
{
2007-02-16 13:48:27 +00:00
s2 = " 0 " ;
s = s2 . get_buffer ( ) ;
1996-09-26 15:26:47 +00:00
len = 1 ;
}
1998-11-10 10:07:12 +00:00
__field_changed = FALSE ;
1996-09-26 15:26:47 +00:00
const char c = ( t = = _intzerofld | | t = = _longzerofld ) ? ' 0 ' : ' ' ;
2005-07-07 17:07:13 +00:00
for ( int i = l - len - 1 ; i > = 0 ; i - - )
1998-11-10 10:07:12 +00:00
{
1999-01-19 09:15:17 +00:00
__field_changed | = ( recout [ i ] ! = c ) ;
1998-11-10 10:07:12 +00:00
recout [ i ] = c ;
}
if ( ! __field_changed )
{
2003-06-24 12:49:44 +00:00
__field_changed = memcmp ( s , recout , l ) ! = 0 ;
1998-11-10 10:07:12 +00:00
if ( ! __field_changed )
return ;
}
1996-09-26 15:26:47 +00:00
strncpy ( & recout [ l - len ] , s , len ) ;
}
else
{
1997-10-16 14:06:40 +00:00
if ( exceeded )
len = l ;
2003-07-21 13:06:37 +00:00
/*
// Il codice seguente e' completamente errato in quanto tutti i prefissi ingannano il test!
// La stringa vuota e' prefisso di qualsiasi stringa
// per cui l'azzeramento di un campo risulta sempre impossibile!
2003-06-24 12:49:44 +00:00
__field_changed = memcmp ( s , recout , len ) ! = 0 ;
1998-11-10 10:07:12 +00:00
if ( ! __field_changed )
return ;
2003-07-21 13:06:37 +00:00
*/
__field_changed = TRUE ; // Per ora e' meglio cosi'
1998-11-10 10:07:12 +00:00
1996-09-26 15:26:47 +00:00
strncpy ( recout , s , len ) ;
2005-07-07 17:07:13 +00:00
for ( int i = l - 1 ; i > = len ; i - - )
1998-11-10 10:07:12 +00:00
recout [ i ] = ' ' ;
1996-09-26 15:26:47 +00:00
}
}
1995-07-03 07:49:30 +00:00
2002-05-31 10:35:40 +00:00
struct TCallbackFileinfo
{
TString16 _var ;
TFilename _app ;
} ;
HIDDEN int find_relapp ( TConfig & cfg , void * jolly )
{
TCallbackFileinfo & info = * ( ( TCallbackFileinfo * ) jolly ) ;
if ( cfg . exist ( info . _var ) )
{
info . _app = cfg . get ( info . _var ) ;
return info . _app . not_empty ( ) ;
}
return FALSE ;
}
bool get_relapp ( int logicnum , TString & app )
{
2009-05-20 15:36:38 +00:00
TConfig ini ( CONFIG_GENERAL ) ;
2002-05-31 10:35:40 +00:00
TCallbackFileinfo fi ;
fi . _var . format ( " Edit_%d " , logicnum ) ;
ini . for_each_paragraph ( find_relapp , & fi ) ;
if ( fi . _app . not_empty ( ) )
app = fi . _app ;
2003-11-03 15:39:51 +00:00
return app . not_empty ( ) ;
2002-05-31 10:35:40 +00:00
}
struct TCallbackTableinfo
{
TString16 _var1 , _var2 , _var3 ;
TString4 _module ;
TFilename _tabapp , _relapp ;
} ;
HIDDEN int find_tabapp ( TConfig & cfg , void * jolly )
{
TCallbackTableinfo & info = * ( ( TCallbackTableinfo * ) jolly ) ;
if ( cfg . exist ( info . _var1 ) )
{
info . _tabapp = cfg . get ( info . _var1 ) ;
if ( info . _tabapp . not_empty ( ) )
return 1 ;
}
if ( cfg . get_paragraph ( ) . compare ( info . _module , 2 , TRUE ) = = 0 )
{
if ( cfg . exist ( info . _var2 ) )
{
info . _relapp = cfg . get ( info . _var2 ) ;
if ( info . _relapp . not_empty ( ) )
return 2 ;
}
2011-02-10 16:20:04 +00:00
if ( info . _var3 . full ( ) & & cfg . exist ( info . _var3 ) )
2002-05-31 10:35:40 +00:00
{
info . _relapp = cfg . get ( info . _var3 ) ;
if ( info . _relapp . not_empty ( ) )
return 3 ;
}
}
return 0 ;
}
2011-02-10 16:20:04 +00:00
bool get_tabapp ( const char * tabname , TString & app )
2002-05-31 10:35:40 +00:00
{
2011-02-10 16:20:04 +00:00
TConfig ini ( CONFIG_GENERAL , " Main " ) ;
2002-05-31 10:35:40 +00:00
TCallbackTableinfo fi ;
TTable t ( tabname ) ;
fi . _var1 . format ( " Edit_%s " , t . name ( ) ) ;
fi . _var2 . format ( " Edit_%d " , t . num ( ) ) ;
2011-02-10 16:20:04 +00:00
fi . _var3 . format ( " Edit_%d " , t . num ( ) = = LF_TABCOM ? LF_TAB : LF_TABCOM ) ;
2002-05-31 10:35:40 +00:00
fi . _module = t . module ( ) ;
ini . for_each_paragraph ( find_tabapp , & fi ) ;
app = fi . _tabapp ;
if ( app . empty ( ) )
app = fi . _relapp ;
2003-11-03 15:39:51 +00:00
2002-05-31 10:35:40 +00:00
if ( app . empty ( ) )
{
app = " ba3 -0 " ;
2011-02-10 16:20:04 +00:00
if ( ! fi . _module . starts_with ( " ba " ) ) // Compatibility mode :-(
2002-05-31 10:35:40 +00:00
{
2011-02-10 16:20:04 +00:00
const TString & tp = ini_get_string ( CONFIG_STUDIO , fi . _module , " TabPrg " ) ;
if ( tp . full ( ) )
app = tp ;
2002-05-31 10:35:40 +00:00
}
}
app < < ' ' < < tabname ;
return tabname & & * tabname > ' ' ;
}
1995-07-03 07:49:30 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////
// Funzioni implementate per la gestione file dati tramite Codebase
////////////////////////////////////////////////////////////////////////////////////////////////////
// Inizio(@)
1996-02-05 19:00:53 +00:00
// @doc INTERNAL
1995-12-12 17:47:56 +00:00
// @func Ritorna una Token_string con in nome dell'indice
2008-12-23 09:05:22 +00:00
int get_table_names (
int logicnum , // @parm Numero logico del file di cui riconoscere l'indice
TToken_string & i_names , // @parm Token_string in cui inserire il nome dell'indice
int mode )
1995-12-12 17:47:56 +00:00
// @comm Ritorna il nome con il prefisso corrente
1995-07-03 07:49:30 +00:00
{
2008-12-04 16:37:47 +00:00
TFilename f = prefix ( ) . get_filename ( logicnum ) ;
1995-07-03 07:49:30 +00:00
i_names . cut ( 0 ) ;
2008-12-23 09:05:22 +00:00
if ( mode & 1 )
i_names = f ;
if ( mode & 2 )
2008-12-04 16:37:47 +00:00
{
2008-12-23 09:05:22 +00:00
f . ext ( " cdx " ) ;
i_names . add ( f ) ;
}
if ( mode & 4 )
{
f . ext ( " fpt " ) ;
if ( f . exist ( ) )
1995-07-03 07:49:30 +00:00
i_names . add ( f ) ;
2008-12-04 16:37:47 +00:00
}
2008-12-23 09:05:22 +00:00
return i_names . items ( ) ;
1995-07-03 07:49:30 +00:00
}
1998-03-30 13:43:36 +00:00
// Converte un errore di codebase in un errore isam
2000-05-05 15:25:49 +00:00
# ifdef DBG
HIDDEN int cb_error = NOERR ;
# endif
1995-07-03 07:49:30 +00:00
int get_error ( int err )
{
1998-03-30 13:43:36 +00:00
// Codici negativi
HIDDEN int error_codes_g [ ] = { - 1 , _isnotopen , - 1 , - 1 , - 1 , _islocked , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , _isfilefull ,
2004-03-12 16:10:04 +00:00
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , _iskeynotfound , _ispatherr , - 1 , - 1 , _isdupkey } ;
1998-03-30 13:43:36 +00:00
// Codici da 0 a 9
HIDDEN int error_codes_ra [ ] = { NOERR , NOERR , _iskeynotfound , _iseof , _isbof , _isnrecerr } ;
// Codici da 10 a ...
HIDDEN int error_codes_rb [ ] = { - 1 , - 1 , _isreinsert , - 1 , - 1 , _islocked , - 1 , _isalropen , _iskeyerr } ;
int isamerr = NOERR ;
2000-05-05 15:25:49 +00:00
2004-03-12 16:10:04 +00:00
# ifdef DBG
2000-05-05 15:25:49 +00:00
if ( err < = 200 | | err > = 230 )
cb_error = err ;
2004-03-12 16:10:04 +00:00
# endif
2000-05-05 15:25:49 +00:00
2004-03-12 16:10:04 +00:00
if ( err > 0 )
{
1995-07-03 07:49:30 +00:00
if ( err > = 10 )
{
2004-03-12 16:10:04 +00:00
if ( err > 80 | | error_codes_rb [ err / 10 ] = = - 1 )
1998-03-30 13:43:36 +00:00
isamerr = err ;
1995-07-03 07:49:30 +00:00
else
1998-03-30 13:43:36 +00:00
isamerr = error_codes_rb [ err / 10 ] ;
1995-07-03 07:49:30 +00:00
}
else
2004-03-12 16:10:04 +00:00
isamerr = error_codes_ra [ err ] ;
1995-07-03 07:49:30 +00:00
}
else
if ( err < 0 )
2004-03-12 16:10:04 +00:00
{
1998-03-30 13:43:36 +00:00
if ( err = = - 1 )
2006-12-13 16:22:33 +00:00
{
# ifdef DBG
int ierr = DB_get_error ( ) ;
# endif
1998-03-30 13:43:36 +00:00
isamerr = _isnotopen ;
2006-12-13 16:22:33 +00:00
}
1998-03-30 13:43:36 +00:00
else
{
int ierr = DB_get_error ( ) ;
if ( ierr = = 0 ) ierr = - err ; // DB_get_error already called
if ( ierr < 0 ) ierr = - ierr ;
2004-03-12 16:10:04 +00:00
if ( ierr > 340 | | error_codes_g [ ierr / 10 ] = = - 1 )
1998-03-30 13:43:36 +00:00
isamerr = - ierr ;
else
isamerr = error_codes_g [ ierr / 10 ] ;
}
2004-03-12 16:10:04 +00:00
}
DB_zero_error ( ) ;
1998-03-30 13:43:36 +00:00
return isamerr ;
1995-07-03 07:49:30 +00:00
}
1999-10-22 10:00:18 +00:00
// Used also by varrec
2008-12-23 09:05:22 +00:00
bool rec_has_memo ( const RecDes & rd )
2004-03-12 16:10:04 +00:00
{
2008-12-23 09:05:22 +00:00
for ( int i = rd . NFields - 1 ; i > = 0 ; i - - )
if ( rd . Fd [ i ] . TypeF = = _memofld )
return true ;
return false ;
2004-03-12 16:10:04 +00:00
}
1995-12-06 14:44:14 +00:00
2001-05-04 10:59:04 +00:00
HIDDEN bool lf_has_memo ( int lffile )
2004-03-12 16:10:04 +00:00
{
2008-12-23 09:05:22 +00:00
return rec_has_memo ( prefix ( ) . get_recdes ( lffile ) ) ;
2004-03-12 16:10:04 +00:00
}
2001-05-04 10:59:04 +00:00
1995-07-03 07:49:30 +00:00
HIDDEN void browse_null ( char * start , int nc )
2004-03-12 16:10:04 +00:00
{
1995-07-03 07:49:30 +00:00
for ( int i = nc - 1 ; i > = 0 ; i - - ) // Anche il primo byte(deletion flag) deve essere cambiato. nc comprende il primo byte
if ( start [ i ] = = ' \0 ' ) start [ i ] = ' ' ;
}
2004-03-12 16:10:04 +00:00
// Traduce l'espressione chiave di CodeBase
1995-07-03 07:49:30 +00:00
2004-03-12 16:10:04 +00:00
/*HIDDEN const char * translate_key(const char* key)
2000-05-05 15:25:49 +00:00
{
// Trasforma l'espressione
2003-05-16 13:13:39 +00:00
TToken_string t = key ;
2000-05-05 15:25:49 +00:00
TToken_string k ( t . get ( 0 ) , ' + ' ) ;
TToken_string range ( " " , ' , ' ) ;
TString ws ;
const bool is_dup = t . get ( 1 ) [ 0 ] = = ' X ' ;
const int items = k . items ( ) ;
t = " " ;
for ( int i = 0 ; i < items ; i + + ) // scorre i campi dell'espressione
{
ws = k . get ( i ) ; ws . upper ( ) ; // Primo campo
const bool is_upper = ws . find ( " UPPER " ) > = 0 ;
const bool is_sub = ws . find ( " SUBSTR " ) > = 0 ;
int paren1 = ws . find ( ' ( ' ) ; // Trova la prima parentesi aperta
2004-03-12 16:10:04 +00:00
int paren2 , last , from = 0 , to = 0 ;
2000-05-05 15:25:49 +00:00
if ( paren1 > = 0 & & is_sub & & is_upper )
paren1 = ws . find ( ' ( ' ) ; // Trova la seconda parentesi (in questo caso c'e' per forza)
if ( paren1 > = 0 ) // Trova la prima virgola o parentesi chiusa (per qualsiasi espressione)
{
paren2 = ws . find ( ' , ' ) ;
if ( paren2 = = - 1 ) // se non ci sono virgole trova la parentesi chiusa
paren2 = ws . find ( ' ) ' ) ;
CHECK ( paren2 > paren1 , " Something wrong happened translating CodeBase expressions. " ) ;
if ( is_sub ) // Se e' una sottostringa estrae i campi DA e A
{
range = ws ;
last = ws . find ( ' ) ' ) ;
range . sub ( paren2 , last ) ; // dalla virgola alla parentesi
from = range . get_int ( 0 ) ;
to = range . get_int ( 1 ) ;
}
ws = ws . sub ( paren1 + 1 , paren2 ) ; // Nome del campo pulito pulito
ws . upper ( ) ;
}
if ( is_upper )
t < < " UPPER( " ;
t < < ws ; // aggiunge il nome del campo
if ( is_sub )
{
t < < " [ " ;
t < < from < < " , " ;
t < < to < < " ] " ;
}
if ( is_upper )
t < < " ) " ;
t < < ' + ' ;
}
t . rtrim ( 1 ) ; // Toglie il + in piu'
t . add ( is_dup ? " X " : " " ) ;
2003-05-16 13:13:39 +00:00
TString & tmp = get_tmp_string ( ) ;
tmp = t ;
return tmp ;
2004-03-12 16:10:04 +00:00
} */
2000-05-05 15:25:49 +00:00
2009-01-15 15:16:02 +00:00
HIDDEN int __build_key ( const RecDes & recd , int numkey , const RecType recin , char * key , bool build_x_cb )
1995-07-05 11:12:13 +00:00
/* *recd; descrittore record */
/* numkey; numero chiave */
/* recin; buffer contenente il record */
/* *key; valore della chiave */
/* build_x_cb flag di costruzione per codebase */
1995-11-13 12:08:59 +00:00
{
CHECKD ( numkey > 0 , " Can't build key " , numkey ) ;
1997-02-03 15:12:38 +00:00
1997-03-28 12:07:58 +00:00
const char null_char = - 1 ;
1995-07-05 14:38:49 +00:00
key [ 0 ] = ' \0 ' ;
2008-12-10 16:52:43 +00:00
if ( numkey - - < = recd . NKeys )
1995-07-05 14:38:49 +00:00
{
1996-05-10 09:26:40 +00:00
int l = 0 ;
2008-12-10 16:52:43 +00:00
for ( int i = 0 ; i < recd . Ky [ numkey ] . NkFields ; i + + )
1995-07-05 14:38:49 +00:00
{
2008-12-10 16:52:43 +00:00
const KeyDes & kd = recd . Ky [ numkey ] ;
1995-07-05 14:38:49 +00:00
const bool upp = kd . FieldSeq [ i ] > MaxFields ;
const int nf = upp ? kd . FieldSeq [ i ] - MaxFields : kd . FieldSeq [ i ] ;
2008-12-10 16:52:43 +00:00
const RecFieldDes & rf = recd . Fd [ nf ] ;
1996-05-10 09:26:40 +00:00
const TFieldtypes f = ( TFieldtypes ) rf . TypeF ;
1995-07-05 14:38:49 +00:00
int off , len ;
if ( kd . FromCh [ i ] = = 255 )
1995-07-03 07:49:30 +00:00
{
1995-07-05 14:38:49 +00:00
off = rf . RecOff ;
len = rf . Len ;
1995-07-03 07:49:30 +00:00
}
else
{
1995-07-05 14:38:49 +00:00
off = rf . RecOff + kd . FromCh [ i ] ;
len = kd . ToCh [ i ] - kd . FromCh [ i ] + 1 ;
1995-07-03 07:49:30 +00:00
}
2009-11-08 22:17:25 +00:00
if ( ( l + len ) > 255 )
1995-07-03 07:49:30 +00:00
{
1995-07-05 14:38:49 +00:00
key [ 0 ] = ' \0 ' ;
1995-07-03 07:49:30 +00:00
return ( _iskeylenerr ) ;
}
1996-09-26 15:26:47 +00:00
if ( f = = _boolfld )
1996-05-30 13:53:00 +00:00
{
const bool on = * ( recin + off ) > ' ' & & strchr ( " STXY " , * ( recin + off ) ) ! = NULL ;
key [ l ] = on ? ' T ' : ' F ' ;
}
else
1996-05-10 09:26:40 +00:00
strncpy ( ( key + l ) , ( recin + off ) , len ) ;
1995-07-05 14:38:49 +00:00
if ( recin [ off ] = = ' \0 ' )
{
memset ( key + l , ' ' , len ) ;
1997-02-03 15:12:38 +00:00
if ( ( f = = _intfld ) | | ( f = = _longfld ) | | ( f = = _wordfld ) | |
( f = = _intzerofld ) | | ( f = = _longzerofld ) )
key [ l + len - 1 ] = build_x_cb ? ' 0 ' : null_char ;
1995-07-05 14:38:49 +00:00
}
1995-07-03 07:49:30 +00:00
else
1995-07-19 09:57:25 +00:00
if ( ( f = = _intfld ) | | ( f = = _longfld ) | | ( f = = _wordfld ) | | ( f = = _intzerofld ) | | ( f = = _longzerofld ) )
1995-07-05 14:38:49 +00:00
{
1995-07-03 07:49:30 +00:00
int w = l , j = l + len ;
while ( w < j & & key [ w ] = = ' ' ) w + + ;
1995-07-06 15:05:23 +00:00
while ( w < j & & key [ w ] = = ' 0 ' ) key [ w + + ] = ' ' ;
1997-06-02 10:06:58 +00:00
if ( w = = j ) key [ w - 1 ] = build_x_cb ? ' 0 ' : null_char ;
1995-07-06 15:05:23 +00:00
}
1995-07-05 14:38:49 +00:00
if ( upp )
for ( int i = l + len - 1 ; i > = l ; i - - )
key [ i ] = toupper ( key [ i ] ) ;
1995-07-03 07:49:30 +00:00
l + = len ;
}
1995-07-05 14:38:49 +00:00
1996-05-10 09:26:40 +00:00
// rtrim
1997-02-03 15:12:38 +00:00
if ( build_x_cb )
{
for ( l - - ; l > = 0 & & key [ l ] = = ' ' ; l - - ) ;
key [ l + 1 ] = ' \0 ' ;
}
else
{
for ( l - - ; l > = 0 & & ( key [ l ] = = ' ' | | key [ l ] = = null_char ) ; l - - ) ;
key [ l + 1 ] = ' \0 ' ;
for ( ; l > = 0 ; l - - )
if ( key [ l ] = = null_char )
key [ l ] = ' 0 ' ;
}
1995-07-03 07:49:30 +00:00
return ( NOERR ) ;
}
return ( _ispatherr ) ;
}
1998-03-30 13:43:36 +00:00
HIDDEN int cisread ( int fhnd , int knum , TRectype & record , int mode , TRecnotype & curr_recno )
1995-07-03 07:49:30 +00:00
{
1998-07-20 13:07:00 +00:00
CHECKD ( fhnd > = 0 , " Can't use codebase handle " , fhnd ) ;
1998-03-30 13:43:36 +00:00
const int rmode = ( mode & READTYPES ) ;
const int lmode = ( mode & RECLOCKTYPES ) ;
1995-07-05 14:38:49 +00:00
1995-07-03 07:49:30 +00:00
// Non usare mai _isnextn o _isprevn, usare il metodo skip!
1995-07-05 14:38:49 +00:00
CHECK ( rmode ! = _isnextn & & rmode ! = _isprevn , " _isnextn and _isprevn not supported in cisread " ) ;
1995-07-03 07:49:30 +00:00
1998-03-30 13:43:36 +00:00
TString256 keystr ;
char * key = keystr . get_buffer ( ) ;
2005-01-18 11:15:37 +00:00
int err = NOERR ;
1995-07-03 07:49:30 +00:00
do
1996-05-10 09:26:40 +00:00
{
1998-03-30 13:43:36 +00:00
if ( rmode > = _isequal & & rmode < = _isgteq )
1995-07-03 07:49:30 +00:00
{
2008-12-10 16:52:43 +00:00
const RecDes & r = record . rec_des ( ) ;
1998-03-30 13:43:36 +00:00
err = __build_key ( r , knum , record . string ( ) , key , TRUE ) ;
1995-07-03 07:49:30 +00:00
if ( err = = NOERR )
{
1998-03-30 13:43:36 +00:00
err = DB_seek ( fhnd , key ) ;
if ( err = = NOERR & & rmode = = _isgreat )
err = DB_next ( fhnd ) ;
1995-11-07 10:05:30 +00:00
if ( err ! = NOERR )
err = get_error ( err ) ;
1995-07-03 07:49:30 +00:00
}
1995-11-07 10:05:30 +00:00
if ( rmode ! = _isequal & & err = = _iskeynotfound )
err = NOERR ;
1995-07-03 07:49:30 +00:00
}
1995-07-05 14:38:49 +00:00
else
{
if ( rmode = = _isfirst )
1998-03-30 13:43:36 +00:00
err = DB_first ( fhnd ) ;
1997-12-02 12:05:16 +00:00
else
if ( rmode = = _islast )
1998-03-30 13:43:36 +00:00
err = DB_last ( fhnd ) ;
1997-12-02 12:05:16 +00:00
else
if ( rmode = = _isnext )
{
1998-03-30 13:43:36 +00:00
if ( curr_recno ! = DB_recno ( fhnd ) )
1997-12-02 12:05:16 +00:00
{
2008-12-10 16:52:43 +00:00
const RecDes & r = record . rec_des ( ) ;
1998-03-30 13:43:36 +00:00
err = __build_key ( r , knum , record . string ( ) , key , TRUE ) ;
1997-12-02 12:05:16 +00:00
if ( err = = NOERR )
{
1998-03-30 13:43:36 +00:00
err = DB_seek ( fhnd , key ) ;
1997-12-02 12:05:16 +00:00
err = get_error ( err ) ;
2000-05-05 15:25:49 +00:00
if ( err ! = NOERR & & err ! = _iskeynotfound & & err ! = _iseof )
1997-12-02 12:05:16 +00:00
fatal_box ( " Errore nella next %d : non posso riposizionarmi " , err ) ;
else
if ( err = = NOERR )
1998-03-30 13:43:36 +00:00
err = DB_next ( fhnd ) ;
1997-12-02 12:05:16 +00:00
}
}
else
1998-03-30 13:43:36 +00:00
err = DB_next ( fhnd ) ;
1997-12-02 12:05:16 +00:00
}
else
if ( rmode = = _isprev )
{
1998-03-30 13:43:36 +00:00
if ( curr_recno ! = DB_recno ( fhnd ) )
1997-12-02 12:05:16 +00:00
{
2008-12-10 16:52:43 +00:00
const RecDes & r = record . rec_des ( ) ;
1998-03-30 13:43:36 +00:00
err = __build_key ( r , knum , record . string ( ) , key , TRUE ) ;
1997-12-02 12:05:16 +00:00
if ( err = = NOERR )
{
1998-03-30 13:43:36 +00:00
err = DB_seek ( fhnd , key ) ;
1997-12-02 12:05:16 +00:00
err = get_error ( err ) ;
2000-05-05 15:25:49 +00:00
if ( err ! = NOERR & & err ! = _iskeynotfound & & err ! = _iseof )
fatal_box ( " Errore nella prev %d : non posso riposizionarmi " , err ) ;
1997-12-02 12:05:16 +00:00
else
if ( err = = NOERR )
1998-03-30 13:43:36 +00:00
err = DB_prev ( fhnd ) ;
1997-12-02 12:05:16 +00:00
}
}
else
1998-03-30 13:43:36 +00:00
err = DB_prev ( fhnd ) ;
1997-12-02 12:05:16 +00:00
}
else
if ( rmode = = _iscurr )
1998-03-30 13:43:36 +00:00
err = DB_go ( fhnd , DB_recno ( fhnd ) ) ;
if ( err ! = NOERR )
err = get_error ( err ) ;
1995-07-05 14:38:49 +00:00
}
1995-07-04 14:06:19 +00:00
if ( err = = _iseof )
1998-03-30 13:43:36 +00:00
DB_last ( fhnd ) ;
1995-07-04 07:31:04 +00:00
if ( err = = NOERR & & ( lmode = = _lock | | lmode = = _testandlock ) ) // _lock e _testandlock
{
1998-03-30 13:43:36 +00:00
err = DB_lock ( fhnd ) ;
if ( err ! = NOERR )
err = get_error ( err ) ;
if ( err = = _islocked & & lmode = = _testandlock )
break ;
1995-07-04 07:31:04 +00:00
}
1995-09-14 13:12:18 +00:00
if ( err = = _islocked )
1995-07-03 07:49:30 +00:00
{
2008-12-10 16:52:43 +00:00
const RecDes & r = record . rec_des ( ) ;
record = ( const char * ) DB_getrecord ( fhnd ) ;
1998-03-30 13:43:36 +00:00
__build_key ( r , knum , record . string ( ) , key , TRUE ) ;
1995-07-03 07:49:30 +00:00
message_box ( " Codice %s in uso da parte \n di un altro utente. " , key ) ;
2000-05-05 15:25:49 +00:00
if ( lmode ! = _lock )
break ;
1995-07-03 07:49:30 +00:00
}
1995-09-14 13:12:18 +00:00
} while ( err = = _islocked ) ;
1995-07-05 14:38:49 +00:00
if ( err = = NOERR & & lmode = = _unlock )
1995-07-03 07:49:30 +00:00
{
1998-03-30 13:43:36 +00:00
err = DB_unlock ( fhnd ) ;
if ( err ! = NOERR )
err = get_error ( err ) ;
1995-07-03 07:49:30 +00:00
}
1996-09-26 15:26:47 +00:00
1998-03-30 13:43:36 +00:00
curr_recno = DB_recno ( fhnd ) ;
record = ( const char * ) DB_getrecord ( fhnd ) ;
1995-07-03 07:49:30 +00:00
1998-03-30 13:43:36 +00:00
return err ;
1995-07-03 07:49:30 +00:00
}
1997-06-02 10:06:58 +00:00
1995-07-03 07:49:30 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////
// Funzioni implementate per la gestione file dati tramite Codebase
////////////////////////////////////////////////////////////////////////////////////////////////////
// Fine(@)
1996-02-05 19:00:53 +00:00
// @doc EXTERNAL
1995-12-12 17:47:56 +00:00
// @func Setta il valore della variabile <p __autoload>
void set_autoload_new_files (
bool on ) // @parm Valore da assegnare
// @comm Il valore di <p __autoload> indica il caricamento dei valori standard dei file
1994-10-31 16:24:26 +00:00
{
__autoload = on ;
}
1995-02-10 17:42:33 +00:00
///////////////////////////////////////////////////////////
// TBaseisamfile
///////////////////////////////////////////////////////////
1998-03-13 10:25:37 +00:00
TBaseisamfile : : TBaseisamfile ( int logicnum )
1994-08-12 10:52:49 +00:00
{
1994-08-22 11:10:49 +00:00
_logicnum = logicnum ;
1998-03-30 13:43:36 +00:00
_isam_handle = 0 ;
_curr_key = 0 ;
1994-08-22 11:10:49 +00:00
_lasterr = NOERR ;
2001-05-04 10:59:04 +00:00
_current = new TRectype ( logicnum ) ;
1994-08-12 10:52:49 +00:00
}
1997-07-22 09:49:11 +00:00
// @doc EXTERNAL
// @mfunc Reperisce il tracciato dal file stesso.
//
TBaseisamfile : : TBaseisamfile (
2001-05-04 10:59:04 +00:00
const char * name , // @parm Indica il nome del file
const char * descname ) // @parm Indica la descrizione del file
1997-07-22 09:49:11 +00:00
// @comm Esiste la possibilita' di codificare i valori di pathpref e prefix in <p name>
// % si riferisce ai dati comuni
// $ si riferisce ai dati di ditta corrente
// # si riferisce al direttorio indicato da PATHPREF.INI
{
2001-05-04 10:59:04 +00:00
if ( descname & & * descname )
{
TTrec r ;
ifstream f ( descname ) ;
f > > r ;
2008-12-10 16:52:43 +00:00
const int err = DB_build ( name , & r . rec ( ) ) ;
2001-05-04 10:59:04 +00:00
if ( err ! = NOERR )
fatal_box ( " Non posso creare il file %s : errore n.ro %d " , name , err ) ;
}
1997-07-22 09:49:11 +00:00
_lasterr = NOERR ;
2002-05-08 16:25:49 +00:00
TFilename filename ( name ) ;
2008-05-15 14:59:21 +00:00
CHECK ( filename . full ( ) , " Must define the file to open! " ) ;
2001-05-07 13:27:50 +00:00
_logicnum = prefix ( ) . get_handle ( filename ) ;
2002-05-08 16:25:49 +00:00
_current = new TRectype ( this ) ;
1997-07-22 09:49:11 +00:00
}
1994-08-12 10:52:49 +00:00
TBaseisamfile : : ~ TBaseisamfile ( )
{
1998-03-13 10:25:37 +00:00
if ( _current )
1994-08-12 10:52:49 +00:00
delete _current ;
}
1998-03-30 13:43:36 +00:00
TCodeb_handle TBaseisamfile : : handle ( int key ) const
{
return prefix ( ) . get_handle ( _isam_handle , key > 0 ? key : _curr_key ) ;
}
1994-08-12 10:52:49 +00:00
2011-09-09 11:03:08 +00:00
TRecnotype TBaseisamfile : : items ( ) const
1995-12-04 11:06:12 +00:00
{
1998-03-30 13:43:36 +00:00
return DB_reccount ( handle ( ) ) ;
1994-08-12 10:52:49 +00:00
}
const char * TBaseisamfile : : name ( ) const
1995-04-10 15:28:03 +00:00
{
2002-02-28 11:35:23 +00:00
TString & tmp = get_tmp_string ( ) ;
tmp . format ( " %d " , num ( ) ) ;
return tmp ;
1994-08-12 10:52:49 +00:00
}
2012-07-02 13:05:43 +00:00
const char * TBaseisamfile : : module ( ) const
{
TFilename app ;
curr ( ) . get_relapp ( app ) ;
if ( app . full ( ) )
return app . left ( 2 ) ;
return " ba " ;
}
1994-08-12 10:52:49 +00:00
const char * TBaseisamfile : : filename ( ) const
1998-03-30 13:43:36 +00:00
{
const int n = _isam_handle > 0 ? _isam_handle : num ( ) ;
2002-02-28 11:35:23 +00:00
TString & tmp = get_tmp_string ( ) ;
tmp = prefix ( ) . get_filename ( n ) ;
tmp < < " .dbf " ;
return tmp ;
1994-08-12 10:52:49 +00:00
}
1997-08-27 09:53:29 +00:00
const char * TBaseisamfile : : description ( )
1994-10-03 08:47:32 +00:00
{
1998-03-30 13:43:36 +00:00
const int n = _isam_handle > 0 ? _isam_handle : num ( ) ;
const FileDes & d = prefix ( ) . get_filedes ( n ) ;
return d . Des ;
1994-10-03 08:47:32 +00:00
}
1995-07-03 07:49:30 +00:00
TRecnotype TBaseisamfile : : eod ( ) const
{
1998-03-30 13:43:36 +00:00
return items ( ) ;
1995-07-03 07:49:30 +00:00
}
1994-10-03 08:47:32 +00:00
1996-09-02 14:20:24 +00:00
void TBaseisamfile : : set_curr ( TRectype * curr )
{
1998-03-30 13:43:36 +00:00
CHECK ( curr ! = NULL , " You must set a valid current record " ) ;
CHECK ( num ( ) = = curr - > num ( ) , " You must set a coherent current record " ) ;
1996-09-02 14:20:24 +00:00
if ( _current ! = NULL )
delete _current ;
_current = curr ;
}
1994-08-12 10:52:49 +00:00
void TBaseisamfile : : setkey ( int nkey )
{
1998-03-30 13:43:36 +00:00
_curr_key = nkey ;
1994-08-12 10:52:49 +00:00
}
int TBaseisamfile : : getkey ( ) const
{
1998-03-30 13:43:36 +00:00
return _curr_key ;
1994-08-12 10:52:49 +00:00
}
int TBaseisamfile : : first ( word lockop )
{
1997-12-02 12:05:16 +00:00
return TBaseisamfile : : read ( curr ( ) , _isfirst , lockop ) ;
1994-08-12 10:52:49 +00:00
}
int TBaseisamfile : : last ( word lockop )
{
1997-12-02 12:05:16 +00:00
return TBaseisamfile : : read ( curr ( ) , _islast , lockop ) ;
1994-08-12 10:52:49 +00:00
}
1997-05-23 14:02:46 +00:00
int TBaseisamfile : : next ( word lockop )
{
1997-12-02 12:05:16 +00:00
return TBaseisamfile : : read ( curr ( ) , _isnext , lockop ) ;
1994-08-12 10:52:49 +00:00
}
int TBaseisamfile : : prev ( word lockop )
{
1997-12-02 12:05:16 +00:00
return TBaseisamfile : : read ( curr ( ) , _isprev , lockop ) ;
1994-08-12 10:52:49 +00:00
}
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : reread ( word lockop )
1994-08-22 11:10:49 +00:00
{
1997-12-02 12:05:16 +00:00
return TBaseisamfile : : reread ( curr ( ) , lockop ) ;
1994-08-12 10:52:49 +00:00
}
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : reread ( TRectype & rec , word lockop )
1994-08-22 11:10:49 +00:00
{
1997-12-02 12:05:16 +00:00
return rec . read ( * this , _iscurr , lockop ) ;
1994-08-12 10:52:49 +00:00
}
int TBaseisamfile : : skip ( TRecnotype nrec , word lockop )
1995-07-03 07:49:30 +00:00
{
2008-07-25 07:59:03 +00:00
if ( nrec = = 0 )
return NOERR ;
1995-07-03 07:49:30 +00:00
curr ( ) . setdirty ( ) ;
1998-03-30 13:43:36 +00:00
const int fhnd = handle ( ) ;
// controllo se mi sono spostato dall'ultima lettura
if ( _recno ! = DB_recno ( fhnd ) )
1995-09-14 13:12:18 +00:00
{
1998-03-30 13:43:36 +00:00
_lasterr = DB_go ( fhnd , _recno ) ;
1995-09-14 13:12:18 +00:00
if ( _lasterr ! = NOERR )
{
_lasterr = get_error ( _lasterr ) ;
if ( _lasterr ! = _islocked )
fatal_box ( " Errore nella skip %d : non posso riposizionarmi " , _lasterr ) ;
}
}
1998-03-30 13:43:36 +00:00
_lasterr = DB_skip ( fhnd , nrec ) ;
if ( _lasterr ! = NOERR )
_lasterr = get_error ( _lasterr ) ;
while ( _lasterr = = _islocked )
{
const RecDes & r = prefix ( ) . get_recdes ( num ( ) ) ;
2009-11-08 22:17:25 +00:00
TString256 key ;
2008-12-10 16:52:43 +00:00
__build_key ( r , _curr_key , curr ( ) . string ( ) , key . get_buffer ( ) , TRUE ) ;
2000-05-05 15:25:49 +00:00
message_box ( " Codice %s in uso da parte \n di un altro utente. \n Skipping " , ( const char * ) key ) ;
1998-03-30 13:43:36 +00:00
_lasterr = cisread ( fhnd , getkey ( ) , curr ( ) , _iscurr + lockop , _recno ) ;
}
2001-04-30 15:04:10 +00:00
_recno = DB_recno ( fhnd ) ;
1998-03-30 13:43:36 +00:00
if ( curr ( ) . has_memo ( ) )
2000-10-03 13:45:12 +00:00
curr ( ) . init_memo ( _recno , _isam_handle ) ;
1998-03-30 13:43:36 +00:00
1994-08-22 11:10:49 +00:00
return _lasterr ;
1994-08-12 10:52:49 +00:00
}
1997-05-23 14:02:46 +00:00
// funzione di lettura dei file
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : _read ( TRectype & rec , word op , word lockop )
1994-08-12 10:52:49 +00:00
{
1998-03-30 13:43:36 +00:00
const TCodeb_handle fhnd = handle ( ) ;
1997-05-23 14:02:46 +00:00
rec . setdirty ( ) ;
1998-08-10 10:20:31 +00:00
_lasterr = cisread ( fhnd , getkey ( ) , rec , op + lockop , _recno ) ;
2003-01-28 14:27:05 +00:00
// _recno = DB_recno(fhnd); // Gia' fatto nella cisread
if ( rec . has_memo ( ) )
2000-10-03 13:45:12 +00:00
rec . init_memo ( _recno , _isam_handle ) ;
1998-08-10 10:20:31 +00:00
if ( _lasterr = = NOERR )
1998-03-30 13:43:36 +00:00
{
2007-09-17 15:33:04 +00:00
if ( lockop = = _lock | | lockop = = _testandlock )
2003-10-07 12:53:38 +00:00
prefix ( ) . lock_record ( _isam_handle , _recno ) ; else
1998-03-30 13:43:36 +00:00
if ( lockop = = _unlock )
prefix ( ) . unlock_record ( _isam_handle , _recno ) ;
}
1998-08-10 10:20:31 +00:00
1994-08-22 11:10:49 +00:00
return _lasterr ;
1994-08-12 10:52:49 +00:00
}
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : read ( TRectype & rec , word op , word lockop )
1994-08-22 11:10:49 +00:00
{
1997-06-02 10:06:58 +00:00
_lasterr = rec . read ( * this , op , lockop ) ;
1994-08-22 11:10:49 +00:00
return _lasterr ;
1994-08-12 10:52:49 +00:00
}
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : read ( word op , word lockop )
1997-05-23 14:02:46 +00:00
{
1997-12-02 12:05:16 +00:00
return TBaseisamfile : : read ( curr ( ) , op , lockop ) ;
1997-05-23 14:02:46 +00:00
}
int TBaseisamfile : : readat ( TRectype & rec , TRecnotype nrec , word lockop )
{
1997-12-02 12:05:16 +00:00
return rec . readat ( * this , nrec , lockop ) ;
1997-05-23 14:02:46 +00:00
}
1994-08-12 10:52:49 +00:00
int TBaseisamfile : : readat ( TRecnotype nrec , word lockop )
{
1997-12-02 12:05:16 +00:00
return TBaseisamfile : : readat ( curr ( ) , nrec , lockop ) ;
1994-08-12 10:52:49 +00:00
}
1997-05-23 14:02:46 +00:00
int TBaseisamfile : : _readat ( TRectype & rec , TRecnotype nrec , word lockop )
1994-08-12 10:52:49 +00:00
{
1998-03-30 13:43:36 +00:00
const int fhnd = handle ( ) ;
1994-08-22 11:10:49 +00:00
rec . setdirty ( ) ;
2009-01-15 15:16:02 +00:00
_lasterr = DB_go ( fhnd , nrec ) ;
1997-05-23 14:02:46 +00:00
if ( _lasterr ! = NOERR )
_lasterr = get_error ( _lasterr ) ;
1995-07-03 07:49:30 +00:00
else
1998-03-30 13:43:36 +00:00
rec = ( const char * ) DB_getrecord ( fhnd ) ;
_recno = DB_recno ( fhnd ) ;
2009-01-15 15:16:02 +00:00
if ( rec . has_memo ( ) )
2000-10-03 13:45:12 +00:00
rec . init_memo ( _recno , _isam_handle ) ;
1994-08-22 11:10:49 +00:00
return _lasterr ;
1994-08-12 10:52:49 +00:00
}
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : _write ( const TRectype & rec )
1994-08-12 10:52:49 +00:00
{
1997-05-23 14:02:46 +00:00
CHECK ( ! rec . empty ( ) , " Can't write an empty record " ) ;
1998-03-30 13:43:36 +00:00
2002-02-26 16:20:19 +00:00
// Controlla che la chiave sia piena
TString256 key ;
2002-02-28 16:45:27 +00:00
__build_key ( rec . rec_des ( ) , 1 , rec . string ( ) , key . get_buffer ( ) , TRUE ) ;
2002-02-26 16:20:19 +00:00
if ( key . blank ( ) )
return _iskeyerr ;
2012-03-23 09:53:09 +00:00
if ( dongle ( ) . demo ( ) & & items ( ) > 979L )
return _isfilefull ;
1997-05-23 14:02:46 +00:00
1998-03-30 13:43:36 +00:00
// Forza l'uso della chiave principale (per chiavi duplicate?)
2006-12-13 16:22:33 +00:00
const int fhnd = handle ( _curr_key > 0 ? 1 : 0 ) ;
1998-03-30 13:43:36 +00:00
const int dst_len = DB_reclen ( fhnd ) ;
if ( dst_len ! = rec . len ( ) )
NFCHECK ( " Record size mismatch on file %d: RecDes=%d, DB_reclen=%d " ,
_logicnum , rec . len ( ) , dst_len ) ;
1997-05-23 14:02:46 +00:00
1998-02-24 10:37:28 +00:00
browse_null ( rec . string ( ) , dst_len ) ;
1998-03-30 13:43:36 +00:00
memcpy ( DB_getrecord ( fhnd ) , rec . string ( ) , dst_len ) ;
_lasterr = DB_add ( fhnd ) ;
2009-01-15 15:16:02 +00:00
_recno = DB_recno ( fhnd ) ;
1998-10-01 13:59:39 +00:00
2009-01-15 15:16:02 +00:00
if ( _lasterr = = NOERR )
{
if ( rec . has_memo ( ) )
( ( TRectype & ) rec ) . write_memo ( _isam_handle , _recno ) ;
}
else
1998-10-01 13:59:39 +00:00
_lasterr = get_error ( _lasterr ) ;
1998-02-24 10:37:28 +00:00
1997-05-23 14:02:46 +00:00
return _lasterr ;
1994-08-12 10:52:49 +00:00
}
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : write ( const TRectype & rec )
1997-05-23 14:02:46 +00:00
{
1997-06-02 10:06:58 +00:00
return rec . write ( * this ) ;
1997-05-23 14:02:46 +00:00
}
1994-08-12 10:52:49 +00:00
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : write ( )
1997-05-23 14:02:46 +00:00
{
1997-06-02 10:06:58 +00:00
return TBaseisamfile : : write ( curr ( ) ) ;
1997-05-23 14:02:46 +00:00
}
2007-12-17 10:32:43 +00:00
int TBaseisamfile : : write_rewrite ( const TRectype & rec )
{
return rec . write_rewrite ( * this ) ;
}
int TBaseisamfile : : write_rewrite ( )
{
return TBaseisamfile : : write_rewrite ( curr ( ) ) ;
}
int TBaseisamfile : : rewrite_write ( const TRectype & rec )
{
return rec . rewrite_write ( * this ) ;
}
int TBaseisamfile : : rewrite_write ( )
{
2012-07-02 13:05:43 +00:00
return TBaseisamfile : : rewrite_write ( curr ( ) ) ;
2007-12-17 10:32:43 +00:00
}
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : _rewrite ( const TRectype & rec )
1994-08-12 10:52:49 +00:00
{
1995-07-07 14:43:41 +00:00
CHECK ( ! rec . empty ( ) , " Can't write an empty record " ) ;
1995-07-03 07:49:30 +00:00
TRectype save_rec ( rec ) ;
1998-03-30 13:43:36 +00:00
// Forza l'uso della chiave principale (per chiavi duplicate?)
const int fhnd = handle ( 1 ) ;
_lasterr = cisread ( fhnd , 1 , save_rec , _isequal + _nolock , _recno ) ; // Si Posiziona per sicurezza...
1995-07-03 07:49:30 +00:00
if ( _lasterr = = NOERR )
1995-07-04 14:06:19 +00:00
{
1998-03-30 13:43:36 +00:00
const int len = DB_reclen ( fhnd ) ;
if ( len ! = save_rec . len ( ) )
NFCHECK ( " Record size mismatch on file %d: RecDes=%d, DB_reclen=%d " ,
_logicnum , save_rec . len ( ) , len ) ;
1996-09-26 15:26:47 +00:00
browse_null ( rec . string ( ) , len ) ;
if ( memcmp ( rec . string ( ) , save_rec . string ( ) , len ) ! = 0 )
{
1998-03-30 13:43:36 +00:00
memcpy ( DB_getrecord ( fhnd ) , rec . string ( ) , len ) ;
_lasterr = DB_rewrite ( fhnd ) ;
1998-10-01 13:59:39 +00:00
if ( _lasterr = = NOERR )
2007-09-17 15:33:04 +00:00
rec_cache ( _logicnum ) . notify_change ( ) ;
1998-10-01 13:59:39 +00:00
else
1998-03-30 13:43:36 +00:00
_lasterr = get_error ( _lasterr ) ;
1996-09-26 15:26:47 +00:00
}
else
2011-06-22 15:44:50 +00:00
DB_unlock ( fhnd ) ; // non vale la pena farlo sempre ?
1998-03-30 13:43:36 +00:00
_recno = DB_recno ( fhnd ) ;
2003-10-07 12:53:38 +00:00
prefix ( ) . unlock_record ( _isam_handle , _recno ) ;
2007-09-17 15:33:04 +00:00
if ( _lasterr = = NOERR )
2003-10-21 11:10:01 +00:00
{
2008-10-07 09:02:41 +00:00
if ( curr ( ) . has_memo ( ) )
( ( TRectype & ) rec ) . write_memo ( _isam_handle , _recno ) ;
2003-10-21 11:10:01 +00:00
}
1995-07-04 14:06:19 +00:00
}
1998-10-01 13:59:39 +00:00
1994-08-22 11:10:49 +00:00
return _lasterr ;
}
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : rewrite ( const TRectype & rec )
1994-08-22 11:10:49 +00:00
{
1997-06-02 10:06:58 +00:00
return rec . rewrite ( * this ) ;
1997-05-23 14:02:46 +00:00
}
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : rewrite ( )
1997-05-23 14:02:46 +00:00
{
1997-06-02 10:06:58 +00:00
return TBaseisamfile : : rewrite ( curr ( ) ) ;
1994-08-22 11:10:49 +00:00
}
int TBaseisamfile : : rewriteat ( const TRectype & rec , TRecnotype nrec )
{
1998-03-30 13:43:36 +00:00
const int fhnd = handle ( ) ;
if ( ( _lasterr = DB_go ( fhnd , nrec ) ) = = NOERR )
1995-07-03 07:49:30 +00:00
{
1998-03-30 13:43:36 +00:00
browse_null ( rec . string ( ) , DB_reclen ( fhnd ) ) ;
memcpy ( DB_getrecord ( fhnd ) , rec . string ( ) , DB_reclen ( fhnd ) ) ;
_lasterr = DB_rewrite ( fhnd ) ;
1995-07-03 07:49:30 +00:00
if ( _lasterr ! = NOERR ) _lasterr = get_error ( _lasterr ) ;
2009-01-15 15:16:02 +00:00
}
else
1995-07-03 07:49:30 +00:00
_lasterr = get_error ( _lasterr ) ;
1998-03-30 13:43:36 +00:00
_recno = DB_recno ( fhnd ) ;
2003-10-21 11:10:01 +00:00
if ( _lasterr = = NOERR )
{
2007-09-17 15:33:04 +00:00
if ( curr ( ) . has_memo ( ) )
( ( TRectype & ) rec ) . write_memo ( _isam_handle , _recno ) ;
2003-10-21 11:10:01 +00:00
rec_cache ( _logicnum ) . notify_change ( ) ;
}
1995-07-03 07:49:30 +00:00
return _lasterr ;
1994-08-12 10:52:49 +00:00
}
1997-05-23 14:02:46 +00:00
int TBaseisamfile : : rewriteat ( TRecnotype nrec )
1994-08-12 10:52:49 +00:00
{
1997-05-23 14:02:46 +00:00
return TBaseisamfile : : rewriteat ( curr ( ) , nrec ) ;
}
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : _remove ( const TRectype & rec )
1997-05-23 14:02:46 +00:00
{
CHECK ( ! rec . empty ( ) , " Can't remove an empty record " ) ;
1995-07-07 14:43:41 +00:00
2009-01-07 15:50:52 +00:00
const int fhnd = handle ( 1 ) ; // Forza l'uso della chiave principale (per chiavi duplicate?)
2009-01-15 15:16:02 +00:00
TRectype save_rec ( rec ) ;
1998-10-01 13:59:39 +00:00
_lasterr = cisread ( fhnd , 1 , save_rec , _isequal + _nolock , _recno ) ; // Si Posiziona per sicurezza...
if ( _lasterr = = NOERR )
1995-07-03 07:49:30 +00:00
{
1998-03-30 13:43:36 +00:00
_lasterr = DB_delete ( fhnd ) ; // Put only deletion flag on record, must remove keys too!
1998-10-01 13:59:39 +00:00
if ( _lasterr = = NOERR )
{
2009-01-15 15:16:02 +00:00
if ( curr ( ) . has_memo ( ) )
curr ( ) . init_memo ( ) ;
rec_cache ( _logicnum ) . notify_change ( ) ;
1998-10-01 13:59:39 +00:00
DB_flush ( fhnd ) ;
}
else
1997-06-02 10:06:58 +00:00
_lasterr = get_error ( _lasterr ) ;
2003-10-21 11:10:01 +00:00
}
2009-01-15 15:16:02 +00:00
if ( _lasterr ! = NOERR )
DB_recall ( fhnd ) ;
1997-05-23 14:02:46 +00:00
1994-08-22 11:10:49 +00:00
return _lasterr ;
1994-08-12 10:52:49 +00:00
}
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : remove ( const TRectype & rec )
1994-08-12 10:52:49 +00:00
{
1997-06-02 10:06:58 +00:00
return rec . remove ( * this ) ;
1997-05-23 14:02:46 +00:00
}
1997-06-02 10:06:58 +00:00
int TBaseisamfile : : remove ( )
1997-05-23 14:02:46 +00:00
{
1997-06-02 10:06:58 +00:00
return TBaseisamfile : : remove ( curr ( ) ) ;
1994-08-12 10:52:49 +00:00
}
int TBaseisamfile : : lock ( )
{
1998-03-30 13:43:36 +00:00
const int fhnd = handle ( ) ;
_lasterr = DB_lockfile ( fhnd ) ;
if ( _lasterr ! = NOERR )
_lasterr = get_error ( _lasterr ) ;
1995-07-03 07:49:30 +00:00
return _lasterr ;
1994-08-12 10:52:49 +00:00
}
1998-03-13 10:25:37 +00:00
int TBaseisamfile : : unlock ( )
1994-08-12 10:52:49 +00:00
{
1998-03-30 13:43:36 +00:00
const int fhnd = handle ( ) ;
_lasterr = DB_unlock ( fhnd ) ;
if ( _lasterr ! = NOERR )
_lasterr = get_error ( _lasterr ) ;
1995-07-03 07:49:30 +00:00
return ( _lasterr ) ;
1994-08-12 10:52:49 +00:00
}
void TBaseisamfile : : indexon ( )
{
}
1998-03-30 13:43:36 +00:00
void TBaseisamfile : : indexoff ( )
{
}
1994-08-12 10:52:49 +00:00
bool TBaseisamfile : : empty ( )
{
1998-03-30 13:43:36 +00:00
return items ( ) < = 0 ;
1994-08-12 10:52:49 +00:00
}
1996-02-05 19:00:53 +00:00
// @doc EXTERNAL
1994-08-12 10:52:49 +00:00
1995-12-12 17:47:56 +00:00
// @mfunc Apre il file isam di base con lock
//
// @rdesc Ritorna NOERR se e' riuscita ad aprire il file, altrimenti ritorna il numero di errore
1995-12-29 12:09:48 +00:00
// generato (vedi <t TIsamerr>).
1995-12-12 17:47:56 +00:00
int TBaseisamfile : : _open (
1997-10-16 14:06:40 +00:00
unsigned int mode , // @parm Indica il modo di apertura del file (default _manulock)
bool index ) // @parm Indica se aprire con indici o meno (default TRUE)
1994-08-12 10:52:49 +00:00
1995-12-12 17:47:56 +00:00
// @comm Il parametro <p mode> puo' assumere i valori:
//
// @flag _manulock | Il lock dei record viene fatto manualmente
// @flag _exclock | Il file viene aperte in modo esclusivo
// @flag _autolock | Il lock dei record viene fatto in modo automatico
1997-10-16 14:06:40 +00:00
// @comm Il parametro <p index> puo' assumere i valori:
//
// @flag TRUE | Il file viene aperto con indici
// @flag FALSE | Il file viene aperto senza indici
1994-08-22 11:10:49 +00:00
{
1998-03-30 13:43:36 +00:00
CHECKD ( _isam_handle = = 0 , " Can't reopen file " , _logicnum ) ;
_curr_key = index ? 1 : 0 ;
TFilename filename ;
_isam_handle = prefix ( ) . open_isamfile ( _logicnum , filename , mode = = _excllock , index ) ;
if ( _isam_handle > 0 )
1995-07-03 07:49:30 +00:00
{
2003-06-24 12:49:44 +00:00
TCodeb_handle cb_handle = prefix ( ) . get_handle ( _isam_handle , _curr_key ) ;
2001-05-04 10:59:04 +00:00
const int dbfreclen = DB_reclen ( cb_handle ) ;
const int trcreclen = prefix ( ) . get_reclen ( _logicnum ) ;
const TRecnotype n = DB_reccount ( cb_handle ) ;
1999-10-22 10:00:18 +00:00
if ( dbfreclen ! = trcreclen )
{
TString msg ;
msg . format ( " Lunghezza record incoerente sul file %d (%s): file=%d trc=%d " ,
2001-05-04 10:59:04 +00:00
num ( ) , ( const char * ) filename , dbfreclen , trcreclen ) ;
2013-12-13 09:33:44 +00:00
if ( n < = 0 )
1999-10-22 10:00:18 +00:00
{
msg < < " \n Si consiglia di eliminare il file ed i suoi indici. " ;
error_box ( msg ) ;
}
else
fatal_box ( msg ) ;
}
2003-01-28 14:27:05 +00:00
if ( prefix ( ) . get_recdes ( _logicnum ) . NKeys < = 0 )
fatal_box ( " Il file %d (%s) e' senza indici " , num ( ) , ( const char * ) filename ) ;
1995-11-22 13:46:11 +00:00
_recno = RECORD_NON_FISICO ;
2001-05-07 13:27:50 +00:00
setkey ( _curr_key ) ;
1995-07-03 07:49:30 +00:00
_lasterr = NOERR ;
1995-07-03 16:19:39 +00:00
}
else
1995-07-03 07:49:30 +00:00
{
1996-01-18 18:20:47 +00:00
TString e_msg ;
1998-03-30 13:43:36 +00:00
_lasterr = get_error ( _isam_handle ) ;
1996-01-18 18:20:47 +00:00
if ( _lasterr = = - 60 )
{
1998-03-30 13:43:36 +00:00
if ( ! filename . exist ( ) )
e_msg . format ( " Il file %d(%s) non esiste, errore %d " , num ( ) , ( const char * ) filename , _lasterr ) ;
1996-01-18 18:20:47 +00:00
else
1998-03-30 13:43:36 +00:00
e_msg . format ( " Il file %d(%s) e' aperto in modo esclusivo da un'altra applicazione " ,
num ( ) , ( const char * ) filename ) ;
1996-01-18 18:20:47 +00:00
}
if ( e_msg . empty ( ) )
1998-03-30 13:43:36 +00:00
e_msg . format ( " Il file %d(%s) non puo' essere aperto, errore %d " , num ( ) , ( const char * ) filename , _lasterr ) ;
1996-01-18 18:20:47 +00:00
fatal_box ( ( const char * ) e_msg ) ;
1994-08-12 10:52:49 +00:00
}
1998-03-30 13:43:36 +00:00
return _lasterr ;
1994-08-12 10:52:49 +00:00
}
1998-01-28 08:29:13 +00:00
int TBaseisamfile : : _open_ex (
unsigned int mode , // @parm Indica il modo di apertura del file (default _manulock)
bool index ) // @parm Indica se aprire con indici o meno (default TRUE)
// @comm Il parametro <p mode> puo' assumere i valori:
//
// @flag _manulock | Il lock dei record viene fatto manualmente
// @flag _exclock | Il file viene aperte in modo esclusivo
// @flag _autolock | Il lock dei record viene fatto in modo automatico
// @comm Il parametro <p index> puo' assumere i valori:
//
// @flag TRUE | Il file viene aperto con indici
// @flag FALSE | Il file viene aperto senza indici
{
1998-03-30 13:43:36 +00:00
CHECKD ( _isam_handle = = 0 , " Can't reopen file " , _logicnum ) ;
_curr_key = index ? 1 : 0 ;
1998-01-28 08:29:13 +00:00
1998-03-30 13:43:36 +00:00
TFilename filename ;
_isam_handle = prefix ( ) . open_isamfile ( _logicnum , filename , mode = = _excllock , index ) ;
if ( _isam_handle > 0 )
{
if ( prefix ( ) . get_reclen ( _logicnum ) > 0 )
1998-01-28 08:29:13 +00:00
{
1998-03-30 13:43:36 +00:00
const int fhnd = handle ( ) ;
if ( fhnd > = 0 )
{
_recno = RECORD_NON_FISICO ;
_lasterr = NOERR ;
}
1998-01-28 08:29:13 +00:00
else
1998-03-30 13:43:36 +00:00
_lasterr = get_error ( fhnd ) ;
1998-01-28 08:29:13 +00:00
}
1998-03-30 13:43:36 +00:00
else
_lasterr = _isbadtrc ;
1998-01-28 08:29:13 +00:00
}
else
1998-03-30 13:43:36 +00:00
{
_isam_handle = 0 ;
_lasterr = get_error ( _isam_handle ) ;
1998-01-28 08:29:13 +00:00
}
1998-03-30 13:43:36 +00:00
return _lasterr ;
1998-01-28 08:29:13 +00:00
}
1994-08-12 10:52:49 +00:00
int TBaseisamfile : : _close ( )
{
1998-05-13 15:07:41 +00:00
int err = NOERR ;
if ( prefix_valid ( ) )
{
err = prefix ( ) . close_isamfile ( _isam_handle ) ;
setstatus ( err ) ;
}
1994-08-22 11:10:49 +00:00
return err ;
1994-08-12 10:52:49 +00:00
}
2002-12-18 10:56:10 +00:00
int TBaseisamfile : : is_valid ( bool exclusive )
1998-03-30 13:43:36 +00:00
{ // Ritorna NOERR se il file puo' essere aperto senza errori
CHECKD ( _isam_handle = = 0 , " Can't reopen file " , _logicnum ) ;
TFilename filename ;
2003-03-04 12:23:04 +00:00
TIsam_handle isam_handle = prefix ( ) . open_isamfile ( _logicnum , filename , exclusive , TRUE ) ;
2004-11-30 22:02:59 +00:00
TCodeb_handle fhnd = isam_handle > 0 ? prefix ( ) . get_handle ( isam_handle , 1 ) : isam_handle ;
2002-05-22 08:42:48 +00:00
int err = NOERR ;
if ( fhnd < 0 )
err = get_error ( fhnd ) ;
1998-03-30 13:43:36 +00:00
else
1995-11-15 18:20:51 +00:00
{
2000-05-05 15:25:49 +00:00
const int trcreclen = prefix ( ) . get_reclen ( _logicnum ) ;
1999-10-22 10:00:18 +00:00
if ( trcreclen > 0 )
2000-10-03 13:45:12 +00:00
{
2004-03-12 16:10:04 +00:00
if ( DB_tagget ( fhnd ) = = - 1 )
2000-10-03 13:45:12 +00:00
err = _ispatherr ;
else
{
2002-05-22 08:42:48 +00:00
const int dbfreclen = DB_reclen ( fhnd ) ;
2000-10-03 13:45:12 +00:00
if ( dbfreclen ! = trcreclen )
err = _istrcerr ;
}
}
1998-03-30 13:43:36 +00:00
else
err = _isbadtrc ;
1995-11-15 18:20:51 +00:00
}
1998-03-30 13:43:36 +00:00
if ( isam_handle > 0 )
prefix ( ) . close_isamfile ( isam_handle ) ;
1995-11-15 17:51:04 +00:00
return err ;
}
1994-08-12 10:52:49 +00:00
1998-12-10 16:25:48 +00:00
bool TBaseisamfile : : get_relapp ( TString & app ) const
{
2002-05-31 10:35:40 +00:00
return curr ( ) . get_relapp ( app ) ;
1998-12-10 16:25:48 +00:00
}
1999-05-24 13:34:11 +00:00
bool TBaseisamfile : : is_changed_since ( long & last ) const
{
2006-12-13 16:22:33 +00:00
bool yes = false ;
2004-03-12 16:10:04 +00:00
# ifdef WIN32
const int fh = : : _sopen ( filename ( ) , _O_RDONLY , _SH_DENYNO ) ;
1999-05-24 13:34:11 +00:00
if ( fh > 0 )
{
2003-10-21 11:10:01 +00:00
struct stat stat ;
if ( : : fstat ( fh , & stat ) = = 0 )
1999-05-24 13:34:11 +00:00
{
2000-05-05 15:25:49 +00:00
const long tim = long ( stat . st_mtime ) ^ long ( stat . st_size ) ;
yes = tim ! = last ;
1999-05-24 13:34:11 +00:00
last = tim ;
}
: : _close ( fh ) ;
2004-03-12 16:10:04 +00:00
}
# else
struct stat stat ;
if ( lstat ( filename ( ) , & stat ) = = 0 )
{
const long tim = long ( stat . st_mtime ) ^ long ( stat . st_size ) ;
yes = tim ! = last ;
last = tim ;
}
# endif
2006-12-13 16:22:33 +00:00
1999-05-24 13:34:11 +00:00
return yes ;
}
1995-02-10 17:42:33 +00:00
///////////////////////////////////////////////////////////
// TLocalisamfile
///////////////////////////////////////////////////////////
1996-02-05 19:00:53 +00:00
// @doc EXTERNAL
1995-02-22 14:21:34 +00:00
1996-02-05 19:00:53 +00:00
// @mfunc Costruttore
//
// @rdesc Ritorna l'oggetto <c TLocalisamfile>
TLocalisamfile : : TLocalisamfile (
1998-03-13 10:25:37 +00:00
int logicnum ) // @parm Numero del logico del file
: TBaseisamfile ( logicnum )
1995-02-10 17:42:33 +00:00
{
1998-03-13 10:25:37 +00:00
if ( open ( ) ! = NOERR )
fatal_box ( " Impossibile aprire il file %d " , logicnum ) ;
1994-08-12 10:52:49 +00:00
}
1997-07-22 09:49:11 +00:00
// @mfunc Costruttore
//
// @rdesc Ritorna l'oggetto <c TLocalisamfile>
TLocalisamfile : : TLocalisamfile (
1998-03-30 13:43:36 +00:00
const char * name , // @parm Nome del file esterno da aprire
2001-05-04 10:59:04 +00:00
const char * descname ) // @parm Indica la descrizione del file
: TBaseisamfile ( name , descname )
1997-07-22 09:49:11 +00:00
{
}
1994-08-12 10:52:49 +00:00
1998-03-13 10:25:37 +00:00
TLocalisamfile : : TLocalisamfile ( int logicnum , bool tmpfile )
: TBaseisamfile ( logicnum )
{
1998-03-30 13:43:36 +00:00
CHECK ( tmpfile = = TRUE , " Protected constructor badly used " ) ;
1998-03-13 10:25:37 +00:00
}
1994-08-12 10:52:49 +00:00
TLocalisamfile : : ~ TLocalisamfile ( )
1995-01-04 15:39:38 +00:00
{
1998-11-10 10:07:12 +00:00
close ( ) ;
1994-08-12 10:52:49 +00:00
}
1998-11-04 18:04:26 +00:00
1994-08-12 10:52:49 +00:00
int TLocalisamfile : : close ( )
{
1998-03-30 13:43:36 +00:00
return TBaseisamfile : : _close ( ) ;
1994-08-12 10:52:49 +00:00
}
int TLocalisamfile : : open ( unsigned int mode )
{
1998-03-30 13:43:36 +00:00
return TBaseisamfile : : _open ( mode ) ;
1994-08-12 10:52:49 +00:00
}
int TLocalisamfile : : operator + = ( const TRecnotype npos )
{
skip ( npos ) ;
return status ( ) ;
}
int TLocalisamfile : : operator - = ( const TRecnotype npos )
{
1994-08-22 11:10:49 +00:00
skip ( - npos ) ;
return status ( ) ;
1994-08-12 10:52:49 +00:00
}
int TLocalisamfile : : operator + + ( )
{
1994-08-22 11:10:49 +00:00
next ( ) ;
return status ( ) ;
1994-08-12 10:52:49 +00:00
}
int TLocalisamfile : : operator - - ( )
{
1994-08-22 11:10:49 +00:00
prev ( ) ;
return status ( ) ;
1994-08-12 10:52:49 +00:00
}
1997-05-23 14:02:46 +00:00
1998-03-13 10:25:37 +00:00
TIsamfile : : TIsamfile ( int logicnum )
: TBaseisamfile ( logicnum )
{ }
1994-08-12 10:52:49 +00:00
TIsamfile : : ~ TIsamfile ( )
{
1994-08-22 11:10:49 +00:00
close ( ) ;
1994-08-12 10:52:49 +00:00
}
1995-02-10 17:42:33 +00:00
///////////////////////////////////////////////////////////
// TIsamtempfile
///////////////////////////////////////////////////////////
1994-08-12 10:52:49 +00:00
1997-10-16 12:49:07 +00:00
TIsamtempfile : : TIsamtempfile ( int logicnum , const char * radix , bool create , bool autodel )
1998-03-13 10:25:37 +00:00
: TLocalisamfile ( logicnum , TRUE )
1995-02-10 17:42:33 +00:00
{
TRecnotype eod = 0 ;
TRecnotype eox = 100 ;
1995-03-24 11:16:17 +00:00
TFilename n ;
if ( radix & & * radix )
{
if ( * radix = = ' % ' )
1997-10-08 10:46:39 +00:00
n = radix + 1 ;
1995-03-24 11:16:17 +00:00
else
{
n . tempdir ( ) ;
2008-03-20 17:11:59 +00:00
n . add ( radix ) ;
1995-03-24 11:16:17 +00:00
}
1997-10-08 10:46:39 +00:00
n . ext ( " dbf " ) ;
1995-03-24 11:16:17 +00:00
}
1997-10-08 10:46:39 +00:00
else
n . temp ( NULL , " dbf " ) ;
1995-02-10 17:42:33 +00:00
if ( ! create )
{
2008-12-04 16:37:47 +00:00
const long sz = fsize ( n ) ;
2013-05-27 12:04:17 +00:00
if ( sz < = 64 )
fatal_box ( " Impossibile aprire il file %s " , ( const char * ) n ) ;
1995-03-24 11:16:17 +00:00
2008-12-10 16:52:43 +00:00
const TDir dir ( logicnum ) ;
const long len = dir . len ( ) ;
2008-12-04 16:37:47 +00:00
eod = eox = sz / len ;
1995-02-10 17:42:33 +00:00
}
1998-03-05 13:54:51 +00:00
CHECK ( create = = FALSE | | create = = TRUE , " Il flag di autodel ora si setta con il terzo parametro del costruttore " ) ;
_autodel = autodel | | ( create ! = FALSE & & create ! = TRUE ) ;
1997-10-16 12:49:07 +00:00
1997-10-13 15:26:11 +00:00
n . insert ( " % " , 0 ) ;
1997-10-16 12:49:07 +00:00
1995-02-10 17:42:33 +00:00
open ( n , create , eod , eox ) ;
}
1994-08-12 10:52:49 +00:00
TIsamtempfile : : ~ TIsamtempfile ( )
{
1994-08-22 11:10:49 +00:00
close ( ) ;
1994-08-12 10:52:49 +00:00
}
1996-02-05 19:00:53 +00:00
// @doc EXTERNAL
1995-12-12 17:47:56 +00:00
// @mfunc Apre il file
//
// @rdesc Ritorna NOERR se e' riuscita ad aprire il file, altrimenti ritorna il numero di errore
1995-12-29 12:09:48 +00:00
// generato (vedi <t TIsamerr>).
1995-12-12 17:47:56 +00:00
int TIsamtempfile : : open (
const char * radix , // @parm Radice del path del file
1998-06-24 07:11:33 +00:00
bool create , // @parm Indica se va creato un nuovo file (se FALSE il file esiste gia')
TRecnotype eod , // @parm Numero di record presenti nel file
TRecnotype eox ) // @parm Numero di record da aggiungere al file
1994-08-12 10:52:49 +00:00
1995-12-12 17:47:56 +00:00
// @comm Nel case <p create> sia TRUE allora viene settato automaticamente il valore di <p _autodel>
// a TRUE, cioe' viene abilitata l'eliminazione del file in chiusura.
1994-08-22 11:10:49 +00:00
{
1995-07-03 07:49:30 +00:00
int err = NOERR ;
1994-08-22 11:10:49 +00:00
1998-03-30 13:43:36 +00:00
TFilename filename ;
1995-07-03 07:49:30 +00:00
if ( radix [ 0 ] = = ' % ' )
1998-06-24 07:11:33 +00:00
filename = radix + 1 ;
1995-07-03 07:49:30 +00:00
else
1998-03-30 13:43:36 +00:00
filename . temp ( radix ) ;
filename . ext ( " " ) ;
CHECKS ( _isam_handle = = 0 , " File already open " , ( const char * ) filename ) ;
1995-07-03 07:49:30 +00:00
if ( create )
{
1998-03-30 13:43:36 +00:00
RecDes * r = ( RecDes * ) & prefix ( ) . get_recdes ( num ( ) ) ;
err = DB_build ( filename , r ) ;
if ( err ! = NOERR )
1995-07-03 07:49:30 +00:00
{
err = get_error ( err ) ;
1999-04-06 15:34:39 +00:00
// dalla 1.5 serve ? relisfd(_isamfile);
1998-03-30 13:43:36 +00:00
fatal_box ( " Can't create temp file '%s' num. %d: Error n. %d " , ( const char * ) filename , num ( ) , err ) ;
1994-08-22 11:10:49 +00:00
}
1995-07-03 07:49:30 +00:00
}
2013-05-27 12:04:17 +00:00
else
{
TFilename test = filename ; test . ext ( " dbf " ) ;
for ( int t = 0 ; t < 2 ; t + + )
{
test . ext ( t = = 0 ? " dbf " : " cdx " ) ;
if ( ! test . exist ( ) )
{
err = - 60 ;
break ;
}
}
}
if ( err = = NOERR )
{
_isam_handle = prefix ( ) . open_isamfile ( _logicnum , filename ) ;
TCodeb_handle fhnd = handle ( _curr_key = 1 ) ;
if ( fhnd < 0 )
err = get_error ( fhnd ) ;
}
1998-03-30 13:43:36 +00:00
1995-07-03 07:49:30 +00:00
if ( err ! = NOERR )
{
1998-03-30 13:43:36 +00:00
filename . ext ( " dbf " ) ;
1997-06-10 14:38:12 +00:00
if ( err = = - 60 )
{
1999-07-21 09:41:56 +00:00
if ( ! filename . exist ( ) )
fatal_box ( " Apertura file %s : errore n. %d. File non esistente. " , ( const char * ) filename , err ) ;
1997-06-10 14:38:12 +00:00
else
1998-03-30 13:43:36 +00:00
fatal_box ( " Apertura file %s : errore n. %d. File aperto in uso esclusivo da un'altra applicazione. " , ( const char * ) filename , err ) ;
1997-06-10 14:38:12 +00:00
}
else
1998-03-30 13:43:36 +00:00
fatal_box ( " Apertura file %s : errore n. %d " , ( const char * ) filename , err ) ;
1994-08-12 10:52:49 +00:00
}
1998-03-30 13:43:36 +00:00
1995-11-22 13:46:11 +00:00
_recno = RECORD_NON_FISICO ;
1994-08-22 11:10:49 +00:00
setstatus ( err ) ;
return err ;
1994-08-12 10:52:49 +00:00
}
1995-02-10 17:42:33 +00:00
int TIsamtempfile : : close ( )
1994-08-12 10:52:49 +00:00
{
1998-03-30 13:43:36 +00:00
TFilename f = filename ( ) ;
int err = prefix ( ) . close_isamfile ( _isam_handle ) ;
if ( err = = NOERR & & _autodel )
1994-08-22 11:10:49 +00:00
{
1998-06-24 07:11:33 +00:00
const long c = DB_getconf ( ) ;
1998-03-30 13:43:36 +00:00
f . ext ( " dbf " ) ;
: : remove ( f ) ;
1998-06-24 07:11:33 +00:00
if ( c & 1 )
f . ext ( " fpt " ) ;
else
f . ext ( " dbt " ) ;
: : remove ( f ) ;
1998-03-30 13:43:36 +00:00
if ( c & 1 ) // FOXPRO format
f . ext ( " cdx " ) ;
if ( c & 4 ) // DBIV format
f . ext ( " mdx " ) ;
if ( c & 8 | | c & 2 ) // CLIPPER and DBIII format
1995-07-03 07:49:30 +00:00
{
1998-03-30 13:43:36 +00:00
f . ext ( " cgp " ) ;
1998-06-24 07:11:33 +00:00
FILE * fp = fopen ( f , " r " ) ;
1998-03-30 13:43:36 +00:00
char in [ 16 ] ;
while ( fgets ( in , 16 , fp ) ! = NULL )
1995-07-03 07:49:30 +00:00
{
1998-03-30 13:43:36 +00:00
TFilename a ( in ) ;
if ( c & 8 ) // DBIII format
a . ext ( " ndx " ) ;
else
a . ext ( " ntx " ) ; // CLIPPER format
: : remove ( ( const char * ) a ) ;
1995-07-03 07:49:30 +00:00
}
1998-03-30 13:43:36 +00:00
fclose ( fp ) ;
1995-07-03 07:49:30 +00:00
}
1998-03-30 13:43:36 +00:00
: : remove ( f ) ;
1999-07-16 14:59:11 +00:00
1999-07-21 09:18:16 +00:00
if ( curr ( ) . has_memo ( ) ) // Cancella eventuale file dei memo
1999-07-16 14:59:11 +00:00
{
f . ext ( " fpt " ) ;
: : remove ( f ) ;
}
1994-08-12 10:52:49 +00:00
}
1998-03-30 13:43:36 +00:00
1994-08-22 11:10:49 +00:00
setstatus ( err ) ;
return err ;
1994-08-12 10:52:49 +00:00
}
1995-02-10 17:42:33 +00:00
///////////////////////////////////////////////////////////
1997-07-22 09:49:11 +00:00
// TExternisamfile
///////////////////////////////////////////////////////////
2001-05-04 10:59:04 +00:00
TExternisamfile : : TExternisamfile ( const char * name , bool exclusive , bool index )
: TLocalisamfile ( name )
1997-07-22 09:49:11 +00:00
{
2001-05-04 10:59:04 +00:00
init ( name , exclusive , index ) ;
}
TExternisamfile : : TExternisamfile ( const char * name , const char * descname , bool exclusive , bool index )
: TLocalisamfile ( name , descname )
{
init ( name , exclusive , index ) ;
1997-07-22 09:49:11 +00:00
}
TExternisamfile : : ~ TExternisamfile ( )
{
2001-05-04 10:59:04 +00:00
close ( ) ;
1997-07-22 09:49:11 +00:00
}
2001-05-04 10:59:04 +00:00
void TExternisamfile : : init ( const char * name , bool exclusive , bool index )
{
2002-07-03 14:48:48 +00:00
_name = name ;
2001-05-04 10:59:04 +00:00
_name . ext ( " dbf " ) ;
// Espande il nome!
const char c = _name [ 0 ] ;
if ( c = = ' % ' | | c = = ' $ ' )
_name = CAddPref ( _name . get_buffer ( ) ) ;
else
if ( c = = ' # ' )
{
_name . ltrim ( 1 ) ;
_name . format ( " %s/%s " , __ptprf , ( const char * ) _name ) ;
}
open ( exclusive , index ) ;
}
int TExternisamfile : : open ( bool exclusive , bool index )
{
_isam_handle = prefix ( ) . open_isamfile ( _logicnum , _name , exclusive , index ) ;
2003-11-05 16:44:33 +00:00
if ( _isam_handle > 0 )
2001-05-04 10:59:04 +00:00
{
if ( prefix ( ) . get_recdes ( _logicnum ) . NKeys < = 0 )
fatal_box ( " Il file %d (%s) e' senza indici " , num ( ) , ( const char * ) filename ( ) ) ;
_recno = RECORD_NON_FISICO ;
setkey ( 1 ) ;
_lasterr = NOERR ;
}
else
{
TString e_msg ;
_lasterr = get_error ( _isam_handle ) ;
if ( _lasterr = = - 60 )
{
if ( ! _name . exist ( ) )
e_msg . format ( " Il file %d(%s) non esiste, errore %d " , num ( ) , ( const char * ) _name , _lasterr ) ;
else
e_msg . format ( " Il file %d(%s) e' aperto in modo esclusivo da un'altra applicazione " ,
num ( ) , ( const char * ) _name ) ;
}
if ( e_msg . empty ( ) )
e_msg . format ( " Il file %d(%s) non puo' essere aperto, errore %d " , num ( ) , ( const char * ) _name , _lasterr ) ;
fatal_box ( ( const char * ) e_msg ) ;
}
return _lasterr ;
}
int TExternisamfile : : close ( )
{
return _close ( ) ;
}
2000-05-05 15:25:49 +00:00
int TExternisamfile : : zap ( )
2003-11-05 16:44:33 +00:00
{
2008-12-10 16:52:43 +00:00
RecDes rd = curr ( ) . rec_des ( ) ;
2003-11-05 16:44:33 +00:00
2001-05-04 10:59:04 +00:00
int err = prefix ( ) . close_isamfile ( _isam_handle ) ;
2000-05-05 15:25:49 +00:00
if ( err = = NOERR )
{
2001-05-04 10:59:04 +00:00
err = DB_packfile ( TRUE , _name , 0 ) ;
2000-05-05 15:25:49 +00:00
if ( err = = NOERR )
{
TRecnotype peod ;
2008-12-10 16:52:43 +00:00
err = DB_packindex ( TRUE , _name , & rd , & peod , FALSE ) ;
2000-05-05 15:25:49 +00:00
}
2001-05-04 10:59:04 +00:00
_isam_handle = prefix ( ) . open_isamfile ( _logicnum , _name ) ;
2000-05-05 15:25:49 +00:00
}
2003-11-05 16:44:33 +00:00
2000-05-05 15:25:49 +00:00
return err ;
}
1997-07-22 09:49:11 +00:00
const char * TExternisamfile : : name ( ) const
{
1998-03-30 13:43:36 +00:00
return filename ( ) ;
1997-07-22 09:49:11 +00:00
}
///////////////////////////////////////////////////////////
// TSystemisamfile
1995-02-10 17:42:33 +00:00
///////////////////////////////////////////////////////////
1994-08-12 10:52:49 +00:00
2009-03-27 10:48:32 +00:00
int TSystemisamfile : : build ( const TTrec & r )
1994-08-12 10:52:49 +00:00
{
2008-12-10 16:52:43 +00:00
int err = NOERR ;
const TDir d ( num ( ) ) ;
if ( r . len ( ) > 0 )
{
TFilename f ( filename ( ) ) ;
TFilename fname ( f ) ; fname . ext ( " " ) ; // sostituto per _filename
1998-03-30 13:43:36 +00:00
2008-12-10 16:52:43 +00:00
f = f . path ( ) ; if ( ! is_not_slash ( f . right ( 1 ) [ 0 ] ) ) f . rtrim ( 1 ) ;
2013-05-06 08:50:32 +00:00
if ( ! dexist ( f ) )
2008-12-10 16:52:43 +00:00
make_dir ( f ) ;
1994-10-14 17:51:32 +00:00
2008-12-10 16:52:43 +00:00
err = DB_build ( fname , & r . rec ( ) ) ;
1998-03-30 13:43:36 +00:00
if ( err ! = NOERR )
1995-07-20 09:10:38 +00:00
err = get_error ( err ) ;
setstatus ( err ) ;
2003-05-19 11:11:40 +00:00
1995-07-20 09:10:38 +00:00
if ( err = = NOERR & & __autoload )
{
1998-03-13 10:25:37 +00:00
TFilename lf ;
1995-07-20 09:10:38 +00:00
lf . format ( " %sstd/lf%04d.txt " , __ptprf , num ( ) ) ;
if ( fexist ( lf ) )
load ( lf , ' | ' , ' \0 ' , ' \n ' , TRUE , TRUE ) ;
}
2008-12-10 16:52:43 +00:00
}
else
{
NFCHECK ( " Can't create a file with empty field info " ) ;
setstatus ( _isbadtrc ) ;
1995-07-20 09:10:38 +00:00
}
1994-08-22 11:10:49 +00:00
return err ;
1994-08-12 10:52:49 +00:00
}
2009-03-27 10:48:32 +00:00
int TSystemisamfile : : build ( )
1997-06-12 15:52:14 +00:00
{
TTrec r ;
r . get ( num ( ) ) ;
2009-03-27 10:48:32 +00:00
return build ( r ) ;
1997-06-12 15:52:14 +00:00
}
1994-08-12 10:52:49 +00:00
long TSystemisamfile : : size ( TRecnotype eox )
{
1995-09-08 11:02:29 +00:00
return 51200L ;
1994-08-12 10:52:49 +00:00
}
# ifndef FOXPRO
1996-02-05 19:00:53 +00:00
// @doc INTERNAL
1995-12-12 17:47:56 +00:00
// @mfunc Esegue la conversione del file
//
// @rdesc Ritorna il rusultato dell'operazione
1996-09-26 15:26:47 +00:00
//
// @flag TRUE | Se la conversione e' stata effettuata correttamente
// @flag FALSE | Se h stato rilevato un errore durante la conversione (viene emesso un <f error_box>)
1996-06-17 09:05:05 +00:00
int TSystemisamfile : : exec_convapp (
1995-12-12 17:47:56 +00:00
long flev , // @parm Livello a cui aggiornare l'archivio
1995-12-29 12:09:48 +00:00
const bool before ) // @parm Indica se viene chiamata prima o dopo la conversione
1994-11-18 17:39:45 +00:00
{
const char * const v = before ? " BCNV " : " ACNV " ;
1996-06-17 09:05:05 +00:00
int err = 0 ;
1994-11-18 17:39:45 +00:00
if ( flev = = 0 ) flev = 199401 ;
else flev + + ;
1998-03-30 13:43:36 +00:00
TConfig conv ( CONFIG_FCONV ) ;
TString16 paragraph ;
TString_array paralist ;
conv . list_paragraphs ( paralist ) ;
2003-05-16 13:13:39 +00:00
for ( unsigned int l = flev ; err = = 0 & & l < = prefix ( ) . get_stdlevel ( ) ; l + + )
1994-11-18 17:39:45 +00:00
{
1998-03-30 13:43:36 +00:00
paragraph . format ( " %06ld " , l ) ;
if ( paralist . find ( paragraph ) < 0 )
continue ;
if ( conv . set_paragraph ( paragraph ) & & conv . exist ( v , num ( ) ) )
1994-11-18 17:39:45 +00:00
{
1997-06-12 15:52:14 +00:00
TToken_string s ( conv . get ( v , NULL , num ( ) ) , ' ' ) ;
TFilename f ( s . get ( 0 ) ) ;
f . ext ( " .exe " ) ;
2002-09-13 14:06:05 +00:00
s < < ' ' < < prefix ( ) . get_codditta ( ) ;
1994-11-24 14:01:20 +00:00
TExternal_app app ( s ) ;
1998-02-24 10:37:28 +00:00
if ( f . exist ( ) )
1994-11-18 17:39:45 +00:00
{
1998-03-13 10:25:37 +00:00
err = app . run ( FALSE , 0x3 ) ; // Synchronous Spawn with User
1998-02-24 10:37:28 +00:00
TMailbox mail ;
TMessage * msg = mail . next ( TRUE ) ;
if ( err = = 0 & & msg ! = NULL )
err = atoi ( msg - > body ( ) ) ;
1994-11-18 17:39:45 +00:00
}
1996-06-17 09:05:05 +00:00
if ( err & & err ! = 8 )
1995-04-10 15:28:03 +00:00
return error_box ( " Impossibile eseguire il programma di %sconversione \n del livello %ld/%ld \n Errore n.ro %d " , before ? " pre " : " post " , l / 100 , l % 100 , err ) ;
1994-11-18 17:39:45 +00:00
}
}
1996-06-17 09:05:05 +00:00
return err ;
1994-11-18 17:39:45 +00:00
}
1994-08-12 10:52:49 +00:00
1996-02-05 19:00:53 +00:00
// @doc INTERNAL
1995-12-29 12:09:48 +00:00
// @mfunc Recupera le conversioni logiche da effettuare sul file
//
// @rdesc Ritorna TRUE se occorre effettuare la conversione sul file
bool TSystemisamfile : : getlcf (
long flev ) // @parm livello archivi di partenza della convesione
// @comm Recupera le conversioni logiche da effettuare sul file per per passare dal
1996-01-18 18:20:47 +00:00
// livello archivi <p flev> a quello attuale degli archivi standard.
1994-09-27 10:19:36 +00:00
{
_flds . destroy ( ) ;
_exps . destroy ( ) ;
if ( flev = = 0 ) flev = 199401 ;
else flev + + ;
1998-03-30 13:43:36 +00:00
TConfig conv ( CONFIG_FCONV ) ;
TString16 paragraph ;
TString_array paralist ;
conv . list_paragraphs ( paralist ) ;
2003-05-16 13:13:39 +00:00
for ( unsigned int l = flev ; l < = prefix ( ) . get_stdlevel ( ) ; l + + )
1994-09-27 10:19:36 +00:00
{
1998-03-30 13:43:36 +00:00
paragraph . format ( " %06ld " , l ) ;
if ( paralist . find ( paragraph ) < 0 )
continue ;
1994-09-27 10:19:36 +00:00
1998-03-30 13:43:36 +00:00
if ( conv . set_paragraph ( paragraph ) & & conv . exist ( " F " , num ( ) ) )
1994-09-27 10:19:36 +00:00
{
TToken_string exprline ( conv . get ( " F " , NULL , num ( ) ) ) ;
if ( exprline . empty ( ) ) return FALSE ;
TToken_string w ( " " , ' = ' ) ;
const char * wexprs = exprline . get ( ) ;
while ( wexprs ! = NULL )
{
w = wexprs ;
TFixed_string fld ( w . get ( ) ) ;
_flds . add ( new TFieldref ( fld , 0 ) ) ;
_exps . add ( new TExpression ( w . get ( ) , _strexpr ) ) ;
wexprs = exprline . get ( ) ;
}
}
}
return _flds . items ( ) > 0 ;
}
void TSystemisamfile : : makelc ( TRectype & rec )
{
for ( int i = 0 ; i < _flds . items ( ) ; i + + )
{
TFieldref & f = ( TFieldref & ) _flds [ i ] ;
TExpression & e = ( TExpression & ) _exps [ i ] ;
for ( int k = 0 ; k < e . numvar ( ) ; k + + )
e . setvar ( k , get ( e . varname ( k ) ) ) ;
1998-08-25 18:07:30 +00:00
f . write ( e . as_string ( ) , rec ) ;
1994-09-27 10:19:36 +00:00
}
}
1996-02-05 19:00:53 +00:00
// @doc EXTERNAL
1995-12-12 17:47:56 +00:00
// @mfunc Esegue la conversione del tracciato record del file
//
// @rdesc Ritorna il risulato della conversione, altrimenti il codice di errore generato
1995-12-29 12:09:48 +00:00
// (vedi <t TIsamerr>)
1998-03-30 13:43:36 +00:00
1995-12-12 17:47:56 +00:00
int TSystemisamfile : : update (
1996-09-26 15:26:47 +00:00
const TTrec & newrec , // @parm Nuovo tracciato record con cui aggiornare il file
2014-09-22 13:54:13 +00:00
bool interactive ) // @parm Indica se riportare i campi personalizzati
1994-08-22 11:10:49 +00:00
1995-04-10 15:28:03 +00:00
{
2005-09-23 15:57:29 +00:00
if ( newrec . len ( ) = = 0 )
{
2012-05-29 08:52:37 +00:00
// if (interactive) error_box(FR("Il nuovo tracciato per il file %d e' vuoto"), num()); // Fastidioso per Ilaria
2005-09-23 15:57:29 +00:00
setstatus ( _istrcerr ) ;
return status ( ) ;
}
1998-03-30 13:43:36 +00:00
int err = NOERR ;
1995-07-20 09:10:38 +00:00
1996-09-26 15:26:47 +00:00
TTrec wrec ( newrec ) ;
1995-12-12 17:47:56 +00:00
TDir dir ;
1994-10-31 16:24:26 +00:00
1995-04-28 13:14:15 +00:00
dir . get ( num ( ) , _unlock , _nordir , _sysdirop ) ;
1995-03-22 09:07:04 +00:00
const bool is_com = prefix ( ) . is_com ( ) ;
1995-02-02 18:08:50 +00:00
const bool toconvert = is_com ? dir . is_com ( ) : dir . is_firm ( ) ;
1994-10-31 16:24:26 +00:00
2008-12-16 10:25:17 +00:00
TTrec oldrec ( num ( ) , is_com ? _comdir : _nordir ) ;
2005-09-23 15:57:29 +00:00
if ( oldrec . fields ( ) < 0 | | oldrec . fields ( ) > MaxFields )
{
if ( yesno_box ( FR ( " Il file %d (%s) \n "
" ha %d campi ed una lunghezza record di %d "
" \n Si desidera azzerare il vecchio tracciato? " ) ,
num ( ) , ( const char * ) filename ( ) , oldrec . fields ( ) , oldrec . len ( ) ) )
{
oldrec . zero ( ) ;
}
else
{
setstatus ( _istrcerr ) ;
return status ( ) ;
}
}
1998-03-30 13:43:36 +00:00
2005-09-23 15:57:29 +00:00
int lenr = wrec . len ( ) ;
1998-03-30 13:43:36 +00:00
if ( lenr ! = 0 )
1994-11-18 17:39:45 +00:00
{
1995-07-20 09:10:38 +00:00
const long lev = prefix ( ) . filelevel ( ) ;
const bool lcf = getlcf ( lev ) ;
1996-06-17 09:05:05 +00:00
1998-03-30 13:43:36 +00:00
if ( toconvert )
1996-06-17 09:05:05 +00:00
{
1998-03-30 13:43:36 +00:00
err = exec_convapp ( lev , TRUE ) ; // Pre-conversion
if ( err ! = NOERR )
{
setstatus ( err ) ;
return err ;
}
1995-07-03 07:49:30 +00:00
1998-03-30 13:43:36 +00:00
if ( ! lcf & & wrec = = oldrec )
{
2007-09-17 15:33:04 +00:00
err = exec_convapp ( lev , FALSE ) ; // Post-conversion (SOLO se il record e' rimasto uguale)
1998-03-30 13:43:36 +00:00
setstatus ( err ) ;
return err ;
}
1994-08-22 11:10:49 +00:00
}
1998-03-30 13:43:36 +00:00
else
1994-08-22 11:10:49 +00:00
{
1998-03-30 13:43:36 +00:00
if ( dir . eox ( ) > 0L )
2008-12-10 16:52:43 +00:00
dir . reset_eox ( ) ;
1994-08-22 11:10:49 +00:00
}
1998-02-09 11:54:26 +00:00
2008-03-20 17:13:20 +00:00
const int oldfields = oldrec . fields ( ) ; //numero campi del vecchio file
const int wfields = wrec . fields ( ) ; //numero campi del nuovo file
int newfields = wfields ; //numero campi del nuovo file compresi quelli personalizzati (_)
TToken_string def ; //riga del file .trr nome|tipo|lungh|dec
2003-02-25 15:22:52 +00:00
for ( int j = 0 ; j < oldfields ; j + + )
{
def = oldrec . fielddef ( j ) ;
2008-03-20 17:13:20 +00:00
const TString16 fname = def . get ( 0 ) ; //nome e basta del campo
if ( ! interactive & & fname [ 0 ] = = ' _ ' )
2003-02-25 15:22:52 +00:00
{
2008-03-20 17:13:20 +00:00
if ( wrec . field ( fname ) = = FIELDERR )
2004-03-16 10:08:50 +00:00
{
if ( newfields < MaxFields )
2008-03-20 17:13:20 +00:00
{
2004-11-30 22:02:59 +00:00
wrec . update_fielddef ( newfields + + , def ) ;
2008-04-04 16:04:15 +00:00
wrec . set_fields ( newfields ) ;
2008-03-20 17:13:20 +00:00
wrec . rehash ( ) ;
2008-04-04 16:04:15 +00:00
}
2004-03-16 10:08:50 +00:00
else
2008-04-04 16:04:15 +00:00
{
2008-03-20 17:13:20 +00:00
if ( ! yesno_box ( " Il campo %s non verra' preservato, devo continuare? " ,
( const char * ) fname ) )
2004-03-16 10:08:50 +00:00
return NOERR ;
2008-04-04 16:04:15 +00:00
}
2004-03-16 10:08:50 +00:00
}
2003-02-25 15:22:52 +00:00
}
}
if ( wfields < newfields )
{
wrec . set_fields ( newfields ) ;
wrec . rehash ( ) ;
lenr = wrec . len ( ) ;
}
1998-03-30 13:43:36 +00:00
TFilename fname ;
if ( toconvert )
fname = filename ( ) ;
1999-04-06 16:31:40 +00:00
if ( toconvert & & ( dir . eox ( ) > 0L | | fname . exist ( ) ) )
1995-07-20 09:10:38 +00:00
{
TRecnotype ni = 0L ;
1998-03-30 13:43:36 +00:00
TFilename tmpfname ; tmpfname . temp ( " tf " ) ;
1995-07-20 09:10:38 +00:00
2008-12-10 16:52:43 +00:00
err = DB_build ( tmpfname , & wrec . rec ( ) ) ;
1998-07-20 13:07:00 +00:00
1995-07-20 09:10:38 +00:00
if ( err ! = NOERR )
{
err = get_error ( err ) ;
return ( err ) ;
}
1998-03-30 13:43:36 +00:00
1998-11-04 18:04:26 +00:00
if ( dir . eod ( ) > 0 & & oldrec . len ( ) > 0 )
1998-03-30 13:43:36 +00:00
{
1998-07-20 13:07:00 +00:00
// Apro il file destinazione in modo esclusivo e senza indici
2009-01-07 15:50:52 +00:00
//int tmpnum = num();
//TIsam_handle ishandle = prefix().open_isamfile(tmpnum, tmpfname, true, false);
// TCodeb_handle fhnd = ishandle > 0 ? prefix().get_handle(ishandle) : ishandle;
TCodeb_handle fhnd = DB_open ( tmpfname , 1 , 0 ) ;
if ( fhnd < 0 )
1998-07-20 13:07:00 +00:00
{
2009-01-07 15:50:52 +00:00
err = get_error ( fhnd ) ;
1998-07-20 13:07:00 +00:00
return err ;
}
2009-01-07 15:50:52 +00:00
err = _open_ex ( _excllock , false ) ;
if ( err ! = NOERR )
return err ;
1998-07-20 13:07:00 +00:00
2014-09-22 13:54:13 +00:00
TString s ; s < < TR ( " Aggiornamento " ) < < ' ' < < fname ;
1998-03-30 13:43:36 +00:00
1998-07-20 13:07:00 +00:00
const TRecnotype nitems = items ( ) ;
2014-09-22 13:54:13 +00:00
TProgress_monitor p ( nitems > 0 ? nitems : 1 , s , is_power_station ( ) ) ;
1998-03-30 13:43:36 +00:00
1998-07-20 13:07:00 +00:00
TExtrectype nrec ( wrec ) ;
2008-12-23 09:05:22 +00:00
1998-07-20 13:07:00 +00:00
const int nflds = curr ( ) . items ( ) ;
TArray infld , outfld ;
2004-03-12 16:10:04 +00:00
int j ;
for ( j = 0 ; j < nflds ; j + + )
1997-10-22 12:58:17 +00:00
{
1998-07-20 13:07:00 +00:00
const char * fld_name = curr ( ) . fieldname ( j ) ;
infld . add ( new TRecfield ( curr ( ) , fld_name ) , j ) ;
if ( nrec . exist ( fld_name ) )
outfld . add ( new TRecfield ( nrec , fld_name ) , j ) ;
1997-10-22 12:58:17 +00:00
}
2008-12-23 09:05:22 +00:00
const bool memo_inside = rec_has_memo ( nrec . rec_des ( ) ) ;
2007-02-16 13:48:27 +00:00
for ( int errore = first ( ) ; errore = = NOERR ; errore = next ( ) )
1998-03-30 13:43:36 +00:00
{
2014-09-22 13:54:13 +00:00
if ( ! p . add_status ( ) )
2007-02-16 13:48:27 +00:00
{
2007-03-06 16:37:44 +00:00
err = _iseof ; // Simula errore in caso di interruzione
2007-02-16 13:48:27 +00:00
break ;
}
1998-07-20 13:07:00 +00:00
ni + + ;
if ( curr ( ) . isdeleted ( ) )
continue ;
2008-12-23 09:05:22 +00:00
1998-07-20 13:07:00 +00:00
nrec . zero ( ) ;
1998-08-10 10:20:31 +00:00
for ( j = outfld . last ( ) ; j > = 0 ; j = outfld . pred ( j ) )
1998-07-20 13:07:00 +00:00
{
1998-08-10 10:20:31 +00:00
TRecfield * in_fld = ( TRecfield * ) infld . objptr ( j ) ;
TRecfield * out_fld = ( TRecfield * ) outfld . objptr ( j ) ;
if ( in_fld ! = NULL & & out_fld ! = NULL )
{
1998-11-10 10:07:12 +00:00
char * fld_val = ( char * ) ( const char * ) * in_fld ;
if ( out_fld - > type ( ) ! = _datefld & & out_fld - > type ( ) ! = _memofld )
{
const int l1 = out_fld - > len ( ) ;
const int l2 = strlen ( fld_val ) ;
if ( l1 < l2 )
{
if ( out_fld - > type ( ) ! = _alfafld )
* fld_val = ' \0 ' ;
else
fld_val [ l1 ] = ' \0 ' ;
}
}
1998-08-10 10:20:31 +00:00
* out_fld = fld_val ;
}
1998-07-20 13:07:00 +00:00
}
if ( lcf )
makelc ( ( TRectype & ) nrec ) ;
1998-08-10 10:20:31 +00:00
browse_null ( nrec . string ( ) , lenr ) ;
memcpy ( DB_getrecord ( fhnd ) , nrec . string ( ) , lenr ) ;
1998-07-20 13:07:00 +00:00
err = DB_add ( fhnd ) ;
2008-12-23 09:05:22 +00:00
if ( err = = NOERR & & memo_inside )
2009-01-07 15:50:52 +00:00
{
// nrec.write_memo(ishandle, DB_recno(fhnd));
for ( j = outfld . last ( ) ; j > = 0 ; j = outfld . pred ( j ) )
{
const TRecfield * in_fld = ( const TRecfield * ) infld . objptr ( j ) ;
const TRecfield * out_fld = ( const TRecfield * ) outfld . objptr ( j ) ;
if ( in_fld ! = NULL & & out_fld ! = NULL & & out_fld - > type ( ) = = _memofld )
{
const TFixed_string val ( * in_fld ) ;
if ( val . full ( ) )
DB_memowrite ( fhnd , out_fld - > name ( ) , val ) ;
}
}
DB_flush ( fhnd ) ;
}
1998-07-20 13:07:00 +00:00
if ( err ! = NOERR )
err = get_error ( err ) ;
setstatus ( err ) ;
2003-03-04 12:23:04 +00:00
1998-03-30 13:43:36 +00:00
}
1998-07-20 13:07:00 +00:00
close ( ) ;
2009-01-07 15:50:52 +00:00
//prefix().close_isamfile(ishandle);
DB_close ( fhnd ) ;
1998-07-20 13:07:00 +00:00
2007-02-16 13:48:27 +00:00
if ( err ! = NOERR )
err = get_error ( err ) ;
2014-09-22 13:54:13 +00:00
if ( ! p . setstatus ( nitems ) )
2007-02-16 13:48:27 +00:00
err = _iseof ;
1998-07-20 13:07:00 +00:00
}
1998-03-30 13:43:36 +00:00
1995-07-20 09:10:38 +00:00
if ( err = = NOERR )
{
long c = DB_getconf ( ) ;
fname . ext ( " dbf " ) ;
tmpfname . ext ( " dbf " ) ;
1998-03-30 13:43:36 +00:00
fcopy ( tmpfname , fname ) ;
: : remove ( tmpfname ) ;
1995-12-15 15:40:37 +00:00
if ( c & 1 )
tmpfname . ext ( " fpt " ) ;
else
tmpfname . ext ( " dbt " ) ;
1998-03-30 13:43:36 +00:00
if ( tmpfname . exist ( ) )
1995-12-05 11:49:39 +00:00
{
1995-12-15 15:40:37 +00:00
if ( c & 1 )
fname . ext ( " fpt " ) ;
else
fname . ext ( " dbt " ) ;
1998-03-30 13:43:36 +00:00
fcopy ( tmpfname , fname ) ;
: : remove ( tmpfname ) ;
1995-12-05 11:49:39 +00:00
}
1995-07-20 09:10:38 +00:00
if ( c & 1 ) // FOXPRO format
tmpfname . ext ( " cdx " ) ;
if ( c & 4 ) // DBIV format
tmpfname . ext ( " mdx " ) ;
if ( c & 8 | | c & 2 )
{
tmpfname . ext ( " cgp " ) ;
1998-03-30 13:43:36 +00:00
TFilename a ;
FILE * fp = fopen ( tmpfname , " rb " ) ;
while ( fgets ( a . get_buffer ( ) , 16 , fp ) ! = NULL )
1995-07-20 09:10:38 +00:00
{
a . rtrim ( 1 ) ; // Cut \n
if ( c & 8 ) // DBIII format
a . ext ( " ndx " ) ;
else
a . ext ( " ntx " ) ; // CLIPPER format
1998-03-30 13:43:36 +00:00
: : remove ( a ) ;
1995-07-20 09:10:38 +00:00
}
fclose ( fp ) ;
1995-07-03 07:49:30 +00:00
}
1998-03-30 13:43:36 +00:00
: : remove ( tmpfname ) ;
2008-12-10 16:52:43 +00:00
dir . set_eod ( ni ) ;
1995-07-03 07:49:30 +00:00
}
}
1998-04-30 15:31:34 +00:00
if ( err = = NOERR )
{
dir . set_len ( lenr ) ;
dir . put ( num ( ) , _nordir , _sysdirop ) ;
wrec . put ( num ( ) ) ;
prefix ( ) . update_recdes ( num ( ) ) ;
if ( toconvert )
2014-09-22 13:54:13 +00:00
packindex ( true ) ;
1998-08-25 18:07:30 +00:00
if ( err = = NOERR )
err = exec_convapp ( lev , FALSE ) ; // Post - conversion
1998-03-30 13:43:36 +00:00
}
1994-08-22 11:10:49 +00:00
}
1998-03-30 13:43:36 +00:00
1995-07-03 07:49:30 +00:00
setstatus ( err ) ;
1994-08-22 11:10:49 +00:00
return err ;
1994-08-12 10:52:49 +00:00
}
1996-02-05 19:00:53 +00:00
// @doc EXTERNAL
1995-12-12 17:47:56 +00:00
// @mfunc Rimuove fisicamente i record cancellati
//
// @rdesc Ritorna NOERR se l'operazione di compattamento e' riuscita, altrimenti il codice di
1995-12-29 12:09:48 +00:00
// di errore generato (vedi <t TIsamerr>).
1995-12-12 17:47:56 +00:00
int TSystemisamfile : : packfile (
1998-01-28 08:29:13 +00:00
bool vis , // @parm Indica se visualizzare lo stato dell'operazione
bool zap ) // @parm Indica se distruggere tutti i records
1994-08-12 10:52:49 +00:00
1995-12-12 17:47:56 +00:00
// @xref <mf TSystemisamfile::packindex>
1994-08-22 11:10:49 +00:00
1995-07-03 07:49:30 +00:00
{
2008-12-10 16:52:43 +00:00
TFilename fname = filename ( ) ; fname . ext ( " " ) ;
TRecnotype new_eod = 0L ;
if ( ! zap )
{
TDir d ( num ( ) ) ; // Chi commenta muore!
d . get ( num ( ) , _nolock , ( d . is_com ( ) ) ? _comdir : _nordir , _sysdirop ) ;
new_eod = d . eod ( ) ;
}
1998-03-30 13:43:36 +00:00
2008-12-10 16:52:43 +00:00
int err = DB_packfile ( vis , fname , new_eod ) ;
1998-01-28 08:29:13 +00:00
if ( zap & & err = = NOERR )
err = packindex ( vis , FALSE ) ;
1996-09-02 14:20:24 +00:00
if ( err = = NOERR & & curr ( ) . has_memo ( ) )
2008-12-10 16:52:43 +00:00
err = DB_packmemo ( vis , fname ) ;
1998-01-28 08:29:13 +00:00
if ( err ! = NOERR )
{
err = get_error ( err ) ;
if ( err ! = NOERR )
2008-12-10 16:52:43 +00:00
error_box ( " Errore in compattamento dati. \n File %d : %d " , num ( ) , err ) ;
1998-01-28 08:29:13 +00:00
}
1995-07-03 07:49:30 +00:00
setstatus ( err ) ;
1994-08-22 11:10:49 +00:00
return err ;
1994-08-12 10:52:49 +00:00
}
2003-05-09 07:42:40 +00:00
int TSystemisamfile : : zap ( )
{
safely_close_closeable_isamfiles ( ) ;
2010-11-18 11:53:17 +00:00
return packfile ( true , true ) ;
2003-05-09 07:42:40 +00:00
}
1996-02-05 19:00:53 +00:00
// @doc EXTERNAL
1995-12-12 17:47:56 +00:00
// @mfunc Rimuove fisicamente gli indici cancellati
//
// @rdesc Ritorna NOERR se l'operazione di compattamento e' riuscita, altrimenti il codice di
1995-12-29 12:09:48 +00:00
// di errore generato (vedi <t TIsamerr>).
1995-12-12 17:47:56 +00:00
int TSystemisamfile : : packindex (
1996-03-28 11:40:04 +00:00
bool vis , // @parm Indica se visualizzare lo stato dell'operazione
bool ask ) // @parm Indica se chiedere il recupero dei record duplicati
1994-08-12 10:52:49 +00:00
1995-12-12 17:47:56 +00:00
// @xref <mf TSystemisamfile::packfile>
1994-08-22 11:10:49 +00:00
1994-08-12 10:52:49 +00:00
{
2008-12-16 10:25:17 +00:00
const TTrec r ( num ( ) ) ;
2008-12-10 16:52:43 +00:00
TDir d ( num ( ) ) ;
const bool is_com = d . is_com ( ) ;
2008-12-16 10:25:17 +00:00
d . get ( num ( ) , _nolock , is_com ? _comdir : _nordir , _sysdirop ) ;
2008-12-10 16:52:43 +00:00
TFilename name = d . filename ( ) ; name . ext ( " " ) ;
1995-07-03 07:49:30 +00:00
TRecnotype peod ;
2008-12-10 16:52:43 +00:00
int err = DB_packindex ( vis , name , & r . rec ( ) , & peod , ask ) ;
1998-03-30 13:43:36 +00:00
if ( err ! = NOERR )
err = get_error ( err ) ;
if ( err ! = NOERR )
2008-12-10 10:49:12 +00:00
{
2014-09-22 13:54:13 +00:00
if ( vis | | ask )
2008-12-10 10:49:12 +00:00
error_box ( " Errore in compattamento indici. \n File %d : %d " , num ( ) , err ) ;
}
1995-07-03 07:49:30 +00:00
else
2014-09-22 13:54:13 +00:00
{
1995-07-03 07:49:30 +00:00
if ( peod > = 0 & & peod ! = d . eod ( ) )
{
2008-12-10 16:52:43 +00:00
d . set_eod ( peod ) ;
1995-08-03 15:07:29 +00:00
d . put ( num ( ) , is_com ? _comdir : _nordir ) ;
1995-07-03 07:49:30 +00:00
}
2014-09-22 13:54:13 +00:00
}
1995-07-03 07:49:30 +00:00
setstatus ( err ) ;
1994-08-22 11:10:49 +00:00
return err ;
1994-08-12 10:52:49 +00:00
}
2003-07-03 08:43:59 +00:00
void TSystemisamfile : : update_file ( )
{
TFilename fname ;
int logicnum = _logicnum ;
int isam_handle = prefix ( ) . open_isamfile ( logicnum , fname , FALSE , 1 ) ;
if ( isam_handle > 0 )
{
TCodeb_handle cb_handle = prefix ( ) . get_handle ( isam_handle , 1 ) ;
const TRecnotype n = DB_reccount ( cb_handle ) ; //numero di elementi del file
TDir dir ;
dir . get ( _logicnum , _lock , _nordir , _sysdirop ) ;
dir . set_eox ( n ) ;
dir . set_eod ( n ) ;
dir . put ( _logicnum , _nordir , _sysdirop ) ;
2007-09-17 15:33:04 +00:00
prefix ( ) . close_isamfile ( isam_handle ) ;
2003-07-03 08:43:59 +00:00
}
}
1996-03-28 11:40:04 +00:00
int TSystemisamfile : : pack ( bool vis , bool ask )
1995-07-03 07:49:30 +00:00
{
1998-08-10 10:20:31 +00:00
int err = packfile ( vis ) ;
if ( err = = NOERR )
err = packindex ( vis , ask ) ;
1995-07-03 07:49:30 +00:00
setstatus ( err ) ;
return err ;
}
1994-08-12 10:52:49 +00:00
1996-02-05 19:00:53 +00:00
// @doc EXTERNAL
1995-12-12 17:47:56 +00:00
// @mfunc Importa un file ascii
//
// @rdesc Ritorna NOERR se l'operazione di lettura e' riuscita, altrimenti il codice di
1995-12-29 12:09:48 +00:00
// di errore generato (vedi <t TIsamerr>).
1995-12-12 17:47:56 +00:00
int TSystemisamfile : : load (
const char * from , // @parm Nome del file da importare
2009-10-21 13:40:18 +00:00
char fs , // @parm Carattere separatore di campo (default <pipe>)
char fd , // @parm Carattere delimitatore di campi (default '\\0')
char rs , // @parm Carattere separatore di record (default '\\n')
bool vis , // @parm Indica se visualizzare lo stato dell'operazione (default TRUE)
bool extended , // @parm Indica se interpretare alcune stringhe come macro (default FALSE)
bool indexed ) // @parm Indica se indicizzare subito o alla fine
1995-12-29 12:09:48 +00:00
// @comm Se <p extended> e' TRUE e trova alcune stringhe col formato %stringa% (es. %frm%)
1996-01-18 18:20:47 +00:00
// ne sostituisce i valori (es. ditta corrente).
1995-12-12 17:47:56 +00:00
// @xref <mf TSystemisamfile::dump>
1994-08-22 11:10:49 +00:00
{
1995-09-20 09:39:06 +00:00
int err = NOERR ;
2009-10-21 13:40:18 +00:00
FILE * fl = NULL ; fopen_s ( & fl , from , " r " ) ;
1995-09-20 09:39:06 +00:00
if ( fl = = NULL )
1995-08-03 15:07:29 +00:00
{
2009-10-21 13:40:18 +00:00
cantread_box ( from ) ;
1999-04-16 12:02:04 +00:00
setstatus ( 2 ) ;
return 2 ;
1995-08-03 15:07:29 +00:00
}
1998-08-10 10:20:31 +00:00
TRecnotype r = 0 , e = 0 , nitems = 0 ;
2006-12-13 16:22:33 +00:00
TString8 firm , year , attprev ( " 00000 " ) ;
1994-12-02 13:06:39 +00:00
if ( extended )
{
2009-10-21 13:40:18 +00:00
const TDate d ( TODAY ) ;
1994-12-02 13:06:39 +00:00
year . format ( " %04d " , d . year ( ) ) ;
2008-04-04 16:04:15 +00:00
firm . format ( " %05ld " , prefix ( ) . get_codditta ( ) ) ;
attprev = cache ( ) . get ( LF_NDITTE , firm , NDT_CODATTPREV ) ;
1994-12-02 13:06:39 +00:00
}
1998-08-10 10:20:31 +00:00
1994-09-27 10:19:36 +00:00
fseek ( fl , 0L , SEEK_END ) ;
1998-08-10 10:20:31 +00:00
nitems = ftell ( fl ) ;
1994-09-27 10:19:36 +00:00
fclose ( fl ) ;
1998-03-30 13:43:36 +00:00
2006-12-13 16:22:33 +00:00
err = _open_ex ( _excllock , indexed ) ;
1998-08-10 10:20:31 +00:00
if ( err ! = NOERR )
1998-01-28 08:29:13 +00:00
{
2009-10-21 13:40:18 +00:00
TString msg ; msg < < _logicnum < < " ( " < < name ( ) < < ' ) ' ;
cantread_box ( msg ) ;
1998-08-10 10:20:31 +00:00
return err ;
1998-01-28 08:29:13 +00:00
}
TScanner f ( from ) ;
2006-12-13 16:22:33 +00:00
const bool fixedlen = ( fs = = ' \0 ' ) ;
1999-04-16 12:02:04 +00:00
TToken_string s ( 1024 , fixedlen ? char ( 255 ) : fs ) ;
1994-08-22 11:10:49 +00:00
int nflds = curr ( ) . items ( ) ;
2009-10-21 13:40:18 +00:00
TString_array fld ( nflds ) ;
TPointer_array fldlen ( nflds ) ;
int reclen = 0 ;
1994-08-22 11:10:49 +00:00
TString sfd ( 3 ) ;
2003-03-04 12:23:04 +00:00
TString s1 ( 256 ) ;
1994-09-27 10:19:36 +00:00
bool lcf = FALSE ;
if ( f . paragraph ( " Header " ) )
1998-01-28 08:29:13 +00:00
{
int equal ;
TString key ;
1994-09-27 10:19:36 +00:00
nflds = 0 ;
1998-01-28 08:29:13 +00:00
while ( ( equal = f . line ( ) . find ( ' = ' ) ) > 0 )
1994-09-27 10:19:36 +00:00
{
1998-01-28 08:29:13 +00:00
key = f . token ( ) . left ( equal ) ;
key . trim ( ) ;
if ( key = = " File " )
1994-09-27 10:19:36 +00:00
{
1998-01-28 08:29:13 +00:00
const int logic = atoi ( f . token ( ) . mid ( equal + 1 ) ) ;
if ( logic ! = num ( ) )
2009-10-21 13:40:18 +00:00
{
error_box ( " L'archivio %s e' stato generato dal file %d " , from , logic ) ;
return _isbadtrc ;
}
1998-01-28 08:29:13 +00:00
} else
if ( key = = " Fields " )
{
2004-03-12 16:10:04 +00:00
TToken_string riga ( f . token ( ) . mid ( equal + 1 ) ) ;
1998-01-28 08:29:13 +00:00
TToken_string wfd ( 32 , ' , ' ) ;
FOR_EACH_TOKEN ( riga , fd )
{
wfd = fd ; wfd . strip_spaces ( ) ;
fld . add ( wfd . get ( 0 ) ) ;
2009-10-21 13:40:18 +00:00
const int l = wfd . get_int ( ) ;
fldlen . add_long ( l , nflds + + ) ;
reclen + = l ;
1998-01-28 08:29:13 +00:00
}
}
1994-09-27 10:19:36 +00:00
}
}
1998-03-13 10:25:37 +00:00
if ( nflds = = 0 | | fld . items ( ) = = 0 )
{
nflds = curr ( ) . items ( ) ;
1994-09-27 10:19:36 +00:00
for ( int j = 0 ; j < nflds ; j + + )
{
1998-03-13 10:25:37 +00:00
fld . add ( curr ( ) . fieldname ( j ) , j ) ;
2009-10-21 13:40:18 +00:00
const TString & wfld = fld . row ( j ) ;
const int l = ( curr ( ) . type ( wfld ) = = _datefld ) ? 10 : curr ( ) . length ( wfld ) ;
fldlen . add_long ( l , j ) ;
1994-09-27 10:19:36 +00:00
}
1994-08-22 11:10:49 +00:00
}
1998-01-28 08:29:13 +00:00
1994-09-27 10:19:36 +00:00
if ( ! f . paragraph ( " Data " ) )
{
1998-03-13 10:25:37 +00:00
error_box ( " Formato file non valido: manca il paragrafo [Data] " ) ;
1994-09-27 10:19:36 +00:00
close ( ) ;
1994-11-10 14:15:41 +00:00
err = 1 ;
setstatus ( err ) ;
return err ;
1994-09-27 10:19:36 +00:00
}
1994-08-22 11:10:49 +00:00
if ( fd ) sfd < < fd ;
int last = NOERR ;
2006-12-13 16:22:33 +00:00
const char * const fmt = FR ( " Importazione archivio %d da %s \n %6ld records %6ld errori - %3d " ) ;
1994-08-22 11:10:49 +00:00
2006-12-13 16:22:33 +00:00
s1 . format ( fmt , _logicnum , from , r , e , last ) ;
2009-10-21 13:40:18 +00:00
TProgind p ( nitems , s1 ) ;
2006-12-13 16:22:33 +00:00
2009-10-21 13:40:18 +00:00
while ( ! f . eof ( ) )
1994-08-22 11:10:49 +00:00
{
2009-10-21 13:40:18 +00:00
if ( fixedlen )
f . getline ( s . get_buffer ( reclen + 2 ) , reclen + 2 ) ;
else
s = f . line ( ) ;
if ( s . empty ( ) )
break ;
1994-12-02 13:06:39 +00:00
if ( extended )
{
int p , i ;
while ( ( p = s . find ( " %yr% " ) ) > = 0 )
for ( i = 0 ; i < 4 ; i + + ) s [ p + i ] = year [ i ] ;
while ( ( p = s . find ( " %frm% " ) ) > = 0 )
for ( i = 0 ; i < 5 ; i + + ) s [ p + i ] = firm [ i ] ;
while ( ( p = s . find ( " %att% " ) ) > = 0 )
for ( i = 0 ; i < 5 ; i + + ) s [ p + i ] = attprev [ i ] ;
}
2006-12-13 16:22:33 +00:00
if ( ( r + e ) % 100 = = 0 )
1994-08-22 11:10:49 +00:00
{
2006-12-13 16:22:33 +00:00
s1 . format ( fmt , _logicnum , from , r , e , last ) ;
1994-08-22 11:10:49 +00:00
p . set_text ( s1 ) ;
}
2003-03-04 12:23:04 +00:00
2010-02-09 10:11:25 +00:00
if ( ! p . setstatus ( ( long ) f . tellg ( ) ) )
2009-10-21 13:40:18 +00:00
break ;
1994-08-22 11:10:49 +00:00
zero ( ) ;
if ( fixedlen )
{
2009-10-21 13:40:18 +00:00
if ( s . len ( ) < reclen )
{
error_box ( FR ( " Record di lunghezza errata: %d invece di %d " ) , s . len ( ) , reclen ) ;
break ;
}
1994-08-22 11:10:49 +00:00
int pos = 0 ;
1994-09-27 10:19:36 +00:00
for ( int j = 0 ; j < nflds ; j + + )
1994-08-22 11:10:49 +00:00
{
2009-10-21 13:40:18 +00:00
const int l = fldlen . get_int ( j ) ;
s1 = s . mid ( pos , l ) ;
1994-09-27 10:19:36 +00:00
s1 . rtrim ( ) ;
2009-10-21 13:40:18 +00:00
put ( fld . row ( j ) , s1 ) ;
pos + = l ;
1994-08-22 11:10:49 +00:00
}
}
else
{
s . restart ( ) ;
1994-09-27 10:19:36 +00:00
for ( int j = 0 ; j < nflds ; j + + )
1994-08-22 11:10:49 +00:00
{
2003-02-04 09:34:53 +00:00
s1 = s . get ( ) ;
1994-08-22 11:10:49 +00:00
if ( fd )
{
2006-09-15 15:27:47 +00:00
s1 . rtrim ( 1 ) ;
s1 . ltrim ( 1 ) ;
1994-08-22 11:10:49 +00:00
}
1999-04-06 15:34:39 +00:00
if ( curr ( ) . type ( ( const TString & ) fld [ j ] ) = = _memofld )
2006-09-15 15:27:47 +00:00
{
TString s2 = s1 ;
2006-12-13 16:22:33 +00:00
2003-02-25 15:22:52 +00:00
s1 = esc ( s2 ) ;
2006-09-15 15:27:47 +00:00
}
2006-12-13 16:22:33 +00:00
1999-04-06 16:31:40 +00:00
put ( ( const TString & ) fld [ j ] , s1 ) ;
1994-08-22 11:10:49 +00:00
}
2003-02-04 09:34:53 +00:00
}
1998-01-28 08:29:13 +00:00
int err = write ( ) ;
if ( err = = NOERR )
r + + ;
1994-08-22 11:10:49 +00:00
else
{
e + + ;
last = status ( ) ;
}
}
2006-12-13 16:22:33 +00:00
s1 . format ( fmt , _logicnum , from , r , e , last ) ;
1994-08-22 11:10:49 +00:00
p . set_text ( s1 ) ;
1998-01-28 08:29:13 +00:00
1998-08-10 10:20:31 +00:00
close ( ) ;
1998-01-28 08:29:13 +00:00
1994-11-10 14:15:41 +00:00
setstatus ( err ) ;
2003-07-03 08:43:59 +00:00
2006-12-13 16:22:33 +00:00
// Devo reindicizzare alla fine
if ( err = = NOERR & & ! indexed )
packindex ( vis , false ) ;
2003-07-03 08:43:59 +00:00
//aggiorna lo sheet con i nuovi valori di EOX EOD caricati
if ( err = = NOERR )
update_file ( ) ;
1994-08-22 11:10:49 +00:00
return err ;
1994-08-12 10:52:49 +00:00
}
1996-02-05 19:00:53 +00:00
// @doc EXTERNAL
2006-11-29 11:34:07 +00:00
// @mfunc Importa un file ascii
//
// @rdesc Ritorna NOERR se l'operazione di lettura e' riuscita, altrimenti il codice di
// di errore generato (vedi <t TIsamerr>).
int TSystemisamfile : : overwrite (
const char * from , // @parm Nome del file da importare
char fs , // @parm Carattere separatore di campo (default <pipe>)
char fd , // @parm Carattere delimitatore di campi (default '\\0')
char rs , // @parm Carattere separatore di record (default '\\n')
bool vis ) // @parm Indica se visualizzare lo stato dell'operazione (default TRUE)
// @comm Se <p extended> e' TRUE e trova alcune stringhe col formato %stringa% (es. %frm%)
// ne sostituisce i valori (es. ditta corrente).
// @xref <mf TSystemisamfile::dump>
{
int err = NOERR ;
FILE * fl = fopen ( from , " r " ) ;
if ( fl = = NULL )
{
error_box ( " Impossibile aprire il file %s " , from ) ;
clearerr ( fl ) ;
setstatus ( 2 ) ;
return 2 ;
}
TRecnotype r = 0 , e = 0 , nitems = 0 ;
TString16 firm , year , attprev ( " 00000 " ) ;
fseek ( fl , 0L , SEEK_END ) ;
nitems = ftell ( fl ) ;
fclose ( fl ) ;
2011-01-26 09:20:47 +00:00
err = _open_ex ( _excllock ) ;
2006-11-29 11:34:07 +00:00
if ( err ! = NOERR )
{
2011-01-26 09:20:47 +00:00
error_box ( " Impossibile aprire il file %d in modo esclusivo " , _logicnum ) ;
2006-11-29 11:34:07 +00:00
return err ;
}
TScanner f ( from ) ;
bool fixedlen = ( fs = = ' \0 ' ) ;
TToken_string s ( 1024 , fixedlen ? char ( 255 ) : fs ) ;
int nflds = curr ( ) . items ( ) ;
TString_array fld ( nflds ) ;
TString_array keyfld ( nflds ) ;
TAssoc_array vals ;
2009-10-21 13:40:18 +00:00
int len [ MaxFields ] ;
2006-11-29 11:34:07 +00:00
TString sfd ( 3 ) ;
TString s1 ( 256 ) ;
bool lcf = FALSE ;
if ( f . paragraph ( " Header " ) )
{
int equal ;
TString key ;
nflds = 0 ;
while ( ( equal = f . line ( ) . find ( ' = ' ) ) > 0 )
{
key = f . token ( ) . left ( equal ) ;
key . trim ( ) ;
if ( key = = " Version " )
{
const unsigned int level = atoi ( f . token ( ) . mid ( equal + 1 ) ) ;
if ( level > prefix ( ) . filelevel ( ) )
{
const unsigned int stdlevel = prefix ( ) . get_stdlevel ( ) ;
error_box ( FR ( " L'archivio %s e' stato generato con gli archivi di livello %ld%/%ld. \n Il livello attuale e' %ld/%ld. \n Convertire gli archivi e ripetere l' operazione. " ) ,
from , level / 100 , level % 100 , stdlevel / 100 , stdlevel % 100 ) ;
}
lcf = getlcf ( level ) ;
} else
if ( key = = " File " )
{
const int logic = atoi ( f . token ( ) . mid ( equal + 1 ) ) ;
if ( logic ! = num ( ) )
error_box ( " L'archivio %s e' stato generato dal file %d " ,
from , logic ) ;
} else
if ( key = = " Fields " )
{
TToken_string riga ( f . token ( ) . mid ( equal + 1 ) ) ;
TToken_string wfd ( 32 , ' , ' ) ;
FOR_EACH_TOKEN ( riga , fd )
{
wfd = fd ; wfd . strip_spaces ( ) ;
fld . add ( wfd . get ( 0 ) ) ;
2009-10-21 13:40:18 +00:00
len [ nflds + + ] = wfd . get_int ( ) ;
2006-11-29 11:34:07 +00:00
}
2008-12-10 16:52:43 +00:00
const RecDes & rd = curr ( ) . rec_des ( ) ;
2006-11-29 11:34:07 +00:00
const KeyDes & kd = rd . Ky [ 0 ] ;
for ( int i = 0 ; i < kd . NkFields ; i + + )
{
const int nf = kd . FieldSeq [ i ] % MaxFields ;
const RecFieldDes & rf = rd . Fd [ nf ] ;
keyfld . add ( rf . Name ) ;
}
}
}
}
if ( nflds = = 0 | | fld . items ( ) = = 0 )
{
nflds = curr ( ) . items ( ) ;
for ( int j = 0 ; j < nflds ; j + + )
{
fld . add ( curr ( ) . fieldname ( j ) , j ) ;
2009-10-21 13:40:18 +00:00
const TString & wfld = fld . row ( j ) ;
int l = 0 ;
switch ( curr ( ) . type ( wfld ) )
{
case _datefld : l = 10 ; break ;
default : l = curr ( ) . length ( wfld ) ; break ;
}
len [ j ] = l ;
2006-11-29 11:34:07 +00:00
}
}
if ( ! f . paragraph ( " Data " ) )
{
error_box ( " Formato file non valido: manca il paragrafo [Data] " ) ;
close ( ) ;
err = 1 ;
setstatus ( err ) ;
return err ;
}
if ( fd ) sfd < < fd ;
int last = NOERR ;
s1 . format ( " Importazione archivio %d da %s \n %6ld records %6ld errori - %3d " ,
_logicnum , from , r , e , last ) ;
TProgind p ( nitems , s1 , true , true , 78 ) ;
long pos = 16 * nflds ;
for ( s = f . line ( ) ; s . not_empty ( ) & & ! p . iscancelled ( ) ; s = f . line ( ) )
{
if ( ( r + e ) % 50 = = 0 )
{
s1 . format ( " Importazione archivio %d da %s \n %6ld records %6ld errori - %3d " ,
_logicnum , from , r , e , last ) ;
p . set_text ( s1 ) ;
}
pos + = s . len ( ) + 2 ;
p . setstatus ( pos ) ;
zero ( ) ;
2006-11-30 13:43:45 +00:00
vals . destroy ( ) ;
2006-11-29 11:34:07 +00:00
if ( fixedlen )
{
int pos = 0 ;
for ( int j = 0 ; j < nflds ; j + + )
{
const TString & fldname = fld . row ( j ) ;
s1 = s . mid ( pos , len [ j ] ) ;
s1 . rtrim ( ) ;
vals . add ( fldname , s1 ) ;
pos + = len [ j ] ;
}
}
else
{
s . restart ( ) ;
for ( int j = 0 ; j < nflds ; j + + )
{
const TString & fldname = fld . row ( j ) ;
s1 = s . get ( ) ;
if ( fd )
{
s1 . rtrim ( 1 ) ;
s1 . ltrim ( 1 ) ;
}
if ( curr ( ) . type ( fldname ) = = _memofld )
{
TString s2 = s1 ;
s1 = esc ( s2 ) ;
}
vals . add ( fldname , s1 ) ;
}
}
FOR_EACH_ARRAY_ROW ( keyfld , r0 , kfldname )
{
const TString * value = ( const TString * ) vals . objptr ( * kfldname ) ;
if ( value ! = NULL )
put ( * kfldname , * value ) ;
}
const bool nuovo = read ( ) ! = NOERR ;
if ( nuovo )
zero ( ) ;
FOR_EACH_ASSOC_STRING ( vals , obj , fldname , value )
put ( fldname , value ) ;
const int err = nuovo ? write ( ) : rewrite ( ) ;
if ( err = = NOERR )
r + + ;
else
{
e + + ;
last = status ( ) ;
}
}
s1 . format ( " Importazione archivio %d da %s \n %6ld records %6ld errori - %3d " ,
_logicnum , from , r , e , last ) ;
2006-12-13 16:22:33 +00:00
2006-11-29 11:34:07 +00:00
p . set_text ( s1 ) ;
close ( ) ;
setstatus ( err ) ;
2006-12-13 16:22:33 +00:00
//aggiorna lo sheet con i nuovi valori di EOX EOD caricati
2006-11-29 11:34:07 +00:00
if ( err = = NOERR )
update_file ( ) ;
return err ;
}
// @doc EXTERNAL
1995-12-12 17:47:56 +00:00
// @mfunc Esporta VERSO un file ascii.
//
// @rdesc Ritorna NOERR se l'operazione di esportazione e' riuscita, altrimenti il codice di
1995-12-29 12:09:48 +00:00
// di errore generato (vedi <t TIsamerr>).
1995-12-12 17:47:56 +00:00
int TSystemisamfile : : dump (
const char * to , // @parm Nome del file verso quale esportare
int nkey , // @parm Numero della chiave di ordinamento con cui scaricare i dati (defualt 1)
char fs , // @parm Carattere seperatore di campo (defualt <pipe>)
char fd , // @parm Carattere delimitatore di campo (default '\\0')
char rs , // @parm Carattere separatore di record (default '\\n')
bool vis , // @parm Indica se visualizzare lo stato dell'operazione (defualt TRUE)
2000-05-05 15:25:49 +00:00
bool withdeleted , // @parm Indica se scaricare anche i record cancellati (dafault FALSE)
2007-01-03 15:49:20 +00:00
const char * filter , // @parm Indica l'espressione filtro
SELECTIONFUNCTION select_func , // @parm funzione filtro
TObject * filter_obj ) // @parm oggetto di filtro
1995-12-12 17:47:56 +00:00
// @xref <mf TSystemisamfile::load>
1994-08-12 10:52:49 +00:00
{
1994-08-22 11:10:49 +00:00
FILE * f = fopen ( to , " w " ) ;
if ( f = = NULL )
{
1996-07-10 07:28:26 +00:00
setstatus ( 2 ) ;
return 2 ;
1994-08-22 11:10:49 +00:00
}
1996-07-10 07:28:26 +00:00
if ( withdeleted ) nkey = 0 ;
int err = ferror ( f ) ;
1997-10-16 14:06:40 +00:00
open ( FALSE , nkey ? TRUE : FALSE ) ;
1994-08-22 11:10:49 +00:00
TString s ( 512 ) ;
bool fixedlen = ( fs = = ' \0 ' ) ;
int nflds = curr ( ) . items ( ) ;
2008-12-16 10:25:17 +00:00
TString_array fld ( nflds ) ;
1994-08-22 11:10:49 +00:00
TBit_array rjust ( nflds ) ;
1994-09-27 10:19:36 +00:00
int len [ MaxFields ] ;
2004-03-12 16:10:04 +00:00
int j ;
1994-08-22 11:10:49 +00:00
2004-03-12 16:10:04 +00:00
for ( j = 0 ; j < nflds ; j + + )
1994-08-22 11:10:49 +00:00
{
2008-12-16 10:25:17 +00:00
fld . add ( curr ( ) . fieldname ( j ) , j ) ;
const TString & wfld = fld . row ( j ) ;
1994-09-27 10:19:36 +00:00
const TFieldtypes t = curr ( ) . type ( wfld ) ;
rjust . set ( j , t = = _intfld | | t = = _longfld | | t = = _realfld | |
t = = _wordfld | | t = = _intzerofld | | t = = _longzerofld ) ;
len [ j ] = ( t = = _datefld ) ? 10 : curr ( ) . length ( wfld ) ;
1999-04-16 12:02:04 +00:00
if ( fixedlen & & t = = _memofld )
2009-10-21 13:40:18 +00:00
{
error_box ( TR ( " Non e' possibile scaricare a lunghezza fissa un file con campi memo " ) ) ;
return _isbadtrc ;
}
1994-08-22 11:10:49 +00:00
}
TRecnotype i = 0 ;
1998-03-30 13:43:36 +00:00
const TRecnotype nitems = items ( ) ;
2008-12-23 09:05:22 +00:00
s . format ( FR ( " Esportazione %s " ) , filename ( ) ) ;
1994-10-31 16:24:26 +00:00
TProgind p ( nitems , s , TRUE , TRUE , 70 ) ;
1999-04-06 15:34:39 +00:00
TString s1 , sfld ;
1994-09-27 10:19:36 +00:00
1998-01-28 08:29:13 +00:00
fprintf ( f , " [Header] \n Version=%ld \n File=%d " ,
2004-03-12 16:10:04 +00:00
( long ) prefix ( ) . filelevel ( ) , num ( ) ) ;
1994-09-27 10:19:36 +00:00
for ( int k = 0 ; k < nflds ; k + + )
{
if ( ( k % 10 ) = = 0 ) fprintf ( f , " \n Fields= " ) ;
else fprintf ( f , " | " ) ;
fprintf ( f , " %s,%d " , ( const char * ) ( const TString & ) fld [ k ] , len [ k ] ) ;
}
fprintf ( f , " \n \n [Data] \n " ) ;
1994-08-22 11:10:49 +00:00
if ( nkey )
{
setkey ( nkey ) ;
for ( first ( ) ; status ( ) = = NOERR & & ! p . iscancelled ( ) ; next ( ) , i + + )
{
p . setstatus ( i + 1 ) ;
2001-04-30 15:04:10 +00:00
if ( filter & & * filter )
2000-05-05 15:25:49 +00:00
{
TToken_string filter_str ( filter ) ;
2001-04-30 15:04:10 +00:00
TString16 fname ;
2007-01-03 15:49:20 +00:00
bool skip = false ;
2000-05-05 15:25:49 +00:00
while ( ! skip & & ! ( fname = filter_str . get ( ) ) . empty ( ) )
{
2001-04-30 15:04:10 +00:00
const char * fval = filter_str . get ( ) ;
const TString & cmp = get ( fname ) ;
skip = cmp ! = fval ;
2000-05-05 15:25:49 +00:00
}
2007-01-03 15:49:20 +00:00
skip | = ( select_func ! = NULL ) & & ( select_func ( curr ( ) , filter_obj ) = = false ) ;
2001-04-30 15:04:10 +00:00
if ( skip )
continue ;
2000-05-05 15:25:49 +00:00
}
2008-12-16 10:25:17 +00:00
s . cut ( 0 ) ;
1994-08-22 11:10:49 +00:00
for ( j = 0 ; j < nflds ; j + + )
{
2008-12-16 10:25:17 +00:00
const TString & fname = fld . row ( j ) ;
1994-08-22 11:10:49 +00:00
if ( fixedlen )
{
2008-12-16 10:25:17 +00:00
s1 = get ( fname ) ;
1994-08-22 11:10:49 +00:00
if ( rjust [ j ] ) s1 . right_just ( len [ j ] ) ;
else s1 . left_just ( len [ j ] ) ;
}
else
{
2008-12-16 10:25:17 +00:00
s1 . cut ( 0 ) ;
1994-08-22 11:10:49 +00:00
if ( j & & fs ) s1 < < fs ;
if ( fd ) s1 < < fd ;
2008-12-16 10:25:17 +00:00
sfld = get ( fname ) ;
switch ( curr ( ) . type ( fname ) )
1999-04-06 15:34:39 +00:00
{
2008-12-16 10:25:17 +00:00
case _intfld :
case _longfld :
case _intzerofld :
case _longzerofld :
case _realfld :
if ( real : : is_null ( sfld ) )
sfld . cut ( 0 ) ;
break ;
case _memofld :
if ( sfld . full ( ) )
1999-04-06 15:34:39 +00:00
{
2008-12-16 10:25:17 +00:00
int p = 0 ;
while ( ( p = sfld . find ( ' \n ' , 0 ) ) > = 0 )
{
sfld . overwrite ( " \\ " , p ) ;
sfld . insert ( " n " , p + 1 ) ;
}
1999-04-06 15:34:39 +00:00
}
2008-12-16 10:25:17 +00:00
else
sfld . cut ( 0 ) ;
break ;
default : // strfld, charfld, boolfld
if ( sfld . blank ( ) )
sfld . cut ( 0 ) ;
break ;
1999-04-06 15:34:39 +00:00
}
s1 < < sfld ;
1994-08-22 11:10:49 +00:00
if ( fd ) s1 < < fd ;
}
s < < s1 ;
}
2008-12-16 10:25:17 +00:00
if ( fs ) // Elimina tutti i campi vuoti a fine record
{
int i ;
for ( i = s . len ( ) - 1 ; i > = 0 & & s [ i ] = = fs ; i - - ) ;
s . cut ( i + 1 ) ;
}
1994-08-22 11:10:49 +00:00
fprintf ( f , " %s%c " , ( const char * ) s , rs ) ;
}
}
else
{
for ( i = 0 ; i < nitems & & ! p . iscancelled ( ) ; i + + )
{
1994-11-10 14:15:41 +00:00
zero ( ) ;
1994-08-22 11:10:49 +00:00
p . setstatus ( i + 1 ) ;
readat ( i + 1 ) ;
2001-04-30 15:04:10 +00:00
if ( filter & & * filter )
{
TToken_string filter_str ( filter ) ;
TString16 fname ;
bool skip = FALSE ;
while ( ! skip & & ! ( fname = filter_str . get ( ) ) . empty ( ) )
{
const char * fval = filter_str . get ( ) ;
const TString & cmp = get ( fname ) ;
skip = cmp ! = fval ;
}
if ( skip )
continue ;
}
1994-08-22 11:10:49 +00:00
s = " " ;
if ( withdeleted | | curr ( ) . valid ( ) )
{
for ( j = 0 ; j < nflds ; j + + )
{
if ( fixedlen )
{
s1 = get ( ( const TString & ) fld [ j ] ) ;
if ( rjust [ j ] ) s1 . right_just ( len [ j ] ) ;
else s1 . left_just ( len [ j ] ) ;
}
else
{
s1 = " " ;
if ( j & & fs ) s1 < < fs ;
if ( fd ) s1 < < fd ;
1999-04-06 15:34:39 +00:00
sfld = get ( ( const TString & ) fld [ j ] ) ;
if ( curr ( ) . type ( ( const TString & ) fld [ j ] ) = = _memofld )
{
int p = 0 ;
while ( ( p = sfld . find ( ' \n ' , 0 ) ) > = 0 )
{
sfld . overwrite ( " \\ " , p ) ;
sfld . insert ( " n " , p + 1 ) ;
}
}
s1 < < sfld ;
1994-08-22 11:10:49 +00:00
if ( fd ) s1 < < fd ;
}
s < < s1 ;
}
fprintf ( f , " %s%c " , ( const char * ) s , rs ) ;
}
}
}
1994-09-27 10:19:36 +00:00
p . setstatus ( nitems ) ;
1994-08-22 11:10:49 +00:00
close ( ) ;
fclose ( f ) ;
1994-09-27 10:19:36 +00:00
setstatus ( err ) ;
1994-08-22 11:10:49 +00:00
return err ;
1994-11-24 14:01:20 +00:00
}
1994-08-12 10:52:49 +00:00
2006-11-29 11:34:07 +00:00
int TSystemisamfile : : dump (
const char * to , // @parm Nome del file verso quale esportare
TToken_string & field_list , // @parm Lista dei campi
int nkey , // @parm Numero della chiave di ordinamento con cui scaricare i dati (defualt 1)
char fs , // @parm Carattere seperatore di campo (defualt <pipe>)
char fd , // @parm Carattere delimitatore di campo (default '\\0')
char rs , // @parm Carattere separatore di record (default '\\n')
bool vis , // @parm Indica se visualizzare lo stato dell'operazione (defualt TRUE)
bool withdeleted , // @parm Indica se scaricare anche i record cancellati (dafault FALSE)
2007-01-03 15:49:20 +00:00
const char * filter , // @parm Indica l'espressione filtro
SELECTIONFUNCTION select_func , // @parm funzione filtro
TObject * filter_obj ) // @parm oggetto di filtro
2006-11-29 11:34:07 +00:00
// @xref <mf TSystemisamfile::load>
{
FILE * f = fopen ( to , " w " ) ;
if ( f = = NULL )
{
setstatus ( 2 ) ;
return 2 ;
}
if ( withdeleted ) nkey = 0 ;
int err = ferror ( f ) ;
open ( FALSE , nkey ? TRUE : FALSE ) ;
TString s ( 512 ) ;
bool fixedlen = ( fs = = ' \0 ' ) ;
int nflds = curr ( ) . items ( ) ;
2014-12-10 16:00:46 +00:00
TString_array fld ( nflds ) ;
2006-11-29 11:34:07 +00:00
TBit_array rjust ( nflds ) ;
2014-12-10 16:00:46 +00:00
int len [ MaxFields ] ;
2006-11-29 11:34:07 +00:00
int j = 0 ;
FOR_EACH_TOKEN ( field_list , str )
{
const TString16 fldname ( str ) ;
fld . add ( fldname ) ;
const TFieldtypes t = curr ( ) . type ( fldname ) ;
2014-12-10 16:00:46 +00:00
rjust . set ( j , t = = _intfld | | t = = _longfld | | t = = _realfld | |
t = = _wordfld | | t = = _intzerofld | | t = = _longzerofld ) ;
2006-11-29 11:34:07 +00:00
len [ j + + ] = ( t = = _datefld ) ? 10 : curr ( ) . length ( fldname ) ;
if ( fixedlen & & t = = _memofld )
2014-12-10 16:00:46 +00:00
return error_box ( TR ( " Non <20> possibile scaricare a lunghezza fissa un file con campi memo " ) ) ;
2006-11-29 11:34:07 +00:00
}
TRecnotype i = 0 ;
const TRecnotype nitems = items ( ) ;
2008-12-23 09:05:22 +00:00
s . format ( FR ( " Esportazione %s " ) , filename ( ) ) ;
2006-11-29 11:34:07 +00:00
TProgind p ( nitems , s , TRUE , TRUE , 70 ) ;
TString s1 , sfld ;
fprintf ( f , " [Header] \n Version=%ld \n File=%d " ,
( long ) prefix ( ) . filelevel ( ) , num ( ) ) ;
FOR_EACH_ARRAY_ROW ( fld , k , el )
{
if ( ( k % 10 ) = = 0 ) fprintf ( f , " \n Fields= " ) ;
else fprintf ( f , " | " ) ;
const TString & fldname = fld . row ( k ) ;
fprintf ( f , " %s,%d " , ( const char * ) fldname , len [ k ] ) ;
}
fprintf ( f , " \n \n [Data] \n " ) ;
if ( nkey )
{
setkey ( nkey ) ;
for ( first ( ) ; status ( ) = = NOERR & & ! p . iscancelled ( ) ; next ( ) , i + + )
{
2007-01-03 14:22:38 +00:00
bool skip = false ;
p . setstatus ( i + 1 ) ;
2006-11-29 11:34:07 +00:00
if ( filter & & * filter )
{
TToken_string filter_str ( filter ) ;
TString16 fname ;
2007-01-03 14:22:38 +00:00
2006-11-29 11:34:07 +00:00
while ( ! skip & & ! ( fname = filter_str . get ( ) ) . empty ( ) )
{
const char * fval = filter_str . get ( ) ;
const TString & cmp = get ( fname ) ;
skip = cmp ! = fval ;
}
}
2007-01-03 15:49:20 +00:00
skip | = ( select_func ! = NULL ) & & ( select_func ( curr ( ) , filter_obj ) = = false ) ;
2007-01-03 14:22:38 +00:00
if ( skip )
continue ;
2006-11-29 11:34:07 +00:00
s = " " ;
FOR_EACH_ARRAY_ROW ( fld , j , el )
{
const TString & fldname = fld . row ( j ) ;
if ( fixedlen )
{
s1 = get ( fldname ) ;
if ( rjust [ j ] ) s1 . right_just ( len [ j ] ) ;
else s1 . left_just ( len [ j ] ) ;
}
else
{
s1 = " " ;
if ( j & & fs ) s1 < < fs ;
if ( fd ) s1 < < fd ;
sfld = get ( fldname ) ;
if ( curr ( ) . type ( fldname ) = = _memofld )
{
int p = 0 ;
while ( ( p = sfld . find ( ' \n ' , 0 ) ) > = 0 )
{
sfld . overwrite ( " \\ " , p ) ;
sfld . insert ( " n " , p + 1 ) ;
}
}
s1 < < sfld ;
if ( fd ) s1 < < fd ;
}
s < < s1 ;
}
fprintf ( f , " %s%c " , ( const char * ) s , rs ) ;
}
}
else
{
for ( i = 0 ; i < nitems & & ! p . iscancelled ( ) ; i + + )
{
zero ( ) ;
p . setstatus ( i + 1 ) ;
readat ( i + 1 ) ;
if ( filter & & * filter )
{
TToken_string filter_str ( filter ) ;
TString16 fname ;
bool skip = FALSE ;
while ( ! skip & & ! ( fname = filter_str . get ( ) ) . empty ( ) )
{
const char * fval = filter_str . get ( ) ;
const TString & cmp = get ( fname ) ;
skip = cmp ! = fval ;
}
if ( skip )
continue ;
}
s = " " ;
if ( withdeleted | | curr ( ) . valid ( ) )
{
FOR_EACH_ARRAY_ROW ( fld , j , el )
{
const TString & fldname = fld . row ( j ) ;
if ( fixedlen )
{
s1 = get ( fldname ) ;
if ( rjust [ j ] ) s1 . right_just ( len [ j ] ) ;
else s1 . left_just ( len [ j ] ) ;
}
else
{
s1 = " " ;
if ( j & & fs ) s1 < < fs ;
if ( fd ) s1 < < fd ;
sfld = get ( fldname ) ;
if ( curr ( ) . type ( fldname ) = = _memofld )
{
int p = 0 ;
while ( ( p = sfld . find ( ' \n ' , 0 ) ) > = 0 )
{
sfld . overwrite ( " \\ " , p ) ;
sfld . insert ( " n " , p + 1 ) ;
}
}
s1 < < sfld ;
if ( fd ) s1 < < fd ;
}
s < < s1 ;
}
fprintf ( f , " %s%c " , ( const char * ) s , rs ) ;
}
}
}
p . setstatus ( nitems ) ;
close ( ) ;
fclose ( f ) ;
setstatus ( err ) ;
return err ;
}
1994-08-12 10:52:49 +00:00
# endif // FOXPRO
1994-11-24 14:01:20 +00:00
void TBaseisamfile : : recover ( )
{
}
2000-10-03 13:45:12 +00:00
////////////////////////////////////////////////////////////
// Memo data
////////////////////////////////////////////////////////////
void TMemo_data : : init ( TRecnotype recno , TIsam_handle file )
{
2004-03-12 16:10:04 +00:00
CHECK ( file > 0 | | recno < 0 , " Valid memo recno with NULL memo file " ) ; // verificare
2000-10-03 13:45:12 +00:00
_recno = recno ;
_isamfile = file ;
}
void TMemo_data : : destroy ( )
{
TString_array : : destroy ( ) ;
_dirty . reset ( ) ;
_recno = RECORD_NON_FISICO ;
2004-03-12 16:10:04 +00:00
_isamfile = 0 ;
2000-10-03 13:45:12 +00:00
}
void TMemo_data : : copy ( const TMemo_data & m )
{
TString_array : : operator = ( m ) ;
_dirty = m . _dirty ;
_recno = m . _recno ;
_isamfile = m . _isamfile ;
}
1994-11-24 14:01:20 +00:00
1994-08-12 10:52:49 +00:00
////////////////////////////////////////////////////////////
2000-10-03 13:45:12 +00:00
// TRectype
1994-08-12 10:52:49 +00:00
////////////////////////////////////////////////////////////
2001-04-30 15:04:10 +00:00
2000-10-03 13:45:12 +00:00
void TRectype : : init ( int logicnum )
{
_logicnum = logicnum ;
2002-07-03 14:48:48 +00:00
CHECK ( _logicnum > 0 , " Impossibile costruire un record di un file esterno " ) ;
2000-10-03 13:45:12 +00:00
2001-05-04 10:59:04 +00:00
_length = prefix ( ) . get_reclen ( logicnum ) ;
2000-10-03 13:45:12 +00:00
_rec = new char [ _length ] ;
* _tab = ' \0 ' ;
if ( _length > 0 )
zero ( ) ;
else
setempty ( TRUE ) ;
2001-05-04 10:59:04 +00:00
2009-01-07 15:50:52 +00:00
if ( _length > 0 & & lf_has_memo ( logicnum ) )
2000-10-03 13:45:12 +00:00
init_memo ( RECORD_NON_FISICO ) ;
}
1996-09-26 15:26:47 +00:00
TRectype : : TRectype ( int logicnum )
2000-10-03 13:45:12 +00:00
: _memo_data ( NULL )
{
2002-07-03 14:48:48 +00:00
init ( logicnum ) ;
2000-10-03 13:45:12 +00:00
}
1996-09-26 15:26:47 +00:00
TRectype : : TRectype ( const TBaseisamfile * i )
2000-10-03 13:45:12 +00:00
: _memo_data ( NULL )
1994-08-12 10:52:49 +00:00
{
2001-05-04 10:59:04 +00:00
init ( i - > num ( ) ) ;
1994-08-12 10:52:49 +00:00
}
TRectype : : TRectype ( const TRectype & r )
2009-01-07 15:50:52 +00:00
: _memo_data ( NULL )
1994-08-22 11:10:49 +00:00
1994-08-12 10:52:49 +00:00
{
2002-07-03 14:48:48 +00:00
init ( r . _logicnum ) ;
1996-09-26 15:26:47 +00:00
if ( r . _memo_data )
{
2001-04-30 15:04:10 +00:00
init_memo ( r . _memo_data - > recno ( ) , r . _memo_data - > file ( ) ) ;
1996-09-26 15:26:47 +00:00
* _memo_data = * r . _memo_data ;
}
1998-10-01 13:59:39 +00:00
memcpy ( _rec , r . _rec , _length ) ;
1994-09-27 10:19:36 +00:00
strcpy ( _tab , r . _tab ) ;
1994-08-22 11:10:49 +00:00
setempty ( r . empty ( ) ) ;
1994-08-12 10:52:49 +00:00
}
TRectype : : ~ TRectype ( )
{
2000-10-03 13:45:12 +00:00
if ( _rec ! = NULL )
delete _rec ;
if ( _memo_data ! = NULL )
delete _memo_data ;
1994-08-12 10:52:49 +00:00
}
1996-09-02 14:20:24 +00:00
void TRectype : : unknown_field ( const char * name ) const
{
2001-04-30 15:04:10 +00:00
static int last_file = 0 ;
if ( _logicnum ! = last_file )
{
NFCHECK ( " Il campo '%s' non appartiene al file %d " , name , _logicnum ) ;
last_file = _logicnum ;
}
1996-09-02 14:20:24 +00:00
}
2002-07-03 14:48:48 +00:00
void TRectype : : write_memo ( TIsam_handle file , const TRecnotype recno )
1996-09-02 14:20:24 +00:00
{
2008-12-10 16:52:43 +00:00
const RecDes & r = rec_des ( ) ;
2000-10-03 13:45:12 +00:00
TIsam_handle orig = _memo_data - > file ( ) ;
2001-05-04 10:59:04 +00:00
if ( orig & & ( file ! = orig | | recno ! = _memo_data - > recno ( ) ) )
2000-10-03 13:45:12 +00:00
{
TCodeb_handle cb_orig = prefix ( ) . get_handle ( orig ) ;
DB_go ( cb_orig , _memo_data - > recno ( ) ) ;
2008-12-10 16:52:43 +00:00
for ( int i = r . NFields - 1 ; i > = 0 ; i - - )
2000-10-03 13:45:12 +00:00
{
2008-12-10 16:52:43 +00:00
if ( r . Fd [ i ] . TypeF = = _memofld )
2000-10-03 13:45:12 +00:00
{
if ( _memo_data - > objptr ( i ) = = NULL )
{
2008-12-10 16:52:43 +00:00
const char * memo = DB_memoptr ( cb_orig , r . Fd [ i ] . Name ) ;
2000-10-03 13:45:12 +00:00
if ( memo & & * memo )
_memo_data - > add ( memo , i ) ;
}
_memo_data - > set_dirty ( i ) ;
}
}
}
2003-09-11 07:26:47 +00:00
CHECKD ( recno > = 0 , " Maiale! Non fare le GO con _recno < 0: " , recno ) ;
2008-12-23 09:05:22 +00:00
const TCodeb_handle cb_handle = prefix ( ) . get_handle ( file ) ;
2002-07-03 14:48:48 +00:00
DB_go ( cb_handle , recno ) ;
2009-01-07 15:50:52 +00:00
FOR_EACH_ARRAY_ROW_BACK ( ( * _memo_data ) , i , memo )
2000-10-03 13:45:12 +00:00
{
if ( _memo_data - > is_dirty ( i ) )
2009-01-07 15:50:52 +00:00
DB_memowrite ( cb_handle , r . Fd [ i ] . Name , * memo ) ;
2000-10-03 13:45:12 +00:00
}
2009-01-07 15:50:52 +00:00
DB_flush ( cb_handle ) ;
2008-12-23 09:05:22 +00:00
* this = ( const char * ) DB_getrecord ( cb_handle ) ;
2000-10-03 13:45:12 +00:00
init_memo ( recno , file ) ;
1996-09-02 14:20:24 +00:00
}
2000-10-03 13:45:12 +00:00
void TRectype : : init_memo ( TRecnotype recno , TIsam_handle file )
1996-09-02 14:20:24 +00:00
{
1996-09-26 15:26:47 +00:00
if ( _memo_data = = NULL )
2000-10-03 13:45:12 +00:00
_memo_data = new TMemo_data ;
1996-09-26 15:26:47 +00:00
else
_memo_data - > destroy ( ) ;
2000-10-03 13:45:12 +00:00
_memo_data - > init ( recno , file ) ;
1996-09-02 14:20:24 +00:00
}
1994-09-27 10:19:36 +00:00
void TRectype : : settab ( const char * tab )
{
strcpy ( _tab , tab ) ;
1994-09-28 15:52:37 +00:00
zero ( ) ;
1994-09-27 10:19:36 +00:00
}
1994-08-12 10:52:49 +00:00
TObject * TRectype : : dup ( ) const
{
1994-08-22 11:10:49 +00:00
TRectype * o = new TRectype ( * this ) ;
return o ;
1994-08-12 10:52:49 +00:00
}
1995-11-10 13:37:28 +00:00
const char * TRectype : : build_key ( int num ) const
{
2009-11-08 22:17:25 +00:00
TString & tmp = get_tmp_string ( 256 ) ;
2003-04-22 14:01:02 +00:00
__build_key ( rec_des ( ) , num , string ( ) , tmp . get_buffer ( ) , TRUE ) ;
return tmp ;
1995-11-10 13:37:28 +00:00
}
1995-11-13 12:08:59 +00:00
const char * TRectype : : last_key_field ( int key ) const
{
2008-12-10 16:52:43 +00:00
const KeyDes & kd = rec_des ( ) . Ky [ key ] ;
1995-11-13 12:08:59 +00:00
const int last = kd . NkFields - 1 ;
const bool upp = kd . FieldSeq [ last ] > MaxFields ;
const int nf = upp ? kd . FieldSeq [ last ] - MaxFields : kd . FieldSeq [ last ] ;
2008-12-10 16:52:43 +00:00
const RecFieldDes & rf = rec_des ( ) . Fd [ nf ] ;
1995-11-13 12:08:59 +00:00
return rf . Name ;
}
1996-02-05 19:00:53 +00:00
// @doc EXTERNAL
1995-12-12 17:47:56 +00:00
// @mfunc Confronta le chiavi di due record
//
// @rdesc Ritorna il risultato di una <f strcmp>:
//
// @flag 0 | Se le due chiavi sono uguali
// @flag <lt><gt>0 | Se le due chiavi sono diverse
int TRectype : : compare_key (
const TRectype & rec , // @parm Record di cui confrontare le chiavi
int key , // @parm Numero della chiave del presente record (defautl 1)
1996-09-19 10:21:32 +00:00
int skip_last ) const // @parm Numero di campi da ignorare nella comparazione a partire dall'ultimo
1995-12-12 17:47:56 +00:00
// @xref <mf TRectype::build_key>
1995-11-10 13:37:28 +00:00
{
2005-01-18 11:15:37 +00:00
/* Vecchio modo con molte operazioni su stringhe e molte chiamate a rec_des()!
2003-02-05 14:26:24 +00:00
TString256 key1 = build_key ( key ) ;
1995-11-10 13:37:28 +00:00
TString256 key2 = rec . build_key ( key ) ;
1995-11-13 12:08:59 +00:00
if ( skip_last > 0 )
{
const KeyDes & kd = rec_des ( ) - > Ky [ key - 1 ] ;
const int last = kd . NkFields - 1 ;
CHECKD ( last > = skip_last , " Can't ignore so many fields in key: " , skip_last ) ;
for ( int l = 0 ; l < skip_last ; l + + )
{
int nf = kd . FieldSeq [ last - l ] ;
if ( nf > MaxFields ) nf - = MaxFields ;
const RecFieldDes & rf = rec_des ( ) - > Fd [ nf ] ;
key1 . rtrim ( rf . Len ) ;
key2 . rtrim ( rf . Len ) ;
}
}
const int res = strcmp ( key1 , key2 ) ;
2005-01-18 11:15:37 +00:00
*/
const char * key1 = build_key ( key ) ;
const char * key2 = rec . build_key ( key ) ;
int res = 0 ;
if ( skip_last > 0 )
{
int maxlen = 0 ;
2008-12-10 16:52:43 +00:00
const RecDes & rd = rec_des ( ) ;
2005-01-18 11:15:37 +00:00
const KeyDes & kd = rd . Ky [ key - 1 ] ;
const int last = kd . NkFields - skip_last ;
for ( int l = 0 ; l < last ; l + + )
{
const int nf = kd . FieldSeq [ l ] % MaxFields ;
const RecFieldDes & rf = rd . Fd [ nf ] ;
maxlen + = rf . Len ;
}
res = strncmp ( key1 , key2 , maxlen ) ;
}
else
res = strcmp ( key1 , key2 ) ;
1995-11-13 12:08:59 +00:00
return res ;
1995-11-10 13:37:28 +00:00
}
1994-08-12 10:52:49 +00:00
2014-03-07 14:20:06 +00:00
HIDDEN bool fld_empty ( const char * s , int len , bool /* number */ )
1994-08-12 10:52:49 +00:00
{
2014-03-07 14:20:06 +00:00
if ( s & & * s & & len > 0 )
1994-08-22 11:10:49 +00:00
{
2014-03-07 14:20:06 +00:00
for ( ; len ; s + + , len - - ) if ( * s ! = ' ' )
return false ;
1994-08-22 11:10:49 +00:00
}
2008-05-15 14:59:21 +00:00
return true ;
1994-08-12 10:52:49 +00:00
}
HIDDEN int fld_cmp ( const char * a , const char * b , int len , bool number )
{
2014-03-07 14:20:06 +00:00
int res = memcmp ( a , b , len ) ;
if ( res = = 0 )
return res ;
int i = 0 ;
if ( number ) // Aggiunta del 11-02-2014: ignoro spazi e zeri iniziali dei numeri
for ( ; i < len & & ( * a = = ' ' | | * a = = ' 0 ' ) & & ( * b = = ' ' | | * b = = ' 0 ' ) ; b + + , a + + , i + + ) ;
for ( ; i < len & & * a = = * b ; b + + , a + + , i + + ) ;
if ( i = = len )
return 0 ;
res = * a - * b ;
1994-08-22 11:10:49 +00:00
if ( number )
{
b - = i ;
i = 0 ;
}
2014-03-07 14:20:06 +00:00
1994-08-22 11:10:49 +00:00
return fld_empty ( b , len - i , number ) ? 0 : res ;
1994-08-12 10:52:49 +00:00
}
///////////////////////////////////////////////////////////
// TRectype (record di un file)
///////////////////////////////////////////////////////////
2008-12-10 16:52:43 +00:00
const RecDes & TRectype : : rec_des ( ) const
1997-07-22 09:49:11 +00:00
{
2008-12-10 16:52:43 +00:00
return prefix ( ) . get_recdes ( _logicnum ) ;
1995-04-10 15:28:03 +00:00
}
1994-08-12 10:52:49 +00:00
int TRectype : : items ( ) const
{
2008-12-10 16:52:43 +00:00
return rec_des ( ) . NFields ;
1994-08-12 10:52:49 +00:00
}
const char * TRectype : : start ( int nf ) const
{
2008-12-10 16:52:43 +00:00
return string ( ) + rec_des ( ) . Fd [ nf ] . RecOff ;
1994-08-12 10:52:49 +00:00
}
2000-10-03 13:45:12 +00:00
// Confronto tra record: Attenzione i campi vuoti di s non vengono confrontati!
1994-08-12 10:52:49 +00:00
int TRectype : : compare ( const TSortable & s ) const
{
const TRectype & br = ( const TRectype & ) s ;
1994-08-22 11:10:49 +00:00
int res = 0 ;
1994-08-12 10:52:49 +00:00
if ( br . empty ( ) ) return UNDEFINED ;
1995-08-09 09:54:36 +00:00
2008-12-10 16:52:43 +00:00
const RecDes & rd = rec_des ( ) ;
2000-10-03 13:45:12 +00:00
for ( int i = 0 ; i < rd . NFields ; i + + )
1994-08-22 11:10:49 +00:00
{
const char * b = br . start ( i ) ;
const char * a = start ( i ) ;
1995-08-09 09:54:36 +00:00
const byte typ = rd . Fd [ i ] . TypeF ;
const int sz = rd . Fd [ i ] . Len ;
1994-08-22 11:10:49 +00:00
const bool number = ( typ = = _intfld ) | | ( typ = = _realfld ) | |
( typ = = _longfld ) | | ( typ = = _wordfld ) | |
1998-11-03 10:27:35 +00:00
( typ = = _intzerofld ) | | ( typ = = _longzerofld ) | | ( typ = = _datefld ) ;
1994-08-22 11:10:49 +00:00
if ( fld_empty ( b , sz , number ) ) continue ;
res = : : fld_cmp ( a , b , sz , number ) ;
if ( res ) return res ;
}
1994-08-12 10:52:49 +00:00
return 0 ;
}
2000-10-03 13:45:12 +00:00
// Confronto stretto
bool TRectype : : is_equal ( const TRectype & r ) const
{
char * r1 = new char [ _length ] ;
char * r2 = new char [ _length ] ;
memcpy ( r1 , _rec , _length ) ;
memcpy ( r2 , r . _rec , _length ) ;
browse_null ( r1 , _length ) ;
browse_null ( r2 , _length ) ;
if ( has_memo ( ) )
{
2008-12-10 16:52:43 +00:00
const RecDes & rd = rec_des ( ) ;
2000-10-03 13:45:12 +00:00
for ( int i = rd . NFields - 1 ; i > = 0 ; i - - )
{
if ( rd . Fd [ i ] . TypeF = = _memofld )
{
memset ( r1 + rd . Fd [ i ] . RecOff , ' ' , rd . Fd [ i ] . Len ) ;
memset ( r2 + rd . Fd [ i ] . RecOff , ' ' , rd . Fd [ i ] . Len ) ;
}
}
}
bool yes = memcmp ( r1 , r2 , _length ) = = 0 ;
delete r1 ;
delete r2 ;
if ( yes & & has_memo ( ) )
{
2008-12-10 16:52:43 +00:00
const RecDes & rd = rec_des ( ) ;
2000-10-03 13:45:12 +00:00
for ( int i = rd . NFields - 1 ; yes & & i > = 0 ; i - - )
{
if ( rd . Fd [ i ] . TypeF = = _memofld )
yes = get ( rd . Fd [ i ] . Name ) = = r . get ( rd . Fd [ i ] . Name ) ;
}
}
return yes ;
}
1994-08-12 10:52:49 +00:00
TFieldtypes TRectype : : type ( const char * fieldname ) const
{
2008-12-10 16:52:43 +00:00
const RecDes & recd = rec_des ( ) ;
const int p = findfld ( & recd , fieldname ) ;
return p ! = FIELDERR ? ( TFieldtypes ) recd . Fd [ p ] . TypeF : _nullfld ;
1994-08-12 10:52:49 +00:00
}
int TRectype : : length ( const char * fieldname ) const
{
2008-12-10 16:52:43 +00:00
const RecDes & recd = rec_des ( ) ;
const int p = findfld ( & recd , fieldname ) ;
return p ! = FIELDERR ? recd . Fd [ p ] . Len : 0 ;
1994-08-12 10:52:49 +00:00
}
int TRectype : : ndec ( const char * fieldname ) const
{
2008-12-10 16:52:43 +00:00
const RecDes & recd = rec_des ( ) ;
const int p = findfld ( & recd , fieldname ) ;
return p ! = FIELDERR ? recd . Fd [ p ] . Dec : 0 ;
1994-08-12 10:52:49 +00:00
}
bool TRectype : : exist ( const char * fieldname ) const
1996-09-26 15:26:47 +00:00
{
2008-12-10 16:52:43 +00:00
return findfld ( & rec_des ( ) , fieldname ) ! = FIELDERR ;
1994-08-12 10:52:49 +00:00
}
const char * TRectype : : fieldname ( int i ) const
{
2008-12-10 16:52:43 +00:00
const RecDes & recd = rec_des ( ) ;
return i > = 0 & & i < recd . NFields ? recd . Fd [ i ] . Name : NULL ;
1996-09-26 15:26:47 +00:00
}
1994-08-12 10:52:49 +00:00
1998-03-30 13:43:36 +00:00
const TString & TRectype : : get_str ( const char * fieldname ) const
1996-09-26 15:26:47 +00:00
{
2008-12-10 16:52:43 +00:00
const RecDes & recd = rec_des ( ) ;
const int nf = findfld ( & recd , fieldname ) ;
2003-06-24 12:49:44 +00:00
if ( nf ! = FIELDERR )
1998-11-10 10:07:12 +00:00
{
2008-12-10 16:52:43 +00:00
const RecFieldDes & fd = recd . Fd [ nf ] ;
2003-06-24 12:49:44 +00:00
TString & tmp = get_tmp_string ( fd . Len + ( fd . TypeF = = _datefld ? 2 : 0 ) ) ;
2012-05-23 14:36:59 +00:00
__getfieldbuff ( fd . Len , fd . TypeF , _rec + fd . RecOff , tmp ) ;
2003-06-24 12:49:44 +00:00
return tmp ;
1998-11-10 10:07:12 +00:00
}
2003-06-24 12:49:44 +00:00
else
unknown_field ( fieldname ) ;
return EMPTY_STRING ;
1995-04-20 14:35:14 +00:00
}
1994-08-12 10:52:49 +00:00
1995-04-20 14:35:14 +00:00
const TString & TRectype : : get ( const char * fieldname ) const
1998-12-22 10:40:23 +00:00
{
if ( _memo_data & & type ( fieldname ) = = _memofld )
1995-11-22 13:46:11 +00:00
{
2008-12-10 16:52:43 +00:00
const RecDes & recd = rec_des ( ) ;
const int index = findfld ( & recd , fieldname ) ;
2000-10-03 13:45:12 +00:00
if ( _memo_data - > objptr ( index ) )
1996-09-26 15:26:47 +00:00
return _memo_data - > row ( index ) ;
2009-03-19 15:50:04 +00:00
if ( _memo_data - > recno ( ) > = 0L )
1996-09-26 15:26:47 +00:00
{
2009-03-19 15:50:04 +00:00
const TIsam_handle orig = _memo_data - > file ( ) ;
2000-10-03 13:45:12 +00:00
if ( orig )
{
2009-03-19 15:50:04 +00:00
CHECKD ( orig > = LF_EXTERNAL | | orig = = num ( ) , " Invalid isam handle " , orig ) ;
2003-06-24 12:49:44 +00:00
TCodeb_handle cb_handle = prefix ( ) . get_handle ( orig , - 1 ) ;
2002-07-03 14:48:48 +00:00
CHECKD ( cb_handle > = 0 , " Can't read memo from file " , orig ) ;
2003-06-24 12:49:44 +00:00
if ( DB_recno ( cb_handle ) ! = _memo_data - > recno ( ) )
DB_go ( cb_handle , _memo_data - > recno ( ) ) ;
2002-07-03 14:48:48 +00:00
_memo_data - > add ( DB_memoptr ( cb_handle , fieldname ) , index ) ;
2000-10-03 13:45:12 +00:00
}
else
NFCHECK ( " Valid memo recno with null memo file " ) ;
1996-09-26 15:26:47 +00:00
}
else
2000-10-03 13:45:12 +00:00
_memo_data - > add ( " " , index ) ;
return _memo_data - > row ( index ) ;
1995-11-22 13:46:11 +00:00
}
1996-09-26 15:26:47 +00:00
return get_str ( fieldname ) ;
1995-04-20 14:35:14 +00:00
}
1994-08-12 10:52:49 +00:00
int TRectype : : get_int ( const char * fieldname ) const
{
1996-09-02 14:20:24 +00:00
return atoi ( get_str ( fieldname ) ) ;
1994-08-12 10:52:49 +00:00
}
long TRectype : : get_long ( const char * fieldname ) const
{
1996-09-02 14:20:24 +00:00
return atol ( get_str ( fieldname ) ) ;
1994-08-12 10:52:49 +00:00
}
word TRectype : : get_word ( const char * fieldname ) const
{
1996-09-02 14:20:24 +00:00
return ( word ) atoi ( get_str ( fieldname ) ) ;
1994-08-12 10:52:49 +00:00
}
real TRectype : : get_real ( const char * fieldname ) const
{
2014-03-07 14:20:06 +00:00
const real r ( get_str ( fieldname ) ) ;
1994-08-22 11:10:49 +00:00
return r ;
1994-08-12 10:52:49 +00:00
}
char TRectype : : get_char ( const char * fieldname ) const
{
2006-12-13 16:22:33 +00:00
return get_str ( fieldname ) [ 0 ] ;
1994-08-12 10:52:49 +00:00
}
bool TRectype : : get_bool ( const char * fieldname ) const
{
2012-04-24 10:23:05 +00:00
const char c = get_char ( fieldname ) ;
2012-05-23 14:36:59 +00:00
return ( c = = ' X ' ) | | ( c = = ' 1 ' ) ;
1994-08-12 10:52:49 +00:00
}
TDate TRectype : : get_date ( const char * fieldname ) const
{
2011-06-30 08:11:19 +00:00
const TDate d ( get_str ( fieldname ) ) ;
1995-10-30 10:19:44 +00:00
return d ;
1994-08-12 10:52:49 +00:00
}
void TRectype : : put ( const char * fieldname , int val )
1996-09-26 15:26:47 +00:00
{
2011-06-30 08:11:19 +00:00
char tmp [ 16 ] ;
2012-04-24 10:23:05 +00:00
_itoa_s ( val , tmp , 10 ) ;
2002-02-28 11:35:23 +00:00
put_str ( fieldname , tmp ) ;
1994-08-12 10:52:49 +00:00
}
void TRectype : : put ( const char * fieldname , long val )
{
2011-06-30 08:11:19 +00:00
char tmp [ 16 ] ;
2012-04-24 10:23:05 +00:00
_ltoa_s ( val , tmp , 10 ) ;
2002-02-28 11:35:23 +00:00
put_str ( fieldname , tmp ) ;
1994-08-12 10:52:49 +00:00
}
void TRectype : : put ( const char * fieldname , word val )
{
2011-06-30 08:11:19 +00:00
put ( fieldname , ( int ) val ) ;
1994-08-12 10:52:49 +00:00
}
void TRectype : : put ( const char * fieldname , const real & val )
{
1996-09-02 14:20:24 +00:00
put_str ( fieldname , val . string ( ) ) ;
2001-04-30 15:04:10 +00:00
}
void TRectype : : put ( const char * fieldname , const TCurrency & val )
{
put_str ( fieldname , val . get_num ( ) . string ( ) ) ;
1994-08-12 10:52:49 +00:00
}
void TRectype : : put ( const char * fieldname , const TDate & val )
1995-10-30 10:19:44 +00:00
{
2005-07-07 17:07:13 +00:00
put ( fieldname , val . date2ansi ( ) ) ;
1994-08-12 10:52:49 +00:00
}
void TRectype : : put ( const char * fieldname , char val )
{
2003-07-23 07:47:28 +00:00
const char w [ 2 ] = { val , ' \0 ' } ;
1996-09-02 14:20:24 +00:00
put_str ( fieldname , w ) ;
1994-08-12 10:52:49 +00:00
}
void TRectype : : put ( const char * fieldname , bool val )
{
2011-06-30 08:11:19 +00:00
put ( fieldname , val ? ' X ' : ' ' ) ;
1994-08-12 10:52:49 +00:00
}
1996-09-02 14:20:24 +00:00
void TRectype : : put_str ( const char * fieldname , const char * val )
1996-05-30 13:53:00 +00:00
{
2008-12-10 16:52:43 +00:00
const RecDes & recd = rec_des ( ) ;
const int nf = findfld ( & recd , fieldname ) ;
1998-03-30 13:43:36 +00:00
if ( nf = = FIELDERR )
1998-11-03 10:27:35 +00:00
{
1998-03-30 13:43:36 +00:00
unknown_field ( fieldname ) ;
1998-11-03 10:27:35 +00:00
return ;
}
1998-11-10 10:07:12 +00:00
2008-12-10 16:52:43 +00:00
const RecFieldDes & fd = recd . Fd [ nf ] ;
1998-11-10 10:07:12 +00:00
const TFieldtypes ft = TFieldtypes ( fd . TypeF ) ;
1998-03-30 13:43:36 +00:00
1996-09-26 15:26:47 +00:00
if ( val = = NULL )
val = " " ;
if ( ft = = _boolfld )
1996-12-13 08:07:49 +00:00
val = ( * val & & strchr ( " 1STXY " , toupper ( * val ) ) ! = NULL ) ? " T " : " F " ;
1994-08-12 10:52:49 +00:00
2003-07-23 07:47:28 +00:00
if ( * val = = ' \0 ' ) // VERIFICARE COL REPOSITORY
1999-04-06 15:34:39 +00:00
{
TRecfield f ( * this , fieldname ) ;
if ( * f . pos ( ) = = ' \0 ' ) return ;
}
1998-03-30 13:43:36 +00:00
if ( ft = = _memofld )
1995-11-22 13:46:11 +00:00
{
1998-03-30 13:43:36 +00:00
_memo_data - > add ( val , nf ) ;
2000-10-03 13:45:12 +00:00
_memo_data - > set_dirty ( nf ) ;
1996-09-26 15:26:47 +00:00
}
1994-08-22 11:10:49 +00:00
else
1995-07-03 07:49:30 +00:00
{
2012-05-23 14:36:59 +00:00
__putfieldbuff ( fd . Len , fd . Dec , ft , val , _rec + fd . RecOff ) ;
1995-07-03 07:49:30 +00:00
}
1998-11-10 10:07:12 +00:00
1994-08-22 11:10:49 +00:00
setempty ( FALSE ) ;
1994-08-12 10:52:49 +00:00
}
2005-05-16 23:44:23 +00:00
void TRectype : : add ( const char * fieldname , const real & val )
{
if ( ! val . is_zero ( ) )
{
real k = get_real ( fieldname ) ;
k + = val ;
put ( fieldname , k ) ;
}
}
1994-08-12 10:52:49 +00:00
void TRectype : : zero ( const char * fieldname )
{
1998-11-10 10:07:12 +00:00
if ( * _tab & & strcmp ( fieldname , " COD " ) = = 0 )
put ( " COD " , _tab ) ;
1996-09-26 15:26:47 +00:00
else
1995-06-15 10:30:27 +00:00
{
2008-12-10 16:52:43 +00:00
const RecDes & recd = rec_des ( ) ;
const int nf = findfld ( & recd , fieldname ) ;
1996-09-26 15:26:47 +00:00
if ( nf = = FIELDERR )
unknown_field ( fieldname ) ;
else
1995-06-15 10:30:27 +00:00
{
2008-12-10 16:52:43 +00:00
const int recoff = recd . Fd [ nf ] . RecOff ;
1996-09-26 15:26:47 +00:00
char * p = _rec + recoff ;
2008-12-10 16:52:43 +00:00
const byte len = recd . Fd [ nf ] . Len ;
const byte dec = recd . Fd [ nf ] . Dec ;
const TFieldtypes type = ( TFieldtypes ) recd . Fd [ nf ] . TypeF ;
2003-12-03 09:41:16 +00:00
switch ( type )
1996-09-26 15:26:47 +00:00
{
2003-12-03 09:41:16 +00:00
case _datefld :
2012-05-23 14:36:59 +00:00
__putfieldbuff ( len , dec , _datefld , " " , p ) ;
2003-12-03 09:41:16 +00:00
break ;
case _memofld :
2012-05-23 14:36:59 +00:00
__putfieldbuff ( len , dec , _memofld , " " , p ) ;
2003-12-03 09:41:16 +00:00
_memo_data - > add ( " " , nf ) ;
_memo_data - > set_dirty ( nf ) ;
break ;
default :
1996-09-26 15:26:47 +00:00
memset ( p , ' ' , len ) ;
if ( ( type = = _intfld ) | | ( type = = _longfld ) | | ( type = = _wordfld ) )
* ( p + len - 1 ) = ' 0 ' ;
else
if ( type = = _realfld )
{
if ( dec )
{
memset ( p + len - dec - 2 , ' 0 ' , dec + 2 ) ;
* ( p + len - dec - 1 ) = ' . ' ;
}
else
* ( p + len - 1 ) = ' 0 ' ;
}
2003-12-03 09:41:16 +00:00
break ;
1996-09-26 15:26:47 +00:00
}
1995-06-15 10:30:27 +00:00
}
1995-11-22 13:46:11 +00:00
}
1994-08-12 10:52:49 +00:00
}
void TRectype : : zero ( char c )
{
1998-11-10 10:07:12 +00:00
memset ( _rec , c , len ( ) ) ;
1994-08-22 11:10:49 +00:00
recall ( ) ;
1994-12-28 15:01:04 +00:00
1998-11-10 10:07:12 +00:00
if ( * _tab )
put ( " COD " , _tab ) ;
1995-11-22 13:46:11 +00:00
1996-09-26 15:26:47 +00:00
if ( has_memo ( ) )
init_memo ( RECORD_NON_FISICO ) ;
1994-08-22 11:10:49 +00:00
setempty ( TRUE ) ;
1994-08-12 10:52:49 +00:00
}
// Certified 99%
TRectype & TRectype : : operator = ( const TRectype & rec )
1994-08-22 11:10:49 +00:00
1994-08-12 10:52:49 +00:00
{
1994-09-27 10:19:36 +00:00
CHECK ( num ( ) = = rec . num ( ) , " Can't assign records of different file " ) ;
1996-01-03 15:54:04 +00:00
memcpy ( _rec , rec . _rec , _length ) ; // Copy contents
1996-09-26 15:26:47 +00:00
if ( rec . _memo_data )
{
2000-10-03 13:45:12 +00:00
init_memo ( rec . _memo_data - > recno ( ) , rec . _memo_data - > file ( ) ) ;
1996-09-26 15:26:47 +00:00
* _memo_data = * rec . _memo_data ;
1996-01-03 15:54:04 +00:00
}
1999-04-06 15:34:39 +00:00
strcpy ( _tab , rec . _tab ) ;
1994-08-12 10:52:49 +00:00
setempty ( rec . empty ( ) ) ; // Copy emptiness status
return * this ;
}
// Certified 100%
TRectype & TRectype : : operator = ( const TBaseisamfile & f )
{
1994-08-22 11:10:49 +00:00
return * this = f . curr ( ) ;
1994-08-12 10:52:49 +00:00
}
1998-03-30 13:43:36 +00:00
// Certified 50%
1997-06-02 10:06:58 +00:00
int TRectype : : read ( TBaseisamfile & f , word op , word lockop )
1997-05-23 14:02:46 +00:00
{
1998-08-10 10:20:31 +00:00
int err = f . _read ( * this , op , lockop ) ;
return err ;
1997-05-23 14:02:46 +00:00
}
int TRectype : : readat ( TBaseisamfile & f , TRecnotype nrec , word lockop )
{
1997-06-02 10:06:58 +00:00
return f . _readat ( * this , nrec , lockop ) ;
1997-05-23 14:02:46 +00:00
}
1995-08-09 09:54:36 +00:00
// Certified 100%
1997-05-23 14:02:46 +00:00
int TRectype : : next ( TBaseisamfile & f , word lockop )
1995-08-09 09:54:36 +00:00
{
1997-12-02 12:05:16 +00:00
return read ( f , _isnext , lockop ) ;
}
// Certified 100%
int TRectype : : prev ( TBaseisamfile & f , word lockop )
{
return read ( f , _isprev , lockop ) ;
}
int TRectype : : first ( TBaseisamfile & f , word lockop )
{
return read ( f , _isfirst , lockop ) ;
}
int TRectype : : last ( TBaseisamfile & f , word lockop )
{
return read ( f , _islast , lockop ) ;
1995-08-09 09:54:36 +00:00
}
1997-05-23 14:02:46 +00:00
// Certified ??%
1997-06-02 10:06:58 +00:00
int TRectype : : write ( TBaseisamfile & f ) const
{ return f . _write ( * this ) ; }
1995-08-09 09:54:36 +00:00
1997-05-23 14:02:46 +00:00
// Certified ??%
1997-06-02 10:06:58 +00:00
int TRectype : : rewrite ( TBaseisamfile & f ) const
1995-08-09 09:54:36 +00:00
{
1997-06-02 10:06:58 +00:00
return f . _rewrite ( * this ) ;
1995-08-09 09:54:36 +00:00
}
2007-12-17 10:32:43 +00:00
int TRectype : : write_rewrite ( TBaseisamfile & f ) const
{
int err = write ( f ) ;
2012-07-02 13:05:43 +00:00
if ( err = = NOERR )
f . _read ( ( TRectype & ) * this , _iscurr , _unlock ) ; // Sblocca record 19-09-2012 (andrebbe nella _write)
else
2007-12-17 10:32:43 +00:00
err = rewrite ( f ) ;
return err ;
}
int TRectype : : rewrite_write ( TBaseisamfile & f ) const
{
int err = rewrite ( f ) ;
2012-07-02 13:05:43 +00:00
if ( err ! = NOERR )
{
2007-12-17 10:32:43 +00:00
err = write ( f ) ;
2012-07-02 13:05:43 +00:00
if ( err = = NOERR )
f . _read ( ( TRectype & ) * this , _iscurr , _unlock ) ; // Sblocca record 19-09-2012 (andrebbe nella _write)
}
return err ;
2007-12-17 10:32:43 +00:00
}
1997-05-23 14:02:46 +00:00
// Certified ??%
1997-06-02 10:06:58 +00:00
int TRectype : : remove ( TBaseisamfile & f ) const
1995-08-09 09:54:36 +00:00
{
1997-06-02 10:06:58 +00:00
return f . _remove ( * this ) ;
1995-08-09 09:54:36 +00:00
}
1994-08-12 10:52:49 +00:00
1995-09-19 15:45:42 +00:00
void TRectype : : renum_key ( const char * field , const char * val )
{
2012-11-30 14:40:18 +00:00
if ( strchr ( field , ' [ ' ) ! = NULL ) // Accept CODTAB[6,10]
{
const TFieldref fref ( field , 0 ) ;
TString80 str = val ;
if ( real : : is_natural ( val ) )
str . right_just ( fref . len ( * this ) , ' 0 ' ) ;
fref . write ( str , * this ) ;
}
else
put ( field , val ) ;
1995-09-19 15:45:42 +00:00
}
1994-08-12 10:52:49 +00:00
// Certified 99%
TRectype & TRectype : : operator = ( const char * rec )
{
2003-09-11 07:26:47 +00:00
if ( rec & & * rec )
{
memcpy ( _rec , rec , _length ) ;
setempty ( FALSE ) ;
}
else
zero ( ) ;
1994-08-12 10:52:49 +00:00
return * this ;
}
const char * TRectype : : key ( int numkey ) const
{
2002-02-28 11:35:23 +00:00
TString & tmp = get_tmp_string ( 256 ) ;
__build_key ( rec_des ( ) , numkey , _rec , tmp . get_buffer ( ) , FALSE ) ;
return tmp ;
1994-08-12 10:52:49 +00:00
}
2000-05-05 15:25:49 +00:00
void TRectype : : fill_transaction ( TConfig & cfg , int row ) const
{
TString16 p ; p < < num ( ) ;
if ( row > 0 ) p < < ' , ' < < row ;
cfg . set_paragraph ( p ) ;
for ( int f = items ( ) - 1 ; f > = 0 ; f - - )
{
const char * name = fieldname ( f ) ;
const char * value = get ( name ) ;
cfg . set ( name , value ) ;
}
}
bool TRectype : : send_mail ( const char * action ) const
{
TWait_cursor hourglass ;
bool ok = : : can_dispatch_transaction ( * this ) ;
if ( ok )
{
TFilename ininame ; ininame . temp ( ) ;
if ( ok ) // Test qualunque per usare {}
{
TConfig ini ( ininame , " Transaction " ) ;
ini . set ( " Action " , action ) ;
ini . set ( " Mode " , " A " ) ;
fill_transaction ( ini ) ;
}
ok = : : dispatch_transaction ( * this , ininame ) ;
: : remove ( ininame ) ;
}
return ok ;
}
2002-05-31 10:35:40 +00:00
bool TRectype : : get_relapp ( TString & app ) const
{
if ( * _tab )
{
2003-07-23 07:47:28 +00:00
TString4 cod ( _tab ) ;
2008-08-29 10:35:54 +00:00
switch ( num ( ) )
{
case LF_TABCOM : cod . insert ( " % " ) ; break ;
case LF_TABGEN : cod . insert ( " ^ " ) ; break ;
case LF_TABMOD :
{
TModule_table mod ( _tab ) ;
return mod . get_relapp ( app ) ;
}
break ;
default : break ;
}
2002-05-31 10:35:40 +00:00
return : : get_tabapp ( cod , app ) ;
}
2008-08-29 10:35:54 +00:00
return : : get_relapp ( num ( ) , app ) ;
2002-05-31 10:35:40 +00:00
}
2003-11-03 15:39:51 +00:00
bool TRectype : : edit ( int logicnum , const char * alternate_key_fields , const char * hint ) const
2002-05-31 10:35:40 +00:00
{
2003-07-24 14:36:06 +00:00
bool ok = false ;
2002-05-31 10:35:40 +00:00
if ( logicnum < = 0 )
logicnum = num ( ) ;
TRectype r ( logicnum ) ;
if ( * _tab )
r . settab ( _tab ) ;
2003-11-03 15:39:51 +00:00
TString app = hint ;
2011-02-10 16:20:04 +00:00
if ( app . blank ( ) )
2003-11-03 15:39:51 +00:00
r . get_relapp ( app ) ;
2011-02-10 16:20:04 +00:00
if ( app . full ( ) )
2003-07-23 07:47:28 +00:00
{
2008-12-10 16:52:43 +00:00
const RecDes & recd = r . rec_des ( ) ; // Descrizione del record della testata
const KeyDes & kd = recd . Ky [ 0 ] ; // Elenco dei campi della chiave 1
2003-07-23 07:47:28 +00:00
TToken_string key_labels ;
for ( int i = 0 ; i < kd . NkFields ; i + + )
{
const int nf = kd . FieldSeq [ i ] % MaxFields ;
2008-12-10 16:52:43 +00:00
const RecFieldDes & rf = recd . Fd [ nf ] ;
2003-07-23 07:47:28 +00:00
key_labels . add ( rf . Name ) ;
}
2002-05-31 10:35:40 +00:00
2003-07-23 07:47:28 +00:00
TToken_string key_fields ( alternate_key_fields ) ;
if ( key_fields . empty_items ( ) )
key_fields = key_labels ;
2002-05-31 10:35:40 +00:00
2011-02-10 16:20:04 +00:00
TFilename ininame ; ininame . temp ( " lnk " , " ini " ) ;
2002-05-31 10:35:40 +00:00
{
2003-07-23 07:47:28 +00:00
TConfig ini ( ininame , " Transaction " ) ;
ini . set ( " Action " , " LINK " ) ;
2011-02-10 16:20:04 +00:00
TString8 p ; p < < logicnum ;
2003-07-23 07:47:28 +00:00
ini . set_paragraph ( p ) ;
FOR_EACH_TOKEN ( key_labels , tok )
{
const TString16 name ( tok ) ;
const TString & value = get ( key_fields . get ( ) ) ;
ini . set ( name , value ) ;
}
}
2002-05-31 10:35:40 +00:00
app < < " -i " < < ininame ;
TExternal_app a ( app ) ;
2003-07-24 14:36:06 +00:00
ok = a . run ( ) = = 0 ;
2003-11-03 15:39:51 +00:00
if ( ok )
{
2014-05-14 08:26:35 +00:00
xvt_sys_sleep ( 500 ) ;
const TString & result = ini_get_string ( ininame , " Transaction " , " Result " ) ;
2003-11-03 15:39:51 +00:00
ok = result = = " OK " ;
}
2008-05-15 14:59:21 +00:00
xvt_fsys_remove_file ( ininame ) ;
2003-10-21 11:10:01 +00:00
if ( ok )
rec_cache ( logicnum ) . notify_change ( ) ;
2002-05-31 10:35:40 +00:00
}
2003-07-24 14:36:06 +00:00
return ok ;
2002-05-31 10:35:40 +00:00
}
2008-08-22 09:04:05 +00:00
bool TRectype : : set_edit_info ( const char * ut , const char * dt , const char * or )
{
bool ok = false ;
if ( num ( ) > LF_TAB ) // Inutile tentare di gestire le tabelle
{
// Se esiste un campo alfanumerioco UT*
if ( ut & & * ut & & type ( ut ) = = _alfafld )
{
put ( ut , user ( ) ) ; // Scrivi utente corrente
ok = true ;
// Se esiste un campo data DT*
if ( dt & & * dt & & type ( dt ) = = _datefld )
{
const TDate oggi ( TODAY ) ;
put ( dt , oggi ) ; // Scrivi data odierna
// Se esisnte un campo long OR*
if ( or & & * or & & ( type ( or ) = = _longfld | | type ( or ) = = _longzerofld ) )
put ( or , daytime ( ) ) ; // Scrivi ora attuale HHMMSS
}
}
}
return ok ;
}
bool TRectype : : set_modify_info ( )
{
return set_edit_info ( " UTCREAZ " , " DTCREAZ " , " ORCREAZ " ) ;
}
bool TRectype : : set_creation_info ( )
{
return set_edit_info ( " UTULAGG " , " DTULAGG " , " ORULAGG " ) ;
}
1994-08-12 10:52:49 +00:00
///////////////////////////////////////////////////////////
// TRecfield (campo/sottocampo di un record)
///////////////////////////////////////////////////////////
2008-11-14 16:41:23 +00:00
TRecfield : : TRecfield ( TRectype & rec , const char * name , int from , int to )
1994-08-12 10:52:49 +00:00
{
2008-11-14 16:41:23 +00:00
_rec = & rec ;
const TFixed_string fname ( name ) ;
const int colon = fname . find ( ' : ' ) ;
if ( colon > 0 )
{
_name . strncpy ( name , colon ) ;
_sub_field = name + colon + 1 ;
_sub_field < < ' = ' ; // ???????????????
}
else
_name = name ;
2008-12-10 16:52:43 +00:00
const RecDes & rd = _rec - > rec_des ( ) ;
2004-09-03 13:47:38 +00:00
2008-12-10 16:52:43 +00:00
const int nf = findfld ( & rd , _name ) ;
2004-09-03 13:47:38 +00:00
1998-11-03 10:27:35 +00:00
if ( nf = = FIELDERR )
1994-08-22 11:10:49 +00:00
{
2008-11-14 11:13:08 +00:00
_sub_field = _name ;
2008-08-28 09:00:16 +00:00
_p = _rec - > string ( ) ;
1999-06-18 15:35:05 +00:00
_len = 0 ;
1994-08-22 11:10:49 +00:00
_dec = 0 ;
1998-11-03 10:27:35 +00:00
_type = _alfafld ;
1994-08-22 11:10:49 +00:00
}
else
{
1998-11-03 10:27:35 +00:00
if ( from < 0 )
{
NFCHECK ( " Invalid Start %d " , from ) ;
from = 0 ;
}
2008-12-10 16:52:43 +00:00
_p = _rec - > string ( ) + rd . Fd [ nf ] . RecOff ;
_dec = rd . Fd [ nf ] . Dec ;
_type = ( TFieldtypes ) rd . Fd [ nf ] . TypeF ;
2008-11-14 11:13:08 +00:00
if ( _sub_field . empty ( ) )
2004-09-03 13:47:38 +00:00
{
_p + = from ;
if ( to > = 0 )
{
2011-06-22 15:44:50 +00:00
CHECKS ( _type = = _memofld | | ( from < = to & & to < = rd . Fd [ nf ] . Len ) , " Invalid Range on field " , ( const char * ) _name ) ;
2004-09-03 13:47:38 +00:00
_len = to - from + 1 ;
}
else
2008-12-10 16:52:43 +00:00
_len = rd . Fd [ nf ] . Len - from ;
2004-09-03 13:47:38 +00:00
}
else
{
CHECK ( _type = = _memofld , " You can use Subfields only with Memo " ) ;
_from = from ;
_to = to ;
if ( _type = = _memofld )
_len = 0 ;
else
2008-12-10 16:52:43 +00:00
_len = rd . Fd [ nf ] . Len ;
2004-09-03 13:47:38 +00:00
}
1994-08-22 11:10:49 +00:00
}
1994-08-12 10:52:49 +00:00
2008-11-14 16:41:23 +00:00
CHECKS ( colon < 0 | | _type = = _memofld , " SubField on non memo field: " , name ) ;
1994-08-12 10:52:49 +00:00
}
2004-09-03 13:47:38 +00:00
void TRecfield : : put_subfield ( const char * s )
{
2008-11-14 11:13:08 +00:00
if ( _name = = _sub_field )
2008-08-27 09:33:08 +00:00
return ;
2004-09-03 13:47:38 +00:00
const TString & str = _rec - > get ( _name ) ;
2008-11-14 11:13:08 +00:00
int p = str . find ( _sub_field ) ;
2004-09-03 13:47:38 +00:00
if ( p = = 0 | | ( p > 0 & & str [ p - 1 ] < ' ' ) )
{
2008-11-14 11:13:08 +00:00
p + = _sub_field . len ( ) ;
2004-09-03 13:47:38 +00:00
int e = str . find ( ' \n ' , p ) ;
if ( _to > 0 & & p + _to < e )
e = p + _to ;
p + = _from ;
if ( p < e )
{
TString val ( s ) ;
if ( _to > 0 )
{
val . left ( e - p + 1 ) ;
val . rpad ( e - p + 1 ) ;
}
TString out = str . left ( p ) ;
out < < val < < str . mid ( e ) ; // ? e + 1
_rec - > put ( _name , out ) ;
}
}
}
1994-08-12 10:52:49 +00:00
int TRecfield : : operator = ( int i )
{
2007-02-16 13:48:27 +00:00
TString16 buff ; buff < < i ;
2008-11-14 11:13:08 +00:00
if ( _sub_field . empty ( ) )
2012-05-23 14:36:59 +00:00
__putfieldbuff ( _len , _dec , _type , buff , _p ) ;
2004-09-03 13:47:38 +00:00
else
put_subfield ( buff ) ;
1994-08-22 11:10:49 +00:00
_rec - > setempty ( FALSE ) ;
return i ;
1994-08-12 10:52:49 +00:00
}
long TRecfield : : operator = ( long l )
{
2007-02-16 13:48:27 +00:00
TString16 buff ; buff < < l ;
2008-11-14 11:13:08 +00:00
if ( _sub_field . empty ( ) )
2012-05-23 14:36:59 +00:00
__putfieldbuff ( _len , _dec , _type , buff , _p ) ;
2004-09-03 13:47:38 +00:00
else
put_subfield ( buff ) ;
2007-02-16 13:48:27 +00:00
_rec - > setempty ( false ) ;
1994-08-22 11:10:49 +00:00
return l ;
1994-08-12 10:52:49 +00:00
}
const real & TRecfield : : operator = ( const real & r )
{
2007-02-16 13:48:27 +00:00
const char * buff = r . string ( ) ;
2008-11-14 11:13:08 +00:00
if ( _sub_field . empty ( ) )
2012-05-23 14:36:59 +00:00
__putfieldbuff ( _len , _dec , _type , buff , _p ) ;
2004-09-03 13:47:38 +00:00
else
put_subfield ( buff ) ;
1994-08-22 11:10:49 +00:00
_rec - > setempty ( FALSE ) ;
return r ;
1994-08-12 10:52:49 +00:00
}
1995-04-20 14:35:14 +00:00
1994-08-12 10:52:49 +00:00
const TDate & TRecfield : : operator = ( const TDate & d )
2007-02-16 13:48:27 +00:00
{
const TString16 buff = d . stringa ( ) ;
2008-11-14 11:13:08 +00:00
if ( _sub_field . empty ( ) )
2012-05-23 14:36:59 +00:00
__putfieldbuff ( _len , _dec , _type , buff , _p ) ;
2004-09-03 13:47:38 +00:00
else
put_subfield ( buff ) ;
1994-08-22 11:10:49 +00:00
_rec - > setempty ( FALSE ) ;
return d ;
1994-08-12 10:52:49 +00:00
}
const char * TRecfield : : operator = ( const char * s )
{
2008-11-14 11:13:08 +00:00
if ( _sub_field . empty ( ) )
2004-09-03 13:47:38 +00:00
{
if ( _type = = _memofld )
_rec - > put ( _name , s ) ;
else
2012-05-23 14:36:59 +00:00
__putfieldbuff ( _len , _dec , _type , s , _p ) ;
2004-09-03 13:47:38 +00:00
}
else
put_subfield ( s ) ;
1994-08-22 11:10:49 +00:00
_rec - > setempty ( FALSE ) ;
return s ;
1994-08-12 10:52:49 +00:00
}
void TRecfield : : setptr ( TRecnotype r )
{
1994-08-22 11:10:49 +00:00
if ( _p = = NULL ) return ;
bool n = r < 0 ;
unsigned char * wp = ( unsigned char * ) _p ;
1994-08-12 10:52:49 +00:00
1994-08-22 11:10:49 +00:00
if ( n ) r = - r ;
while ( wp - ( unsigned char * ) _p < = 3 )
{
* wp = r & & 0x000000FF ;
r > > = 8 ;
wp + + ;
}
if ( n ) * wp + = 128 ;
1994-08-12 10:52:49 +00:00
}
2007-02-16 13:48:27 +00:00
void TRecfield : : get_subfield ( TString & s ) const
2004-09-03 13:47:38 +00:00
{
const TString & str = _rec - > get ( _name ) ;
2008-08-27 09:33:08 +00:00
2008-11-14 11:13:08 +00:00
if ( _name = = _sub_field )
2008-08-28 09:00:16 +00:00
s = str ;
2008-08-27 09:33:08 +00:00
else
{
2008-11-14 11:13:08 +00:00
int p = str . find ( _sub_field ) ;
2004-09-03 13:47:38 +00:00
2008-08-28 09:00:16 +00:00
if ( p = = 0 | | ( p > 0 & & str [ p - 1 ] < ' ' ) )
{
2008-11-14 11:13:08 +00:00
p + = _sub_field . len ( ) ;
2008-08-28 09:00:16 +00:00
int e = str . find ( ' \n ' , p ) ;
2009-08-10 07:52:25 +00:00
if ( e < 0 ) e = str . len ( ) ; // L'ultima variabile non termina con \n
2008-08-28 09:00:16 +00:00
if ( _to > 0 & & p + _to < e )
e = p + _to ;
p + = _from ;
if ( p < e )
s = str . sub ( p , e ) ;
else
s . cut ( 0 ) ;
}
else
2007-02-16 13:48:27 +00:00
s . cut ( 0 ) ;
2004-09-03 13:47:38 +00:00
}
}
1994-08-12 10:52:49 +00:00
TRecfield : : operator int ( ) const
{
2007-02-16 13:48:27 +00:00
TString16 tmp ;
2008-11-14 11:13:08 +00:00
if ( _sub_field . empty ( ) )
2004-09-03 13:47:38 +00:00
{
if ( _type = = _intfld | | _type = = _intzerofld | | _type = = _longfld | | _type = = _longzerofld )
2007-02-16 13:48:27 +00:00
tmp . strncpy ( _p , _len ) ;
2004-09-03 13:47:38 +00:00
else
2012-05-23 14:36:59 +00:00
__getfieldbuff ( _len , _type , _p , tmp ) ;
2004-09-03 13:47:38 +00:00
}
else
get_subfield ( tmp ) ;
2002-02-28 11:35:23 +00:00
return atoi ( tmp ) ;
1994-08-12 10:52:49 +00:00
}
TRecfield : : operator long ( ) const
{
2007-02-16 13:48:27 +00:00
TString16 tmp ;
2004-09-03 13:47:38 +00:00
2008-11-14 11:13:08 +00:00
if ( _sub_field . empty ( ) )
2004-09-03 13:47:38 +00:00
{
if ( _type = = _longfld | | _type = = _longzerofld | | _type = = _intfld | | _type = = _intzerofld )
2007-02-16 13:48:27 +00:00
tmp . strncpy ( _p , _len ) ;
2004-09-03 13:47:38 +00:00
else
2012-05-23 14:36:59 +00:00
__getfieldbuff ( _len , _type , _p , tmp ) ;
2004-09-03 13:47:38 +00:00
}
else
get_subfield ( tmp ) ;
1996-12-02 11:01:06 +00:00
2002-02-28 11:35:23 +00:00
return atol ( tmp ) ;
1994-08-12 10:52:49 +00:00
}
1995-05-09 13:33:34 +00:00
TRecfield : : operator const real ( ) const
1994-08-12 10:52:49 +00:00
{
2007-02-16 13:48:27 +00:00
TString80 tmp ;
2004-09-03 13:47:38 +00:00
2008-11-14 11:13:08 +00:00
if ( _sub_field . empty ( ) )
2004-09-03 13:47:38 +00:00
{
if ( _type = = _realfld )
2007-02-16 13:48:27 +00:00
tmp . strncpy ( _p , _len ) ;
2004-09-03 13:47:38 +00:00
else
2012-05-23 14:36:59 +00:00
__getfieldbuff ( _len , _type , _p , tmp ) ;
2004-09-03 13:47:38 +00:00
}
else
get_subfield ( tmp ) ;
2008-11-14 11:13:08 +00:00
return real ( tmp ) ;
1994-08-12 10:52:49 +00:00
}
1995-05-09 13:33:34 +00:00
1994-08-12 10:52:49 +00:00
TRecfield : : operator TDate ( ) const
1996-12-02 11:01:06 +00:00
{
2007-02-16 13:48:27 +00:00
TString16 tmp ;
2004-09-03 13:47:38 +00:00
2008-11-14 11:13:08 +00:00
if ( _sub_field . empty ( ) )
2004-09-03 13:47:38 +00:00
{
if ( _type = = _datefld )
{
2007-02-16 13:48:27 +00:00
tmp . strncpy ( _p , 8 ) ;
2004-09-03 13:47:38 +00:00
return TDate ( atol ( tmp ) ) ;
}
2012-05-23 14:36:59 +00:00
__getfieldbuff ( _len , _type , _p , tmp ) ;
2004-09-03 13:47:38 +00:00
}
else
get_subfield ( tmp ) ;
2002-02-28 11:35:23 +00:00
return TDate ( tmp ) ;
1994-08-12 10:52:49 +00:00
}
TRecfield : : operator const char * ( ) const
1996-05-08 11:09:13 +00:00
{
2008-11-17 17:02:15 +00:00
TString & tmp = get_tmp_string ( max ( _len , 50 ) ) ;
if ( _sub_field . empty ( ) )
{
if ( _type = = _memofld )
return _rec - > get ( _name ) ;
2012-05-23 14:36:59 +00:00
__getfieldbuff ( _len , _type , _p , tmp ) ;
2008-11-17 17:02:15 +00:00
}
2004-09-03 13:47:38 +00:00
else
2007-02-16 13:48:27 +00:00
get_subfield ( tmp ) ;
2004-09-03 13:47:38 +00:00
2008-11-17 17:02:15 +00:00
return tmp ;
1994-08-12 10:52:49 +00:00
}
TRecnotype TRecfield : : ptr ( ) const
{
1995-11-22 13:46:11 +00:00
if ( _p = = NULL ) return ( RECORD_NON_FISICO ) ;
1994-08-22 11:10:49 +00:00
unsigned char * wp = ( unsigned char * ) _p + 3 ;
TRecnotype r = * wp ;
bool n = r > 127 ;
1994-08-12 10:52:49 +00:00
1994-08-22 11:10:49 +00:00
if ( n ) r - = 128 ;
1999-01-19 09:15:17 +00:00
while ( wp - - > ( unsigned char * ) _p )
r = ( r < < 8 ) + * wp ;
1994-08-22 11:10:49 +00:00
return n ? - r : r ;
2008-03-20 17:11:59 +00:00
}