summaryrefslogtreecommitdiff
path: root/packages/dblib
diff options
context:
space:
mode:
authormichael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2>2014-06-16 08:36:30 +0000
committermichael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2>2014-06-16 08:36:30 +0000
commit2a57ebc6c475f52c797f3f94dc997d530152107c (patch)
treee2200c4a3b3342901c55d305db00cfece7a7ef04 /packages/dblib
parent7241d1ea1e198f2468c5becb7eedbb3316518304 (diff)
downloadfpc-2a57ebc6c475f52c797f3f94dc997d530152107c.tar.gz
* Patch from Laco to implement Date/time structures in tds (Bug ID 26235)
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@27979 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/dblib')
-rw-r--r--packages/dblib/src/dblib.pp58
1 files changed, 51 insertions, 7 deletions
diff --git a/packages/dblib/src/dblib.pp b/packages/dblib/src/dblib.pp
index 098a10bfe1..b518808815 100644
--- a/packages/dblib/src/dblib.pp
+++ b/packages/dblib/src/dblib.pp
@@ -143,15 +143,18 @@ const
SQLDATETIM4=$3a;
SQLDECIMAL=$6a;
SQLNUMERIC=$6c;
- //from tds.h:
+ // from proto.h:
SYBNTEXT=$63;
- SYBINT8=$7F;
- SYBUNIQUE=$24;
+ // MS only types:
+ SYBINT8 =$7F;
+ SYBUNIQUE =$24;
SYBVARIANT=$62;
- //XSYBVARCHAR=$A7;
- //XSYBNVARCHAR=$E7;
- //XSYBNCHAR = $EF;
- //XSYBBINARY= $AD;
+ SYBMSUDT =$F0;
+ SYBMSXML =$F1;
+ SYBMSDATE =$28;
+ SYBMSTIME =$29;
+ SYBMSDATETIME2=$2A;
+ SYBMSDATETIMEOFFSET=$2B;
MAXTABLENAME ={$IFDEF freetds}512+1{$ELSE}30{$ENDIF};
MAXCOLNAMELEN={$IFDEF freetds}512+1{$ELSE}30{$ENDIF};
@@ -201,6 +204,18 @@ type
end;
PDBDATETIME=^DBDATETIME;
+ DBDATETIMEALL=record
+ time: qword; // time, 7 digit precision (64-bit unsigned)
+ date: longint; // date, 0 = 1900-01-01 (32-bit int)
+ offset: smallint; // time offset (16-bit int)
+ info: word; // unsigned short time_prec:3;
+ // unsigned short _res:10;
+ // unsigned short has_time:1;
+ // unsigned short has_date:1;
+ // unsigned short has_offset:1;
+ end;
+ PDBDATETIMEALL=^DBDATETIMEALL;
+
// DBDATEREC structure used by dbdatecrack
DBDATEREC=packed record
case boolean of
@@ -238,6 +253,11 @@ type
end;
PDBDATEREC=^DBDATEREC;
+ DBMONEY=record
+ mnyhigh: DBINT;
+ mnylow: ULONG;
+ end;
+
DBNUMERIC=packed record
precision: BYTE;
scale: BYTE;
@@ -308,6 +328,7 @@ var
function dbprtype(token:INT):PChar; cdecl; external DBLIBDLL;
function dbdatlen(dbproc:PDBPROCESS; column:INT):DBINT; cdecl; external DBLIBDLL;
function dbdata(dbproc:PDBPROCESS; column:INT):PByte; cdecl; external DBLIBDLL;
+ function dbwillconvert(srctype, desttype: INT):{$IFDEF freetds}DBBOOL{$ELSE}BOOL{$ENDIF}; cdecl; external DBLIBDLL;
function dbconvert(dbproc:PDBPROCESS; srctype:INT; src:PByte; srclen:DBINT; desttype:INT; dest:PByte; destlen:DBINT):INT; cdecl; external DBLIBDLL;
function dbdatecrack(dbproc:PDBPROCESS; dateinfo:PDBDATEREC; datetime: PDBDATETIME):RETCODE; cdecl; external DBLIBDLL;
function dbcount(dbproc:PDBPROCESS):DBINT; cdecl; external DBLIBDLL;
@@ -356,6 +377,7 @@ var
dbprtype: function(token:INT):PChar; cdecl;
dbdatlen: function(dbproc:PDBPROCESS; column:INT):DBINT; cdecl;
dbdata: function(dbproc:PDBPROCESS; column:INT):PByte; cdecl;
+ dbwillconvert: function(srctype, desttype: INT):{$IFDEF freetds}DBBOOL{$ELSE}BOOL{$ENDIF}; cdecl;
dbconvert: function(dbproc:PDBPROCESS; srctype:INT; src:PByte; srclen:DBINT; desttype:INT; dest:PByte; destlen:DBINT):INT; cdecl;
dbdatecrack: function(dbproc:PDBPROCESS; dateinfo:PDBDATEREC; datetime: PDBDATETIME):RETCODE; cdecl;
dbcount: function(dbproc:PDBPROCESS):DBINT; cdecl;
@@ -397,6 +419,8 @@ procedure dbwinexit;
{$ENDIF}
function dbsetlcharset(login:PLOGINREC; charset:PChar):RETCODE;
function dbsetlsecure(login:PLOGINREC):RETCODE;
+function dbdatetimeallcrack(dta: PDBDATETIMEALL): TDateTime;
+function dbmoneytocurr(pdbmoney: PQWord): Currency;
function InitialiseDBLib(const LibraryName : ansistring): integer;
procedure ReleaseDBLib;
@@ -452,6 +476,7 @@ begin
pointer(dbprtype) := GetProcedureAddress(DBLibLibraryHandle,'dbprtype');
pointer(dbdatlen) := GetProcedureAddress(DBLibLibraryHandle,'dbdatlen');
pointer(dbdata) := GetProcedureAddress(DBLibLibraryHandle,'dbdata');
+ pointer(dbwillconvert) := GetProcedureAddress(DBLibLibraryHandle,'dbwillconvert');
pointer(dbconvert) := GetProcedureAddress(DBLibLibraryHandle,'dbconvert');
pointer(dbdatecrack) := GetProcedureAddress(DBLibLibraryHandle,'dbdatecrack');
pointer(dbcount) := GetProcedureAddress(DBLibLibraryHandle,'dbcount');
@@ -574,6 +599,25 @@ begin
end;
{$ENDIF}
+
+function dbdatetimeallcrack(dta: PDBDATETIMEALL): TDateTime;
+begin
+ if dta^.info and $4000 = 0 then
+ Result := 0
+ else
+ Result := dta^.date + 2;
+ Result := ComposeDateTime(Result, dta^.time/MSecsPerDay/10000 + dta^.offset/MinsPerDay);
+end;
+
+function dbmoneytocurr(pdbmoney: PQWord): Currency;
+begin
+{$IFDEF ENDIAN_LITTLE}
+ PQWord(@Result)^ := pdbmoney^ shr 32 or pdbmoney^ shl 32;
+{$ELSE}
+ move(pdbmoney^, Result, sizeof(Currency));
+{$ENDIF}
+end;
+
{
//ntwdblib uses low significant values first
//freetds uses variable length array (based on precision) see numeric.c: tds_numeric_bytes_per_prec