fields.inc 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Michael Van Canneyt, member of the
  4. Free Pascal development team
  5. TFields and related components implementations.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {Procedure DumpMem (P : Pointer;Size : Longint);
  13. Var i : longint;
  14. begin
  15. Write ('Memory dump : ');
  16. For I:=0 to Size-1 do
  17. Write (Pbyte(P)[i],' ');
  18. Writeln;
  19. end;}
  20. { ---------------------------------------------------------------------
  21. TFieldDef
  22. ---------------------------------------------------------------------}
  23. Constructor TFieldDef.Create(ACollection : TCollection);
  24. begin
  25. Inherited create(ACollection);
  26. FFieldNo:=Index+1;
  27. end;
  28. Constructor TFieldDef.Create(AOwner: TFieldDefs; const AName: string;
  29. ADataType: TFieldType; ASize: Integer; ARequired: Boolean; AFieldNo: Longint);
  30. begin
  31. {$ifdef dsdebug }
  32. Writeln('TFieldDef.Create : ',Aname,'(',AFieldNo,')');
  33. {$endif}
  34. Inherited Create(AOwner);
  35. Name:=Aname;
  36. FDatatype:=ADatatype;
  37. FSize:=ASize;
  38. FRequired:=ARequired;
  39. FPrecision:=-1;
  40. FFieldNo:=AFieldNo;
  41. end;
  42. Destructor TFieldDef.Destroy;
  43. begin
  44. Inherited destroy;
  45. end;
  46. procedure TFieldDef.Assign(APersistent: TPersistent);
  47. var fd: TFieldDef;
  48. begin
  49. fd := nil;
  50. if APersistent is TFieldDef then
  51. fd := APersistent as TFieldDef;
  52. if Assigned(fd) then begin
  53. Collection.BeginUpdate;
  54. try
  55. Name := fd.Name;
  56. DataType := fd.DataType;
  57. Size := fd.Size;
  58. Precision := fd.Precision;
  59. FRequired := fd.Required;
  60. finally
  61. Collection.EndUpdate;
  62. end;
  63. end else
  64. inherited Assign(APersistent);
  65. end;
  66. Function TFieldDef.CreateField(AOwner: TComponent): TField;
  67. Var TheField : TFieldClass;
  68. begin
  69. {$ifdef dsdebug}
  70. Writeln ('Creating field '+FNAME);
  71. {$endif dsdebug}
  72. TheField:=GetFieldClass;
  73. if TheField=Nil then
  74. DatabaseErrorFmt(SUnknownFieldType,[FName]);
  75. Result:=Thefield.Create(AOwner);
  76. Try
  77. Result.Size:=FSize;
  78. Result.Required:=FRequired;
  79. Result.FFieldName:=FName;
  80. Result.FDisplayLabel:=DisplayName;
  81. Result.FFieldNo:=Self.FieldNo;
  82. Result.SetFieldType(DataType);
  83. Result.FReadOnly:= (faReadOnly in Attributes);
  84. {$ifdef dsdebug}
  85. Writeln ('TFieldDef.CReateField : Trying to set dataset');
  86. {$endif dsdebug}
  87. {$ifdef dsdebug}
  88. Writeln ('TFieldDef.CReateField : Result Fieldno : ',Result.FieldNo,' Self : ',FieldNo);
  89. {$endif dsdebug}
  90. Result.Dataset:=TFieldDefs(Collection).Dataset;
  91. If (Result is TFloatField) then
  92. TFloatField(Result).Precision:=FPrecision;
  93. if (Result is TBCDField) then
  94. TBCDField(Result).Precision:=FPrecision;
  95. if (Result is TFmtBCDField) then
  96. TFmtBCDField(Result).Precision:=FPrecision;
  97. except
  98. Result.Free;
  99. Raise;
  100. end;
  101. end;
  102. procedure TFieldDef.SetAttributes(AValue: TFieldAttributes);
  103. begin
  104. FAttributes := AValue;
  105. Changed(False);
  106. end;
  107. procedure TFieldDef.SetDataType(AValue: TFieldType);
  108. begin
  109. FDataType := AValue;
  110. Changed(False);
  111. end;
  112. procedure TFieldDef.SetPrecision(const AValue: Longint);
  113. begin
  114. FPrecision := AValue;
  115. Changed(False);
  116. end;
  117. procedure TFieldDef.SetSize(const AValue: Integer);
  118. begin
  119. FSize := AValue;
  120. Changed(False);
  121. end;
  122. procedure TFieldDef.SetRequired(const AValue: Boolean);
  123. begin
  124. FRequired := AValue;
  125. Changed(False);
  126. end;
  127. Function TFieldDef.GetFieldClass : TFieldClass;
  128. begin
  129. //!! Should be owner as tdataset but that doesn't work ??
  130. If Assigned(Collection) And
  131. (Collection is TFieldDefs) And
  132. Assigned(TFieldDefs(Collection).Dataset) then
  133. Result:=TFieldDefs(Collection).Dataset.GetFieldClass(FDataType)
  134. else
  135. Result:=Nil;
  136. end;
  137. { ---------------------------------------------------------------------
  138. TFieldDefs
  139. ---------------------------------------------------------------------}
  140. {
  141. destructor TFieldDefs.Destroy;
  142. begin
  143. FItems.Free;
  144. // This will destroy all fielddefs since we own them...
  145. Inherited Destroy;
  146. end;
  147. }
  148. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType);
  149. begin
  150. Add(AName,ADatatype,0,False);
  151. end;
  152. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize : Word);
  153. begin
  154. Add(AName,ADatatype,ASize,False);
  155. end;
  156. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize: Word;
  157. ARequired: Boolean);
  158. begin
  159. If Length(AName)=0 Then
  160. DatabaseError(SNeedFieldName);
  161. // the fielddef will register itself here as a owned component.
  162. // fieldno is 1 based !
  163. BeginUpdate;
  164. try
  165. TFieldDef.Create(Self,AName,ADataType,ASize,Arequired,Count+1);
  166. finally
  167. EndUpdate;
  168. end;
  169. end;
  170. function TFieldDefs.GetItem(Index: Longint): TFieldDef;
  171. begin
  172. Result := TFieldDef(inherited Items[Index]);
  173. end;
  174. procedure TFieldDefs.SetItem(Index: Longint; const AValue: TFieldDef);
  175. begin
  176. inherited Items[Index] := AValue;
  177. end;
  178. constructor TFieldDefs.Create(ADataset: TDataset);
  179. begin
  180. Inherited Create(ADataset, Owner, TFieldDef);
  181. end;
  182. procedure TFieldDefs.Assign(FieldDefs: TFieldDefs);
  183. Var I : longint;
  184. begin
  185. Clear;
  186. For i:=0 to FieldDefs.Count-1 do
  187. With FieldDefs[i] do
  188. Add(Name,DataType,Size,Required);
  189. end;
  190. function TFieldDefs.Find(const AName: string): TFieldDef;
  191. begin
  192. Result := (Inherited Find(AName)) as TFieldDef;
  193. if Result=nil then DatabaseErrorFmt(SFieldNotFound,[AName],FDataset);
  194. end;
  195. {
  196. procedure TFieldDefs.Clear;
  197. Var I : longint;
  198. begin
  199. For I:=FItems.Count-1 downto 0 do
  200. TFieldDef(Fitems[i]).Free;
  201. FItems.Clear;
  202. end;
  203. }
  204. procedure TFieldDefs.Update;
  205. begin
  206. if not Updated then
  207. begin
  208. If Assigned(Dataset) then
  209. DataSet.InitFieldDefs;
  210. Updated := True;
  211. end;
  212. end;
  213. function TFieldDefs.MakeNameUnique(const AName: String): string;
  214. var DblFieldCount : integer;
  215. begin
  216. DblFieldCount := 0;
  217. Result := AName;
  218. while assigned(inherited Find(Result)) do
  219. begin
  220. inc(DblFieldCount);
  221. Result := AName + '_' + IntToStr(DblFieldCount);
  222. end;
  223. end;
  224. Function TFieldDefs.AddFieldDef : TFieldDef;
  225. begin
  226. Result:=TFieldDef.Create(Self,'',ftUnknown,0,False,Count+1);
  227. end;
  228. { ---------------------------------------------------------------------
  229. TField
  230. ---------------------------------------------------------------------}
  231. Const
  232. SBCD = 'BCD';
  233. SBoolean = 'Boolean';
  234. SDateTime = 'TDateTime';
  235. SFloat = 'Float';
  236. SInteger = 'Integer';
  237. SLargeInt = 'LargeInt';
  238. SVariant = 'Variant';
  239. SString = 'String';
  240. constructor TField.Create(AOwner: TComponent);
  241. begin
  242. Inherited Create(AOwner);
  243. FVisible:=True;
  244. FValidChars:=[#0..#255];
  245. FProviderFlags := [pfInUpdate,pfInWhere];
  246. end;
  247. destructor TField.Destroy;
  248. begin
  249. IF Assigned(FDataSet) then
  250. begin
  251. FDataSet.Active:=False;
  252. if Assigned(FFields) then
  253. FFields.Remove(Self);
  254. end;
  255. FLookupList.Free;
  256. Inherited Destroy;
  257. end;
  258. function TField.AccessError(const TypeName: string): EDatabaseError;
  259. begin
  260. Result:=EDatabaseError.CreateFmt(SinvalidTypeConversion,[TypeName,FFieldName]);
  261. end;
  262. procedure TField.Assign(Source: TPersistent);
  263. begin
  264. if Source = nil then Clear
  265. else if Source is TField then begin
  266. Value := TField(Source).Value;
  267. end else
  268. inherited Assign(Source);
  269. end;
  270. procedure TField.AssignValue(const AValue: TVarRec);
  271. procedure Error;
  272. begin
  273. DatabaseErrorFmt(SFieldValueError, [DisplayName]);
  274. end;
  275. begin
  276. with AValue do
  277. case VType of
  278. vtInteger:
  279. AsInteger := VInteger;
  280. vtBoolean:
  281. AsBoolean := VBoolean;
  282. vtChar:
  283. AsString := VChar;
  284. vtExtended:
  285. AsFloat := VExtended^;
  286. vtString:
  287. AsString := VString^;
  288. vtPointer:
  289. if VPointer <> nil then Error;
  290. vtPChar:
  291. AsString := VPChar;
  292. vtObject:
  293. if (VObject = nil) or (VObject is TPersistent) then
  294. Assign(TPersistent(VObject))
  295. else
  296. Error;
  297. vtAnsiString:
  298. AsString := string(VAnsiString);
  299. vtCurrency:
  300. AsCurrency := VCurrency^;
  301. vtVariant:
  302. if not VarIsClear(VVariant^) then Self.Value := VVariant^;
  303. vtWideString:
  304. AsWideString := WideString(VWideString);
  305. vtInt64:
  306. AsLargeInt := VInt64^;
  307. else
  308. Error;
  309. end;
  310. end;
  311. procedure TField.Change;
  312. begin
  313. If Assigned(FOnChange) Then
  314. FOnChange(Self);
  315. end;
  316. procedure TField.CheckInactive;
  317. begin
  318. If Assigned(FDataSet) then
  319. FDataset.CheckInactive;
  320. end;
  321. procedure TField.Clear;
  322. begin
  323. if FieldKind in [fkData, fkInternalCalc] then
  324. SetData(Nil);
  325. end;
  326. procedure TField.DataChanged;
  327. begin
  328. FDataset.DataEvent(deFieldChange,ptrint(Self));
  329. end;
  330. procedure TField.FocusControl;
  331. var
  332. Field1: TField;
  333. begin
  334. Field1 := Self;
  335. FDataSet.DataEvent(deFocusControl,ptrint(@Field1));
  336. end;
  337. procedure TField.FreeBuffers;
  338. begin
  339. // Empty. Provided for backward compatibiliy;
  340. // TDataset manages the buffers.
  341. end;
  342. function TField.GetAsBoolean: Boolean;
  343. begin
  344. raise AccessError(SBoolean);
  345. end;
  346. function TField.GetAsDateTime: TDateTime;
  347. begin
  348. raise AccessError(SdateTime);
  349. end;
  350. function TField.GetAsFloat: Double;
  351. begin
  352. raise AccessError(SDateTime);
  353. end;
  354. function TField.GetAsLongint: Longint;
  355. begin
  356. raise AccessError(SInteger);
  357. end;
  358. function TField.GetAsVariant: Variant;
  359. begin
  360. raise AccessError(SVariant);
  361. end;
  362. function TField.GetAsInteger: Integer;
  363. begin
  364. Result:=GetAsLongint;
  365. end;
  366. function TField.GetAsString: string;
  367. begin
  368. Result := GetClassDesc;
  369. end;
  370. function TField.GetAsWideString: WideString;
  371. begin
  372. Result := GetAsString;
  373. end;
  374. function TField.GetOldValue: Variant;
  375. var SaveState : TDatasetState;
  376. begin
  377. SaveState := FDataset.State;
  378. try
  379. FDataset.SetTempState(dsOldValue);
  380. Result := GetAsVariant;
  381. finally
  382. FDataset.RestoreState(SaveState);
  383. end;
  384. end;
  385. function TField.GetNewValue: Variant;
  386. var SaveState : TDatasetState;
  387. begin
  388. SaveState := FDataset.State;
  389. try
  390. FDataset.SetTempState(dsNewValue);
  391. Result := GetAsVariant;
  392. finally
  393. FDataset.RestoreState(SaveState);
  394. end;
  395. end;
  396. procedure TField.SetNewValue(const AValue: Variant);
  397. var SaveState : TDatasetState;
  398. begin
  399. SaveState := FDataset.State;
  400. try
  401. FDataset.SetTempState(dsNewValue);
  402. SetAsVariant(AValue);
  403. finally
  404. FDataset.RestoreState(SaveState);
  405. end;
  406. end;
  407. function TField.GetCurValue: Variant;
  408. var SaveState : TDatasetState;
  409. begin
  410. SaveState := FDataset.State;
  411. try
  412. FDataset.SetTempState(dsCurValue);
  413. Result := GetAsVariant;
  414. finally
  415. FDataset.RestoreState(SaveState);
  416. end;
  417. end;
  418. function TField.GetCanModify: Boolean;
  419. begin
  420. Result:=Not ReadOnly;
  421. If Result then
  422. begin
  423. Result := FieldKind in [fkData, fkInternalCalc];
  424. if Result then
  425. begin
  426. Result:=Assigned(DataSet) and Dataset.Active;
  427. If Result then
  428. Result:= DataSet.CanModify;
  429. end;
  430. end;
  431. end;
  432. function TField.GetClassDesc: String;
  433. var ClassN : string;
  434. begin
  435. ClassN := copy(ClassName,2,pos('Field',ClassName)-2);
  436. if isNull then
  437. result := '(' + LowerCase(ClassN) + ')'
  438. else
  439. result := '(' + UpperCase(ClassN) + ')';
  440. end;
  441. function TField.GetData(Buffer: Pointer): Boolean;
  442. begin
  443. Result:=GetData(Buffer,True);
  444. end;
  445. function TField.GetData(Buffer: Pointer; NativeFormat : Boolean): Boolean;
  446. begin
  447. IF FDataset=Nil then
  448. DatabaseErrorFmt(SNoDataset,[FieldName]);
  449. If FVAlidating then
  450. begin
  451. result:=Not(FValueBuffer=Nil);
  452. If Result then
  453. Move (FValueBuffer^,Buffer^ ,DataSize);
  454. end
  455. else
  456. Result:=FDataset.GetFieldData(Self,Buffer,NativeFormat);
  457. end;
  458. function TField.GetDataSize: Integer;
  459. begin
  460. Result:=0;
  461. end;
  462. function TField.GetDefaultWidth: Longint;
  463. begin
  464. Result:=10;
  465. end;
  466. function TField.GetDisplayName : String;
  467. begin
  468. If FDisplayLabel<>'' then
  469. result:=FDisplayLabel
  470. else
  471. Result:=FFieldName;
  472. end;
  473. Function TField.IsDisplayStored : Boolean;
  474. begin
  475. Result:=(DisplayLabel<>FieldName);
  476. end;
  477. function TField.GetLookupList: TLookupList;
  478. begin
  479. if not Assigned(FLookupList) then
  480. FLookupList := TLookupList.Create;
  481. Result := FLookupList;
  482. end;
  483. procedure TField.CalcLookupValue;
  484. begin
  485. if FLookupCache then
  486. Value := LookupList.ValueOfKey(FDataSet.FieldValues[FKeyFields])
  487. else if Assigned(FLookupDataSet) and FDataSet.Active then
  488. Value := FLookupDataSet.Lookup(FLookupKeyfields, FDataSet.FieldValues[FKeyFields], FLookupresultField);
  489. end;
  490. function TField.getIndex : longint;
  491. begin
  492. If Assigned(FDataset) then
  493. Result:=FDataset.FFieldList.IndexOf(Self)
  494. else
  495. Result:=-1;
  496. end;
  497. function TField.GetAsBCD: TBCD;
  498. begin
  499. raise AccessError(SBCD);
  500. end;
  501. function TField.GetLookup: Boolean;
  502. begin
  503. Result := FieldKind = fkLookup;
  504. end;
  505. function TField.GetAsLargeInt: LargeInt;
  506. begin
  507. Raise AccessError(SLargeInt);
  508. end;
  509. function TField.GetAsCurrency: Currency;
  510. begin
  511. Result := GetAsFloat;
  512. end;
  513. procedure TField.SetAlignment(const AValue: TAlignMent);
  514. begin
  515. if FAlignment <> AValue then
  516. begin
  517. FAlignment := Avalue;
  518. PropertyChanged(false);
  519. end;
  520. end;
  521. procedure TField.SetAsBCD(const AValue: TBCD);
  522. begin
  523. Raise AccessError(SBCD);
  524. end;
  525. procedure TField.SetIndex(const AValue: Integer);
  526. begin
  527. if FFields <> nil then FFields.SetFieldIndex(Self, AValue)
  528. end;
  529. procedure TField.SetAsCurrency(AValue: Currency);
  530. begin
  531. SetAsFloat(AValue);
  532. end;
  533. function TField.GetIsNull: Boolean;
  534. begin
  535. Result:=Not(GetData (Nil));
  536. end;
  537. function TField.GetParentComponent: TComponent;
  538. begin
  539. Result := DataSet;
  540. end;
  541. procedure TField.GetText(var AText: string; ADisplayText: Boolean);
  542. begin
  543. AText:=GetAsString;
  544. end;
  545. function TField.HasParent: Boolean;
  546. begin
  547. HasParent:=True;
  548. end;
  549. function TField.IsValidChar(InputChar: Char): Boolean;
  550. begin
  551. // FValidChars must be set in Create.
  552. Result:=InputChar in FValidChars;
  553. end;
  554. procedure TField.RefreshLookupList;
  555. var
  556. tmpActive: Boolean;
  557. begin
  558. if not Assigned(FLookupDataSet) or (Length(FLookupKeyfields) = 0)
  559. or (Length(FLookupresultField) = 0) or (Length(FKeyFields) = 0) then
  560. Exit;
  561. tmpActive := FLookupDataSet.Active;
  562. try
  563. FLookupDataSet.Active := True;
  564. FFields.CheckFieldNames(FLookupKeyfields);
  565. FLookupDataset.FieldByName(FLookupresultField); // I presume that if it doesn't exist it throws exception, and that a field with null value is still valid
  566. LookupList.Clear; // have to be F-less because we might be creating it here with getter!
  567. FLookupDataSet.DisableControls;
  568. try
  569. FLookupDataSet.Open;
  570. repeat
  571. FLookupList.Add(FLookupDataSet.FieldValues[FLookupKeyfields], FLookupDataSet.FieldValues[FLookupResultField]);
  572. FLookupDataSet.Next;
  573. until FLookupDataSet.EOF;
  574. finally
  575. FLookupDataSet.EnableControls;
  576. end;
  577. finally
  578. FLookupDataSet.Active := tmpActive;
  579. end;
  580. end;
  581. procedure TField.Notification(AComponent: TComponent; Operation: TOperation);
  582. begin
  583. Inherited Notification(AComponent,Operation);
  584. if (Operation = opRemove) and (AComponent = FLookupDataSet) then
  585. FLookupDataSet := nil;
  586. end;
  587. procedure TField.PropertyChanged(LayoutAffected: Boolean);
  588. begin
  589. If (FDataset<>Nil) and (FDataset.Active) then
  590. If LayoutAffected then
  591. FDataset.DataEvent(deLayoutChange,0)
  592. else
  593. FDataset.DataEvent(deDatasetchange,0);
  594. end;
  595. procedure TField.ReadState(Reader: TReader);
  596. begin
  597. inherited ReadState(Reader);
  598. if Reader.Parent is TDataSet then
  599. DataSet := TDataSet(Reader.Parent);
  600. end;
  601. procedure TField.SetAsBoolean(AValue: Boolean);
  602. begin
  603. Raise AccessError(SBoolean);
  604. end;
  605. procedure TField.SetAsDateTime(AValue: TDateTime);
  606. begin
  607. Raise AccessError(SDateTime);
  608. end;
  609. procedure TField.SetAsFloat(AValue: Double);
  610. begin
  611. Raise AccessError(SFloat);
  612. end;
  613. procedure TField.SetAsVariant(const AValue: Variant);
  614. begin
  615. if VarIsNull(AValue) then
  616. Clear
  617. else
  618. try
  619. SetVarValue(AValue);
  620. except
  621. on EVariantError do DatabaseErrorFmt(SFieldValueError, [DisplayName]);
  622. end;
  623. end;
  624. procedure TField.SetAsLongint(AValue: Longint);
  625. begin
  626. Raise AccessError(SInteger);
  627. end;
  628. procedure TField.SetAsInteger(AValue: Integer);
  629. begin
  630. SetAsLongint(AValue);
  631. end;
  632. procedure TField.SetAsLargeint(AValue: Largeint);
  633. begin
  634. Raise AccessError(SLargeInt);
  635. end;
  636. procedure TField.SetAsString(const AValue: string);
  637. begin
  638. Raise AccessError(SString);
  639. end;
  640. procedure TField.SetAsWideString(const aValue: WideString);
  641. begin
  642. SetAsString(aValue);
  643. end;
  644. procedure TField.SetData(Buffer: Pointer);
  645. begin
  646. SetData(Buffer,True);
  647. end;
  648. procedure TField.SetData(Buffer: Pointer; NativeFormat : Boolean);
  649. begin
  650. If Not Assigned(FDataset) then
  651. DatabaseErrorFmt(SNoDataset,[FieldName]);
  652. if (FieldNo>0) and not (FDataSet.State in [dsSetKey, dsFilter]) then
  653. begin
  654. if ReadOnly then
  655. DatabaseErrorFmt(SReadOnlyField, [DisplayName], Self);
  656. Validate(Buffer);
  657. end;
  658. FDataSet.SetFieldData(Self,Buffer, NativeFormat);
  659. end;
  660. Procedure TField.SetDataset (AValue : TDataset);
  661. begin
  662. {$ifdef dsdebug}
  663. Writeln ('Setting dataset');
  664. {$endif}
  665. If AValue=FDataset then exit;
  666. If Assigned(FDataset) Then
  667. begin
  668. FDataset.CheckInactive;
  669. FDataset.FFieldList.Remove(Self);
  670. end;
  671. If Assigned(AValue) then
  672. begin
  673. AValue.CheckInactive;
  674. AValue.FFieldList.Add(Self);
  675. end;
  676. FDataset:=AValue;
  677. end;
  678. procedure TField.SetDataType(AValue: TFieldType);
  679. begin
  680. FDataType := AValue;
  681. end;
  682. procedure TField.SetFieldType(AValue: TFieldType);
  683. begin
  684. { empty }
  685. end;
  686. procedure TField.SetParentComponent(AParent: TComponent);
  687. begin
  688. if not (csLoading in ComponentState) then
  689. DataSet := AParent as TDataSet;
  690. end;
  691. procedure TField.SetSize(AValue: Integer);
  692. begin
  693. CheckInactive;
  694. CheckTypeSize(AValue);
  695. FSize:=AValue;
  696. end;
  697. procedure TField.SetText(const AValue: string);
  698. begin
  699. AsString:=AValue;
  700. end;
  701. procedure TField.SetVarValue(const AValue: Variant);
  702. begin
  703. Raise AccessError(SVariant);
  704. end;
  705. procedure TField.Validate(Buffer: Pointer);
  706. begin
  707. If assigned(OnValidate) Then
  708. begin
  709. FValueBuffer:=Buffer;
  710. FValidating:=True;
  711. Try
  712. OnValidate(Self);
  713. finally
  714. FValidating:=False;
  715. end;
  716. end;
  717. end;
  718. class function Tfield.IsBlob: Boolean;
  719. begin
  720. Result:=False;
  721. end;
  722. class procedure TField.CheckTypeSize(AValue: Longint);
  723. begin
  724. If (AValue<>0) and Not IsBlob Then
  725. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  726. end;
  727. // TField private methods
  728. procedure TField.SetEditText(const AValue: string);
  729. begin
  730. if Assigned(OnSetText) then
  731. OnSetText(Self, AValue)
  732. else
  733. SetText(AValue);
  734. end;
  735. function TField.GetEditText: String;
  736. begin
  737. SetLength(Result, 0);
  738. if Assigned(OnGetText) then
  739. OnGetText(Self, Result, False)
  740. else
  741. GetText(Result, False);
  742. end;
  743. function TField.GetDisplayText: String;
  744. begin
  745. SetLength(Result, 0);
  746. if Assigned(OnGetText) then
  747. OnGetText(Self, Result, True)
  748. else
  749. GetText(Result, True);
  750. end;
  751. procedure TField.SetDisplayLabel(const AValue: string);
  752. begin
  753. if FDisplayLabel<>Avalue then
  754. begin
  755. FDisplayLabel:=Avalue;
  756. PropertyChanged(true);
  757. end;
  758. end;
  759. procedure TField.SetDisplayWidth(const AValue: Longint);
  760. begin
  761. if FDisplayWidth<>AValue then
  762. begin
  763. FDisplayWidth:=AValue;
  764. PropertyChanged(True);
  765. end;
  766. end;
  767. function TField.GetDisplayWidth: integer;
  768. begin
  769. if FDisplayWidth=0 then
  770. result:=GetDefaultWidth
  771. else
  772. result:=FDisplayWidth;
  773. end;
  774. procedure TField.SetLookup(const AValue: Boolean);
  775. const
  776. ValueToLookupMap: array[Boolean] of TFieldKind = (fkData, fkLookup);
  777. begin
  778. FieldKind := ValueToLookupMap[AValue];
  779. end;
  780. procedure TField.SetReadOnly(const AValue: Boolean);
  781. begin
  782. if (FReadOnly<>Avalue) then
  783. begin
  784. FReadOnly:=AValue;
  785. PropertyChanged(True);
  786. end;
  787. end;
  788. procedure TField.SetVisible(const AValue: Boolean);
  789. begin
  790. if FVisible<>Avalue then
  791. begin
  792. FVisible:=AValue;
  793. PropertyChanged(True);
  794. end;
  795. end;
  796. { ---------------------------------------------------------------------
  797. TStringField
  798. ---------------------------------------------------------------------}
  799. constructor TStringField.Create(AOwner: TComponent);
  800. begin
  801. Inherited Create(AOwner);
  802. SetDataType(ftString);
  803. FFixedChar := False;
  804. FTransliterate := False;
  805. FSize:=20;
  806. end;
  807. procedure TStringField.SetFieldType(AValue: TFieldType);
  808. begin
  809. if avalue in [ftString, ftFixedChar] then
  810. SetDataType(AValue);
  811. end;
  812. class procedure TStringField.CheckTypeSize(AValue: Longint);
  813. begin
  814. // A size of 0 is allowed, since for example Firebird allows
  815. // a query like: 'select '' as fieldname from table' which
  816. // results in a string with size 0.
  817. If (AValue<0) Then
  818. databaseErrorFmt(SInvalidFieldSize,[AValue])
  819. end;
  820. function TStringField.GetAsBoolean: Boolean;
  821. Var S : String;
  822. begin
  823. S:=GetAsString;
  824. result := (Length(S)>0) and (Upcase(S[1]) in ['T',YesNoChars[True]]);
  825. end;
  826. function TStringField.GetAsDateTime: TDateTime;
  827. begin
  828. Result:=StrToDateTime(GetAsString);
  829. end;
  830. function TStringField.GetAsFloat: Double;
  831. begin
  832. Result:=StrToFloat(GetAsString);
  833. end;
  834. function TStringField.GetAsLongint: Longint;
  835. begin
  836. Result:=StrToInt(GetAsString);
  837. end;
  838. function TStringField.GetAsString: string;
  839. begin
  840. If Not GetValue(Result) then
  841. Result:='';
  842. end;
  843. function TStringField.GetAsVariant: Variant;
  844. Var s : string;
  845. begin
  846. If GetValue(s) then
  847. Result:=s
  848. else
  849. Result:=Null;
  850. end;
  851. function TStringField.GetDataSize: Integer;
  852. begin
  853. if DataType=ftFixedChar then
  854. Result:=Size+1
  855. else
  856. Result:=Size+1;
  857. end;
  858. function TStringField.GetDefaultWidth: Longint;
  859. begin
  860. result:=Size;
  861. end;
  862. Procedure TStringField.GetText(var AText: string; ADisplayText: Boolean);
  863. begin
  864. AText:=GetAsString;
  865. end;
  866. function TStringField.GetValue(var AValue: string): Boolean;
  867. Var Buf, TBuf : TStringFieldBuffer;
  868. DynBuf, TDynBuf : Array of char;
  869. begin
  870. if DataSize <= dsMaxStringSize then
  871. begin
  872. Result:=GetData(@Buf);
  873. If Result then
  874. begin
  875. if transliterate then
  876. begin
  877. DataSet.Translate(Buf,TBuf,False);
  878. AValue:=TBuf;
  879. end
  880. else
  881. AValue:=Buf
  882. end
  883. end
  884. else
  885. begin
  886. SetLength(DynBuf,DataSize);
  887. Result:=GetData(@DynBuf[0]);
  888. If Result then
  889. begin
  890. if transliterate then
  891. begin
  892. SetLength(TDynBuf,DataSize);
  893. DataSet.Translate(@DynBuf[0],@TDynBuf[0],False);
  894. AValue:=pchar(TDynBuf);
  895. end
  896. else
  897. AValue:=pchar(DynBuf);
  898. end
  899. end;
  900. end;
  901. procedure TStringField.SetAsBoolean(AValue: Boolean);
  902. begin
  903. If AValue Then
  904. SetAsString('T')
  905. else
  906. SetAsString('F');
  907. end;
  908. procedure TStringField.SetAsDateTime(AValue: TDateTime);
  909. begin
  910. SetAsString(DateTimeToStr(AValue));
  911. end;
  912. procedure TStringField.SetAsFloat(AValue: Double);
  913. begin
  914. SetAsString(FloatToStr(AValue));
  915. end;
  916. procedure TStringField.SetAsLongint(AValue: Longint);
  917. begin
  918. SetAsString(intToStr(AValue));
  919. end;
  920. procedure TStringField.SetAsString(const AValue: string);
  921. var Buf : TStringFieldBuffer;
  922. begin
  923. IF Length(AValue)=0 then
  924. begin
  925. Buf := #0;
  926. SetData(@buf);
  927. end
  928. else if FTransliterate then
  929. begin
  930. DataSet.Translate(@AValue[1],Buf,True);
  931. Buf[DataSize-1] := #0;
  932. SetData(@buf);
  933. end
  934. else
  935. begin
  936. // The data is copied into the buffer, since some TDataset descendents copy
  937. // the whole buffer-length in SetData. (See bug 8477)
  938. Buf := AValue;
  939. // If length(AValue) > Datasize the buffer isn't terminated properly
  940. Buf[DataSize-1] := #0;
  941. SetData(@Buf);
  942. end;
  943. end;
  944. procedure TStringField.SetVarValue(const AValue: Variant);
  945. begin
  946. SetAsString(AValue);
  947. end;
  948. { ---------------------------------------------------------------------
  949. TWideStringField
  950. ---------------------------------------------------------------------}
  951. class procedure TWideStringField.CheckTypeSize(aValue: Integer);
  952. begin
  953. // A size of 0 is allowed, since for example Firebird allows
  954. // a query like: 'select '' as fieldname from table' which
  955. // results in a string with size 0.
  956. If (AValue<0) Then
  957. databaseErrorFmt(SInvalidFieldSize,[AValue]);
  958. end;
  959. constructor TWideStringField.Create(AOwner: TComponent);
  960. begin
  961. inherited Create(AOwner);
  962. SetDataType(ftWideString);
  963. end;
  964. procedure TWideStringField.SetFieldType(AValue: TFieldType);
  965. begin
  966. if avalue in [ftWideString, ftFixedWideChar] then
  967. SetDataType(AValue);
  968. end;
  969. function TWideStringField.GetValue(var aValue: WideString): Boolean;
  970. var
  971. FixBuffer : array[0..dsMaxStringSize div 2] of WideChar;
  972. DynBuffer : array of WideChar;
  973. Buffer : PWideChar;
  974. begin
  975. if DataSize <= dsMaxStringSize then begin
  976. Result := GetData(@FixBuffer, False);
  977. aValue := FixBuffer;
  978. end else begin
  979. SetLength(DynBuffer, Succ(Size));
  980. Buffer := PWideChar(DynBuffer);
  981. Result := GetData(Buffer, False);
  982. if Result then
  983. aValue := Buffer;
  984. end;
  985. end;
  986. function TWideStringField.GetAsString: string;
  987. begin
  988. Result := GetAsWideString;
  989. end;
  990. procedure TWideStringField.SetAsString(const aValue: string);
  991. begin
  992. SetAsWideString(aValue);
  993. end;
  994. function TWideStringField.GetAsVariant: Variant;
  995. var
  996. ws: WideString;
  997. begin
  998. if GetValue(ws) then
  999. Result := ws
  1000. else
  1001. Result := Null;
  1002. end;
  1003. procedure TWideStringField.SetVarValue(const aValue: Variant);
  1004. begin
  1005. SetAsWideString(aValue);
  1006. end;
  1007. function TWideStringField.GetAsWideString: WideString;
  1008. begin
  1009. if not GetValue(Result) then
  1010. Result := '';
  1011. end;
  1012. procedure TWideStringField.SetAsWideString(const aValue: WideString);
  1013. const
  1014. NullWideChar : WideChar = #0;
  1015. var
  1016. Buffer : PWideChar;
  1017. begin
  1018. if Length(aValue)>0 then
  1019. Buffer := PWideChar(@aValue[1])
  1020. else
  1021. Buffer := @NullWideChar;
  1022. SetData(Buffer, False);
  1023. end;
  1024. function TWideStringField.GetDataSize: Integer;
  1025. begin
  1026. Result :=
  1027. (Size + 1) * 2;
  1028. end;
  1029. { ---------------------------------------------------------------------
  1030. TNumericField
  1031. ---------------------------------------------------------------------}
  1032. constructor TNumericField.Create(AOwner: TComponent);
  1033. begin
  1034. Inherited Create(AOwner);
  1035. AlignMent:=taRightJustify;
  1036. end;
  1037. class procedure TNumericField.CheckTypeSize(AValue: Longint);
  1038. begin
  1039. // This procedure is only added because some TDataset descendents have the
  1040. // but that they set the Size property as if it is the DataSize property.
  1041. // To avoid problems with those descendents, allow values <= 16.
  1042. If (AValue>16) Then
  1043. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  1044. end;
  1045. procedure TNumericField.RangeError(AValue, Min, Max: Double);
  1046. begin
  1047. DatabaseErrorFMT(SRangeError,[AValue,Min,Max,FieldName]);
  1048. end;
  1049. procedure TNumericField.SetDisplayFormat(const AValue: string);
  1050. begin
  1051. If FDisplayFormat<>AValue then
  1052. begin
  1053. FDisplayFormat:=AValue;
  1054. PropertyChanged(True);
  1055. end;
  1056. end;
  1057. procedure TNumericField.SetEditFormat(const AValue: string);
  1058. begin
  1059. If FEDitFormat<>AValue then
  1060. begin
  1061. FEDitFormat:=AVAlue;
  1062. PropertyChanged(True);
  1063. end;
  1064. end;
  1065. function TNumericField.GetAsBoolean: Boolean;
  1066. begin
  1067. Result:=GetAsInteger<>0;
  1068. end;
  1069. { ---------------------------------------------------------------------
  1070. TLongintField
  1071. ---------------------------------------------------------------------}
  1072. constructor TLongintField.Create(AOwner: TComponent);
  1073. begin
  1074. Inherited Create(AOwner);
  1075. SetDatatype(ftinteger);
  1076. FMinRange:=Low(LongInt);
  1077. FMaxRange:=High(LongInt);
  1078. FValidchars:=['+','-','0'..'9'];
  1079. end;
  1080. function TLongintField.GetAsFloat: Double;
  1081. begin
  1082. Result:=GetAsLongint;
  1083. end;
  1084. function TLongintField.GetAsLongint: Longint;
  1085. begin
  1086. If Not GetValue(Result) then
  1087. Result:=0;
  1088. end;
  1089. function TLongintField.GetAsVariant: Variant;
  1090. Var L : Longint;
  1091. begin
  1092. If GetValue(L) then
  1093. Result:=L
  1094. else
  1095. Result:=Null;
  1096. end;
  1097. function TLongintField.GetAsString: string;
  1098. Var L : Longint;
  1099. begin
  1100. If GetValue(L) then
  1101. Result:=IntTostr(L)
  1102. else
  1103. Result:='';
  1104. end;
  1105. function TLongintField.GetDataSize: Integer;
  1106. begin
  1107. Result:=SizeOf(Longint);
  1108. end;
  1109. procedure TLongintField.GetText(var AText: string; ADisplayText: Boolean);
  1110. var l : longint;
  1111. fmt : string;
  1112. begin
  1113. Atext:='';
  1114. If Not GetValue(l) then exit;
  1115. If ADisplayText or (FEditFormat='') then
  1116. fmt:=FDisplayFormat
  1117. else
  1118. fmt:=FEditFormat;
  1119. If length(fmt)<>0 then
  1120. AText:=FormatFloat(fmt,L)
  1121. else
  1122. Str(L,AText);
  1123. end;
  1124. function TLongintField.GetValue(var AValue: Longint): Boolean;
  1125. Var L : Longint;
  1126. P : PLongint;
  1127. begin
  1128. P:=@L;
  1129. Result:=GetData(P);
  1130. If Result then
  1131. Case Datatype of
  1132. ftInteger,ftautoinc : AValue:=Plongint(P)^;
  1133. ftword : Avalue:=Pword(P)^;
  1134. ftsmallint : AValue:=PSmallint(P)^;
  1135. end;
  1136. end;
  1137. procedure TLongintField.SetAsFloat(AValue: Double);
  1138. begin
  1139. SetAsLongint(Round(Avalue));
  1140. end;
  1141. procedure TLongintField.SetAsLongint(AValue: Longint);
  1142. begin
  1143. If CheckRange(AValue) then
  1144. SetData(@AValue)
  1145. else
  1146. RangeError(Avalue,FMinrange,FMaxRange);
  1147. end;
  1148. procedure TLongintField.SetVarValue(const AValue: Variant);
  1149. begin
  1150. SetAsLongint(AValue);
  1151. end;
  1152. procedure TLongintField.SetAsString(const AValue: string);
  1153. Var L,Code : longint;
  1154. begin
  1155. If length(AValue)=0 then
  1156. Clear
  1157. else
  1158. begin
  1159. Val(AVAlue,L,Code);
  1160. If Code=0 then
  1161. SetAsLongint(L)
  1162. else
  1163. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  1164. end;
  1165. end;
  1166. Function TLongintField.CheckRange(AValue : longint) : Boolean;
  1167. begin
  1168. result := true;
  1169. if (FMaxValue=0) then
  1170. begin
  1171. if (AValue>FMaxRange) Then result := false;
  1172. end
  1173. else
  1174. if AValue>FMaxValue then result := false;
  1175. if (FMinValue=0) then
  1176. begin
  1177. if (AValue<FMinRange) Then result := false;
  1178. end
  1179. else
  1180. if AValue<FMinValue then result := false;
  1181. end;
  1182. Procedure TLongintField.SetMaxValue (AValue : longint);
  1183. begin
  1184. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1185. FMaxValue:=AValue
  1186. else
  1187. RangeError(AValue,FMinRange,FMaxRange);
  1188. end;
  1189. Procedure TLongintField.SetMinValue (AValue : longint);
  1190. begin
  1191. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1192. FMinValue:=AValue
  1193. else
  1194. RangeError(AValue,FMinRange,FMaxRange);
  1195. end;
  1196. { ---------------------------------------------------------------------
  1197. TLargeintField
  1198. ---------------------------------------------------------------------}
  1199. constructor TLargeintField.Create(AOwner: TComponent);
  1200. begin
  1201. Inherited Create(AOwner);
  1202. SetDatatype(ftLargeint);
  1203. FMinRange:=Low(Largeint);
  1204. FMaxRange:=High(Largeint);
  1205. FValidchars:=['+','-','0'..'9'];
  1206. end;
  1207. function TLargeintField.GetAsFloat: Double;
  1208. begin
  1209. Result:=GetAsLargeint;
  1210. end;
  1211. function TLargeintField.GetAsLargeint: Largeint;
  1212. begin
  1213. If Not GetValue(Result) then
  1214. Result:=0;
  1215. end;
  1216. function TLargeIntField.GetAsVariant: Variant;
  1217. Var L : Largeint;
  1218. begin
  1219. If GetValue(L) then
  1220. Result:=L
  1221. else
  1222. Result:=Null;
  1223. end;
  1224. function TLargeintField.GetAsLongint: Longint;
  1225. begin
  1226. Result:=GetAsLargeint;
  1227. end;
  1228. function TLargeintField.GetAsString: string;
  1229. Var L : Largeint;
  1230. begin
  1231. If GetValue(L) then
  1232. Result:=IntTostr(L)
  1233. else
  1234. Result:='';
  1235. end;
  1236. function TLargeintField.GetDataSize: Integer;
  1237. begin
  1238. Result:=SizeOf(Largeint);
  1239. end;
  1240. procedure TLargeintField.GetText(var AText: string; ADisplayText: Boolean);
  1241. var l : largeint;
  1242. fmt : string;
  1243. begin
  1244. Atext:='';
  1245. If Not GetValue(l) then exit;
  1246. If ADisplayText or (FEditFormat='') then
  1247. fmt:=FDisplayFormat
  1248. else
  1249. fmt:=FEditFormat;
  1250. If length(fmt)<>0 then
  1251. AText:=FormatFloat(fmt,L)
  1252. else
  1253. Str(L,AText);
  1254. end;
  1255. function TLargeintField.GetValue(var AValue: Largeint): Boolean;
  1256. type
  1257. PLargeint = ^Largeint;
  1258. Var P : PLargeint;
  1259. begin
  1260. P:=@AValue;
  1261. Result:=GetData(P);
  1262. end;
  1263. procedure TLargeintField.SetAsFloat(AValue: Double);
  1264. begin
  1265. SetAsLargeint(Round(Avalue));
  1266. end;
  1267. procedure TLargeintField.SetAsLargeint(AValue: Largeint);
  1268. begin
  1269. If CheckRange(AValue) then
  1270. SetData(@AValue)
  1271. else
  1272. RangeError(Avalue,FMinrange,FMaxRange);
  1273. end;
  1274. procedure TLargeintField.SetAsLongint(AValue: Longint);
  1275. begin
  1276. SetAsLargeint(Avalue);
  1277. end;
  1278. procedure TLargeintField.SetAsString(const AValue: string);
  1279. Var L : largeint;
  1280. code : longint;
  1281. begin
  1282. If length(AValue)=0 then
  1283. Clear
  1284. else
  1285. begin
  1286. Val(AVAlue,L,Code);
  1287. If Code=0 then
  1288. SetAsLargeint(L)
  1289. else
  1290. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  1291. end;
  1292. end;
  1293. procedure TLargeintField.SetVarValue(const AValue: Variant);
  1294. begin
  1295. SetAsLargeint(AValue);
  1296. end;
  1297. Function TLargeintField.CheckRange(AValue : largeint) : Boolean;
  1298. begin
  1299. result := true;
  1300. if (FMaxValue=0) then
  1301. begin
  1302. if (AValue>FMaxRange) Then result := false;
  1303. end
  1304. else
  1305. if AValue>FMaxValue then result := false;
  1306. if (FMinValue=0) then
  1307. begin
  1308. if (AValue<FMinRange) Then result := false;
  1309. end
  1310. else
  1311. if AValue<FMinValue then result := false;
  1312. end;
  1313. Procedure TLargeintField.SetMaxValue (AValue : largeint);
  1314. begin
  1315. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1316. FMaxValue:=AValue
  1317. else
  1318. RangeError(AValue,FMinRange,FMaxRange);
  1319. end;
  1320. Procedure TLargeintField.SetMinValue (AValue : largeint);
  1321. begin
  1322. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1323. FMinValue:=AValue
  1324. else
  1325. RangeError(AValue,FMinRange,FMaxRange);
  1326. end;
  1327. { TSmallintField }
  1328. function TSmallintField.GetDataSize: Integer;
  1329. begin
  1330. Result:=SizeOf(SmallInt);
  1331. end;
  1332. constructor TSmallintField.Create(AOwner: TComponent);
  1333. begin
  1334. inherited Create(AOwner);
  1335. SetDataType(ftSmallInt);
  1336. FMinRange:=-32768;
  1337. FMaxRange:=32767;
  1338. end;
  1339. { TWordField }
  1340. function TWordField.GetDataSize: Integer;
  1341. begin
  1342. Result:=SizeOf(Word);
  1343. end;
  1344. constructor TWordField.Create(AOwner: TComponent);
  1345. begin
  1346. inherited Create(AOwner);
  1347. SetDataType(ftWord);
  1348. FMinRange:=0;
  1349. FMaxRange:=65535;
  1350. FValidchars:=['+','0'..'9'];
  1351. end;
  1352. { TAutoIncField }
  1353. constructor TAutoIncField.Create(AOwner: TComponent);
  1354. begin
  1355. Inherited Create(AOWner);
  1356. SetDataType(ftAutoInc);
  1357. FReadOnly:=True;
  1358. FProviderFlags:=FProviderFlags-[pfInUpdate];
  1359. end;
  1360. Procedure TAutoIncField.SetAsLongint(AValue : Longint);
  1361. begin
  1362. DataBaseError(SCantSetAutoIncfields);
  1363. end;
  1364. { TFloatField }
  1365. procedure TFloatField.SetCurrency(const AValue: Boolean);
  1366. begin
  1367. if FCurrency=AValue then exit;
  1368. FCurrency:=AValue;
  1369. end;
  1370. procedure TFloatField.SetPrecision(const AValue: Longint);
  1371. begin
  1372. if (AValue = -1) or (AValue > 1) then
  1373. FPrecision := AValue
  1374. else
  1375. FPrecision := 2;
  1376. end;
  1377. function TFloatField.GetAsFloat: Double;
  1378. begin
  1379. If Not GetData(@Result) Then
  1380. Result:=0.0;
  1381. end;
  1382. function TFloatField.GetAsVariant: Variant;
  1383. Var f : Double;
  1384. begin
  1385. If GetData(@f) then
  1386. Result := f
  1387. else
  1388. Result:=Null;
  1389. end;
  1390. function TFloatField.GetAsLongint: Longint;
  1391. begin
  1392. Result:=Round(GetAsFloat);
  1393. end;
  1394. function TFloatField.GetAsString: string;
  1395. Var R : Double;
  1396. begin
  1397. If GetData(@R) then
  1398. Result:=FloatToStr(R)
  1399. else
  1400. Result:='';
  1401. end;
  1402. function TFloatField.GetDataSize: Integer;
  1403. begin
  1404. Result:=SizeOf(Double);
  1405. end;
  1406. procedure TFloatField.GetText(var TheText: string; ADisplayText: Boolean);
  1407. Var
  1408. fmt : string;
  1409. E : Double;
  1410. Digits : integer;
  1411. ff: TFloatFormat;
  1412. begin
  1413. TheText:='';
  1414. If Not GetData(@E) then exit;
  1415. If ADisplayText or (Length(FEditFormat) = 0) Then
  1416. Fmt:=FDisplayFormat
  1417. else
  1418. Fmt:=FEditFormat;
  1419. Digits := 0;
  1420. if not FCurrency then
  1421. ff := ffGeneral
  1422. else
  1423. begin
  1424. Digits := CurrencyDecimals;
  1425. if ADisplayText then
  1426. ff := ffCurrency
  1427. else
  1428. ff := ffFixed;
  1429. end;
  1430. If fmt<>'' then
  1431. TheText:=FormatFloat(fmt,E)
  1432. else
  1433. TheText:=FloatToStrF(E,ff,FPrecision,Digits);
  1434. end;
  1435. procedure TFloatField.SetAsFloat(AValue: Double);
  1436. begin
  1437. If CheckRange(AValue) then
  1438. SetData(@Avalue)
  1439. else
  1440. RangeError(AValue,FMinValue,FMaxValue);
  1441. end;
  1442. procedure TFloatField.SetAsLongint(AValue: Longint);
  1443. begin
  1444. SetAsFloat(Avalue);
  1445. end;
  1446. procedure TFloatField.SetAsString(const AValue: string);
  1447. Var R : Double;
  1448. begin
  1449. If (AValue='') then
  1450. Clear
  1451. else
  1452. try
  1453. R := StrToFloat(AValue);
  1454. SetAsFloat(R);
  1455. except
  1456. DatabaseErrorFmt(SNotAFloat, [AValue]);
  1457. end;
  1458. end;
  1459. procedure TFloatField.SetVarValue(const AValue: Variant);
  1460. begin
  1461. SetAsFloat(Avalue);
  1462. end;
  1463. constructor TFloatField.Create(AOwner: TComponent);
  1464. begin
  1465. Inherited Create(AOwner);
  1466. SetDatatype(ftfloat);
  1467. FPrecision:=15;
  1468. FValidChars := [DecimalSeparator, '+', '-', '0'..'9', 'E', 'e'];
  1469. end;
  1470. Function TFloatField.CheckRange(AValue : Double) : Boolean;
  1471. begin
  1472. If (FMinValue<>0) or (FmaxValue<>0) then
  1473. Result:=(AValue>=FMinValue) and (AVAlue<=FMAxValue)
  1474. else
  1475. Result:=True;
  1476. end;
  1477. { TCurrencyField }
  1478. Constructor TCurrencyField.Create(AOwner: TComponent);
  1479. begin
  1480. inherited Create(AOwner);
  1481. SetDataType(ftCurrency);
  1482. Currency := True;
  1483. end;
  1484. { TBooleanField }
  1485. function TBooleanField.GetAsBoolean: Boolean;
  1486. var b : wordbool;
  1487. begin
  1488. If GetData(@b) then
  1489. result := b
  1490. else
  1491. Result:=False;
  1492. end;
  1493. function TBooleanField.GetAsVariant: Variant;
  1494. Var b : wordbool;
  1495. begin
  1496. If GetData(@b) then
  1497. Result := b
  1498. else
  1499. Result:=Null;
  1500. end;
  1501. function TBooleanField.GetAsString: string;
  1502. Var B : wordbool;
  1503. begin
  1504. If Getdata(@B) then
  1505. Result:=FDisplays[False,B]
  1506. else
  1507. result:='';
  1508. end;
  1509. function TBooleanField.GetDataSize: Integer;
  1510. begin
  1511. Result:=SizeOf(wordBool);
  1512. end;
  1513. function TBooleanField.GetDefaultWidth: Longint;
  1514. begin
  1515. Result:=Length(FDisplays[false,false]);
  1516. If Result<Length(FDisplays[false,True]) then
  1517. Result:=Length(FDisplays[false,True]);
  1518. end;
  1519. function TBooleanField.GetAsInteger: integer;
  1520. begin
  1521. if GetAsBoolean then
  1522. Result:=1
  1523. else
  1524. Result:=0;
  1525. end;
  1526. procedure TBooleanField.SetAsInteger(AValue: Integer);
  1527. begin
  1528. SetAsBoolean(avalue<>0);
  1529. end;
  1530. procedure TBooleanField.SetAsBoolean(AValue: Boolean);
  1531. var b : wordbool;
  1532. begin
  1533. b := AValue;
  1534. SetData(@b);
  1535. end;
  1536. procedure TBooleanField.SetAsString(const AValue: string);
  1537. Var Temp : string;
  1538. begin
  1539. Temp:=UpperCase(AValue);
  1540. if Temp='' then
  1541. Clear
  1542. else if pos(Temp, FDisplays[True,True])=1 then
  1543. SetAsBoolean(True)
  1544. else if pos(Temp, FDisplays[True,False])=1 then
  1545. SetAsBoolean(False)
  1546. else
  1547. DatabaseErrorFmt(SNotABoolean,[AValue]);
  1548. end;
  1549. procedure TBooleanField.SetVarValue(const AValue: Variant);
  1550. begin
  1551. SetAsBoolean(AValue);
  1552. end;
  1553. constructor TBooleanField.Create(AOwner: TComponent);
  1554. begin
  1555. Inherited Create(AOwner);
  1556. SetDataType(ftBoolean);
  1557. DisplayValues:='True;False';
  1558. end;
  1559. Procedure TBooleanField.SetDisplayValues(const AValue : String);
  1560. Var I : longint;
  1561. begin
  1562. If FDisplayValues<>AValue then
  1563. begin
  1564. I:=Pos(';',AValue);
  1565. If (I<2) or (I=Length(AValue)) then
  1566. DatabaseErrorFmt(SInvalidDisplayValues,[AValue]);
  1567. FdisplayValues:=AValue;
  1568. // Store display values and their uppercase equivalents;
  1569. FDisplays[False,True]:=Copy(AValue,1,I-1);
  1570. FDisplays[True,True]:=UpperCase(FDisplays[False,True]);
  1571. FDisplays[False,False]:=Copy(AValue,I+1,Length(AValue)-i);
  1572. FDisplays[True,False]:=UpperCase(FDisplays[False,False]);
  1573. PropertyChanged(True);
  1574. end;
  1575. end;
  1576. { TDateTimeField }
  1577. procedure TDateTimeField.SetDisplayFormat(const AValue: string);
  1578. begin
  1579. if FDisplayFormat<>AValue then begin
  1580. FDisplayFormat:=AValue;
  1581. PropertyChanged(True);
  1582. end;
  1583. end;
  1584. function TDateTimeField.GetAsDateTime: TDateTime;
  1585. begin
  1586. If Not GetData(@Result,False) then
  1587. Result:=0;
  1588. end;
  1589. procedure TDateTimeField.SetVarValue(const AValue: Variant);
  1590. begin
  1591. SetAsDateTime(AValue);
  1592. end;
  1593. function TDateTimeField.GetAsVariant: Variant;
  1594. Var d : tDateTime;
  1595. begin
  1596. If Getdata(@d,False) then
  1597. Result := d
  1598. else
  1599. Result:=Null;
  1600. end;
  1601. function TDateTimeField.GetAsFloat: Double;
  1602. begin
  1603. Result:=GetAsdateTime;
  1604. end;
  1605. function TDateTimeField.GetAsString: string;
  1606. begin
  1607. GetText(Result,False);
  1608. end;
  1609. function TDateTimeField.GetDataSize: Integer;
  1610. begin
  1611. Result:=SizeOf(TDateTime);
  1612. end;
  1613. procedure TDateTimeField.GetText(var TheText: string; ADisplayText: Boolean);
  1614. Var R : TDateTime;
  1615. F : String;
  1616. begin
  1617. If Not Getdata(@R,False) then
  1618. TheText:=''
  1619. else
  1620. begin
  1621. If (ADisplayText) and (Length(FDisplayFormat)<>0) then
  1622. F:=FDisplayFormat
  1623. else
  1624. Case DataType of
  1625. ftTime : F:=LongTimeFormat;
  1626. ftDate : F:=ShortDateFormat;
  1627. else
  1628. F:='c'
  1629. end;
  1630. TheText:=FormatDateTime(F,R);
  1631. end;
  1632. end;
  1633. procedure TDateTimeField.SetAsDateTime(AValue: TDateTime);
  1634. begin
  1635. SetData(@Avalue,False);
  1636. end;
  1637. procedure TDateTimeField.SetAsFloat(AValue: Double);
  1638. begin
  1639. SetAsDateTime(AValue);
  1640. end;
  1641. procedure TDateTimeField.SetAsString(const AValue: string);
  1642. Var R : TDateTime;
  1643. begin
  1644. if AValue<>'' then
  1645. begin
  1646. R:=StrToDateTime(AVAlue);
  1647. SetData(@R,False);
  1648. end
  1649. else
  1650. SetData(Nil);
  1651. end;
  1652. constructor TDateTimeField.Create(AOwner: TComponent);
  1653. begin
  1654. Inherited Create(AOwner);
  1655. SetDataType(ftDateTime);
  1656. end;
  1657. { TDateField }
  1658. constructor TDateField.Create(AOwner: TComponent);
  1659. begin
  1660. Inherited Create(AOwner);
  1661. SetDataType(ftDate);
  1662. end;
  1663. { TTimeField }
  1664. constructor TTimeField.Create(AOwner: TComponent);
  1665. begin
  1666. Inherited Create(AOwner);
  1667. SetDataType(ftTime);
  1668. end;
  1669. procedure TTimeField.SetAsString(const AValue: string);
  1670. Var R : TDateTime;
  1671. begin
  1672. R:=StrToTime(AVAlue);
  1673. SetData(@R);
  1674. end;
  1675. { TBinaryField }
  1676. class procedure TBinaryField.CheckTypeSize(AValue: Longint);
  1677. begin
  1678. // Just check for really invalid stuff; actual size is
  1679. // dependent on the record...
  1680. If AValue<1 then
  1681. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  1682. end;
  1683. function TBinaryField.GetAsString: string;
  1684. begin
  1685. Setlength(Result,DataSize);
  1686. GetData(Pointer(Result));
  1687. end;
  1688. procedure TBinaryField.GetText(var TheText: string; ADisplayText: Boolean);
  1689. begin
  1690. TheText:=GetAsString;
  1691. end;
  1692. procedure TBinaryField.SetAsString(const AValue: string);
  1693. Var Buf : PChar;
  1694. Allocated : Boolean;
  1695. begin
  1696. Allocated:=False;
  1697. If Length(AVAlue)=DataSize then
  1698. Buf:=PChar(Avalue)
  1699. else
  1700. begin
  1701. GetMem(Buf,DataSize);
  1702. Move(Pchar(Avalue)[0],Buf^,DataSize);
  1703. Allocated:=True;
  1704. end;
  1705. SetData(Buf);
  1706. If Allocated then
  1707. FreeMem(Buf,DataSize);
  1708. end;
  1709. procedure TBinaryField.SetText(const AValue: string);
  1710. begin
  1711. SetAsString(Avalue);
  1712. end;
  1713. procedure TBinaryField.SetVarValue(const AValue: Variant);
  1714. begin
  1715. SetAsString(Avalue);
  1716. end;
  1717. constructor TBinaryField.Create(AOwner: TComponent);
  1718. begin
  1719. Inherited Create(AOwner);
  1720. end;
  1721. { TBytesField }
  1722. function TBytesField.GetDataSize: Integer;
  1723. begin
  1724. Result:=Size;
  1725. end;
  1726. constructor TBytesField.Create(AOwner: TComponent);
  1727. begin
  1728. Inherited Create(AOwner);
  1729. SetDataType(ftBytes);
  1730. Size:=16;
  1731. end;
  1732. { TVarBytesField }
  1733. function TVarBytesField.GetDataSize: Integer;
  1734. begin
  1735. Result:=Size+2;
  1736. end;
  1737. constructor TVarBytesField.Create(AOwner: TComponent);
  1738. begin
  1739. INherited Create(AOwner);
  1740. SetDataType(ftvarbytes);
  1741. Size:=16;
  1742. end;
  1743. { TBCDField }
  1744. class procedure TBCDField.CheckTypeSize(AValue: Longint);
  1745. begin
  1746. If not (AValue in [0..4]) then
  1747. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  1748. end;
  1749. function TBCDField.GetAsCurrency: Currency;
  1750. begin
  1751. if not GetData(@Result) then
  1752. result := 0;
  1753. end;
  1754. function TBCDField.GetAsVariant: Variant;
  1755. Var c : system.Currency;
  1756. begin
  1757. If GetData(@c) then
  1758. Result := c
  1759. else
  1760. Result:=Null;
  1761. end;
  1762. function TBCDField.GetAsFloat: Double;
  1763. begin
  1764. result := GetAsCurrency;
  1765. end;
  1766. function TBCDField.GetAsLongint: Longint;
  1767. begin
  1768. result := round(GetAsCurrency);
  1769. end;
  1770. function TBCDField.GetAsString: string;
  1771. var c : system.currency;
  1772. begin
  1773. If GetData(@C) then
  1774. Result:=CurrToStr(C)
  1775. else
  1776. Result:='';
  1777. end;
  1778. function TBCDField.GetValue(var AValue: Currency): Boolean;
  1779. begin
  1780. Result := GetData(@AValue);
  1781. end;
  1782. function TBCDField.GetDataSize: Integer;
  1783. begin
  1784. result := sizeof(system.currency);
  1785. end;
  1786. function TBCDField.GetDefaultWidth: Longint;
  1787. begin
  1788. if precision > 0 then result := precision
  1789. else result := 10;
  1790. end;
  1791. procedure TBCDField.GetText(var TheText: string; ADisplayText: Boolean);
  1792. var
  1793. c : system.currency;
  1794. fmt: String;
  1795. begin
  1796. if GetData(@C) then begin
  1797. if aDisplayText or (FEditFormat='') then
  1798. fmt := FDisplayFormat
  1799. else
  1800. fmt := FEditFormat;
  1801. if fmt<>'' then
  1802. TheText := FormatFloat(fmt,C)
  1803. else if fCurrency then begin
  1804. if aDisplayText then
  1805. TheText := FloatToStrF(C, ffCurrency, FPrecision, 2{digits?})
  1806. else
  1807. TheText := FloatToStrF(C, ffFixed, FPrecision, 2{digits?});
  1808. end else
  1809. TheText := FloatToStrF(C, ffGeneral, FPrecision, 0{digits?});
  1810. end else
  1811. TheText := '';
  1812. end;
  1813. procedure TBCDField.SetAsCurrency(AValue: Currency);
  1814. begin
  1815. If CheckRange(AValue) then
  1816. setdata(@AValue)
  1817. else
  1818. RangeError(AValue,FMinValue,FMaxvalue);
  1819. end;
  1820. procedure TBCDField.SetVarValue(const AValue: Variant);
  1821. begin
  1822. SetAsCurrency(AValue);
  1823. end;
  1824. Function TBCDField.CheckRange(AValue : Currency) : Boolean;
  1825. begin
  1826. If (FMinValue<>0) or (FmaxValue<>0) then
  1827. Result:=(AValue>=FMinValue) and (AVAlue<=FMaxValue)
  1828. else
  1829. Result:=True;
  1830. end;
  1831. procedure TBCDField.SetAsFloat(AValue: Double);
  1832. begin
  1833. SetAsCurrency(AValue);
  1834. end;
  1835. procedure TBCDField.SetAsLongint(AValue: Longint);
  1836. begin
  1837. SetAsCurrency(AValue);
  1838. end;
  1839. procedure TBCDField.SetAsString(const AValue: string);
  1840. begin
  1841. SetAsCurrency(strtocurr(AValue));
  1842. end;
  1843. constructor TBCDField.Create(AOwner: TComponent);
  1844. begin
  1845. Inherited Create(AOwner);
  1846. FMaxvalue := 0;
  1847. FMinvalue := 0;
  1848. FValidChars := [DecimalSeparator, '+', '-', '0'..'9'];
  1849. SetDataType(ftBCD);
  1850. FPrecision := 15;
  1851. Size:=4;
  1852. end;
  1853. { TFMTBCDField }
  1854. class procedure TFMTBCDField.CheckTypeSize(AValue: Longint);
  1855. begin
  1856. If AValue > MAXFMTBcdFractionSize then
  1857. DatabaseErrorfmt(SInvalidFieldSize,[AValue]);
  1858. end;
  1859. constructor TFMTBCDField.Create(AOwner: TComponent);
  1860. begin
  1861. Inherited Create(AOwner);
  1862. FMaxValue := 0;
  1863. FMinValue := 0;
  1864. FValidChars := [DecimalSeparator, '+', '-', '0'..'9'];
  1865. SetDataType(ftFMTBCD);
  1866. // Max.precision for NUMERIC,DECIMAL datatypes supported by some databases:
  1867. // Firebird-18; Oracle,SqlServer-38; MySQL-65; PostgreSQL-1000
  1868. Precision := 15; //default number of digits
  1869. Size:=4; //default number of digits after decimal place
  1870. end;
  1871. function TFMTBCDField.GetDataSize: Integer;
  1872. begin
  1873. Result := sizeof(TBCD);
  1874. end;
  1875. function TFMTBCDField.GetDefaultWidth: Longint;
  1876. begin
  1877. if Precision > 0 then Result := Precision+1
  1878. else Result := inherited GetDefaultWidth;
  1879. end;
  1880. function TFMTBCDField.GetAsBCD: TBCD;
  1881. begin
  1882. if not GetData(@Result) then
  1883. Result := NullBCD;
  1884. end;
  1885. function TFMTBCDField.GetAsCurrency: Currency;
  1886. var bcd: TBCD;
  1887. begin
  1888. if GetData(@bcd) then
  1889. BCDToCurr(bcd, Result)
  1890. else
  1891. Result := 0;
  1892. end;
  1893. function TFMTBCDField.GetAsVariant: Variant;
  1894. var bcd: TBCD;
  1895. begin
  1896. If GetData(@bcd) then
  1897. Result := VarFMTBcdCreate(bcd)
  1898. else
  1899. Result := Null;
  1900. end;
  1901. function TFMTBCDField.GetAsFloat: Double;
  1902. var bcd: TBCD;
  1903. begin
  1904. If GetData(@bcd) then
  1905. Result := BCDToDouble(bcd)
  1906. else
  1907. Result := 0;
  1908. end;
  1909. function TFMTBCDField.GetAsLongint: Longint;
  1910. begin
  1911. Result := round(GetAsFloat);
  1912. end;
  1913. function TFMTBCDField.GetAsString: string;
  1914. var bcd: TBCD;
  1915. begin
  1916. If GetData(@bcd) then
  1917. Result:=BCDToStr(bcd)
  1918. else
  1919. Result:='';
  1920. end;
  1921. procedure TFMTBCDField.GetText(var TheText: string; ADisplayText: Boolean);
  1922. var
  1923. bcd: TBCD;
  1924. fmt: String;
  1925. begin
  1926. if GetData(@bcd) then begin
  1927. if aDisplayText or (FEditFormat='') then
  1928. fmt := FDisplayFormat
  1929. else
  1930. fmt := FEditFormat;
  1931. if fmt<>'' then
  1932. TheText := BCDToStr(bcd)
  1933. //TheText := FormatBCD(fmt,bcd) //uncomment when formatBCD in fmtbcd.pp will be implemented
  1934. else if fCurrency then begin
  1935. if aDisplayText then
  1936. TheText := BcdToStrF(bcd, ffCurrency, FPrecision, 2)
  1937. else
  1938. TheText := BcdToStrF(bcd, ffFixed, FPrecision, 2);
  1939. end else
  1940. TheText := BcdToStrF(bcd, ffGeneral, FPrecision, FSize);
  1941. end else
  1942. TheText := '';
  1943. end;
  1944. function TFMTBCDField.GetMaxValue: string;
  1945. begin
  1946. Result:=BCDToStr(FMaxValue);
  1947. end;
  1948. function TFMTBCDField.GetMinValue: string;
  1949. begin
  1950. Result:=BCDToStr(FMinValue);
  1951. end;
  1952. procedure TFMTBCDField.SetMaxValue(const AValue: string);
  1953. begin
  1954. FMaxValue:=StrToBCD(AValue);
  1955. end;
  1956. procedure TFMTBCDField.SetMinValue(const AValue: string);
  1957. begin
  1958. FMinValue:=StrToBCD(AValue);
  1959. end;
  1960. Function TFMTBCDField.CheckRange(AValue: TBCD) : Boolean;
  1961. begin
  1962. If (FMinValue<>0) or (FMaxValue<>0) then
  1963. Result:=(AValue>=FMinValue) and (AValue<=FMaxValue)
  1964. else
  1965. Result:=True;
  1966. end;
  1967. procedure TFMTBCDField.SetAsBCD(const AValue: TBCD);
  1968. begin
  1969. if CheckRange(AValue) then
  1970. SetData(@AValue)
  1971. else
  1972. RangeError(AValue, BCDToDouble(FMinValue), BCDToDouble(FMaxValue));
  1973. end;
  1974. procedure TFMTBCDField.SetAsCurrency(AValue: Currency);
  1975. var bcd: TBCD;
  1976. begin
  1977. if CurrToBCD(AValue, bcd, 32, Size) then
  1978. SetAsBCD(bcd);
  1979. end;
  1980. procedure TFMTBCDField.SetVarValue(const AValue: Variant);
  1981. begin
  1982. SetAsBCD(VarToBCD(AValue));
  1983. end;
  1984. procedure TFMTBCDField.SetAsFloat(AValue: Double);
  1985. begin
  1986. SetAsBCD(DoubleToBCD(AValue));
  1987. end;
  1988. procedure TFMTBCDField.SetAsLongint(AValue: Longint);
  1989. begin
  1990. SetAsBCD(IntegerToBCD(AValue));
  1991. end;
  1992. procedure TFMTBCDField.SetAsString(const AValue: string);
  1993. begin
  1994. SetAsBCD(StrToBCD(AValue));
  1995. end;
  1996. { TBlobField }
  1997. Function TBlobField.GetBlobStream(Mode : TBlobStreamMode) : TStream;
  1998. begin
  1999. Result:=FDataset.CreateBlobStream(Self,Mode);
  2000. end;
  2001. procedure TBlobField.FreeBuffers;
  2002. begin
  2003. end;
  2004. function TBlobField.GetAsString: string;
  2005. var
  2006. Stream : TStream;
  2007. Len : Integer;
  2008. begin
  2009. Stream := GetBlobStream(bmRead);
  2010. if Stream <> nil then
  2011. With Stream do
  2012. try
  2013. Len := Size;
  2014. SetLength(Result, Len);
  2015. if Len > 0 then
  2016. ReadBuffer(Result[1], Len);
  2017. finally
  2018. Free
  2019. end
  2020. else
  2021. Result := '';
  2022. end;
  2023. function TBlobField.GetAsWideString: WideString;
  2024. var
  2025. Stream : TStream;
  2026. Len : Integer;
  2027. begin
  2028. Stream := GetBlobStream(bmRead);
  2029. if Stream <> nil then
  2030. With Stream do
  2031. try
  2032. Len := Size;
  2033. SetLength(Result,Len div 2);
  2034. if Len > 0 then
  2035. ReadBuffer(Result[1] ,Len);
  2036. finally
  2037. Free
  2038. end
  2039. else
  2040. Result := '';
  2041. end;
  2042. function TBlobField.GetAsVariant: Variant;
  2043. Var s : string;
  2044. begin
  2045. if not GetIsNull then
  2046. begin
  2047. s := GetAsString;
  2048. result := s;
  2049. end
  2050. else result := Null;
  2051. end;
  2052. function TBlobField.GetBlobSize: Longint;
  2053. var
  2054. Stream: TStream;
  2055. begin
  2056. Stream := GetBlobStream(bmread);
  2057. if Stream <> nil then
  2058. With Stream do
  2059. try
  2060. Result:=Size;
  2061. finally
  2062. Free;
  2063. end
  2064. else
  2065. result := 0;
  2066. end;
  2067. function TBlobField.GetIsNull: Boolean;
  2068. begin
  2069. If Not Modified then
  2070. result:= inherited GetIsnull
  2071. else
  2072. With GetBlobStream(bmread) do
  2073. try
  2074. Result:=(Size=0);
  2075. Finally
  2076. Free;
  2077. end;
  2078. end;
  2079. procedure TBlobField.GetText(var TheText: string; ADisplayText: Boolean);
  2080. begin
  2081. TheText:=inherited GetAsString;
  2082. end;
  2083. procedure TBlobField.SetAsString(const AValue: string);
  2084. var
  2085. Len : Integer;
  2086. begin
  2087. With GetBlobStream(bmwrite) do
  2088. try
  2089. Len := Length(Avalue);
  2090. if Len > 0 then
  2091. WriteBuffer(aValue[1], Len);
  2092. finally
  2093. Free;
  2094. end;
  2095. end;
  2096. procedure TBlobField.SetAsWideString(const AValue: WideString);
  2097. var
  2098. Len : Integer;
  2099. begin
  2100. With GetBlobStream(bmwrite) do
  2101. try
  2102. Len := Length(Avalue) * 2;
  2103. if Len > 0 then
  2104. WriteBuffer(aValue[1], Len);
  2105. finally
  2106. Free;
  2107. end;
  2108. end;
  2109. procedure TBlobField.SetText(const AValue: string);
  2110. begin
  2111. SetAsString(AValue);
  2112. end;
  2113. procedure TBlobField.SetVarValue(const AValue: Variant);
  2114. begin
  2115. SetAsString(AValue);
  2116. end;
  2117. constructor TBlobField.Create(AOwner: TComponent);
  2118. begin
  2119. Inherited Create(AOWner);
  2120. SetDataType(ftBlob);
  2121. end;
  2122. procedure TBlobField.Clear;
  2123. begin
  2124. GetBlobStream(bmWrite).free;
  2125. end;
  2126. class function TBlobField.IsBlob: Boolean;
  2127. begin
  2128. Result:=True;
  2129. end;
  2130. procedure TBlobField.LoadFromFile(const FileName: string);
  2131. Var S : TFileStream;
  2132. begin
  2133. S:=TFileStream.Create(FileName,fmOpenRead);
  2134. try
  2135. LoadFromStream(S);
  2136. finally
  2137. S.Free;
  2138. end;
  2139. end;
  2140. procedure TBlobField.LoadFromStream(Stream: TStream);
  2141. begin
  2142. With GetBlobStream(bmWrite) do
  2143. Try
  2144. CopyFrom(Stream,0);
  2145. finally
  2146. Free;
  2147. end;
  2148. end;
  2149. procedure TBlobField.SaveToFile(const FileName: string);
  2150. Var S : TFileStream;
  2151. begin
  2152. S:=TFileStream.Create(FileName,fmCreate);
  2153. try
  2154. SaveToStream(S);
  2155. finally
  2156. S.Free;
  2157. end;
  2158. end;
  2159. procedure TBlobField.SaveToStream(Stream: TStream);
  2160. Var S : TStream;
  2161. begin
  2162. S:=GetBlobStream(bmRead);
  2163. Try
  2164. If Assigned(S) then
  2165. Stream.CopyFrom(S,0);
  2166. finally
  2167. S.Free;
  2168. end;
  2169. end;
  2170. procedure TBlobField.SetFieldType(AValue: TFieldType);
  2171. begin
  2172. If AValue in [Low(TBlobType)..High(TBlobType)] then
  2173. SetDatatype(Avalue);
  2174. end;
  2175. { TMemoField }
  2176. constructor TMemoField.Create(AOwner: TComponent);
  2177. begin
  2178. Inherited Create(AOwner);
  2179. SetDataType(ftMemo);
  2180. end;
  2181. function TMemoField.GetAsWideString: WideString;
  2182. begin
  2183. Result := GetAsString;
  2184. end;
  2185. procedure TMemoField.SetAsWideString(const aValue: WideString);
  2186. begin
  2187. SetAsString(aValue);
  2188. end;
  2189. { TWideMemoField }
  2190. constructor TWideMemoField.Create(AOwner: TComponent);
  2191. begin
  2192. inherited Create(AOwner);
  2193. SetDataType(ftWideMemo);
  2194. end;
  2195. function TWideMemoField.GetAsString: string;
  2196. begin
  2197. Result := GetAsWideString;
  2198. end;
  2199. procedure TWideMemoField.SetAsString(const aValue: string);
  2200. begin
  2201. SetAsWideString(aValue);
  2202. end;
  2203. function TWideMemoField.GetAsVariant: Variant;
  2204. Var s : string;
  2205. begin
  2206. if not GetIsNull then
  2207. begin
  2208. s := GetAsWideString;
  2209. result := s;
  2210. end
  2211. else result := Null;
  2212. end;
  2213. procedure TWideMemoField.SetVarValue(const AValue: Variant);
  2214. begin
  2215. SetAsWideString(AValue);
  2216. end;
  2217. { TGraphicField }
  2218. constructor TGraphicField.Create(AOwner: TComponent);
  2219. begin
  2220. Inherited Create(AOwner);
  2221. SetDataType(ftGraphic);
  2222. end;
  2223. { TGuidField }
  2224. constructor TGuidField.Create(AOwner: TComponent);
  2225. begin
  2226. Size := 38;
  2227. inherited Create(AOwner);
  2228. SetDataType(ftGuid);
  2229. end;
  2230. class procedure TGuidField.CheckTypeSize(AValue: LongInt);
  2231. begin
  2232. if aValue <> 38 then
  2233. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  2234. end;
  2235. function TGuidField.GetAsGuid: TGUID;
  2236. const
  2237. nullguid: TGUID = '{00000000-0000-0000-0000-000000000000}';
  2238. var
  2239. S: string;
  2240. begin
  2241. S := GetAsString;
  2242. if S = '' then
  2243. Result := nullguid
  2244. else
  2245. Result := StringToGuid(S);
  2246. end;
  2247. function TGuidField.GetDefaultWidth: LongInt;
  2248. begin
  2249. Result := 38;
  2250. end;
  2251. procedure TGuidField.SetAsGuid(const aValue: TGUID);
  2252. begin
  2253. SetAsString(GuidToString(aValue));
  2254. end;
  2255. function TVariantField.GetDefaultWidth: Integer;
  2256. begin
  2257. Result := 15;
  2258. end;
  2259. { TVariantField }
  2260. constructor TVariantField.Create(AOwner: TComponent);
  2261. begin
  2262. inherited Create(AOwner);
  2263. SetDataType(ftVariant);
  2264. end;
  2265. class procedure TVariantField.CheckTypeSize(aValue: Integer);
  2266. begin
  2267. { empty }
  2268. end;
  2269. function TVariantField.GetAsBoolean: Boolean;
  2270. begin
  2271. Result := GetAsVariant;
  2272. end;
  2273. function TVariantField.GetAsDateTime: TDateTime;
  2274. begin
  2275. Result := GetAsVariant;
  2276. end;
  2277. function TVariantField.GetAsFloat: Double;
  2278. begin
  2279. Result := GetAsVariant;
  2280. end;
  2281. function TVariantField.GetAsInteger: Longint;
  2282. begin
  2283. Result := GetAsVariant;
  2284. end;
  2285. function TVariantField.GetAsString: string;
  2286. begin
  2287. Result := VarToStr(GetAsVariant);
  2288. end;
  2289. function TVariantField.GetAsWideString: WideString;
  2290. begin
  2291. Result := VarToWideStr(GetAsVariant);
  2292. end;
  2293. function TVariantField.GetAsVariant: Variant;
  2294. begin
  2295. if not GetData(@Result) then
  2296. Result := Null;
  2297. end;
  2298. procedure TVariantField.SetAsBoolean(aValue: Boolean);
  2299. begin
  2300. SetVarValue(aValue);
  2301. end;
  2302. procedure TVariantField.SetAsDateTime(aValue: TDateTime);
  2303. begin
  2304. SetVarValue(aValue);
  2305. end;
  2306. procedure TVariantField.SetAsFloat(aValue: Double);
  2307. begin
  2308. SetVarValue(aValue);
  2309. end;
  2310. procedure TVariantField.SetAsInteger(aValue: Longint);
  2311. begin
  2312. SetVarValue(aValue);
  2313. end;
  2314. procedure TVariantField.SetAsString(const aValue: string);
  2315. begin
  2316. SetVarValue(aValue);
  2317. end;
  2318. procedure TVariantField.SetAsWideString(const aValue: WideString);
  2319. begin
  2320. SetVarValue(aValue);
  2321. end;
  2322. procedure TVariantField.SetVarValue(const aValue: Variant);
  2323. begin
  2324. SetData(@aValue);
  2325. end;
  2326. { TFieldsEnumerator }
  2327. function TFieldsEnumerator.GetCurrent: TField;
  2328. begin
  2329. Result := FFields[FPosition];
  2330. end;
  2331. constructor TFieldsEnumerator.Create(AFields: TFields);
  2332. begin
  2333. inherited Create;
  2334. FFields := AFields;
  2335. FPosition := -1;
  2336. end;
  2337. function TFieldsEnumerator.MoveNext: Boolean;
  2338. begin
  2339. inc(FPosition);
  2340. Result := FPosition < FFields.Count;
  2341. end;
  2342. { TFields }
  2343. Constructor TFields.Create(ADataset : TDataset);
  2344. begin
  2345. FDataSet:=ADataset;
  2346. FFieldList:=TList.Create;
  2347. FValidFieldKinds:=[fkData..fkInternalcalc];
  2348. end;
  2349. Destructor TFields.Destroy;
  2350. begin
  2351. if FFieldList <> nil then Clear;
  2352. FFieldList.Free;
  2353. inherited Destroy;
  2354. end;
  2355. Procedure Tfields.Changed;
  2356. begin
  2357. if (FDataSet <> nil) and not (csDestroying in FDataSet.ComponentState) and FDataset.Active then
  2358. FDataSet.DataEvent(deFieldListChange, 0);
  2359. If Assigned(FOnChange) then
  2360. FOnChange(Self);
  2361. end;
  2362. Procedure TFields.CheckfieldKind(Fieldkind : TFieldKind; Field : TField);
  2363. begin
  2364. If Not (FieldKind in ValidFieldKinds) Then
  2365. DatabaseErrorFmt(SInvalidFieldKind,[Field.FieldName]);
  2366. end;
  2367. Function Tfields.GetCount : Longint;
  2368. begin
  2369. Result:=FFieldList.Count;
  2370. end;
  2371. Function TFields.GetField (Index : longint) : TField;
  2372. begin
  2373. Result:=Tfield(FFieldList[Index]);
  2374. end;
  2375. procedure Tfields.SetField(Index: Integer; Value: TField);
  2376. begin
  2377. Fields[Index].Assign(Value);
  2378. end;
  2379. Procedure TFields.SetFieldIndex (Field : TField;Value : Integer);
  2380. Var Old : Longint;
  2381. begin
  2382. Old := FFieldList.indexOf(Field);
  2383. If Old=-1 then
  2384. Exit;
  2385. // Check value
  2386. If Value<0 Then Value:=0;
  2387. If Value>=Count then Value:=Count-1;
  2388. If Value<>Old then
  2389. begin
  2390. FFieldList.Delete(Old);
  2391. FFieldList.Insert(Value,Field);
  2392. Field.PropertyChanged(True);
  2393. Changed;
  2394. end;
  2395. end;
  2396. Procedure TFields.Add(Field : TField);
  2397. begin
  2398. CheckFieldName(Field.FieldName);
  2399. FFieldList.Add(Field);
  2400. Field.FFields:=Self;
  2401. Changed;
  2402. end;
  2403. Procedure TFields.CheckFieldName (Const Value : String);
  2404. begin
  2405. If FindField(Value)<>Nil then
  2406. DataBaseErrorFmt(SDuplicateFieldName,[Value],FDataset);
  2407. end;
  2408. Procedure TFields.CheckFieldNames (Const Value : String);
  2409. Var I : longint;
  2410. S,T : String;
  2411. begin
  2412. T:=Value;
  2413. Repeat
  2414. I:=Pos(';',T);
  2415. If I=0 Then I:=Length(T)+1;
  2416. S:=Copy(T,1,I-1);
  2417. Delete(T,1,I);
  2418. // Will raise an error if no such field...
  2419. FieldByName(S);
  2420. Until (T='');
  2421. end;
  2422. Procedure TFields.Clear;
  2423. begin
  2424. with FFieldList do
  2425. while Count > 0 do begin
  2426. TField(Last).FDataSet := Nil;
  2427. TField(Last).Free;
  2428. FFieldList.Delete(Count - 1);
  2429. end;
  2430. Changed;
  2431. end;
  2432. Function TFields.FindField (Const Value : String) : TField;
  2433. Var S : String;
  2434. I : longint;
  2435. begin
  2436. Result:=Nil;
  2437. S:=UpperCase(Value);
  2438. For I:=0 To FFieldList.Count-1 do
  2439. If S=UpperCase(TField(FFieldList[i]).FieldName) Then
  2440. Begin
  2441. {$ifdef dsdebug}
  2442. Writeln ('Found field ',Value);
  2443. {$endif}
  2444. Result:=TField(FFieldList[I]);
  2445. Exit;
  2446. end;
  2447. end;
  2448. Function TFields.FieldByName (Const Value : String) : TField;
  2449. begin
  2450. Result:=FindField(Value);
  2451. If result=Nil then
  2452. DatabaseErrorFmt(SFieldNotFound,[Value],FDataset);
  2453. end;
  2454. Function TFields.FieldByNumber(FieldNo : Integer) : TField;
  2455. Var i : Longint;
  2456. begin
  2457. Result:=Nil;
  2458. For I:=0 to FFieldList.Count-1 do
  2459. If FieldNo=TField(FFieldList[I]).FieldNo then
  2460. begin
  2461. Result:=TField(FFieldList[i]);
  2462. Exit;
  2463. end;
  2464. end;
  2465. Function TFields.GetEnumerator: TFieldsEnumerator;
  2466. begin
  2467. Result:=TFieldsEnumerator.Create(Self);
  2468. end;
  2469. Procedure TFields.GetFieldNames (Values : TStrings);
  2470. Var i : longint;
  2471. begin
  2472. Values.Clear;
  2473. For I:=0 to FFieldList.Count-1 do
  2474. Values.Add(Tfield(FFieldList[I]).FieldName);
  2475. end;
  2476. Function TFields.IndexOf(Field : TField) : Longint;
  2477. begin
  2478. Result:=FFieldList.IndexOf(Field);
  2479. end;
  2480. procedure TFields.Remove(Value : TField);
  2481. begin
  2482. FFieldList.Remove(Value);
  2483. Value.FFields := nil;
  2484. Changed;
  2485. end;