📄 mysqldataset.pas
字号:
// Author: Jacques Venter, jacques@scibit.com
// Copyright: 1999,2000,2001,2002,2003,2004,2005,2006,2007 SciBit - Scientific Bitware (Pty) Ltd
// Version: 2006.4.5.0
// Comments: The MySQLDatasetBase, descendants and utility classes
// History:
// 2006.4.5.0 (2007-03-20)
// Delphi 2007 Support
// 2006.4.4.2 (2006-07-06)
// Enlarge doSmallMemoToStr to 256K memos to provide for MySQL5's "show columns from..."
// 2006.4.4.1 (2006-06-10)
// Various fixes as reported by Surinder on our forum in regards to inserts with CheckChanged.
// 2006.4.3.5 (2006-05-03)
// Correctly handle Macro/Param.IsNull and Macro/Params of undefined types.
// 2006.4.3.4 (2006-03-12)
// Fix StringReplace rfReplaceAll flags for FPrimFields variables. Should only replace first part.
// 2006.4.3.3 (2006-01-19)
// Refix LocateRecord for loPartial values tp default Delphi behavior.
// 2006.4.3.2 (2005-12-30)
// Fix: Clear TempRec in RecInfoClear
// 2006.4.3.1 (2005-12-29)
// Fix: LocateRecord checking ansipos from first pos ">0"
// 2006.4.3.0 (2005-12-20)
// Delphi 2006 release
// 2005.4.2.5 (2005-10-21)
// Fix MasterSource columnames with formatidentifier
// 2005.4.2.4 (2005-10-18)
// Fix MySQL fault of supplying BLOB columns without marking them with the blob_flag
// 2005.4.2.3 (2005-10-09)
// Fix LocateRecord for loPartial values
// 2005.4.2.2 (2005-09-20)
// Add Delphi 2006 support
// 2005.4.2.1 (2005-9-5)
// Add doSingleSQL option to allow SQL script to be executed as a single SQL statement, instead of preparsing it and breaking it into separate statements. This will help with new MySQL 5 SQL like CREATE PROCEDURE etc
// 2005.4.1.4 (2005-6-15)
// Add FIELD_TYPE_BIT new MySQL 5.0.3 type as ftBoolean
// Add FIELD_TYPE_DEC (246) new MySQL 5 decimal type as ftFloat
// Remove SQL quoting for all integer type values
// Quoting and Escaping routines added and simplified. Now even allows linking blob columns in master-detail linking
// 2005.4.1.3 (2005-5-23)
// Add QueryInfo method to dataset
// 2005.4.1.3 (2005-4-1)
// Fix PSExecuteStatement SQL execution bug
// 2005.4.1.2 (2005-3-16)
// Carry over old macro values to the new ones in ParseSQL
// 2005.4.1.1 (2005-3-01)
// Fix & Check IProviderSupport interface methods
// 2005.4.0.3 (2005-2-12)
// Fix :-Param for sql containing assignments
// 2005.4.0.2 (2005-2-7)
// Improve uncached lookup fields
// 2005.4.0.1 (2004-12-24)
// Remove extra >DB<.TB.CL part from fieldname if query was not cross DB and driver returned original DB and TB names & truncate primarykeynames accordingly.
// 2004.3.2.11 (2004-12-19)
// Add semicolon as delimiter for macros/params.
// Added default for ExecSQL's SQL param. If no SQL is specified it will do a Execute which will either Open or do a ThreadedOpen.
// 2004.3.2.10 (2004-12-08)
// Fix Use TableName Origin for [$TABLENAME]. It can be an alias.
// 2004.3.2.9 (2004-12-02)
// Fix timestamp setting convertion for MySQL 4.1.0 which was not version checked!
// 2004.3.2.8 (2004-12-01)
// Fix no recording of origin/tablenames when it is a calculated field (especially bad for 4.1.7 with 4.1.7 clientlib)
// 2004.3.2.7 (2004-11-08)
// Fix fetch of calculated column values for float and currency values
// 2004.3.2.6 (2004-10-29)
// Fix timestamp fetching convertion for MySQL 4.1.0 from wrongly correcting for 4.10.0
// 2004.3.2.5 (2004-10-27)
// Add ParamByName method as stub for MacroByName
// 2004.3.2.4 (2004-10-24)
// Fix parser for selects with an immediate colon postfixed to the statement where a Filter is to be applied
// 2004.3.2.3 (2004-10-01)
// Add check for missing datasource in master link else if fieldlink assigned it will get added to where clause
// 2004.3.2.2 (2004-09-27)
// Make sure doRetrieveFieldValues is set when doSetToWord is set
// Add defaults for LocateRecord method parameters
// 2004.3.2.1 (2004-09-22)
// Added OnAfterAdd event to capture when records have actually been added vs the default AfterInsert event which fires after the client is still busy adding
// 2004.3.2.0 (2004-09-22)
// Released
// 2004.3.1.1 (2004-09-21)
// Fix Field Origin for persistent fields in InternalOpen
// 2004.3.0.7 (2004-08-24)
// Fix updating bug for simple queries when using doRecursiveUpdates, in short simple queries didn't update because complex queries could update.
// 2004.3.0.6 (2004-08-20)
// Add different default Options for Dataset/Query vs Table
// 2004.3.0.5 (2004-08-16)
// Improved master-detail performance, by checking master editing and disabling detail controls while refreshing for downstream detail datasets - submitted by Dave
// 2004.3.0.4 (2004-08-15)
// Force unsigned FIELD_TYPE_LONGLONG into TString of size 20, rather than a float (hope this is the last time we worry abt unsigned 64 bit integer, time Borland made a TField which can handle it)
// 2004.3.0.3 (2004-08-15)
// Add doRetrieveIndexDefs to be able to selectively disable this behaviour, default is true (easier for beginners to just use CreateTable or doAutoCreate etc)
// 2004.3.0.2 (2004-08-13)
// Fix original tablename bug when user uses aliases tables
// 2004.3.0.1 (2004-08-11)
// Use WordBool for ftBoolean instead of Boolean - Suggested from the forum by Andreas
// 2004.3.0.0 (2004-08-10)
// Time for a new release, no use being selfish and keeping all these nice to haves from the customers! :P
// 2004.2.0.17 (2004-08-02)
// Force FIELD_TYPE_LONGLONG into ftFloat if unsigned, Delphi has no TField large enough for a MySQL unsigned BIGINT
// Force FIELD_TYPE_LONG into ftLargeInt if unsigned, Delphi's TIntegerField not capable of handling unsigned INT
// Force FIELD_TYPE_INT24 into ftInteger
// 2004.2.0.16 (2004-06-30)
// Fix for the new TIMESTAMP=DATETIME format in version 4.1.0 MySQL
// 2004.2.0.15 (2004-06-29)
// Add rtUnidirectional method of fetching data, with this only the current record is ever valid and available. Only Next and Last methods maybe called
// 2004.2.0.14 (2004-06-25)
// Always call server's FreeConnection when closing
// 2004.2.0.13 (2004-06-22)
// Add OnCustomValue and OnDefaultValue events
// 2004.2.0.12 (2004-06-20)
// Add FormatIdentifier method to dataset for correctly formating an identifier in an SQL statement using Server's method and ultimately the driver's FormatIdentifier method
// 2004.2.0.11 (2004-06-19)
// Implement OnResolveMacro event so default behaviour on all macros can be completely customized
// 2004.2.0.10 (2004-06-10)
// Implement complete IProvider interface for Midas & ClientDataset apps
// 2004.2.0.9 (2004-05-28)
// Use first tablename from query for $TABLENAME if end-user has not specified a TableName property for dataset
// 2004.2.0.8 (2004-05-28)
// Exclude Blob/Memo/Float field columns when compiling macro $PRIMARYFIELDS&VALUES in the case where the end-user table has no primarykey defined and no FieldName property was specified.
// 2004.2.0.7 (2004-05-25)
// Add transactional support with the doTransactions option
// 2004.2.0.6 (2004-05-20)
// Change FIELD_TYPE_LONG to create a ftInteger field, ignoring signed/unsigned
// 2004.2.0.5 (2004-05-19)
// Remove autoset of DatabaseName when setting Server if DatabaseName='' and SharedConnection
// if SharedCon, then server already set it for connection
// 2004.2.0.4 (2004-05-18)
// Implement doAutoCreate,doDropIfExists,doCreateTemp,CreateTable and IndexDefs capturing at long last :)
// 2004.2.0.3 (2004-05-18)
// Void usage of [$FIELDS] macro for persistent fields of TMySQLTable, as it can not be set designtime,i.e. always use * for TMySQLTable
// 2004.2.0.2 (2004-05-18)
// Fix calcfields bug if Buffer=nil
// 2004.2.0.1 (2004-05-07)
// Add alternative Open for Execute method if not threaded
// 2004.2.0.0 (2004-04-05)
// Add new compiler directives
// Add backward compatibility support for loading old style properties
// 2004.1.4.0 (2004-04-03)
// Fix rtIncremental duplicate connection for fielddefs bug
// 2004.1.3.0 (2004-03-27)
// Fix rtIncremental no result bug
// 2004.1.2.0 (2004-03-21)
// Fix semicolon bug for cachedupdates
// 2004.1.1.0 (2004-02-15)
// Certify for Delphi 5,6,7 and Kylix 1,2,3
// 2003.1.1.0 (2003-12-15)
// Added Threaded updating support
// Remove AllFieldValues property, put it in Options as doRetrieveFieldValues with True default
// 2002.1.1.0 (2002-12-19)
// Certify for Delphi 5,6,7 and Kylix 1,2,3
// Added compiler directive for console applications
// 2002.1.0.2 (2002-5-21)
// $PRIMARYFIELDS&VALUES resolve to FFieldName if no primary keys like JOIN
// 2002.1.0.1 (2002-2-9)
// Add Tag integer for any custom use for each record
// 2002.1.0.0 (2002-1-9)
// Add Options property with RawData and 2K TMemoField options
// 2001.1.0.24 (2001-12-13)
// Fix FCurRec counter in InternalAddRecord and InternalDelete for case of first record
// 2001.1.0.0
// Certify for Delphi 5, Delphi 6 and Kylix 1
// Make Single Source
// Fix minor bug in HexStr
// Add feature to initialize Detail Dataset fieldvalues automatically to linked Master Dataset fieldvalues
// Add TMySQLTable, TMySQLQuery to make things simpler for beginners
// 2000.0.3.1
// Added ResultType property
// Fixed minor bugs
// 2000.0.2.1
// Added AllFieldValues property
// Added Filter and Filtered properties
// Added MasterSource and MasterFields properties
// Added updating for tables without keys
// Fixed minor bugs
// 2000.0.1.1
// First release
//
// Licensing
//
// Copyright (c) 1998-2004 SciBit - Scientific Bitware (Pty) Ltd
// ALL RIGHTS RESERVED
//
// The entire contents of this file is protected by South African and
// International Copyright Laws. Unauthorized reproduction,
// reverse-engineering, and distribution of all or any portion of
// the code contained in this file is strictly prohibited and may
// result in severe civil and criminal penalties and will be
// prosecuted to the maximum extent possible under the law.
//
// RESTRICTIONS
//
// THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES
// (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE
// SECRETS OF SCIBIT (Pty) Ltd. THE REGISTERED DEVELOPER IS
// LICENSED TO DISTRIBUTE THE SOURCECODE AND ALL
// ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY.
//
// THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED
// FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE
// COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE
// AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT
// AND PERMISSION FROM SciBit - Scientific Bitware (Pty) Ltd
//
// CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON
// ADDITIONAL RESTRICTIONS.
//
//*******************************************************************
unit MySQLDataset;
interface
{$I product.inc}
uses
DB, Classes, SysUtils,
{$IFDEF MSWINDOWS}
Windows, Controls,
{$IFDEF DELPHI6UP}
Variants,
{$ENDIF}
{$ENDIF}
{$IFDEF LINUX}
Libc,
{$IFNDEF CONSOLEAPP}
QControls,
{$ENDIF}
Variants,
{$ENDIF}
MySQLServer,MySQLParser;
const
DefaultMacroString = '[,]';
type
TMySQLDatasetBase = class;
TMySQLDataset = class;
TMySQLTable = class;
TMySQLQuery = class;
TMySQLEvent = procedure(Dataset: TMySQLDatasetBase; var SQL: string; var Continue: boolean) of object;
TMySQLMacroEvent = procedure(Dataset: TMySQLDatasetBase; AMacro: string; var AValue: string; var ADefault: boolean) of object;
TMySQLFieldValue = procedure(Dataset: TMySQLDatasetBase; AField: string; AIndex: int64; var AValue: string) of object;
TBlobList = array of string;
PRecInfo = ^TRecInfo;
TRecInfo = packed record
Data: TBufferList;
Blob: TBlobList;
Calc: PChar;
Tag: integer;
Bookmark: int64;
BookmarkFlag:TBookmarkFlag;
end;
TFieldInfo = class
public
FieldName,
FieldOriginal,
FieldTable,
FieldTableOriginal,
FieldDB,
FieldDefault,
FieldOrigin,
FieldFullName,
FieldValues: string;
FieldType: byte;
FieldLength,
FieldMaxLength,
FieldFlags,
FieldDec,
FieldOfs: longword;
FieldChanged,
FieldReal: boolean;
end;
TTableInfo = class
public
TableName,
TableOriginal,
TableOrigin,
TableDB,
PrimFields,
UniqFields,
MultFields,
AffectedRows,
LastInsertID: string;
end;
TMySQLStringTypes = (stNone,stNormal,stEnum,stSet);
TMySQLStringField = class(TStringField)
private
FStringType: TMySQLStringTypes;
FValues: TStrings;
protected
function GetStringType: TMySQLStringTypes;
function GetStringValues: TStrings;
procedure SetStringValues(Value : TStrings);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
class procedure CheckTypeSize(Value: Integer); override;
function StrInValue(const Value: string): boolean;
published
property StringType: TMySQLStringTypes read GetStringType write FStringType;
property StringValues: TStrings read GetStringValues write SetStringValues;
end;
TMySQLBlobStream = class(TStream)
private
FField: TBlobField;
FDataSet: TMySQLDatasetBase;
FBuffer: PChar;
FMode: TBlobStreamMode;
FOpened: Boolean;
FModified: Boolean;
FPosition: Longint;
FCached: Boolean;
function GetBlobSize: Longint;
function GetBlobFromRecord(Field: TField): TBlobData;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -