From 15c3cb35df7411f76387fe65fbbc172a790cbc84 Mon Sep 17 00:00:00 2001 From: marco Date: Fri, 13 Feb 2015 10:16:14 +0000 Subject: [PATCH] --- Merging r29430 into '.': U packages/fcl-db/src/sqldb/mssql/mssqlconn.pp --- Merging r29442 into '.': U packages/fcl-db/src/base/bufdataset.pas U packages/fcl-db/src/sqldb/sqldb.pp --- Merging r29443 into '.': G packages/fcl-db/src/sqldb/mssql/mssqlconn.pp G packages/fcl-db/src/sqldb/sqldb.pp G packages/fcl-db/src/base/bufdataset.pas U packages/fcl-db/src/base/db.pas U packages/fcl-db/tests/testsqldb.pas --- Merging r29448 into '.': U packages/fcl-db/src/sqldb/sqlite/sqlite3conn.pp U packages/fcl-db/src/sqldb/mysql/mysqlconn.inc --- Merging r29451 into '.': G packages/fcl-db/tests/testsqldb.pas --- Merging r29462 into '.': G packages/fcl-db/tests/testsqldb.pas --- Merging r29479 into '.': U packages/fcl-db/src/sqldb/postgres/pqconnection.pp --- Merging r29480 into '.': G packages/fcl-db/tests/testsqldb.pas --- Merging r29507 into '.': G packages/fcl-db/src/sqldb/postgres/pqconnection.pp --- Merging r29624 into '.': G packages/fcl-db/src/base/db.pas U packages/fcl-db/src/base/fields.inc --- Merging r29638 into '.': U packages/rtl-unicode/fpmake.pp U packages/rtl-unicode/src/inc/cpbuildu.pp A packages/rtl-unicode/src/inc/cp895.pas A rtl/ucmaps/cp895.txt --- Merging r29662 into '.': U packages/fcl-db/src/sqldb/mssql/readme.txt --- Merging r29679 into '.': U packages/fcl-db/src/base/dsparams.inc U packages/fcl-db/src/base/datasource.inc G packages/fcl-db/tests/testsqldb.pas # revisions: 29430,29442,29443,29448,29451,29462,29479,29480,29507,29624,29638,29662,29679 git-svn-id: branches/fixes_3_0@29682 - --- .gitattributes | 2 + packages/fcl-db/src/base/bufdataset.pas | 21 +- packages/fcl-db/src/base/datasource.inc | 18 +- packages/fcl-db/src/base/db.pas | 24 +- packages/fcl-db/src/base/dsparams.inc | 8 +- packages/fcl-db/src/base/fields.inc | 51 +- packages/fcl-db/src/sqldb/mssql/mssqlconn.pp | 20 +- packages/fcl-db/src/sqldb/mssql/readme.txt | 5 +- packages/fcl-db/src/sqldb/mysql/mysqlconn.inc | 2 +- .../fcl-db/src/sqldb/postgres/pqconnection.pp | 170 +++--- packages/fcl-db/src/sqldb/sqldb.pp | 37 +- .../fcl-db/src/sqldb/sqlite/sqlite3conn.pp | 2 +- packages/fcl-db/tests/testsqldb.pas | 198 ++++--- packages/rtl-unicode/fpmake.pp | 2 + packages/rtl-unicode/src/inc/cp895.pas | 543 ++++++++++++++++++ packages/rtl-unicode/src/inc/cpbuildu.pp | 2 +- rtl/ucmaps/cp895.txt | 275 +++++++++ 17 files changed, 1119 insertions(+), 261 deletions(-) create mode 100644 packages/rtl-unicode/src/inc/cp895.pas create mode 100644 rtl/ucmaps/cp895.txt diff --git a/.gitattributes b/.gitattributes index b74cf1f752..f68581784c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6787,6 +6787,7 @@ packages/rtl-unicode/src/collations/collation_sv_le.inc svneol=native#text/pasca packages/rtl-unicode/src/collations/collation_zh.pas svneol=native#text/pascal packages/rtl-unicode/src/collations/collation_zh_be.inc svneol=native#text/pascal packages/rtl-unicode/src/collations/collation_zh_le.inc svneol=native#text/pascal +packages/rtl-unicode/src/inc/cp895.pas svneol=native#text/plain packages/rtl-unicode/src/inc/cp932.pas svneol=native#text/pascal packages/rtl-unicode/src/inc/cp936.pas svneol=native#text/pascal packages/rtl-unicode/src/inc/cp949.pas svneol=native#text/pascal @@ -9207,6 +9208,7 @@ rtl/ucmaps/cp1258.txt svneol=native#text/plain rtl/ucmaps/cp852.txt svneol=native#text/plain rtl/ucmaps/cp856.txt svneol=native#text/plain rtl/ucmaps/cp874.txt svneol=native#text/plain +rtl/ucmaps/cp895.txt svneol=native#text/plain rtl/ucmaps/cp932.txt svneol=native#text/plain rtl/ucmaps/cp936.txt svneol=native#text/plain rtl/ucmaps/cp949.txt svneol=native#text/plain diff --git a/packages/fcl-db/src/base/bufdataset.pas b/packages/fcl-db/src/base/bufdataset.pas index 5b4bdd3062..f2a1c5b53c 100644 --- a/packages/fcl-db/src/base/bufdataset.pas +++ b/packages/fcl-db/src/base/bufdataset.pas @@ -546,7 +546,7 @@ type procedure SetFilterText(const Value: String); override; {virtual;} procedure SetFiltered(Value: Boolean); override; {virtual;} procedure InternalRefresh; override; - procedure DataEvent(Event: TDataEvent; Info: Ptrint); override; + procedure DataEvent(Event: TDataEvent; Info: PtrInt); override; // virtual or methods, which can be used by descendants function GetNewBlobBuffer : PBlobBuffer; function GetNewWriteBlobBuffer : PBlobBuffer; @@ -2104,9 +2104,10 @@ end; function TCustomBufDataset.GetCurrentBuffer: TRecordBuffer; begin case State of - dsFilter: Result := FFilterBuffer; - dsCalcFields: Result := CalcBuffer; - else Result := ActiveBuffer; + dsFilter: Result := FFilterBuffer; + dsCalcFields: Result := CalcBuffer; + dsRefreshFields: Result := FCurrentIndex.CurrentBuffer + else Result := ActiveBuffer; end; end; @@ -2144,7 +2145,7 @@ begin begin if GetFieldIsNull(pbyte(CurrBuff),Field.FieldNo-1) then Exit; - if assigned(buffer) then + if assigned(Buffer) then begin inc(CurrBuff,FFieldBufPositions[Field.FieldNo-1]); Move(CurrBuff^, Buffer^, GetFieldSize(FieldDefs[Field.FieldNo-1])); @@ -2155,7 +2156,7 @@ begin begin Inc(CurrBuff, GetRecordSize + Field.Offset); Result := Boolean(CurrBuff^); - if result and assigned(Buffer) then + if Result and assigned(Buffer) then begin inc(CurrBuff); Move(CurrBuff^, Buffer^, Field.DataSize); @@ -2180,7 +2181,7 @@ begin CurrBuff := GetCurrentBuffer; If Field.FieldNo > 0 then // If =-1, then calculated/lookup field or =0 unbound field begin - if Field.ReadOnly and not (State in [dsSetKey, dsFilter]) then + if Field.ReadOnly and not (State in [dsSetKey, dsFilter, dsRefreshFields]) then DatabaseErrorFmt(SReadOnlyField, [Field.DisplayName]); if State in [dsEdit, dsInsert, dsNewValue] then Field.Validate(Buffer); @@ -2204,7 +2205,7 @@ begin Move(Buffer^, CurrBuff^, Field.DataSize); end; if not (State in [dsCalcFields, dsFilter, dsNewValue]) then - DataEvent(deFieldChange, Ptrint(Field)); + DataEvent(deFieldChange, PtrInt(Field)); end; procedure TCustomBufDataset.InternalDelete; @@ -2374,7 +2375,7 @@ begin if not ((FUpdateBuffer[r].UpdateKind=ukDelete) and not (assigned(FUpdateBuffer[r].OldValuesBuffer))) then begin FCurrentIndex.GotoBookmark(@FUpdateBuffer[r].BookmarkData); - // Synchronise the Currentbuffer to the ActiveBuffer + // Synchronise the CurrentBuffer to the ActiveBuffer CurrentRecordToBuffer(ActiveBuffer); Response := rrApply; try @@ -3247,7 +3248,7 @@ begin // Do nothing end; -procedure TCustomBufDataset.DataEvent(Event: TDataEvent; Info: Ptrint); +procedure TCustomBufDataset.DataEvent(Event: TDataEvent; Info: PtrInt); begin if Event = deUpdateState then // Save DataSet.State set by DataSet.SetState (filter out State set by DataSet.SetTempState) diff --git a/packages/fcl-db/src/base/datasource.inc b/packages/fcl-db/src/base/datasource.inc index 6dee4bb6e5..4dabb5182a 100644 --- a/packages/fcl-db/src/base/datasource.inc +++ b/packages/fcl-db/src/base/datasource.inc @@ -360,12 +360,12 @@ Procedure TMasterDataLink.ActiveChanged; begin FFields.Clear; if Active then - try - DataSet.GetFieldList(FFields, FFieldNames); - except - FFields.Clear; - raise; - end; + try + DataSet.GetFieldList(FFields, FFieldNames); + except + FFields.Clear; + raise; + end; if FDetailDataSet.Active and not (csDestroying in FDetailDataSet.ComponentState) then if Active and (FFields.Count > 0) then DoMasterChange @@ -502,8 +502,8 @@ Procedure TMasterParamsDataLink.DoMasterDisable; begin Inherited; - If Assigned(DetailDataset) and DetailDataset.Active then - DetailDataset.Close; + // If master dataset is closing, leave detail dataset intact (Delphi compatible behavior) + // If master dataset is reopened, relationship will be reestablished end; Procedure TMasterParamsDataLink.DoMasterChange; @@ -667,7 +667,7 @@ begin else FState:=dsInactive; // Don't do events if nothing changed. - If FState=FlastState then + If FState=FLastState then exit; end else diff --git a/packages/fcl-db/src/base/db.pas b/packages/fcl-db/src/base/db.pas index 8369fc2c7b..a04ce2a3db 100644 --- a/packages/fcl-db/src/base/db.pas +++ b/packages/fcl-db/src/base/db.pas @@ -22,7 +22,7 @@ unit db; interface -uses Classes,Sysutils,Variants,FmtBCD,MaskUtils; +uses Classes,SysUtils,Variants,FmtBCD,MaskUtils; const @@ -48,7 +48,7 @@ type TDataSetState = (dsInactive, dsBrowse, dsEdit, dsInsert, dsSetKey, dsCalcFields, dsFilter, dsNewValue, dsOldValue, dsCurValue, dsBlockRead, - dsInternalCalc, dsOpening); + dsInternalCalc, dsOpening, dsRefreshFields); TDataEvent = (deFieldChange, deRecordChange, deDataSetChange, deDataSetScroll, deLayoutChange, deUpdateRecord, deUpdateState, @@ -328,7 +328,7 @@ type function GetAsBoolean: Boolean; virtual; function GetAsBytes: TBytes; virtual; function GetAsCurrency: Currency; virtual; - function GetAsLargeInt: LargeInt; virtual; + function GetAsLargeInt: Largeint; virtual; function GetAsDateTime: TDateTime; virtual; function GetAsFloat: Double; virtual; function GetAsLongint: Longint; virtual; @@ -359,7 +359,7 @@ type procedure SetAsFloat(AValue: Double); virtual; procedure SetAsLongint(AValue: Longint); virtual; procedure SetAsInteger(AValue: Longint); virtual; - procedure SetAsLargeint(AValue: Largeint); virtual; + procedure SetAsLargeInt(AValue: Largeint); virtual; procedure SetAsVariant(const AValue: variant); virtual; procedure SetAsString(const AValue: string); virtual; procedure SetAsWideString(const AValue: WideString); virtual; @@ -462,6 +462,7 @@ type function GetAsDateTime: TDateTime; override; function GetAsFloat: Double; override; function GetAsInteger: Longint; override; + function GetAsLargeInt: Largeint; override; function GetAsString: string; override; function GetAsVariant: variant; override; function GetDataSize: Integer; override; @@ -472,6 +473,7 @@ type procedure SetAsDateTime(AValue: TDateTime); override; procedure SetAsFloat(AValue: Double); override; procedure SetAsInteger(AValue: Longint); override; + procedure SetAsLargeInt(AValue: Largeint); override; procedure SetAsString(const AValue: string); override; procedure SetVarValue(const AValue: Variant); override; public @@ -552,8 +554,8 @@ type procedure SetAsInteger(AValue: Longint); override; procedure SetAsString(const AValue: string); override; procedure SetVarValue(const AValue: Variant); override; - function GetAsLargeint: Largeint; override; - procedure SetAsLargeint(AValue: Largeint); override; + function GetAsLargeInt: Largeint; override; + procedure SetAsLargeInt(AValue: Largeint); override; public constructor Create(AOwner: TComponent); override; Function CheckRange(AValue : Longint) : Boolean; @@ -577,7 +579,7 @@ type protected function GetAsFloat: Double; override; function GetAsInteger: Longint; override; - function GetAsLargeint: Largeint; override; + function GetAsLargeInt: Largeint; override; function GetAsString: string; override; function GetAsVariant: variant; override; function GetDataSize: Integer; override; @@ -585,13 +587,13 @@ type function GetValue(var AValue: Largeint): Boolean; procedure SetAsFloat(AValue: Double); override; procedure SetAsInteger(AValue: Longint); override; - procedure SetAsLargeint(AValue: Largeint); override; + procedure SetAsLargeInt(AValue: Largeint); override; procedure SetAsString(const AValue: string); override; procedure SetVarValue(const AValue: Variant); override; public constructor Create(AOwner: TComponent); override; - Function CheckRange(AValue : largeint) : Boolean; - property Value: Largeint read GetAsLargeint write SetAsLargeint; + Function CheckRange(AValue : Largeint) : Boolean; + property Value: Largeint read GetAsLargeInt write SetAsLargeInt; published property MaxValue: Largeint read FMaxValue write SetMaxValue default 0; property MinValue: Largeint read FMinValue write SetMinValue default 0; @@ -2157,7 +2159,7 @@ const dsEditModes = [dsEdit, dsInsert, dsSetKey]; dsWriteModes = [dsEdit, dsInsert, dsSetKey, dsCalcFields, dsFilter, - dsNewValue, dsInternalCalc]; + dsNewValue, dsInternalCalc, dsRefreshFields]; // Correct list of all field types that are BLOB types. // Please use this instead of checking TBlobType which will give // incorrect results diff --git a/packages/fcl-db/src/base/dsparams.inc b/packages/fcl-db/src/base/dsparams.inc index 54654a1449..7cc5665e2f 100644 --- a/packages/fcl-db/src/base/dsparams.inc +++ b/packages/fcl-db/src/base/dsparams.inc @@ -1148,7 +1148,7 @@ begin end; -Procedure TParams.CopyParamValuesFromDataset(ADataset: TDataset; +Procedure TParams.CopyParamValuesFromDataset(ADataSet: TDataSet; CopyBound: Boolean); Var @@ -1157,13 +1157,15 @@ Var F : TField; begin - If (ADataSet<>Nil) then + If assigned(ADataSet) then For I:=0 to Count-1 do begin P:=Items[i]; if CopyBound or (not P.Bound) then begin - F:=ADataset.FieldByName(P.Name); + // Master dataset must be active and unbound parameters must have fields + // with same names in master dataset (Delphi compatible behavior) + F:=ADataSet.FieldByName(P.Name); P.AssignField(F); If Not CopyBound then P.Bound:=False; diff --git a/packages/fcl-db/src/base/fields.inc b/packages/fcl-db/src/base/fields.inc index 893ad21435..2af451279d 100644 --- a/packages/fcl-db/src/base/fields.inc +++ b/packages/fcl-db/src/base/fields.inc @@ -814,7 +814,7 @@ begin raise AccessError(SInteger); end; -procedure TField.SetAsLargeint(AValue: Largeint); +procedure TField.SetAsLargeInt(AValue: Largeint); begin Raise AccessError(SLargeInt); end; @@ -1068,6 +1068,12 @@ begin Result:=StrToInt(GetAsString); end; +function TStringField.GetAsLargeInt: Largeint; + +begin + Result:=StrToInt64(GetAsString); +end; + function TStringField.GetAsString: string; begin @@ -1169,7 +1175,13 @@ end; procedure TStringField.SetAsInteger(AValue: Longint); begin - SetAsString(intToStr(AValue)); + SetAsString(IntToStr(AValue)); +end; + +procedure TStringField.SetAsLargeInt(AValue: Largeint); + +begin + SetAsString(IntToStr(AValue)); end; procedure TStringField.SetAsString(const AValue: string); @@ -1385,7 +1397,7 @@ begin Result:=GetAsInteger; end; -function TLongintField.GetAsLargeint: Largeint; +function TLongintField.GetAsLargeInt: Largeint; begin Result:=GetAsInteger; end; @@ -1459,7 +1471,7 @@ begin end; end; -procedure TLongintField.SetAsLargeint(AValue: Largeint); +procedure TLongintField.SetAsLargeInt(AValue: Largeint); begin if (AValue>=FMinRange) and (AValue<=FMaxRange) then SetAsInteger(AValue) @@ -1552,10 +1564,10 @@ end; function TLargeintField.GetAsFloat: Double; begin - Result:=GetAsLargeint; + Result:=GetAsLargeInt; end; -function TLargeintField.GetAsLargeint: Largeint; +function TLargeintField.GetAsLargeInt: Largeint; begin If Not GetValue(Result) then @@ -1576,7 +1588,7 @@ end; function TLargeintField.GetAsInteger: Longint; begin - Result:=GetAsLargeint; + Result:=GetAsLargeInt; end; function TLargeintField.GetAsString: string; @@ -1598,7 +1610,7 @@ end; procedure TLargeintField.GetText(var AText: string; ADisplayText: Boolean); -var l : largeint; +var l : Largeint; fmt : string; begin @@ -1616,9 +1628,6 @@ end; function TLargeintField.GetValue(var AValue: Largeint): Boolean; -type - PLargeint = ^Largeint; - var P : PLargeint; begin @@ -1629,10 +1638,10 @@ end; procedure TLargeintField.SetAsFloat(AValue: Double); begin - SetAsLargeint(Round(AValue)); + SetAsLargeInt(Round(AValue)); end; -procedure TLargeintField.SetAsLargeint(AValue: Largeint); +procedure TLargeintField.SetAsLargeInt(AValue: Largeint); begin If CheckRange(AValue) then @@ -1644,13 +1653,13 @@ end; procedure TLargeintField.SetAsInteger(AValue: Longint); begin - SetAsLargeint(AValue); + SetAsLargeInt(AValue); end; procedure TLargeintField.SetAsString(const AValue: string); -var L : largeint; - code : longint; +var L : Largeint; + code : Longint; begin If length(AValue)=0 then @@ -1659,7 +1668,7 @@ begin begin Val(AValue,L,Code); If Code=0 then - SetAsLargeint(L) + SetAsLargeInt(L) else DatabaseErrorFmt(SNotAnInteger,[AValue]); end; @@ -1667,10 +1676,10 @@ end; procedure TLargeintField.SetVarValue(const AValue: Variant); begin - SetAsLargeint(AValue); + SetAsLargeInt(AValue); end; -Function TLargeintField.CheckRange(AValue : largeint) : Boolean; +Function TLargeintField.CheckRange(AValue : Largeint) : Boolean; begin if (FMinValue<>0) or (FMaxValue<>0) then @@ -1679,7 +1688,7 @@ begin Result := (AValue>=FMinRange) and (AValue<=FMaxRange); end; -Procedure TLargeintField.SetMaxValue (AValue : largeint); +Procedure TLargeintField.SetMaxValue (AValue : Largeint); begin If (AValue>=FMinRange) and (AValue<=FMaxRange) then @@ -1688,7 +1697,7 @@ begin RangeError(AValue,FMinRange,FMaxRange); end; -Procedure TLargeintField.SetMinValue (AValue : largeint); +Procedure TLargeintField.SetMinValue (AValue : Largeint); begin If (AValue>=FMinRange) and (AValue<=FMaxRange) then diff --git a/packages/fcl-db/src/sqldb/mssql/mssqlconn.pp b/packages/fcl-db/src/sqldb/mssql/mssqlconn.pp index 0dd94c3584..a63586a5b7 100644 --- a/packages/fcl-db/src/sqldb/mssql/mssqlconn.pp +++ b/packages/fcl-db/src/sqldb/mssql/mssqlconn.pp @@ -96,6 +96,7 @@ type // - Statement execution procedure Execute(cursor:TSQLCursor; ATransaction:TSQLTransaction; AParams:TParams); override; function RowsAffected(cursor: TSQLCursor): TRowsCount; override; + function RefreshLastInsertID(Query : TCustomSQLQuery; Field : TField): boolean; override; // - Result retrieving procedure AddFieldDefs(cursor:TSQLCursor; FieldDefs:TFieldDefs); override; function Fetch(cursor:TSQLCursor):boolean; override; @@ -315,7 +316,7 @@ end; constructor TMSSQLConnection.Create(AOwner: TComponent); begin inherited Create(AOwner); - FConnOptions := FConnOptions + [sqSupportEmptyDatabaseName, sqEscapeRepeat]; + FConnOptions := [sqSupportEmptyDatabaseName, sqEscapeRepeat, sqImplicitTransaction, sqLastInsertID]; //FieldNameQuoteChars:=DoubleQuotes; //default Ftds := DBTDS_UNKNOWN; end; @@ -540,7 +541,7 @@ end; function TMSSQLConnection.Rollback(trans: TSQLHandle): boolean; begin - Execute('ROLLBACK'); + Execute('IF @@TRANCOUNT>0 ROLLBACK'); Result:=true; end; @@ -659,6 +660,21 @@ begin Result := inherited RowsAffected(cursor); end; +function TMSSQLConnection.RefreshLastInsertID(Query: TCustomSQLQuery; Field: TField): boolean; +var Identity: int64; +begin + // global variable @@IDENTITY is NUMERIC(38,0) + Result:=False; + if dbcmd(FDBProc, 'SELECT @@IDENTITY') = FAIL then Exit; + if dbsqlexec(FDBProc) = FAIL then Exit; + if dbresults(FDBProc) = FAIL then Exit; + if dbnextrow(FDBProc) = FAIL then Exit; + if dbconvert(FDBProc, dbcoltype(FDBProc,1), dbdata(FDBProc,1), -1, SYBINT8, @Identity, sizeof(Identity)) = -1 then Exit; + // by default identity columns are ReadOnly + Field.AsLargeInt := Identity; + Result:=True; +end; + function TMSSQLConnection.TranslateFldType(SQLDataType: integer): TFieldType; begin case SQLDataType of diff --git a/packages/fcl-db/src/sqldb/mssql/readme.txt b/packages/fcl-db/src/sqldb/mssql/readme.txt index ecfcfd0a2e..ad45af9d93 100644 --- a/packages/fcl-db/src/sqldb/mssql/readme.txt +++ b/packages/fcl-db/src/sqldb/mssql/readme.txt @@ -27,9 +27,10 @@ Compiling FreeTDS DB-Lib with MS Visual C++ 2005/2008/2010: Note: To avoid dependency on msvc*.dll you can set in C/C++ / Code Generation / Runtime Library : "Multi-threaded (/MT)" in all projects To build dblib.dll under MS Visual C++ 2010 Express for Win64 you must: - - download and install Microsoft Windows Software Development Kit 7.1 + - download and install Microsoft Windows Software Development Kit 7.1 (install before Visual Studio 2010 SP1 !) + - if you upgrade to Visual Studio 2010 SP1 then you must install Microsoft Visual C++ 2010 Service Pack 1 Compiler Update for the Windows SDK 7.1 (http://support.microsoft.com/kb/2519277/en-us) - setup FreeTDS project to target 64-bit platform (http://msdn.microsoft.com/en-us/library/9yb4317s.aspx) - - Right-click on project "dblib_dll" and select "Properties". + - Right-click on project "dblib" and select "Properties". Linker / General / Additional Library Directories add path to "Microsoft SDKs\Windows\v7.1\Lib\x64" diff --git a/packages/fcl-db/src/sqldb/mysql/mysqlconn.inc b/packages/fcl-db/src/sqldb/mysql/mysqlconn.inc index cc9c26164e..49839fbd0a 100644 --- a/packages/fcl-db/src/sqldb/mysql/mysqlconn.inc +++ b/packages/fcl-db/src/sqldb/mysql/mysqlconn.inc @@ -1130,7 +1130,7 @@ constructor TConnectionName.Create(AOwner: TComponent); const SingleBackQoutes: TQuoteChars = ('`','`'); begin inherited Create(AOwner); - FConnOptions := FConnOptions + [sqEscapeRepeat, sqEscapeSlash, sqImplicitTransaction, sqLastInsertID]; + FConnOptions := [sqEscapeRepeat, sqEscapeSlash, sqImplicitTransaction, sqLastInsertID]; FieldNameQuoteChars:=SingleBackQoutes; FMySQL := Nil; end; diff --git a/packages/fcl-db/src/sqldb/postgres/pqconnection.pp b/packages/fcl-db/src/sqldb/postgres/pqconnection.pp index d31ebbe238..bcf43828a1 100644 --- a/packages/fcl-db/src/sqldb/postgres/pqconnection.pp +++ b/packages/fcl-db/src/sqldb/postgres/pqconnection.pp @@ -21,10 +21,10 @@ type TPQTrans = Class(TSQLHandle) protected - PGConn : PPGConn; - FList : TThreadList; - Procedure RegisterCursor(S : TPQCursor); - Procedure UnRegisterCursor(S : TPQCursor); + PGConn : PPGConn; + FList : TThreadList; + Procedure RegisterCursor(Cursor : TPQCursor); + Procedure UnRegisterCursor(Cursor : TPQCursor); Public Constructor Create; Destructor Destroy; override; @@ -60,6 +60,8 @@ type Destructor Destroy; override; end; + { EPQDatabaseError } + EPQDatabaseError = class(EDatabaseError) public SEVERITY:string; @@ -70,6 +72,8 @@ type STATEMENT_POSITION:string; end; + { TPQTranConnection } + TPQTranConnection = class protected FPGConn : PPGConn; @@ -125,7 +129,7 @@ type function RowsAffected(cursor: TSQLCursor): TRowsCount; override; public constructor Create(AOwner : TComponent); override; - destructor destroy; override; + destructor Destroy; override; function GetConnectionInfo(InfoType:TConnInfoType): string; override; procedure CreateDB; override; procedure DropDB; override; @@ -189,23 +193,12 @@ const Oid_Bool = 16; oid_numeric = 1700; Oid_uuid = 2950; + { TPQTrans } -procedure TPQTrans.RegisterCursor(S: TPQCursor); -begin - FList.Add(S); - S.tr:=Self; -end; - -procedure TPQTrans.UnRegisterCursor(S: TPQCursor); -begin - S.tr:=Nil; - FList.Remove(S); -end; - constructor TPQTrans.Create; begin - Flist:=TThreadList.Create; + FList:=TThreadList.Create; FList.Duplicates:=dupIgnore; end; @@ -216,19 +209,39 @@ Var I : integer; begin - L:=Flist.LockList; + L:=FList.LockList; try For I:=0 to L.Count-1 do TPQCursor(L[i]).tr:=Nil; finally - Flist.UnlockList; + FList.UnlockList; end; FreeAndNil(FList); inherited Destroy; end; +procedure TPQTrans.RegisterCursor(Cursor: TPQCursor); +begin + FList.Add(Cursor); + Cursor.tr:=Self; +end; + +procedure TPQTrans.UnRegisterCursor(Cursor: TPQCursor); +begin + Cursor.tr:=Nil; + FList.Remove(Cursor); +end; + + { TPQCursor } +destructor TPQCursor.Destroy; +begin + if Assigned(tr) then + tr.UnRegisterCursor(Self); + inherited Destroy; +end; + function TPQCursor.GetFieldBinding(F: TFieldDef): PFieldBinding; Var @@ -252,13 +265,8 @@ begin end; end; -destructor TPQCursor.Destroy; -begin - if Assigned(tr) then - Tr.UnRegisterCursor(Self); - inherited Destroy; -end; +{ TPQConnection } constructor TPQConnection.Create(AOwner : TComponent); @@ -270,7 +278,7 @@ begin FConnectionPool:=TThreadlist.Create; end; -destructor TPQConnection.destroy; +destructor TPQConnection.Destroy; begin // We must disconnect here. If it is done in inherited, then connection pool is gone. Connected:=False; @@ -432,6 +440,7 @@ var begin result := false; tr := trans as TPQTrans; + // unprepare statements associated with given transaction L:=tr.FList.LockList; try For I:=0 to L.Count-1 do @@ -441,8 +450,9 @@ begin end; L.Clear; finally - tr.flist.UnlockList; + tr.FList.UnlockList; end; + res := PQexec(tr.PGConn, 'ROLLBACK'); CheckResultError(res,tr.PGConn,SErrRollbackFailed); PQclear(res); @@ -465,56 +475,6 @@ begin result := true; end; -function TPQConnection.StartImplicitTransaction(trans : TSQLHandle; AParams : string) : boolean; -var - tr : TPQTrans; - i : Integer; - t : TPQTranConnection; - L : TList; -begin - result:=false; - tr := trans as TPQTrans; - - //find an unused connection in the pool - i:=0; - t:=Nil; - L:=FConnectionPool.LockList; - try - while (Inil) then - tr.PGConn:=T.FPGConn - else - begin - tr.PGConn := PQconnectdb(pchar(FConnectString)); - T.FPGConn:=tr.PGConn; - CheckConnectionStatus(tr.PGConn); - if CharSet <> '' then - PQsetClientEncoding(tr.PGConn, pchar(CharSet)); - end; - result := true; -end; - procedure TPQConnection.RollBackRetaining(trans : TSQLHandle); var res : PPGresult; @@ -547,6 +507,53 @@ begin PQclear(res); end; +function TPQConnection.StartImplicitTransaction(trans : TSQLHandle; AParams : string) : boolean; +var + i : Integer; + T : TPQTranConnection; + L : TList; +begin + //find an unused connection in the pool + i:=0; + T:=Nil; + L:=FConnectionPool.LockList; + try + while (i '' then + PQsetClientEncoding(T.FPGConn, pchar(CharSet)); + end; + + TPQTrans(trans).PGConn := T.FPGConn; + Result := true; +end; + function TPQConnection.StartDBTransaction(trans: TSQLHandle; AParams: string): boolean; @@ -866,7 +873,6 @@ var i : integer; P : TParam; PQ : TSQLDBParam; - r : PPGresult; begin with (cursor as TPQCursor) do @@ -947,7 +953,7 @@ begin res:=nil; if FPrepared then begin - if PQtransactionStatus(tr.PGConn) <> PQTRANS_INERROR then + if assigned(tr) and (PQtransactionStatus(tr.PGConn) <> PQTRANS_INERROR) then begin res := PQexec(tr.PGConn,pchar('deallocate '+StmtName)); CheckResultError(res,nil,SErrUnPrepareFailed); @@ -1029,7 +1035,7 @@ begin end else begin - // Registercursor sets tr + // RegisterCursor sets tr TPQTrans(aTransaction.Handle).RegisterCursor(Cursor as TPQCursor); if Assigned(AParams) and (AParams.Count > 0) then @@ -1119,7 +1125,7 @@ begin end else if ErrorOnUnknownType then - DatabaseError('unhandled field type :'+FB^.TypeName,Self); + DatabaseError('Unhandled field type :'+FB^.TypeName,Self); end; end; end; diff --git a/packages/fcl-db/src/sqldb/sqldb.pp b/packages/fcl-db/src/sqldb/sqldb.pp index ec8ca35a2d..0c39f9d5c0 100644 --- a/packages/fcl-db/src/sqldb/sqldb.pp +++ b/packages/fcl-db/src/sqldb/sqldb.pp @@ -472,7 +472,6 @@ type public constructor Create(AOwner : TComponent); override; destructor Destroy; override; - Procedure ApplyUpdates(MaxErrors: Integer); override; overload; procedure Prepare; virtual; procedure UnPrepare; virtual; procedure ExecSQL; virtual; @@ -482,6 +481,8 @@ type Property Prepared : boolean read IsPrepared; Property SQLConnection : TSQLConnection Read GetSQLConnection Write SetSQLConnection; Property SQLTransaction: TSQLTransaction Read GetSQLTransaction Write SetSQLTransaction; + // overriden TBufDataSet methods + Procedure ApplyUpdates(MaxErrors: Integer); override; overload; // overriden TDataSet methods Procedure Post; override; Procedure Delete; override; @@ -2086,10 +2087,10 @@ begin F.FQuery:=Self; FStatement:=F; - FUpdateSQL := TStringList.Create; - FUpdateSQL.OnChange := @OnChangeModifySQL; FInsertSQL := TStringList.Create; FInsertSQL.OnChange := @OnChangeModifySQL; + FUpdateSQL := TStringList.Create; + FUpdateSQL.OnChange := @OnChangeModifySQL; FDeleteSQL := TStringList.Create; FDeleteSQL.OnChange := @OnChangeModifySQL; FRefreshSQL := TStringList.Create; @@ -2116,24 +2117,13 @@ begin UnPrepare; FreeAndNil(FStatement); FreeAndNil(FInsertSQL); - FreeAndNil(FDeleteSQL); FreeAndNil(FUpdateSQL); + FreeAndNil(FDeleteSQL); FreeAndNil(FRefreshSQL); FServerIndexDefs.Free; inherited Destroy; end; -Procedure TCustomSQLQuery.ApplyUpdates(MaxErrors: Integer); -begin - inherited ApplyUpdates(MaxErrors); - If sqoAutoCommit in Options then - begin - // Retrieve rows affected for last update. - FStatement.RowsAffected; - SQLTransaction.Commit; - end; -end; - function TCustomSQLQuery.ParamByName(Const AParamName: String): TParam; begin @@ -2544,6 +2534,17 @@ begin end; end; +Procedure TCustomSQLQuery.ApplyUpdates(MaxErrors: Integer); +begin + inherited ApplyUpdates(MaxErrors); + If sqoAutoCommit in Options then + begin + // Retrieve rows affected for last update. + FStatement.RowsAffected; + SQLTransaction.Commit; + end; +end; + Procedure TCustomSQLQuery.Post; begin inherited Post; @@ -2643,7 +2644,9 @@ begin DoRefresh:=(UpdateKind in [ukModify,ukInsert]) and NeedRefreshRecord(UpdateKind); if assigned(LastIDField) or DoRefresh then begin - S:=SetTempState(dsNewValue); + // updates fields directly in record buffer of TBufDataSet + // TDataSet buffers are resynchronized at end of ApplyUpdates process + S:=SetTempState(dsRefreshFields); try RecordRefreshed:=False; if assigned(LastIDField) then @@ -2655,7 +2658,7 @@ begin end; if RecordRefreshed then // Active buffer is updated, move to record. - ActiveBufferToRecord; + //ActiveBufferToRecord; end; end; diff --git a/packages/fcl-db/src/sqldb/sqlite/sqlite3conn.pp b/packages/fcl-db/src/sqldb/sqlite/sqlite3conn.pp index 8ff1054673..f7feb99fa5 100644 --- a/packages/fcl-db/src/sqldb/sqlite/sqlite3conn.pp +++ b/packages/fcl-db/src/sqldb/sqlite/sqlite3conn.pp @@ -294,7 +294,7 @@ end; constructor TSQLite3Connection.Create(AOwner: TComponent); begin inherited Create(AOwner); - FConnOptions := FConnOptions + [sqEscapeRepeat,sqEscapeSlash,sqLastInsertID]; + FConnOptions := [sqEscapeRepeat, sqEscapeSlash, sqImplicitTransaction, sqLastInsertID]; FieldNameQuoteChars:=DoubleQuotes; end; diff --git a/packages/fcl-db/tests/testsqldb.pas b/packages/fcl-db/tests/testsqldb.pas index e96a12ec61..e812014165 100644 --- a/packages/fcl-db/tests/testsqldb.pas +++ b/packages/fcl-db/tests/testsqldb.pas @@ -31,9 +31,8 @@ type private FMyQ: TSQLQuery; procedure DoAfterPost(DataSet: TDataSet); - Procedure Allow; Procedure DoApplyUpdates; - Procedure SetQueryOptions; + Procedure TrySetQueryOptions; Procedure TrySetPacketRecords; Protected Procedure Setup; override; @@ -87,14 +86,10 @@ implementation { TTestTSQLQuery } -procedure TTestTSQLQuery.DoAfterPost(DataSet: TDataSet); +Procedure TTestTSQLQuery.Setup; begin - AssertTrue('Have modifications in after post',FMyq.UpdateStatus=usModified) -end; - -Procedure TTestTSQLQuery.Allow; -begin - + inherited Setup; + SQLDBConnector.Connection.Options:=[]; end; procedure TTestTSQLQuery.TestMasterDetail; @@ -115,6 +110,9 @@ begin CheckEquals('TestName1', DetailQuery.Fields[0].AsString); MasterQuery.MoveBy(3); CheckEquals('TestName4', DetailQuery.Fields[0].AsString); + + MasterQuery.Close; + CheckTrue(DetailQuery.Active, 'Detail dataset should remain intact, when master dataset is closed'); finally MasterSource.Free; end; @@ -191,20 +189,21 @@ begin // Test also that an edit still works. with SQLDBConnector do begin - TryDropIfExist('testdiscon'); - ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))'); + ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10), constraint PK_FPDEV2 primary key(id))'); Transaction.Commit; for I:=1 to 20 do - ExecuteDirect(Format('INSERT INTO testdiscon values (%d,''%.6d'')',[i,i])); + ExecuteDirect(Format('INSERT INTO FPDEV2 values (%d,''%.6d'')',[i,i])); Transaction.Commit; + Q := SQLDBConnector.Query; - Q.SQL.Text:='select * from testdiscon'; + Q.SQL.Text:='select * from FPDEV2'; Q.Options:=[sqoKeepOpenOnCommit]; AssertEquals('PacketRecords forced to -1',-1,Q.PacketRecords); Q.Open; AssertEquals('Got all records',20,Q.RecordCount); Q.SQLTransaction.Commit; AssertTrue('Still open after transaction',Q.Active); + // Now check editing Q.Locate('id',20,[]); Q.Edit; @@ -214,7 +213,7 @@ begin Q.ApplyUpdates; AssertTrue('Have no more updates pending',Q.UpdateStatus=usUnmodified); Q.Close; - Q.SQL.Text:='select * from testdiscon where (id=20) and (a=''abc'')'; + Q.SQL.Text:='select * from FPDEV2 where (id=20) and (a=''abc'')'; Q.Open; AssertTrue('Have modified data record in database', not (Q.EOF AND Q.BOF)); end; @@ -225,12 +224,6 @@ begin FMyQ.PacketRecords:=10; end; -Procedure TTestTSQLQuery.Setup; -begin - inherited Setup; - SQLDBConnector.Connection.Options:=[]; -end; - Procedure TTestTSQLQuery.TestKeepOpenOnCommitPacketRecords; begin with SQLDBConnector do @@ -241,7 +234,7 @@ begin end; end; -Procedure TTestTSQLQuery.SetQueryOptions; +Procedure TTestTSQLQuery.TrySetQueryOptions; begin FMyQ.Options:=[sqoKeepOpenOnCommit]; end; @@ -251,19 +244,23 @@ begin // Check that we can only set QueryOptions when the query is inactive. with SQLDBConnector do begin - TryDropIfExist('testdiscon'); - ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))'); - Transaction.COmmit; - ExecuteDirect(Format('INSERT INTO testdiscon values (%d,''%.6d'')',[1,1])); - Transaction.COmmit; + ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10), constraint PK_FPDEV2 primary key(id))'); + Transaction.Commit; + ExecuteDirect(Format('INSERT INTO FPDEV2 values (%d,''%.6d'')',[1,1])); + Transaction.Commit; FMyQ := SQLDBConnector.Query; - FMyQ.SQL.Text:='select * from testdiscon'; + FMyQ.SQL.Text:='select * from FPDEV2'; FMyQ := SQLDBConnector.Query; - FMyQ.OPen; - AssertException('Cannot set packetrecords when sqoDisconnected is active',EDatabaseError,@SetQueryOptions); + FMyQ.Open; + AssertException('Cannot set Options when query is active',EDatabaseError,@TrySetQueryOptions); end; end; +procedure TTestTSQLQuery.DoAfterPost(DataSet: TDataSet); +begin + AssertTrue('Have modifications in after post',FMyq.UpdateStatus=usModified) +end; + Procedure TTestTSQLQuery.TestAutoApplyUpdatesPost; var Q: TSQLQuery; I: Integer; @@ -272,15 +269,14 @@ begin // Test also that POST afterpost event is backwards compatible. with SQLDBConnector do begin - TryDropIfExist('testdiscon'); - ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))'); + ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10), constraint PK_FPDEV2 primary key(id))'); Transaction.COmmit; for I:=1 to 2 do - ExecuteDirect(Format('INSERT INTO testdiscon values (%d,''%.6d'')',[i,i])); + ExecuteDirect(Format('INSERT INTO FPDEV2 values (%d,''%.6d'')',[i,i])); Transaction.COmmit; Q := SQLDBConnector.Query; FMyQ:=Q; // so th event handler can reach it. - Q.SQL.Text:='select * from testdiscon'; + Q.SQL.Text:='select * from FPDEV2'; Q.Options:=[sqoAutoApplyUpdates]; // We must test that in AfterPost, the modification is still there, for backwards compatibilty Q.AfterPost:=@DoAfterPost; @@ -293,7 +289,7 @@ begin Q.Post; AssertTrue('Have no more updates pending',Q.UpdateStatus=usUnmodified); Q.Close; - Q.SQL.Text:='select * from testdiscon where (id=2) and (a=''abc'')'; + Q.SQL.Text:='select * from FPDEV2 where (id=2) and (a=''abc'')'; Q.Open; AssertTrue('Have modified data record in database',not (Q.EOF AND Q.BOF)); end; @@ -308,15 +304,14 @@ begin // Test that if sqoAutoApplyUpdates is in QueryOptions, then Delete automatically does an ApplyUpdates with SQLDBConnector do begin - TryDropIfExist('testdiscon'); - ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))'); + ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10), constraint PK_FPDEV2 primary key(id))'); Transaction.COmmit; for I:=1 to 2 do - ExecuteDirect(Format('INSERT INTO testdiscon values (%d,''%.6d'')',[i,i])); + ExecuteDirect(Format('INSERT INTO FPDEV2 values (%d,''%.6d'')',[i,i])); Transaction.COmmit; Q := SQLDBConnector.Query; FMyQ:=Q; // so th event handler can reach it. - Q.SQL.Text:='select * from testdiscon'; + Q.SQL.Text:='select * from FPDEV2'; Q.Options:=[sqoAutoApplyUpdates]; // We must test that in AfterPost, the modification is still there, for backwards compatibilty Q.AfterPost:=@DoAfterPost; @@ -327,7 +322,7 @@ begin Q.Delete; AssertTrue('Have no more updates pending',Q.UpdateStatus=usUnmodified); Q.Close; - Q.SQL.Text:='select * from testdiscon where (id=2)'; + Q.SQL.Text:='select * from FPDEV2 where (id=2)'; Q.Open; AssertTrue('Data record is deleted in database', (Q.EOF AND Q.BOF)); end; @@ -346,22 +341,21 @@ begin // Test that if sqoAutoApplyUpdates is in QueryOptions, then Delete automatically does an ApplyUpdates with SQLDBConnector do begin - TryDropIfExist('testdiscon'); - ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))'); + ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10), constraint PK_FPDEV2 primary key(id))'); Transaction.COmmit; for I:=1 to 2 do - ExecuteDirect(Format('INSERT INTO testdiscon values (%d,''%.6d'')',[i,i])); + ExecuteDirect(Format('INSERT INTO FPDEV2 values (%d,''%.6d'')',[i,i])); Transaction.COmmit; SQLDBConnector.Connection.Options:=[scoApplyUpdatesChecksRowsAffected]; Q := SQLDBConnector.Query; - Q.SQL.Text:='select * from testdiscon'; - Q.DeleteSQL.Text:='delete from testdiscon'; + Q.SQL.Text:='select * from FPDEV2'; + Q.DeleteSQL.Text:='delete from FPDEV2'; Q.Open; AssertEquals('Got all records',2,Q.RecordCount); // Now check editing Q.Delete; FMyQ:=Q; - AssertException('Rowsaffected > 1 raises exception',EUpdateError,@DoApplyUpdates); + AssertException('RowsAffected > 1 raises exception',EUpdateError,@DoApplyUpdates); end; end; @@ -371,15 +365,14 @@ var begin with SQLDBConnector do begin - TryDropIfExist('testdiscon'); - ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))'); + ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10), constraint PK_FPDEV2 primary key(id))'); if Transaction.Active then Transaction.Commit; Query.Options:=[sqoAutoCommit]; for I:=1 to 2 do begin - Query.SQL.Text:=Format('INSERT INTO testdiscon values (%d,''%.6d'');',[i,i]); + Query.SQL.Text:=Format('INSERT INTO FPDEV2 values (%d,''%.6d'');',[i,i]); Query.Prepare; Query.ExecSQL; // We do not commit anything explicitly. @@ -390,7 +383,7 @@ begin Connection.Close; Connection.Open; - Query.SQL.Text:='SELECT COUNT(*) from testdiscon'; + Query.SQL.Text:='SELECT COUNT(*) from FPDEV2'; Query.Open; AssertEquals('Records haven''t been committed to database', 2, Query.Fields[0].AsInteger); end; @@ -403,23 +396,32 @@ var begin with SQLDBConnector do begin - TryDropIfExist('testdefval'); - ExecuteDirect('create table testdefval (id integer not null, a varchar(10) default ''abcde'', constraint pk_testdefval primary key(id))'); + ExecuteDirect('create table FPDEV2 (id integer not null primary key, a varchar(5) default ''abcde'', b integer default 1)'); if Transaction.Active then Transaction.Commit; end; Q:=SQLDBConnector.Query; - Q.SQL.Text:='select * from testdefval'; - Q.InsertSQL.Text:='insert into testdefval (id) values (:id)'; - Q.RefreshSQL.Text:='SELECT a FROM testdefval WHERE (id=:id)'; + Q.SQL.Text:='select * from FPDEV2'; + Q.InsertSQL.Text:='insert into FPDEV2 (id) values (:id)'; + Q.RefreshSQL.Text:='SELECT a,b FROM FPDEV2 WHERE (id=:id)'; Q.Open; - Q.Insert; + Q.Insert; // #1 record Q.FieldByName('id').AsInteger:=1; Q.Post; - AssertTrue('field value has not been fetched after post',Q.FieldByName('a').IsNull); + Q.Append; // #2 record + Q.FieldByName('id').AsInteger:=2; + Q.Post; + AssertTrue('Field value has not been fetched after Post', Q.FieldByName('a').IsNull); Q.ApplyUpdates(0); - AssertEquals('Still on correc field',1,Q.FieldByName('id').AsInteger); - AssertEquals('field value has been fetched from the database ','abcde',Q.FieldByName('a').AsString); + // #2 record: + AssertEquals('Still on correct field', 2, Q.FieldByName('id').AsInteger); + AssertEquals('Field value has been fetched from the database', 'abcde', Q.FieldByName('a').AsString); + AssertEquals('Field value has been fetched from the database', 1, Q.FieldByName('b').AsInteger); + Q.Prior; + // #1 record: + AssertEquals('Still on correct field', 1, Q.FieldByName('id').AsInteger); + AssertEquals('Field value has been fetched from the database', 'abcde', Q.FieldByName('a').AsString); + AssertEquals('Field value has been fetched from the database', 1, Q.FieldByName('b').AsInteger); end; Procedure TTestTSQLQuery.TestGeneratedRefreshSQL; @@ -430,14 +432,13 @@ var begin with SQLDBConnector do begin - TryDropIfExist('testdefval'); - ExecuteDirect('create table testdefval (id integer not null, a varchar(10) default ''abcde'', b varchar(5) default ''fgh'', constraint pk_testdefval primary key(id))'); + ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10) default ''abcde'', b varchar(5) default ''fgh'', constraint PK_FPDEV2 primary key(id))'); if Transaction.Active then Transaction.Commit; end; Q:=SQLDBConnector.Query; - Q.SQL.Text:='select * from testdefval'; - Q.InsertSQL.Text:='insert into testdefval (id) values (:id)'; + Q.SQL.Text:='select * from FPDEV2'; + Q.InsertSQL.Text:='insert into FPDEV2 (id) values (:id)'; Q.Open; With Q.FieldByName('id') do ProviderFlags:=ProviderFlags+[pfInKey]; @@ -448,11 +449,11 @@ begin Q.Insert; Q.FieldByName('id').AsInteger:=1; Q.Post; - AssertTrue('field value has not been fetched after post',Q.FieldByName('a').IsNull); + AssertTrue('Field value has not been fetched after post',Q.FieldByName('a').IsNull); Q.ApplyUpdates(0); - AssertEquals('Still on correc field',1,Q.FieldByName('id').AsInteger); - AssertEquals('field value has been fetched from the database ','abcde',Q.FieldByName('a').AsString); - AssertEquals('field value has been fetched from the database ','fgh',Q.FieldByName('b').AsString); + AssertEquals('Still on correct field',1,Q.FieldByName('id').AsInteger); + AssertEquals('Field value has been fetched from the database ','abcde',Q.FieldByName('a').AsString); + AssertEquals('Field value has been fetched from the database ','fgh',Q.FieldByName('b').AsString); end; Procedure TTestTSQLQuery.TestGeneratedRefreshSQL1Field; @@ -462,14 +463,13 @@ var begin with SQLDBConnector do begin - TryDropIfExist('testdefval'); - ExecuteDirect('create table testdefval (id integer not null, a varchar(10) default ''abcde'', b varchar(5) default ''fgh'', constraint pk_testdefval primary key(id))'); + ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10) default ''abcde'', b varchar(5) default ''fgh'', constraint PK_FPDEV2 primary key(id))'); if Transaction.Active then Transaction.Commit; end; Q:=SQLDBConnector.Query; - Q.SQL.Text:='select * from testdefval'; - Q.InsertSQL.Text:='insert into testdefval (id) values (:id)'; + Q.SQL.Text:='select * from FPDEV2'; + Q.InsertSQL.Text:='insert into FPDEV2 (id) values (:id)'; Q.Open; With Q.FieldByName('id') do ProviderFlags:=ProviderFlags+[pfInKey]; @@ -478,25 +478,24 @@ begin Q.Insert; Q.FieldByName('id').AsInteger:=1; Q.Post; - AssertTrue('field value has not been fetched after post',Q.FieldByName('a').IsNull); + AssertTrue('Field value has not been fetched after post',Q.FieldByName('a').IsNull); Q.ApplyUpdates(0); - AssertEquals('Still on correc field',1,Q.FieldByName('id').AsInteger); - AssertEquals('field value a has been fetched from the database ','abcde',Q.FieldByName('a').AsString); - AssertEquals('field value b has NOT been fetched from the database ','',Q.FieldByName('b').AsString); + AssertEquals('Still on correct field',1,Q.FieldByName('id').AsInteger); + AssertEquals('Field value a has been fetched from the database ','abcde',Q.FieldByName('a').AsString); + AssertEquals('Field value b has NOT been fetched from the database ','',Q.FieldByName('b').AsString); end; Procedure TTestTSQLQuery.TestGeneratedRefreshSQLNoKey; begin with SQLDBConnector do begin - TryDropIfExist('testdefval'); - ExecuteDirect('create table testdefval (id integer not null, a varchar(10) default ''abcde'', b varchar(5) default ''fgh'', constraint pk_testdefval primary key(id))'); + ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10) default ''abcde'', b varchar(5) default ''fgh'', constraint PK_FPDEV2 primary key(id))'); if Transaction.Active then Transaction.Commit; end; FMyQ:=SQLDBConnector.Query; - FMyQ.SQL.Text:='select * from testdefval'; - FMyQ.InsertSQL.Text:='insert into testdefval (id) values (:id)'; + FMyQ.SQL.Text:='select * from FPDEV2'; + FMyQ.InsertSQL.Text:='insert into FPDEV2 (id) values (:id)'; FMyQ.Open; With FMyQ.FieldByName('id') do ProviderFlags:=ProviderFlags-[pfInKey]; @@ -513,18 +512,17 @@ Procedure TTestTSQLQuery.TestRefreshSQLMultipleRecords; begin with SQLDBConnector do begin - TryDropIfExist('testdefval'); - ExecuteDirect('create table testdefval (id integer not null, a varchar(10) default ''abcde'', b varchar(5) default ''fgh'', constraint pk_testdefval primary key(id))'); + ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10) default ''abcde'', b varchar(5) default ''fgh'', constraint PK_FPDEV2 primary key(id))'); if Transaction.Active then Transaction.Commit; - ExecuteDirect('insert into testdefval (id) values (123)'); + ExecuteDirect('insert into FPDEV2 (id) values (123)'); if Transaction.Active then Transaction.Commit; end; FMyQ:=SQLDBConnector.Query; - FMyQ.SQL.Text:='select * from testdefval'; - FMyQ.InsertSQL.Text:='insert into testdefval (id) values (:id)'; - FMyQ.RefreshSQL.Text:='select * from testdefval'; + FMyQ.SQL.Text:='select * from FPDEV2'; + FMyQ.InsertSQL.Text:='insert into FPDEV2 (id) values (:id)'; + FMyQ.RefreshSQL.Text:='select * from FPDEV2'; FMyQ.Open; With FMyQ.FieldByName('id') do ProviderFlags:=ProviderFlags+[pfInKey]; @@ -540,18 +538,17 @@ Procedure TTestTSQLQuery.TestRefreshSQLNoRecords; begin with SQLDBConnector do begin - TryDropIfExist('testdefval'); - ExecuteDirect('create table testdefval (id integer not null, a varchar(10) default ''abcde'', b varchar(5) default ''fgh'', constraint pk_testdefval primary key(id))'); + ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10) default ''abcde'', b varchar(5) default ''fgh'', constraint PK_FPDEV2 primary key(id))'); if Transaction.Active then Transaction.Commit; - ExecuteDirect('insert into testdefval (id) values (123)'); + ExecuteDirect('insert into FPDEV2 (id) values (123)'); if Transaction.Active then Transaction.Commit; end; FMyQ:=SQLDBConnector.Query; - FMyQ.SQL.Text:='select * from testdefval'; - FMyQ.InsertSQL.Text:='insert into testdefval (id) values (:id)'; - FMyQ.RefreshSQL.Text:='select * from testdefval where 1=2'; + FMyQ.SQL.Text:='select * from FPDEV2'; + FMyQ.InsertSQL.Text:='insert into FPDEV2 (id) values (:id)'; + FMyQ.RefreshSQL.Text:='select * from FPDEV2 where 1=2'; FMyQ.Open; With FMyQ.FieldByName('id') do ProviderFlags:=ProviderFlags+[pfInKey]; @@ -560,7 +557,7 @@ begin FMyQ.Insert; FMyQ.FieldByName('id').AsInteger:=1; FMyQ.Post; - AssertException('Multiple records returned by RefreshSQL gives an error',EUpdateError,@DoApplyUpdates); + AssertException('No records returned by RefreshSQL gives an error',EUpdateError,@DoApplyUpdates); end; Procedure TTestTSQLQuery.TestFetchAutoInc; @@ -574,12 +571,13 @@ begin case SQLServerType of ssMySQL: datatype := 'integer auto_increment'; + ssMSSQL, ssSybase: + datatype := 'integer identity'; ssSQLite: datatype := 'integer'; else Ignore(STestNotApplicable); end; - TryDropIfExist('FPDEV2'); ExecuteDirect('create table FPDEV2 (id '+datatype+' primary key, f varchar(5))'); CommitDDL; end; @@ -590,18 +588,18 @@ begin Open; Insert; FieldByName('f').AsString:='a'; - Post; + Post; // #1 record Append; FieldByName('f').AsString:='b'; - Post; + Post; // #2 record AssertTrue('ID field is not null after Post', FieldByName('id').IsNull); - First; + First; // #1 record ApplyUpdates(0); AssertTrue('ID field is still null after ApplyUpdates', Not FieldByName('id').IsNull); // Should be 1 after the table was created, but this is not guaranteed... So we just test positive values. id := FieldByName('id').AsLargeInt; AssertTrue('ID field has not positive value', id>0); - Next; + Next; // #2 record AssertTrue('Next ID value is not greater than previous', FieldByName('id').AsLargeInt>id); end; end; @@ -655,7 +653,6 @@ end; procedure TTestTSQLConnection.TestImplicitTransactionOK; - var Q : TSQLQuery; T : TSQLTransaction; @@ -663,8 +660,7 @@ var begin with SQLDBConnector do begin - TryDropIfExist('testdiscon'); - ExecuteDirect('create table testdiscon (id integer not null, a varchar(10), constraint pk_testdiscon primary key(id))'); + ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10), constraint PK_FPDEV2 primary key(id))'); if Transaction.Active then Transaction.Commit; end; @@ -672,7 +668,7 @@ begin Q:=SQLDBConnector.Query; for I:=1 to 2 do begin - Q.SQL.Text:=Format('INSERT INTO testdiscon values (%d,''%.6d'');',[i,i]); + Q.SQL.Text:=Format('INSERT INTO FPDEV2 values (%d,''%.6d'');',[i,i]); Q.Prepare; Q.ExecSQL; // We do not commit anything explicitly. @@ -685,7 +681,7 @@ begin Q.Transaction:=T; Q.Database:=SQLDBConnector.Connection; T.Database:=SQLDBConnector.Connection; - Q.SQL.text:='SELECT COUNT(*) from testdiscon'; + Q.SQL.text:='SELECT COUNT(*) from FPDEV2'; Q.Open; AssertEquals('Records have been committed to database',2,Q.Fields[0].AsInteger); finally diff --git a/packages/rtl-unicode/fpmake.pp b/packages/rtl-unicode/fpmake.pp index 48fc7b34df..043912a5c5 100644 --- a/packages/rtl-unicode/fpmake.pp +++ b/packages/rtl-unicode/fpmake.pp @@ -112,11 +112,13 @@ begin T.Install:=False; with T.Dependencies do begin + AddUnit('cp895',CPUnits); AddUnit('cp932',CPUnits); AddUnit('cp936',CPUnits); AddUnit('cp949',CPUnits); AddUnit('cp950',CPUnits); end; + T:=P.Targets.AddImplicitUnit('cp895.pas',CPUnits); T:=P.Targets.AddImplicitUnit('cp932.pas',CPUnits); T:=P.Targets.AddImplicitUnit('cp936.pas',CPUnits); T:=P.Targets.AddImplicitUnit('cp949.pas',CPUnits); diff --git a/packages/rtl-unicode/src/inc/cp895.pas b/packages/rtl-unicode/src/inc/cp895.pas new file mode 100644 index 0000000000..90ef457877 --- /dev/null +++ b/packages/rtl-unicode/src/inc/cp895.pas @@ -0,0 +1,543 @@ +{ This is an automatically created file, so don't edit it } +unit cp895; + + interface + + implementation + + uses + charset; + + const + map : array[0..255] of tunicodecharmapping = ( + (unicode : 0; flag : umf_noinfo; reserved: 0), + (unicode : 1; flag : umf_noinfo; reserved: 0), + (unicode : 2; flag : umf_noinfo; reserved: 0), + (unicode : 3; flag : umf_noinfo; reserved: 0), + (unicode : 4; flag : umf_noinfo; reserved: 0), + (unicode : 5; flag : umf_noinfo; reserved: 0), + (unicode : 6; flag : umf_noinfo; reserved: 0), + (unicode : 7; flag : umf_noinfo; reserved: 0), + (unicode : 8; flag : umf_noinfo; reserved: 0), + (unicode : 9; flag : umf_noinfo; reserved: 0), + (unicode : 10; flag : umf_noinfo; reserved: 0), + (unicode : 11; flag : umf_noinfo; reserved: 0), + (unicode : 12; flag : umf_noinfo; reserved: 0), + (unicode : 13; flag : umf_noinfo; reserved: 0), + (unicode : 14; flag : umf_noinfo; reserved: 0), + (unicode : 15; flag : umf_noinfo; reserved: 0), + (unicode : 16; flag : umf_noinfo; reserved: 0), + (unicode : 17; flag : umf_noinfo; reserved: 0), + (unicode : 18; flag : umf_noinfo; reserved: 0), + (unicode : 19; flag : umf_noinfo; reserved: 0), + (unicode : 20; flag : umf_noinfo; reserved: 0), + (unicode : 21; flag : umf_noinfo; reserved: 0), + (unicode : 22; flag : umf_noinfo; reserved: 0), + (unicode : 23; flag : umf_noinfo; reserved: 0), + (unicode : 24; flag : umf_noinfo; reserved: 0), + (unicode : 25; flag : umf_noinfo; reserved: 0), + (unicode : 26; flag : umf_noinfo; reserved: 0), + (unicode : 27; flag : umf_noinfo; reserved: 0), + (unicode : 28; flag : umf_noinfo; reserved: 0), + (unicode : 29; flag : umf_noinfo; reserved: 0), + (unicode : 30; flag : umf_noinfo; reserved: 0), + (unicode : 31; flag : umf_noinfo; reserved: 0), + (unicode : 32; flag : umf_noinfo; reserved: 0), + (unicode : 33; flag : umf_noinfo; reserved: 0), + (unicode : 34; flag : umf_noinfo; reserved: 0), + (unicode : 35; flag : umf_noinfo; reserved: 0), + (unicode : 36; flag : umf_noinfo; reserved: 0), + (unicode : 37; flag : umf_noinfo; reserved: 0), + (unicode : 38; flag : umf_noinfo; reserved: 0), + (unicode : 39; flag : umf_noinfo; reserved: 0), + (unicode : 40; flag : umf_noinfo; reserved: 0), + (unicode : 41; flag : umf_noinfo; reserved: 0), + (unicode : 42; flag : umf_noinfo; reserved: 0), + (unicode : 43; flag : umf_noinfo; reserved: 0), + (unicode : 44; flag : umf_noinfo; reserved: 0), + (unicode : 45; flag : umf_noinfo; reserved: 0), + (unicode : 46; flag : umf_noinfo; reserved: 0), + (unicode : 47; flag : umf_noinfo; reserved: 0), + (unicode : 48; flag : umf_noinfo; reserved: 0), + (unicode : 49; flag : umf_noinfo; reserved: 0), + (unicode : 50; flag : umf_noinfo; reserved: 0), + (unicode : 51; flag : umf_noinfo; reserved: 0), + (unicode : 52; flag : umf_noinfo; reserved: 0), + (unicode : 53; flag : umf_noinfo; reserved: 0), + (unicode : 54; flag : umf_noinfo; reserved: 0), + (unicode : 55; flag : umf_noinfo; reserved: 0), + (unicode : 56; flag : umf_noinfo; reserved: 0), + (unicode : 57; flag : umf_noinfo; reserved: 0), + (unicode : 58; flag : umf_noinfo; reserved: 0), + (unicode : 59; flag : umf_noinfo; reserved: 0), + (unicode : 60; flag : umf_noinfo; reserved: 0), + (unicode : 61; flag : umf_noinfo; reserved: 0), + (unicode : 62; flag : umf_noinfo; reserved: 0), + (unicode : 63; flag : umf_noinfo; reserved: 0), + (unicode : 64; flag : umf_noinfo; reserved: 0), + (unicode : 65; flag : umf_noinfo; reserved: 0), + (unicode : 66; flag : umf_noinfo; reserved: 0), + (unicode : 67; flag : umf_noinfo; reserved: 0), + (unicode : 68; flag : umf_noinfo; reserved: 0), + (unicode : 69; flag : umf_noinfo; reserved: 0), + (unicode : 70; flag : umf_noinfo; reserved: 0), + (unicode : 71; flag : umf_noinfo; reserved: 0), + (unicode : 72; flag : umf_noinfo; reserved: 0), + (unicode : 73; flag : umf_noinfo; reserved: 0), + (unicode : 74; flag : umf_noinfo; reserved: 0), + (unicode : 75; flag : umf_noinfo; reserved: 0), + (unicode : 76; flag : umf_noinfo; reserved: 0), + (unicode : 77; flag : umf_noinfo; reserved: 0), + (unicode : 78; flag : umf_noinfo; reserved: 0), + (unicode : 79; flag : umf_noinfo; reserved: 0), + (unicode : 80; flag : umf_noinfo; reserved: 0), + (unicode : 81; flag : umf_noinfo; reserved: 0), + (unicode : 82; flag : umf_noinfo; reserved: 0), + (unicode : 83; flag : umf_noinfo; reserved: 0), + (unicode : 84; flag : umf_noinfo; reserved: 0), + (unicode : 85; flag : umf_noinfo; reserved: 0), + (unicode : 86; flag : umf_noinfo; reserved: 0), + (unicode : 87; flag : umf_noinfo; reserved: 0), + (unicode : 88; flag : umf_noinfo; reserved: 0), + (unicode : 89; flag : umf_noinfo; reserved: 0), + (unicode : 90; flag : umf_noinfo; reserved: 0), + (unicode : 91; flag : umf_noinfo; reserved: 0), + (unicode : 92; flag : umf_noinfo; reserved: 0), + (unicode : 93; flag : umf_noinfo; reserved: 0), + (unicode : 94; flag : umf_noinfo; reserved: 0), + (unicode : 95; flag : umf_noinfo; reserved: 0), + (unicode : 96; flag : umf_noinfo; reserved: 0), + (unicode : 97; flag : umf_noinfo; reserved: 0), + (unicode : 98; flag : umf_noinfo; reserved: 0), + (unicode : 99; flag : umf_noinfo; reserved: 0), + (unicode : 100; flag : umf_noinfo; reserved: 0), + (unicode : 101; flag : umf_noinfo; reserved: 0), + (unicode : 102; flag : umf_noinfo; reserved: 0), + (unicode : 103; flag : umf_noinfo; reserved: 0), + (unicode : 104; flag : umf_noinfo; reserved: 0), + (unicode : 105; flag : umf_noinfo; reserved: 0), + (unicode : 106; flag : umf_noinfo; reserved: 0), + (unicode : 107; flag : umf_noinfo; reserved: 0), + (unicode : 108; flag : umf_noinfo; reserved: 0), + (unicode : 109; flag : umf_noinfo; reserved: 0), + (unicode : 110; flag : umf_noinfo; reserved: 0), + (unicode : 111; flag : umf_noinfo; reserved: 0), + (unicode : 112; flag : umf_noinfo; reserved: 0), + (unicode : 113; flag : umf_noinfo; reserved: 0), + (unicode : 114; flag : umf_noinfo; reserved: 0), + (unicode : 115; flag : umf_noinfo; reserved: 0), + (unicode : 116; flag : umf_noinfo; reserved: 0), + (unicode : 117; flag : umf_noinfo; reserved: 0), + (unicode : 118; flag : umf_noinfo; reserved: 0), + (unicode : 119; flag : umf_noinfo; reserved: 0), + (unicode : 120; flag : umf_noinfo; reserved: 0), + (unicode : 121; flag : umf_noinfo; reserved: 0), + (unicode : 122; flag : umf_noinfo; reserved: 0), + (unicode : 123; flag : umf_noinfo; reserved: 0), + (unicode : 124; flag : umf_noinfo; reserved: 0), + (unicode : 125; flag : umf_noinfo; reserved: 0), + (unicode : 126; flag : umf_noinfo; reserved: 0), + (unicode : 127; flag : umf_noinfo; reserved: 0), + (unicode : 268; flag : umf_noinfo; reserved: 0), + (unicode : 252; flag : umf_noinfo; reserved: 0), + (unicode : 233; flag : umf_noinfo; reserved: 0), + (unicode : 271; flag : umf_noinfo; reserved: 0), + (unicode : 228; flag : umf_noinfo; reserved: 0), + (unicode : 270; flag : umf_noinfo; reserved: 0), + (unicode : 356; flag : umf_noinfo; reserved: 0), + (unicode : 269; flag : umf_noinfo; reserved: 0), + (unicode : 283; flag : umf_noinfo; reserved: 0), + (unicode : 282; flag : umf_noinfo; reserved: 0), + (unicode : 313; flag : umf_noinfo; reserved: 0), + (unicode : 205; flag : umf_noinfo; reserved: 0), + (unicode : 318; flag : umf_noinfo; reserved: 0), + (unicode : 314; flag : umf_noinfo; reserved: 0), + (unicode : 196; flag : umf_noinfo; reserved: 0), + (unicode : 193; flag : umf_noinfo; reserved: 0), + (unicode : 201; flag : umf_noinfo; reserved: 0), + (unicode : 382; flag : umf_noinfo; reserved: 0), + (unicode : 381; flag : umf_noinfo; reserved: 0), + (unicode : 244; flag : umf_noinfo; reserved: 0), + (unicode : 246; flag : umf_noinfo; reserved: 0), + (unicode : 211; flag : umf_noinfo; reserved: 0), + (unicode : 367; flag : umf_noinfo; reserved: 0), + (unicode : 218; flag : umf_noinfo; reserved: 0), + (unicode : 253; flag : umf_noinfo; reserved: 0), + (unicode : 214; flag : umf_noinfo; reserved: 0), + (unicode : 220; flag : umf_noinfo; reserved: 0), + (unicode : 352; flag : umf_noinfo; reserved: 0), + (unicode : 317; flag : umf_noinfo; reserved: 0), + (unicode : 221; flag : umf_noinfo; reserved: 0), + (unicode : 344; flag : umf_noinfo; reserved: 0), + (unicode : 357; flag : umf_noinfo; reserved: 0), + (unicode : 225; flag : umf_noinfo; reserved: 0), + (unicode : 237; flag : umf_noinfo; reserved: 0), + (unicode : 243; flag : umf_noinfo; reserved: 0), + (unicode : 250; flag : umf_noinfo; reserved: 0), + (unicode : 328; flag : umf_noinfo; reserved: 0), + (unicode : 327; flag : umf_noinfo; reserved: 0), + (unicode : 366; flag : umf_noinfo; reserved: 0), + (unicode : 212; flag : umf_noinfo; reserved: 0), + (unicode : 353; flag : umf_noinfo; reserved: 0), + (unicode : 345; flag : umf_noinfo; reserved: 0), + (unicode : 341; flag : umf_noinfo; reserved: 0), + (unicode : 340; flag : umf_noinfo; reserved: 0), + (unicode : 188; flag : umf_noinfo; reserved: 0), + (unicode : 167; flag : umf_noinfo; reserved: 0), + (unicode : 171; flag : umf_noinfo; reserved: 0), + (unicode : 187; flag : umf_noinfo; reserved: 0), + (unicode : 9617; flag : umf_noinfo; reserved: 0), + (unicode : 9618; flag : umf_noinfo; reserved: 0), + (unicode : 9619; flag : umf_noinfo; reserved: 0), + (unicode : 9474; flag : umf_noinfo; reserved: 0), + (unicode : 9508; flag : umf_noinfo; reserved: 0), + (unicode : 9569; flag : umf_noinfo; reserved: 0), + (unicode : 9570; flag : umf_noinfo; reserved: 0), + (unicode : 9558; flag : umf_noinfo; reserved: 0), + (unicode : 9557; flag : umf_noinfo; reserved: 0), + (unicode : 9571; flag : umf_noinfo; reserved: 0), + (unicode : 9553; flag : umf_noinfo; reserved: 0), + (unicode : 9559; flag : umf_noinfo; reserved: 0), + (unicode : 9565; flag : umf_noinfo; reserved: 0), + (unicode : 9564; flag : umf_noinfo; reserved: 0), + (unicode : 9563; flag : umf_noinfo; reserved: 0), + (unicode : 9488; flag : umf_noinfo; reserved: 0), + (unicode : 9492; flag : umf_noinfo; reserved: 0), + (unicode : 9524; flag : umf_noinfo; reserved: 0), + (unicode : 9516; flag : umf_noinfo; reserved: 0), + (unicode : 9500; flag : umf_noinfo; reserved: 0), + (unicode : 9472; flag : umf_noinfo; reserved: 0), + (unicode : 9532; flag : umf_noinfo; reserved: 0), + (unicode : 9566; flag : umf_noinfo; reserved: 0), + (unicode : 9567; flag : umf_noinfo; reserved: 0), + (unicode : 9562; flag : umf_noinfo; reserved: 0), + (unicode : 9556; flag : umf_noinfo; reserved: 0), + (unicode : 9577; flag : umf_noinfo; reserved: 0), + (unicode : 9574; flag : umf_noinfo; reserved: 0), + (unicode : 9568; flag : umf_noinfo; reserved: 0), + (unicode : 9552; flag : umf_noinfo; reserved: 0), + (unicode : 9580; flag : umf_noinfo; reserved: 0), + (unicode : 9575; flag : umf_noinfo; reserved: 0), + (unicode : 9576; flag : umf_noinfo; reserved: 0), + (unicode : 9572; flag : umf_noinfo; reserved: 0), + (unicode : 9573; flag : umf_noinfo; reserved: 0), + (unicode : 9561; flag : umf_noinfo; reserved: 0), + (unicode : 9560; flag : umf_noinfo; reserved: 0), + (unicode : 9554; flag : umf_noinfo; reserved: 0), + (unicode : 9555; flag : umf_noinfo; reserved: 0), + (unicode : 9579; flag : umf_noinfo; reserved: 0), + (unicode : 9578; flag : umf_noinfo; reserved: 0), + (unicode : 9496; flag : umf_noinfo; reserved: 0), + (unicode : 9484; flag : umf_noinfo; reserved: 0), + (unicode : 9608; flag : umf_noinfo; reserved: 0), + (unicode : 9604; flag : umf_noinfo; reserved: 0), + (unicode : 9612; flag : umf_noinfo; reserved: 0), + (unicode : 9616; flag : umf_noinfo; reserved: 0), + (unicode : 9600; flag : umf_noinfo; reserved: 0), + (unicode : 945; flag : umf_noinfo; reserved: 0), + (unicode : 223; flag : umf_noinfo; reserved: 0), + (unicode : 915; flag : umf_noinfo; reserved: 0), + (unicode : 960; flag : umf_noinfo; reserved: 0), + (unicode : 931; flag : umf_noinfo; reserved: 0), + (unicode : 963; flag : umf_noinfo; reserved: 0), + (unicode : 181; flag : umf_noinfo; reserved: 0), + (unicode : 964; flag : umf_noinfo; reserved: 0), + (unicode : 934; flag : umf_noinfo; reserved: 0), + (unicode : 920; flag : umf_noinfo; reserved: 0), + (unicode : 937; flag : umf_noinfo; reserved: 0), + (unicode : 948; flag : umf_noinfo; reserved: 0), + (unicode : 8734; flag : umf_noinfo; reserved: 0), + (unicode : 966; flag : umf_noinfo; reserved: 0), + (unicode : 949; flag : umf_noinfo; reserved: 0), + (unicode : 8745; flag : umf_noinfo; reserved: 0), + (unicode : 8801; flag : umf_noinfo; reserved: 0), + (unicode : 177; flag : umf_noinfo; reserved: 0), + (unicode : 8805; flag : umf_noinfo; reserved: 0), + (unicode : 8804; flag : umf_noinfo; reserved: 0), + (unicode : 8992; flag : umf_noinfo; reserved: 0), + (unicode : 8993; flag : umf_noinfo; reserved: 0), + (unicode : 247; flag : umf_noinfo; reserved: 0), + (unicode : 8776; flag : umf_noinfo; reserved: 0), + (unicode : 176; flag : umf_noinfo; reserved: 0), + (unicode : 8729; flag : umf_noinfo; reserved: 0), + (unicode : 183; flag : umf_noinfo; reserved: 0), + (unicode : 8730; flag : umf_noinfo; reserved: 0), + (unicode : 8319; flag : umf_noinfo; reserved: 0), + (unicode : 178; flag : umf_noinfo; reserved: 0), + (unicode : 9632; flag : umf_noinfo; reserved: 0), + (unicode : 160; flag : umf_noinfo; reserved: 0) + ); + + reversemap : array[0..255] of treversecharmapping = ( + (unicode : 0; char1 : 0; char2 : 0), + (unicode : 1; char1 : 1; char2 : 0), + (unicode : 2; char1 : 2; char2 : 0), + (unicode : 3; char1 : 3; char2 : 0), + (unicode : 4; char1 : 4; char2 : 0), + (unicode : 5; char1 : 5; char2 : 0), + (unicode : 6; char1 : 6; char2 : 0), + (unicode : 7; char1 : 7; char2 : 0), + (unicode : 8; char1 : 8; char2 : 0), + (unicode : 9; char1 : 9; char2 : 0), + (unicode : 10; char1 : 10; char2 : 0), + (unicode : 11; char1 : 11; char2 : 0), + (unicode : 12; char1 : 12; char2 : 0), + (unicode : 13; char1 : 13; char2 : 0), + (unicode : 14; char1 : 14; char2 : 0), + (unicode : 15; char1 : 15; char2 : 0), + (unicode : 16; char1 : 16; char2 : 0), + (unicode : 17; char1 : 17; char2 : 0), + (unicode : 18; char1 : 18; char2 : 0), + (unicode : 19; char1 : 19; char2 : 0), + (unicode : 20; char1 : 20; char2 : 0), + (unicode : 21; char1 : 21; char2 : 0), + (unicode : 22; char1 : 22; char2 : 0), + (unicode : 23; char1 : 23; char2 : 0), + (unicode : 24; char1 : 24; char2 : 0), + (unicode : 25; char1 : 25; char2 : 0), + (unicode : 26; char1 : 26; char2 : 0), + (unicode : 27; char1 : 27; char2 : 0), + (unicode : 28; char1 : 28; char2 : 0), + (unicode : 29; char1 : 29; char2 : 0), + (unicode : 30; char1 : 30; char2 : 0), + (unicode : 31; char1 : 31; char2 : 0), + (unicode : 32; char1 : 32; char2 : 0), + (unicode : 33; char1 : 33; char2 : 0), + (unicode : 34; char1 : 34; char2 : 0), + (unicode : 35; char1 : 35; char2 : 0), + (unicode : 36; char1 : 36; char2 : 0), + (unicode : 37; char1 : 37; char2 : 0), + (unicode : 38; char1 : 38; char2 : 0), + (unicode : 39; char1 : 39; char2 : 0), + (unicode : 40; char1 : 40; char2 : 0), + (unicode : 41; char1 : 41; char2 : 0), + (unicode : 42; char1 : 42; char2 : 0), + (unicode : 43; char1 : 43; char2 : 0), + (unicode : 44; char1 : 44; char2 : 0), + (unicode : 45; char1 : 45; char2 : 0), + (unicode : 46; char1 : 46; char2 : 0), + (unicode : 47; char1 : 47; char2 : 0), + (unicode : 48; char1 : 48; char2 : 0), + (unicode : 49; char1 : 49; char2 : 0), + (unicode : 50; char1 : 50; char2 : 0), + (unicode : 51; char1 : 51; char2 : 0), + (unicode : 52; char1 : 52; char2 : 0), + (unicode : 53; char1 : 53; char2 : 0), + (unicode : 54; char1 : 54; char2 : 0), + (unicode : 55; char1 : 55; char2 : 0), + (unicode : 56; char1 : 56; char2 : 0), + (unicode : 57; char1 : 57; char2 : 0), + (unicode : 58; char1 : 58; char2 : 0), + (unicode : 59; char1 : 59; char2 : 0), + (unicode : 60; char1 : 60; char2 : 0), + (unicode : 61; char1 : 61; char2 : 0), + (unicode : 62; char1 : 62; char2 : 0), + (unicode : 63; char1 : 63; char2 : 0), + (unicode : 64; char1 : 64; char2 : 0), + (unicode : 65; char1 : 65; char2 : 0), + (unicode : 66; char1 : 66; char2 : 0), + (unicode : 67; char1 : 67; char2 : 0), + (unicode : 68; char1 : 68; char2 : 0), + (unicode : 69; char1 : 69; char2 : 0), + (unicode : 70; char1 : 70; char2 : 0), + (unicode : 71; char1 : 71; char2 : 0), + (unicode : 72; char1 : 72; char2 : 0), + (unicode : 73; char1 : 73; char2 : 0), + (unicode : 74; char1 : 74; char2 : 0), + (unicode : 75; char1 : 75; char2 : 0), + (unicode : 76; char1 : 76; char2 : 0), + (unicode : 77; char1 : 77; char2 : 0), + (unicode : 78; char1 : 78; char2 : 0), + (unicode : 79; char1 : 79; char2 : 0), + (unicode : 80; char1 : 80; char2 : 0), + (unicode : 81; char1 : 81; char2 : 0), + (unicode : 82; char1 : 82; char2 : 0), + (unicode : 83; char1 : 83; char2 : 0), + (unicode : 84; char1 : 84; char2 : 0), + (unicode : 85; char1 : 85; char2 : 0), + (unicode : 86; char1 : 86; char2 : 0), + (unicode : 87; char1 : 87; char2 : 0), + (unicode : 88; char1 : 88; char2 : 0), + (unicode : 89; char1 : 89; char2 : 0), + (unicode : 90; char1 : 90; char2 : 0), + (unicode : 91; char1 : 91; char2 : 0), + (unicode : 92; char1 : 92; char2 : 0), + (unicode : 93; char1 : 93; char2 : 0), + (unicode : 94; char1 : 94; char2 : 0), + (unicode : 95; char1 : 95; char2 : 0), + (unicode : 96; char1 : 96; char2 : 0), + (unicode : 97; char1 : 97; char2 : 0), + (unicode : 98; char1 : 98; char2 : 0), + (unicode : 99; char1 : 99; char2 : 0), + (unicode : 100; char1 : 100; char2 : 0), + (unicode : 101; char1 : 101; char2 : 0), + (unicode : 102; char1 : 102; char2 : 0), + (unicode : 103; char1 : 103; char2 : 0), + (unicode : 104; char1 : 104; char2 : 0), + (unicode : 105; char1 : 105; char2 : 0), + (unicode : 106; char1 : 106; char2 : 0), + (unicode : 107; char1 : 107; char2 : 0), + (unicode : 108; char1 : 108; char2 : 0), + (unicode : 109; char1 : 109; char2 : 0), + (unicode : 110; char1 : 110; char2 : 0), + (unicode : 111; char1 : 111; char2 : 0), + (unicode : 112; char1 : 112; char2 : 0), + (unicode : 113; char1 : 113; char2 : 0), + (unicode : 114; char1 : 114; char2 : 0), + (unicode : 115; char1 : 115; char2 : 0), + (unicode : 116; char1 : 116; char2 : 0), + (unicode : 117; char1 : 117; char2 : 0), + (unicode : 118; char1 : 118; char2 : 0), + (unicode : 119; char1 : 119; char2 : 0), + (unicode : 120; char1 : 120; char2 : 0), + (unicode : 121; char1 : 121; char2 : 0), + (unicode : 122; char1 : 122; char2 : 0), + (unicode : 123; char1 : 123; char2 : 0), + (unicode : 124; char1 : 124; char2 : 0), + (unicode : 125; char1 : 125; char2 : 0), + (unicode : 126; char1 : 126; char2 : 0), + (unicode : 127; char1 : 127; char2 : 0), + (unicode : 160; char1 : 255; char2 : 0), + (unicode : 167; char1 : 173; char2 : 0), + (unicode : 171; char1 : 174; char2 : 0), + (unicode : 176; char1 : 248; char2 : 0), + (unicode : 177; char1 : 241; char2 : 0), + (unicode : 178; char1 : 253; char2 : 0), + (unicode : 181; char1 : 230; char2 : 0), + (unicode : 183; char1 : 250; char2 : 0), + (unicode : 187; char1 : 175; char2 : 0), + (unicode : 188; char1 : 172; char2 : 0), + (unicode : 193; char1 : 143; char2 : 0), + (unicode : 196; char1 : 142; char2 : 0), + (unicode : 201; char1 : 144; char2 : 0), + (unicode : 205; char1 : 139; char2 : 0), + (unicode : 211; char1 : 149; char2 : 0), + (unicode : 212; char1 : 167; char2 : 0), + (unicode : 214; char1 : 153; char2 : 0), + (unicode : 218; char1 : 151; char2 : 0), + (unicode : 220; char1 : 154; char2 : 0), + (unicode : 221; char1 : 157; char2 : 0), + (unicode : 223; char1 : 225; char2 : 0), + (unicode : 225; char1 : 160; char2 : 0), + (unicode : 228; char1 : 132; char2 : 0), + (unicode : 233; char1 : 130; char2 : 0), + (unicode : 237; char1 : 161; char2 : 0), + (unicode : 243; char1 : 162; char2 : 0), + (unicode : 244; char1 : 147; char2 : 0), + (unicode : 246; char1 : 148; char2 : 0), + (unicode : 247; char1 : 246; char2 : 0), + (unicode : 250; char1 : 163; char2 : 0), + (unicode : 252; char1 : 129; char2 : 0), + (unicode : 253; char1 : 152; char2 : 0), + (unicode : 268; char1 : 128; char2 : 0), + (unicode : 269; char1 : 135; char2 : 0), + (unicode : 270; char1 : 133; char2 : 0), + (unicode : 271; char1 : 131; char2 : 0), + (unicode : 282; char1 : 137; char2 : 0), + (unicode : 283; char1 : 136; char2 : 0), + (unicode : 313; char1 : 138; char2 : 0), + (unicode : 314; char1 : 141; char2 : 0), + (unicode : 317; char1 : 156; char2 : 0), + (unicode : 318; char1 : 140; char2 : 0), + (unicode : 327; char1 : 165; char2 : 0), + (unicode : 328; char1 : 164; char2 : 0), + (unicode : 340; char1 : 171; char2 : 0), + (unicode : 341; char1 : 170; char2 : 0), + (unicode : 344; char1 : 158; char2 : 0), + (unicode : 345; char1 : 169; char2 : 0), + (unicode : 352; char1 : 155; char2 : 0), + (unicode : 353; char1 : 168; char2 : 0), + (unicode : 356; char1 : 134; char2 : 0), + (unicode : 357; char1 : 159; char2 : 0), + (unicode : 366; char1 : 166; char2 : 0), + (unicode : 367; char1 : 150; char2 : 0), + (unicode : 381; char1 : 146; char2 : 0), + (unicode : 382; char1 : 145; char2 : 0), + (unicode : 915; char1 : 226; char2 : 0), + (unicode : 920; char1 : 233; char2 : 0), + (unicode : 931; char1 : 228; char2 : 0), + (unicode : 934; char1 : 232; char2 : 0), + (unicode : 937; char1 : 234; char2 : 0), + (unicode : 945; char1 : 224; char2 : 0), + (unicode : 948; char1 : 235; char2 : 0), + (unicode : 949; char1 : 238; char2 : 0), + (unicode : 960; char1 : 227; char2 : 0), + (unicode : 963; char1 : 229; char2 : 0), + (unicode : 964; char1 : 231; char2 : 0), + (unicode : 966; char1 : 237; char2 : 0), + (unicode : 8319; char1 : 252; char2 : 0), + (unicode : 8729; char1 : 249; char2 : 0), + (unicode : 8730; char1 : 251; char2 : 0), + (unicode : 8734; char1 : 236; char2 : 0), + (unicode : 8745; char1 : 239; char2 : 0), + (unicode : 8776; char1 : 247; char2 : 0), + (unicode : 8801; char1 : 240; char2 : 0), + (unicode : 8804; char1 : 243; char2 : 0), + (unicode : 8805; char1 : 242; char2 : 0), + (unicode : 8992; char1 : 244; char2 : 0), + (unicode : 8993; char1 : 245; char2 : 0), + (unicode : 9472; char1 : 196; char2 : 0), + (unicode : 9474; char1 : 179; char2 : 0), + (unicode : 9484; char1 : 218; char2 : 0), + (unicode : 9488; char1 : 191; char2 : 0), + (unicode : 9492; char1 : 192; char2 : 0), + (unicode : 9496; char1 : 217; char2 : 0), + (unicode : 9500; char1 : 195; char2 : 0), + (unicode : 9508; char1 : 180; char2 : 0), + (unicode : 9516; char1 : 194; char2 : 0), + (unicode : 9524; char1 : 193; char2 : 0), + (unicode : 9532; char1 : 197; char2 : 0), + (unicode : 9552; char1 : 205; char2 : 0), + (unicode : 9553; char1 : 186; char2 : 0), + (unicode : 9554; char1 : 213; char2 : 0), + (unicode : 9555; char1 : 214; char2 : 0), + (unicode : 9556; char1 : 201; char2 : 0), + (unicode : 9557; char1 : 184; char2 : 0), + (unicode : 9558; char1 : 183; char2 : 0), + (unicode : 9559; char1 : 187; char2 : 0), + (unicode : 9560; char1 : 212; char2 : 0), + (unicode : 9561; char1 : 211; char2 : 0), + (unicode : 9562; char1 : 200; char2 : 0), + (unicode : 9563; char1 : 190; char2 : 0), + (unicode : 9564; char1 : 189; char2 : 0), + (unicode : 9565; char1 : 188; char2 : 0), + (unicode : 9566; char1 : 198; char2 : 0), + (unicode : 9567; char1 : 199; char2 : 0), + (unicode : 9568; char1 : 204; char2 : 0), + (unicode : 9569; char1 : 181; char2 : 0), + (unicode : 9570; char1 : 182; char2 : 0), + (unicode : 9571; char1 : 185; char2 : 0), + (unicode : 9572; char1 : 209; char2 : 0), + (unicode : 9573; char1 : 210; char2 : 0), + (unicode : 9574; char1 : 203; char2 : 0), + (unicode : 9575; char1 : 207; char2 : 0), + (unicode : 9576; char1 : 208; char2 : 0), + (unicode : 9577; char1 : 202; char2 : 0), + (unicode : 9578; char1 : 216; char2 : 0), + (unicode : 9579; char1 : 215; char2 : 0), + (unicode : 9580; char1 : 206; char2 : 0), + (unicode : 9600; char1 : 223; char2 : 0), + (unicode : 9604; char1 : 220; char2 : 0), + (unicode : 9608; char1 : 219; char2 : 0), + (unicode : 9612; char1 : 221; char2 : 0), + (unicode : 9616; char1 : 222; char2 : 0), + (unicode : 9617; char1 : 176; char2 : 0), + (unicode : 9618; char1 : 177; char2 : 0), + (unicode : 9619; char1 : 178; char2 : 0), + (unicode : 9632; char1 : 254; char2 : 0) + ); + + unicodemap : tunicodemap = ( + cpname : 'cp895'; + cp : 895; + map : @map; + lastchar : 255; + reversemap : @reversemap; + reversemaplength : 256; + next : nil; + internalmap : true + ); + + begin + registermapping(@unicodemap) + end. diff --git a/packages/rtl-unicode/src/inc/cpbuildu.pp b/packages/rtl-unicode/src/inc/cpbuildu.pp index ca91958d75..7980ef35ce 100644 --- a/packages/rtl-unicode/src/inc/cpbuildu.pp +++ b/packages/rtl-unicode/src/inc/cpbuildu.pp @@ -1,7 +1,7 @@ unit cpbuildu; // buildunit for cp* interface -uses cp932,cp936,cp949,cp950; +uses cp895,cp932,cp936,cp949,cp950; implementation diff --git a/rtl/ucmaps/cp895.txt b/rtl/ucmaps/cp895.txt new file mode 100644 index 0000000000..5e681657cb --- /dev/null +++ b/rtl/ucmaps/cp895.txt @@ -0,0 +1,275 @@ +# +# Name: cp895_KamenickyBrothers to Unicode table +# Unicode version: 1.1 +# Table version: 1.1 +# Table format: Format A +# Date: 03/31/95 +# Authors: Tomas Hajny based on public domain description of Kamenicky +# brothers encoding found on Internet and cp437 created by: +# Michel Suignard +# Lori Hoerth +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp895_KamenickyBrothers code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp895_KamenickyBrothers order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0a 0x000a #LINE FEED +0x0b 0x000b #VERTICAL TABULATION +0x0c 0x000c #FORM FEED +0x0d 0x000d #CARRIAGE RETURN +0x0e 0x000e #SHIFT OUT +0x0f 0x000f #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1a 0x001a #SUBSTITUTE +0x1b 0x001b #ESCAPE +0x1c 0x001c #FILE SEPARATOR +0x1d 0x001d #GROUP SEPARATOR +0x1e 0x001e #RECORD SEPARATOR +0x1f 0x001f #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2a 0x002a #ASTERISK +0x2b 0x002b #PLUS SIGN +0x2c 0x002c #COMMA +0x2d 0x002d #HYPHEN-MINUS +0x2e 0x002e #FULL STOP +0x2f 0x002f #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3a 0x003a #COLON +0x3b 0x003b #SEMICOLON +0x3c 0x003c #LESS-THAN SIGN +0x3d 0x003d #EQUALS SIGN +0x3e 0x003e #GREATER-THAN SIGN +0x3f 0x003f #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4a 0x004a #LATIN CAPITAL LETTER J +0x4b 0x004b #LATIN CAPITAL LETTER K +0x4c 0x004c #LATIN CAPITAL LETTER L +0x4d 0x004d #LATIN CAPITAL LETTER M +0x4e 0x004e #LATIN CAPITAL LETTER N +0x4f 0x004f #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5a 0x005a #LATIN CAPITAL LETTER Z +0x5b 0x005b #LEFT SQUARE BRACKET +0x5c 0x005c #REVERSE SOLIDUS +0x5d 0x005d #RIGHT SQUARE BRACKET +0x5e 0x005e #CIRCUMFLEX ACCENT +0x5f 0x005f #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6a 0x006a #LATIN SMALL LETTER J +0x6b 0x006b #LATIN SMALL LETTER K +0x6c 0x006c #LATIN SMALL LETTER L +0x6d 0x006d #LATIN SMALL LETTER M +0x6e 0x006e #LATIN SMALL LETTER N +0x6f 0x006f #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7a 0x007a #LATIN SMALL LETTER Z +0x7b 0x007b #LEFT CURLY BRACKET +0x7c 0x007c #VERTICAL LINE +0x7d 0x007d #RIGHT CURLY BRACKET +0x7e 0x007e #TILDE +0x7f 0x007f #DELETE +0x80 0x010c #LATIN CAPITAL LETTER C WITH CARON +0x81 0x00fc #LATIN SMALL LETTER U WITH DIAERESIS +0x82 0x00e9 #LATIN SMALL LETTER E WITH ACUTE +0x83 0x010f #LATIN SMALL LETTER D WITH CARON +0x84 0x00e4 #LATIN SMALL LETTER A WITH DIAERESIS +0x85 0x010e #LATIN CAPITAL LETTER D WITH CARON +0x86 0x0164 #LATIN CAPITAL LETTER T WITH CARON +0x87 0x010d #LATIN SMALL LETTER C WITH CARON +0x88 0x011b #LATIN SMALL LETTER E WITH CARON +0x89 0x011a #LATIN CAPITAL LETTER E WITH CARON +0x8a 0x0139 #LATIN CAPITAL LETTER L WITH ACUTE +0x8b 0x00cd #LATIN CAPITAL LETTER I WITH ACUTE +0x8c 0x013e #LATIN SMALL LETTER L WITH CARON +0x8d 0x013a #LATIN SMALL LETTER L WITH ACUTE +0x8e 0x00c4 #LATIN CAPITAL LETTER A WITH DIAERESIS +0x8f 0x00c1 #LATIN CAPITAL LETTER A WITH ACUTE +0x90 0x00c9 #LATIN CAPITAL LETTER E WITH ACUTE +0x91 0x017e #LATIN SMALL LETTER Z WITH CARON +0x92 0x017d #LATIN CAPITAL LETTER Z WITH CARON +0x93 0x00f4 #LATIN SMALL LETTER O WITH CIRCUMFLEX +0x94 0x00f6 #LATIN SMALL LETTER O WITH DIAERESIS +0x95 0x00d3 #LATIN CAPITAL LETTER O WITH ACUTE +0x96 0x016f #LATIN SMALL LETTER U WITH RING ABOVE +0x97 0x00da #LATIN CAPITAL LETTER U WITH ACUTE +0x98 0x00fd #LATIN SMALL LETTER Y WITH ACUTE +0x99 0x00d6 #LATIN CAPITAL LETTER O WITH DIAERESIS +0x9a 0x00dc #LATIN CAPITAL LETTER U WITH DIAERESIS +0x9b 0x0160 #LATIN CAPITAL LETTER S WITH CARON +0x9c 0x013d #LATIN CAPITAL LETTER L WITH CARON +0x9d 0x00dd #LATIN CAPITAL LETTER Y WITH ACUTE +0x9e 0x0158 #LATIN CAPITAL LETTER R WITH CARON +0x9f 0x0165 #LATIN SMALL LETTER T WITH CARON +0xa0 0x00e1 #LATIN SMALL LETTER A WITH ACUTE +0xa1 0x00ed #LATIN SMALL LETTER I WITH ACUTE +0xa2 0x00f3 #LATIN SMALL LETTER O WITH ACUTE +0xa3 0x00fa #LATIN SMALL LETTER U WITH ACUTE +0xa4 0x0148 #LATIN SMALL LETTER N WITH CARON +0xa5 0x0147 #LATIN CAPITAL LETTER N WITH CARON +0xa6 0x016e #LATIN CAPITAL LETTER U WITH RING ABOVE +0xa7 0x00d4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xa8 0x0161 #LATIN SMALL LETTER S WITH CARON +0xa9 0x0159 #LATIN SMALL LETTER R WITH CARON +0xaa 0x0155 #LATIN SMALL LETTER R WITH ACUTE +0xab 0x0154 #LATIN CAPITAL LETTER R WITH ACUTE +0xac 0x00bc #VULGAR FRACTION ONE QUARTER +0xad 0x00a7 #SECTION SIGN +0xae 0x00ab #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xaf 0x00bb #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xb0 0x2591 #LIGHT SHADE +0xb1 0x2592 #MEDIUM SHADE +0xb2 0x2593 #DARK SHADE +0xb3 0x2502 #BOX DRAWINGS LIGHT VERTICAL +0xb4 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT +0xb5 0x2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +0xb6 0x2562 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +0xb7 0x2556 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +0xb8 0x2555 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +0xb9 0x2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT +0xba 0x2551 #BOX DRAWINGS DOUBLE VERTICAL +0xbb 0x2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT +0xbc 0x255d #BOX DRAWINGS DOUBLE UP AND LEFT +0xbd 0x255c #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +0xbe 0x255b #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +0xbf 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT +0xc0 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT +0xc1 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL +0xc2 0x252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +0xc3 0x251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT +0xc4 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL +0xc5 0x253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +0xc6 0x255e #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +0xc7 0x255f #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +0xc8 0x255a #BOX DRAWINGS DOUBLE UP AND RIGHT +0xc9 0x2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT +0xca 0x2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL +0xcb 0x2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +0xcc 0x2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +0xcd 0x2550 #BOX DRAWINGS DOUBLE HORIZONTAL +0xce 0x256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +0xcf 0x2567 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +0xd0 0x2568 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +0xd1 0x2564 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +0xd2 0x2565 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +0xd3 0x2559 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +0xd4 0x2558 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +0xd5 0x2552 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +0xd6 0x2553 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +0xd7 0x256b #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +0xd8 0x256a #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +0xd9 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT +0xda 0x250c #BOX DRAWINGS LIGHT DOWN AND RIGHT +0xdb 0x2588 #FULL BLOCK +0xdc 0x2584 #LOWER HALF BLOCK +0xdd 0x258c #LEFT HALF BLOCK +0xde 0x2590 #RIGHT HALF BLOCK +0xdf 0x2580 #UPPER HALF BLOCK +0xe0 0x03b1 #GREEK SMALL LETTER ALPHA +0xe1 0x00df #LATIN SMALL LETTER SHARP S +0xe2 0x0393 #GREEK CAPITAL LETTER GAMMA +0xe3 0x03c0 #GREEK SMALL LETTER PI +0xe4 0x03a3 #GREEK CAPITAL LETTER SIGMA +0xe5 0x03c3 #GREEK SMALL LETTER SIGMA +0xe6 0x00b5 #MICRO SIGN +0xe7 0x03c4 #GREEK SMALL LETTER TAU +0xe8 0x03a6 #GREEK CAPITAL LETTER PHI +0xe9 0x0398 #GREEK CAPITAL LETTER THETA +0xea 0x03a9 #GREEK CAPITAL LETTER OMEGA +0xeb 0x03b4 #GREEK SMALL LETTER DELTA +0xec 0x221e #INFINITY +0xed 0x03c6 #GREEK SMALL LETTER PHI +0xee 0x03b5 #GREEK SMALL LETTER EPSILON +0xef 0x2229 #INTERSECTION +0xf0 0x2261 #IDENTICAL TO +0xf1 0x00b1 #PLUS-MINUS SIGN +0xf2 0x2265 #GREATER-THAN OR EQUAL TO +0xf3 0x2264 #LESS-THAN OR EQUAL TO +0xf4 0x2320 #TOP HALF INTEGRAL +0xf5 0x2321 #BOTTOM HALF INTEGRAL +0xf6 0x00f7 #DIVISION SIGN +0xf7 0x2248 #ALMOST EQUAL TO +0xf8 0x00b0 #DEGREE SIGN +0xf9 0x2219 #BULLET OPERATOR +0xfa 0x00b7 #MIDDLE DOT +0xfb 0x221a #SQUARE ROOT +0xfc 0x207f #SUPERSCRIPT LATIN SMALL LETTER N +0xfd 0x00b2 #SUPERSCRIPT TWO +0xfe 0x25a0 #BLACK SQUARE +0xff 0x00a0 #NO-BREAK SPACE