fields.inc 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2014 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. ACodePage: TSystemCodePage);
  31. begin
  32. {$ifdef dsdebug }
  33. Writeln('TFieldDef.Create : ',Aname,'(',AFieldNo,')');
  34. {$endif}
  35. Inherited Create(AOwner);
  36. Name:=Aname;
  37. FDatatype:=ADatatype;
  38. FSize:=ASize;
  39. FRequired:=ARequired;
  40. FPrecision:=-1;
  41. FFieldNo:=AFieldNo;
  42. case FDataType of
  43. ftString, ftFixedChar, ftMemo:
  44. FCodePage := ACodePage;
  45. ftWideString, ftFixedWideChar, ftWideMemo:
  46. FCodePage := CP_UTF16;
  47. else
  48. FCodePage := 0;
  49. end;
  50. end;
  51. destructor TFieldDef.Destroy;
  52. begin
  53. Inherited destroy;
  54. end;
  55. procedure TFieldDef.Assign(APersistent: TPersistent);
  56. var fd: TFieldDef;
  57. begin
  58. fd := nil;
  59. if APersistent is TFieldDef then
  60. fd := APersistent as TFieldDef;
  61. if Assigned(fd) then begin
  62. Collection.BeginUpdate;
  63. try
  64. Name := fd.Name;
  65. DataType := fd.DataType;
  66. Size := fd.Size;
  67. Precision := fd.Precision;
  68. FRequired := fd.Required;
  69. FCodePage := fd.FCodePage;
  70. finally
  71. Collection.EndUpdate;
  72. end;
  73. end
  74. else
  75. inherited Assign(APersistent);
  76. end;
  77. function TFieldDef.CreateField(AOwner: TComponent): TField;
  78. var TheField : TFieldClass;
  79. begin
  80. {$ifdef dsdebug}
  81. Writeln ('Creating field '+FNAME);
  82. {$endif dsdebug}
  83. TheField:=GetFieldClass;
  84. if TheField=Nil then
  85. DatabaseErrorFmt(SUnknownFieldType,[FName]);
  86. Result:=TheField.Create(AOwner);
  87. Try
  88. Result.FFieldDef:=Self;
  89. Result.Size:=FSize;
  90. Result.Required:=FRequired;
  91. Result.FFieldName:=FName;
  92. Result.FDisplayLabel:=DisplayName;
  93. Result.FFieldNo:=Self.FieldNo;
  94. Result.SetFieldType(DataType);
  95. Result.FReadOnly:=(faReadOnly in Attributes);
  96. {$ifdef dsdebug}
  97. Writeln ('TFieldDef.CreateField : Result Fieldno : ',Result.FieldNo,'; Self : ',FieldNo);
  98. Writeln ('TFieldDef.CreateField : Trying to set dataset');
  99. {$endif dsdebug}
  100. Result.Dataset:=TFieldDefs(Collection).Dataset;
  101. if (Result is TStringField) then
  102. TStringField(Result).FCodePage := FCodePage
  103. else if (Result is TMemoField) then
  104. TMemoField(Result).FCodePage := FCodePage
  105. else if (Result is TFloatField) then
  106. TFloatField(Result).Precision := FPrecision
  107. else if (Result is TBCDField) then
  108. TBCDField(Result).Precision := FPrecision
  109. else if (Result is TFmtBCDField) then
  110. TFmtBCDField(Result).Precision := FPrecision;
  111. except
  112. Result.Free;
  113. Raise;
  114. end;
  115. end;
  116. procedure TFieldDef.SetAttributes(AValue: TFieldAttributes);
  117. begin
  118. FAttributes := AValue;
  119. Changed(False);
  120. end;
  121. procedure TFieldDef.SetDataType(AValue: TFieldType);
  122. begin
  123. FDataType := AValue;
  124. Changed(False);
  125. end;
  126. procedure TFieldDef.SetPrecision(const AValue: Longint);
  127. begin
  128. FPrecision := AValue;
  129. Changed(False);
  130. end;
  131. procedure TFieldDef.SetSize(const AValue: Integer);
  132. begin
  133. FSize := AValue;
  134. Changed(False);
  135. end;
  136. procedure TFieldDef.SetRequired(const AValue: Boolean);
  137. begin
  138. FRequired := AValue;
  139. Changed(False);
  140. end;
  141. function TFieldDef.GetFieldClass: TFieldClass;
  142. begin
  143. //!! Should be owner as tdataset but that doesn't work ??
  144. If Assigned(Collection) And
  145. (Collection is TFieldDefs) And
  146. Assigned(TFieldDefs(Collection).Dataset) then
  147. Result:=TFieldDefs(Collection).Dataset.GetFieldClass(FDataType)
  148. else
  149. Result:=Nil;
  150. end;
  151. function TFieldDef.GetCharSize: Word;
  152. begin
  153. case FDataType of
  154. ftGuid:
  155. Result := 1;
  156. ftString, ftFixedChar:
  157. case FCodePage of
  158. CP_UTF8: Result := 4;
  159. else Result := 1;
  160. end;
  161. ftWideString, ftFixedWideChar:
  162. Result := 2;
  163. else
  164. Result := 0;
  165. end;
  166. end;
  167. { ---------------------------------------------------------------------
  168. TFieldDefs
  169. ---------------------------------------------------------------------}
  170. {
  171. destructor TFieldDefs.Destroy;
  172. begin
  173. FItems.Free;
  174. // This will destroy all fielddefs since we own them...
  175. Inherited Destroy;
  176. end;
  177. }
  178. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType);
  179. begin
  180. Add(AName,ADatatype,0,False);
  181. end;
  182. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize : Word);
  183. begin
  184. Add(AName,ADatatype,ASize,False);
  185. end;
  186. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize: Word;
  187. ARequired: Boolean);
  188. begin
  189. If Length(AName)=0 Then
  190. DatabaseError(SNeedFieldName);
  191. // the fielddef will register itself here as an owned component.
  192. // fieldno is 1 based !
  193. BeginUpdate;
  194. try
  195. Add(AName,ADataType,ASize,ARequired,Count+1);
  196. finally
  197. EndUpdate;
  198. end;
  199. end;
  200. function TFieldDefs.GetItem(Index: Longint): TFieldDef;
  201. begin
  202. Result := TFieldDef(inherited Items[Index]);
  203. end;
  204. procedure TFieldDefs.SetItem(Index: Longint; const AValue: TFieldDef);
  205. begin
  206. inherited Items[Index] := AValue;
  207. end;
  208. class function TFieldDefs.FieldDefClass: TFieldDefClass;
  209. begin
  210. Result:=TFieldDef;
  211. end;
  212. constructor TFieldDefs.Create(ADataSet: TDataSet);
  213. begin
  214. Inherited Create(ADataset, Owner, FieldDefClass);
  215. end;
  216. function TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize, APrecision: Integer;
  217. ARequired, AReadOnly: Boolean; AFieldNo: Integer; ACodePage: TSystemCodePage): TFieldDef;
  218. begin
  219. Result:=FieldDefClass.Create(Self, MakeNameUnique(AName), ADataType, ASize, ARequired, AFieldNo, ACodePage);
  220. case ADataType of
  221. ftBCD, ftFmtBCD:
  222. Result.Precision := APrecision;
  223. end;
  224. if AReadOnly then
  225. Result.Attributes := Result.Attributes + [faReadOnly];
  226. end;
  227. function TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize: Word; ARequired: Boolean; AFieldNo: Integer): TFieldDef;
  228. begin
  229. Result:=FieldDefClass.Create(Self,AName,ADataType,ASize,ARequired,AFieldNo);
  230. end;
  231. procedure TFieldDefs.Assign(FieldDefs: TFieldDefs);
  232. var I : longint;
  233. begin
  234. Clear;
  235. For i:=0 to FieldDefs.Count-1 do
  236. With FieldDefs[i] do
  237. Add(Name,DataType,Size,Required);
  238. end;
  239. function TFieldDefs.Find(const AName: string): TFieldDef;
  240. begin
  241. Result := (Inherited Find(AName)) as TFieldDef;
  242. if Result=nil then DatabaseErrorFmt(SFieldNotFound,[AName],FDataset);
  243. end;
  244. {
  245. procedure TFieldDefs.Clear;
  246. var I : longint;
  247. begin
  248. For I:=FItems.Count-1 downto 0 do
  249. TFieldDef(Fitems[i]).Free;
  250. FItems.Clear;
  251. end;
  252. }
  253. procedure TFieldDefs.Update;
  254. begin
  255. if not Updated then
  256. begin
  257. If Assigned(Dataset) then
  258. DataSet.InitFieldDefs;
  259. Updated := True;
  260. end;
  261. end;
  262. function TFieldDefs.MakeNameUnique(const AName: String): string;
  263. var DblFieldCount : integer;
  264. begin
  265. DblFieldCount := 0;
  266. Result := AName;
  267. while assigned(inherited Find(Result)) do
  268. begin
  269. inc(DblFieldCount);
  270. Result := AName + '_' + IntToStr(DblFieldCount);
  271. end;
  272. end;
  273. function TFieldDefs.AddFieldDef: TFieldDef;
  274. begin
  275. Result:=FieldDefClass.Create(Self,'',ftUnknown,0,False,Count+1);
  276. end;
  277. { ---------------------------------------------------------------------
  278. TField
  279. ---------------------------------------------------------------------}
  280. Const
  281. SBCD = 'BCD';
  282. SBoolean = 'Boolean';
  283. SDateTime = 'TDateTime';
  284. SFloat = 'Float';
  285. SInteger = 'Integer';
  286. SLargeInt = 'LargeInt';
  287. SLongWord = 'LongWord';
  288. SVariant = 'Variant';
  289. SString = 'String';
  290. SBytes = 'Bytes';
  291. constructor TField.Create(AOwner: TComponent);
  292. begin
  293. Inherited Create(AOwner);
  294. FVisible:=True;
  295. FValidChars:=[#0..#255];
  296. FProviderFlags := [pfInUpdate,pfInWhere];
  297. end;
  298. destructor TField.Destroy;
  299. begin
  300. IF Assigned(FDataSet) then
  301. begin
  302. FDataSet.Active:=False;
  303. if Assigned(FFields) then
  304. FFields.Remove(Self);
  305. end;
  306. FLookupList.Free;
  307. Inherited Destroy;
  308. end;
  309. function TField.AccessError(const TypeName: string): EDatabaseError;
  310. begin
  311. Result:=EDatabaseError.CreateFmt(SInvalidTypeConversion,[TypeName,FFieldName]);
  312. end;
  313. procedure TField.Assign(Source: TPersistent);
  314. begin
  315. if Source = nil then Clear
  316. else if Source is TField then begin
  317. Value := TField(Source).Value;
  318. end else
  319. inherited Assign(Source);
  320. end;
  321. procedure TField.AssignValue(const AValue: TVarRec);
  322. procedure Error;
  323. begin
  324. DatabaseErrorFmt(SFieldValueError, [DisplayName]);
  325. end;
  326. begin
  327. with AValue do
  328. case VType of
  329. vtInteger:
  330. AsInteger := VInteger;
  331. vtBoolean:
  332. AsBoolean := VBoolean;
  333. vtChar:
  334. AsString := VChar;
  335. vtExtended:
  336. AsFloat := VExtended^;
  337. vtString:
  338. AsString := VString^;
  339. vtPointer:
  340. if VPointer <> nil then Error;
  341. vtPChar:
  342. AsString := VPChar;
  343. vtObject:
  344. if (VObject = nil) or (VObject is TPersistent) then
  345. Assign(TPersistent(VObject))
  346. else
  347. Error;
  348. vtCurrency:
  349. AsCurrency := VCurrency^;
  350. vtVariant:
  351. if not VarIsClear(VVariant^) then Self.Value := VVariant^;
  352. vtAnsiString:
  353. AsAnsiString := AnsiString(VAnsiString);
  354. vtUnicodeString:
  355. AsUnicodeString := UnicodeString(VUnicodeString);
  356. vtWideString:
  357. AsWideString := WideString(VWideString);
  358. vtInt64:
  359. AsLargeInt := VInt64^;
  360. else
  361. Error;
  362. end;
  363. end;
  364. procedure TField.Bind(Binding: Boolean);
  365. begin
  366. if Binding and (FieldKind=fkLookup) then
  367. begin
  368. if ((FLookupDataSet = nil) or (FLookupKeyFields = '') or
  369. (FLookupResultField = '') or (FKeyFields = '')) then
  370. DatabaseErrorFmt(SLookupInfoError, [DisplayName]);
  371. FFields.CheckFieldNames(FKeyFields);
  372. FLookupDataSet.Open;
  373. FLookupDataSet.Fields.CheckFieldNames(FLookupKeyFields);
  374. FLookupDataSet.FieldByName(FLookupResultField);
  375. if FLookupCache then
  376. RefreshLookupList;
  377. end;
  378. end;
  379. procedure TField.Change;
  380. begin
  381. If Assigned(FOnChange) Then
  382. FOnChange(Self);
  383. end;
  384. procedure TField.CheckInactive;
  385. begin
  386. If Assigned(FDataSet) then
  387. FDataset.CheckInactive;
  388. end;
  389. procedure TField.Clear;
  390. begin
  391. SetData(Nil);
  392. end;
  393. procedure TField.DataChanged;
  394. begin
  395. FDataset.DataEvent(deFieldChange,ptrint(Self));
  396. end;
  397. procedure TField.FocusControl;
  398. var
  399. Field1: TField;
  400. begin
  401. Field1 := Self;
  402. FDataSet.DataEvent(deFocusControl,ptrint(@Field1));
  403. end;
  404. procedure TField.FreeBuffers;
  405. begin
  406. // Empty. Provided for backward compatibiliy;
  407. // TDataset manages the buffers.
  408. end;
  409. function TField.GetAsBCD: TBCD;
  410. begin
  411. raise AccessError(SBCD);
  412. end;
  413. function TField.GetAsBoolean: Boolean;
  414. begin
  415. raise AccessError(SBoolean);
  416. end;
  417. function TField.GetAsBytes: TBytes;
  418. begin
  419. Result:=Default(TBytes);
  420. // Writeln('Allocating ',Datasize,' bytes');
  421. SetLength(Result, DataSize);
  422. if assigned(result) and not GetData(@Result[0], False) then
  423. Result := nil;
  424. end;
  425. function TField.GetAsCurrency: Currency;
  426. begin
  427. Result := GetAsFloat;
  428. end;
  429. function TField.GetAsDateTime: TDateTime;
  430. begin
  431. raise AccessError(SdateTime);
  432. end;
  433. function TField.GetAsFloat: Double;
  434. begin
  435. raise AccessError(SDateTime);
  436. end;
  437. function TField.GetAsLargeInt: Largeint;
  438. begin
  439. Raise AccessError(SLargeInt);
  440. end;
  441. function TField.GetAsLongint: Longint;
  442. begin
  443. Result:=GetAsInteger;
  444. end;
  445. function TField.GetAsLongWord: LongWord;
  446. begin
  447. raise AccessError(SLongWord);
  448. end;
  449. function TField.GetAsInteger: Longint;
  450. begin
  451. raise AccessError(SInteger);
  452. end;
  453. function TField.GetAsVariant: variant;
  454. begin
  455. raise AccessError(SVariant);
  456. end;
  457. function TField.GetAsString: string;
  458. begin
  459. Result := GetClassDesc
  460. end;
  461. function TField.GetAsAnsiString: AnsiString;
  462. begin
  463. Result := GetAsString;
  464. end;
  465. function TField.GetAsUnicodeString: UnicodeString;
  466. begin
  467. Result := GetAsString;
  468. end;
  469. function TField.GetAsUTF8String: UTF8String;
  470. begin
  471. Result := GetAsString;
  472. end;
  473. function TField.GetAsWideString: WideString;
  474. begin
  475. Result := GetAsUnicodeString;
  476. end;
  477. function TField.GetOldValue: variant;
  478. var SaveState : TDatasetState;
  479. begin
  480. SaveState := FDataset.State;
  481. try
  482. FDataset.SetTempState(dsOldValue);
  483. Result := GetAsVariant;
  484. finally
  485. FDataset.RestoreState(SaveState);
  486. end;
  487. end;
  488. function TField.GetNewValue: Variant;
  489. var SaveState : TDatasetState;
  490. begin
  491. SaveState := FDataset.State;
  492. try
  493. FDataset.SetTempState(dsNewValue);
  494. Result := GetAsVariant;
  495. finally
  496. FDataset.RestoreState(SaveState);
  497. end;
  498. end;
  499. procedure TField.SetNewValue(const AValue: Variant);
  500. var SaveState : TDatasetState;
  501. begin
  502. SaveState := FDataset.State;
  503. try
  504. FDataset.SetTempState(dsNewValue);
  505. SetAsVariant(AValue);
  506. finally
  507. FDataset.RestoreState(SaveState);
  508. end;
  509. end;
  510. function TField.GetCurValue: Variant;
  511. var SaveState : TDatasetState;
  512. begin
  513. SaveState := FDataset.State;
  514. try
  515. FDataset.SetTempState(dsCurValue);
  516. Result := GetAsVariant;
  517. finally
  518. FDataset.RestoreState(SaveState);
  519. end;
  520. end;
  521. function TField.GetCanModify: Boolean;
  522. begin
  523. Result:=Not ReadOnly;
  524. If Result then
  525. begin
  526. Result := FieldKind in [fkData, fkInternalCalc];
  527. if Result then
  528. begin
  529. Result:=Assigned(DataSet) and Dataset.Active;
  530. If Result then
  531. Result:= DataSet.CanModify;
  532. end;
  533. end;
  534. end;
  535. function TField.GetClassDesc: String;
  536. var ClassN : string;
  537. begin
  538. ClassN := copy(ClassName,2,pos('Field',ClassName)-2);
  539. if isNull then
  540. result := '(' + LowerCase(ClassN) + ')'
  541. else
  542. result := '(' + UpperCase(ClassN) + ')';
  543. end;
  544. function TField.GetData(Buffer: Pointer): Boolean;
  545. begin
  546. Result:=GetData(Buffer,True);
  547. end;
  548. function TField.GetData(Buffer: Pointer; NativeFormat : Boolean): Boolean;
  549. begin
  550. IF FDataset=Nil then
  551. DatabaseErrorFmt(SNoDataset,[FieldName]);
  552. If FValidating then
  553. begin
  554. result:=assigned(FValueBuffer);
  555. If Result and assigned(Buffer) then
  556. Move (FValueBuffer^,Buffer^ ,DataSize);
  557. end
  558. else
  559. Result:=FDataset.GetFieldData(Self,Buffer,NativeFormat);
  560. end;
  561. function TField.GetDataSize: Integer;
  562. begin
  563. Result:=0;
  564. end;
  565. function TField.GetDefaultWidth: Longint;
  566. begin
  567. Result:=10;
  568. end;
  569. function TField.GetDisplayName : String;
  570. begin
  571. If FDisplayLabel<>'' then
  572. result:=FDisplayLabel
  573. else
  574. Result:=FFieldName;
  575. end;
  576. function TField.IsDisplayLabelStored: Boolean;
  577. begin
  578. Result:=(DisplayLabel<>FieldName);
  579. end;
  580. function TField.IsDisplayWidthStored: Boolean;
  581. begin
  582. Result:=(FDisplayWidth<>0);
  583. end;
  584. function TField.GetLookupList: TLookupList;
  585. begin
  586. if not Assigned(FLookupList) then
  587. FLookupList := TLookupList.Create;
  588. Result := FLookupList;
  589. end;
  590. procedure TField.CalcLookupValue;
  591. begin
  592. if FLookupCache then
  593. Value := LookupList.ValueOfKey(FDataSet.FieldValues[FKeyFields])
  594. else if Assigned(FLookupDataSet) and FDataSet.Active then
  595. Value := FLookupDataSet.Lookup(FLookupKeyfields, FDataSet.FieldValues[FKeyFields], FLookupresultField);
  596. end;
  597. function TField.GetIndex: longint;
  598. begin
  599. If Assigned(FDataset) then
  600. Result:=FDataset.FFieldList.IndexOf(Self)
  601. else
  602. Result:=-1;
  603. end;
  604. function TField.GetLookup: Boolean;
  605. begin
  606. Result := FieldKind = fkLookup;
  607. end;
  608. procedure TField.SetAlignment(const AValue: TAlignMent);
  609. begin
  610. if FAlignment <> AValue then
  611. begin
  612. FAlignment := AValue;
  613. PropertyChanged(false);
  614. end;
  615. end;
  616. procedure TField.SetIndex(const AValue: Longint);
  617. begin
  618. if FFields <> nil then FFields.SetFieldIndex(Self, AValue)
  619. end;
  620. procedure TField.SetAsCurrency(AValue: Currency);
  621. begin
  622. SetAsFloat(AValue);
  623. end;
  624. function TField.GetIsNull: Boolean;
  625. begin
  626. Result:=Not(GetData (Nil));
  627. end;
  628. function TField.GetParentComponent: TComponent;
  629. begin
  630. Result := DataSet;
  631. end;
  632. procedure TField.GetText(var AText: string; ADisplayText: Boolean);
  633. begin
  634. AText:=GetAsString;
  635. end;
  636. function TField.HasParent: Boolean;
  637. begin
  638. HasParent:=True;
  639. end;
  640. function TField.IsValidChar(InputChar: Char): Boolean;
  641. begin
  642. // FValidChars must be set in Create.
  643. Result:=InputChar in FValidChars;
  644. end;
  645. procedure TField.RefreshLookupList;
  646. var
  647. tmpActive: Boolean;
  648. begin
  649. if not Assigned(FLookupDataSet) or (Length(FLookupKeyfields) = 0)
  650. or (Length(FLookupresultField) = 0) or (Length(FKeyFields) = 0) then
  651. Exit;
  652. tmpActive := FLookupDataSet.Active;
  653. try
  654. FLookupDataSet.Active := True;
  655. FFields.CheckFieldNames(FKeyFields);
  656. FLookupDataSet.Fields.CheckFieldNames(FLookupKeyFields);
  657. FLookupDataset.FieldByName(FLookupResultField); // I presume that if it doesn't exist it throws exception, and that a field with null value is still valid
  658. LookupList.Clear; // have to be F-less because we might be creating it here with getter!
  659. FLookupDataSet.DisableControls;
  660. try
  661. FLookupDataSet.First;
  662. while not FLookupDataSet.Eof do
  663. begin
  664. FLookupList.Add(FLookupDataSet.FieldValues[FLookupKeyfields], FLookupDataSet.FieldValues[FLookupResultField]);
  665. FLookupDataSet.Next;
  666. end;
  667. finally
  668. FLookupDataSet.EnableControls;
  669. end;
  670. finally
  671. FLookupDataSet.Active := tmpActive;
  672. end;
  673. end;
  674. procedure TField.Notification(AComponent: TComponent; Operation: TOperation);
  675. begin
  676. Inherited Notification(AComponent,Operation);
  677. if (Operation = opRemove) and (AComponent = FLookupDataSet) then
  678. FLookupDataSet := nil;
  679. end;
  680. procedure TField.PropertyChanged(LayoutAffected: Boolean);
  681. begin
  682. If (FDataset<>Nil) and (FDataset.Active) then
  683. If LayoutAffected then
  684. FDataset.DataEvent(deLayoutChange,0)
  685. else
  686. FDataset.DataEvent(deDatasetchange,0);
  687. end;
  688. procedure TField.ReadState(Reader: TReader);
  689. begin
  690. inherited ReadState(Reader);
  691. if Reader.Parent is TDataSet then
  692. DataSet := TDataSet(Reader.Parent);
  693. end;
  694. procedure TField.SetAsBCD(const AValue: TBCD);
  695. begin
  696. Raise AccessError(SBCD);
  697. end;
  698. procedure TField.SetAsBytes(const AValue: TBytes);
  699. begin
  700. raise AccessError(SBytes);
  701. end;
  702. procedure TField.SetAsBoolean(AValue: Boolean);
  703. begin
  704. Raise AccessError(SBoolean);
  705. end;
  706. procedure TField.SetAsDateTime(AValue: TDateTime);
  707. begin
  708. Raise AccessError(SDateTime);
  709. end;
  710. procedure TField.SetAsFloat(AValue: Double);
  711. begin
  712. Raise AccessError(SFloat);
  713. end;
  714. procedure TField.SetAsVariant(const AValue: variant);
  715. begin
  716. if VarIsNull(AValue) then
  717. Clear
  718. else
  719. try
  720. SetVarValue(AValue);
  721. except
  722. on EVariantError do
  723. DatabaseErrorFmt(SFieldError+SInvalidVariant, [DisplayName]);
  724. end;
  725. end;
  726. procedure TField.SetAsLongint(AValue: Longint);
  727. begin
  728. SetAsInteger(AValue);
  729. end;
  730. procedure TField.SetAsLongWord(AValue: LongWord);
  731. begin
  732. raise AccessError(SLongWord);
  733. end;
  734. procedure TField.SetAsInteger(AValue: Longint);
  735. begin
  736. raise AccessError(SInteger);
  737. end;
  738. procedure TField.SetAsLargeInt(AValue: Largeint);
  739. begin
  740. Raise AccessError(SLargeInt);
  741. end;
  742. procedure TField.SetAsString(const AValue: string);
  743. begin
  744. Raise AccessError(SString);
  745. end;
  746. procedure TField.SetAsAnsiString(const AValue: AnsiString);
  747. begin
  748. SetAsString(AValue);
  749. end;
  750. procedure TField.SetAsUnicodeString(const AValue: UnicodeString);
  751. begin
  752. SetAsString(AValue);
  753. end;
  754. procedure TField.SetAsUTF8String(const AValue: UTF8String);
  755. begin
  756. SetAsString(AValue);
  757. end;
  758. procedure TField.SetAsWideString(const AValue: WideString);
  759. begin
  760. SetAsUnicodeString(AValue);
  761. end;
  762. procedure TField.SetData(Buffer: Pointer);
  763. begin
  764. SetData(Buffer,True);
  765. end;
  766. procedure TField.SetData(Buffer: Pointer; NativeFormat : Boolean);
  767. begin
  768. If Not Assigned(FDataset) then
  769. DatabaseErrorFmt(SNoDataset,[DisplayName]);
  770. FDataSet.SetFieldData(Self,Buffer, NativeFormat);
  771. end;
  772. procedure TField.SetDataset(AValue: TDataset);
  773. begin
  774. {$ifdef dsdebug}
  775. Writeln ('Setting dataset');
  776. {$endif}
  777. If AValue=FDataset then exit;
  778. If Assigned(FDataset) Then
  779. begin
  780. FDataset.CheckInactive;
  781. FDataset.FFieldList.Remove(Self);
  782. end;
  783. If Assigned(AValue) then
  784. begin
  785. AValue.CheckInactive;
  786. AValue.FFieldList.Add(Self);
  787. end;
  788. FDataset:=AValue;
  789. end;
  790. procedure TField.SetDataType(AValue: TFieldType);
  791. begin
  792. FDataType := AValue;
  793. end;
  794. procedure TField.SetFieldType(AValue: TFieldType);
  795. begin
  796. { empty }
  797. end;
  798. procedure TField.SetParentComponent(AParent: TComponent);
  799. begin
  800. if not (csLoading in ComponentState) then
  801. DataSet := AParent as TDataSet;
  802. end;
  803. procedure TField.SetSize(AValue: Integer);
  804. begin
  805. CheckInactive;
  806. CheckTypeSize(AValue);
  807. FSize:=AValue;
  808. end;
  809. procedure TField.SetText(const AValue: string);
  810. begin
  811. SetAsString(AValue);
  812. end;
  813. procedure TField.SetVarValue(const AValue: Variant);
  814. begin
  815. Raise AccessError(SVariant);
  816. end;
  817. procedure TField.Validate(Buffer: Pointer);
  818. begin
  819. If assigned(OnValidate) Then
  820. begin
  821. FValueBuffer:=Buffer;
  822. FValidating:=True;
  823. Try
  824. OnValidate(Self);
  825. finally
  826. FValidating:=False;
  827. end;
  828. end;
  829. end;
  830. class function TField.IsBlob: Boolean;
  831. begin
  832. Result:=False;
  833. end;
  834. class procedure TField.CheckTypeSize(AValue: Longint);
  835. begin
  836. If (AValue<>0) and Not IsBlob Then
  837. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  838. end;
  839. // TField private methods
  840. procedure TField.SetEditText(const AValue: string);
  841. begin
  842. if Assigned(OnSetText) then
  843. OnSetText(Self, AValue)
  844. else
  845. SetText(AValue);
  846. end;
  847. function TField.GetEditText: String;
  848. begin
  849. SetLength(Result, 0);
  850. if Assigned(OnGetText) then
  851. OnGetText(Self, Result, False)
  852. else
  853. GetText(Result, False);
  854. end;
  855. function TField.GetDisplayText: String;
  856. begin
  857. SetLength(Result, 0);
  858. if Assigned(OnGetText) then
  859. OnGetText(Self, Result, True)
  860. else
  861. GetText(Result, True);
  862. end;
  863. procedure TField.SetDisplayLabel(const AValue: string);
  864. begin
  865. if FDisplayLabel<>AValue then
  866. begin
  867. FDisplayLabel:=AValue;
  868. PropertyChanged(true);
  869. end;
  870. end;
  871. procedure TField.SetDisplayWidth(const AValue: Longint);
  872. begin
  873. if FDisplayWidth<>AValue then
  874. begin
  875. FDisplayWidth:=AValue;
  876. PropertyChanged(True);
  877. end;
  878. end;
  879. function TField.GetDisplayWidth: integer;
  880. begin
  881. if FDisplayWidth=0 then
  882. result:=GetDefaultWidth
  883. else
  884. result:=FDisplayWidth;
  885. end;
  886. procedure TField.SetLookup(const AValue: Boolean);
  887. const
  888. ValueToLookupMap: array[Boolean] of TFieldKind = (fkData, fkLookup);
  889. begin
  890. FieldKind := ValueToLookupMap[AValue];
  891. end;
  892. procedure TField.SetReadOnly(const AValue: Boolean);
  893. begin
  894. if (FReadOnly<>AValue) then
  895. begin
  896. FReadOnly:=AValue;
  897. PropertyChanged(True);
  898. end;
  899. end;
  900. procedure TField.SetVisible(const AValue: Boolean);
  901. begin
  902. if FVisible<>AValue then
  903. begin
  904. FVisible:=AValue;
  905. PropertyChanged(True);
  906. end;
  907. end;
  908. { ---------------------------------------------------------------------
  909. TStringField
  910. ---------------------------------------------------------------------}
  911. constructor TStringField.Create(AOwner: TComponent);
  912. begin
  913. Inherited Create(AOwner);
  914. SetDataType(ftString);
  915. FCodePage := CP_ACP;
  916. FFixedChar := False;
  917. FTransliterate := False;
  918. FSize := 20;
  919. end;
  920. procedure TStringField.SetFieldType(AValue: TFieldType);
  921. begin
  922. if AValue in [ftString, ftFixedChar] then
  923. SetDataType(AValue);
  924. end;
  925. class procedure TStringField.CheckTypeSize(AValue: Longint);
  926. begin
  927. // A size of 0 is allowed, since for example Firebird allows
  928. // a query like: 'select '' as fieldname from table' which
  929. // results in a string with size 0.
  930. If (AValue<0) Then
  931. DatabaseErrorFmt(SInvalidFieldSize,[AValue])
  932. end;
  933. function TStringField.GetAsBoolean: Boolean;
  934. var S : String;
  935. begin
  936. S:=GetAsString;
  937. result := (Length(S)>0) and (Upcase(S[1]) in ['T',YesNoChars[True]]);
  938. end;
  939. function TStringField.GetAsDateTime: TDateTime;
  940. begin
  941. Result:=StrToDateTime(GetAsString);
  942. end;
  943. function TStringField.GetAsFloat: Double;
  944. begin
  945. Result:=StrToFloat(GetAsString);
  946. end;
  947. function TStringField.GetAsInteger: Longint;
  948. begin
  949. Result:=StrToInt(GetAsString);
  950. end;
  951. function TStringField.GetAsLargeInt: Largeint;
  952. begin
  953. Result:=StrToInt64(GetAsString);
  954. end;
  955. function TStringField.GetAsLongWord: LongWord;
  956. begin
  957. Result:=StrToDWord(GetAsString);
  958. end;
  959. function TStringField.GetAsString: String;
  960. begin
  961. {$IFDEF UNICODE}
  962. Result := GetAsAnsiString;
  963. {$ELSE}
  964. if GetValue(RawByteString(Result)) then
  965. SetCodePage(RawByteString(Result), CP_ACP, True)
  966. else
  967. Result:='';
  968. {$ENDIF}
  969. end;
  970. function TStringField.GetAsAnsiString: AnsiString;
  971. begin
  972. if GetValue(RawByteString(Result)) then
  973. SetCodePage(RawByteString(Result), CP_ACP, True)
  974. else
  975. Result:='';
  976. end;
  977. function TStringField.GetAsUTF8String: UTF8String;
  978. begin
  979. if GetValue(RawByteString(Result)) then
  980. SetCodePage(RawByteString(Result), CP_UTF8, True)
  981. else
  982. Result:='';
  983. end;
  984. function TStringField.GetAsVariant: variant;
  985. var s : rawbytestring;
  986. begin
  987. If GetValue(s) then
  988. begin
  989. SetCodePage(s, CP_ACP, True);
  990. Result:=s
  991. end
  992. else
  993. Result:=Null;
  994. end;
  995. function TStringField.GetDataSize: Integer;
  996. begin
  997. case FCodePage of
  998. CP_UTF8: Result := 4*Size+1;
  999. else Result := Size+1;
  1000. end;
  1001. end;
  1002. function TStringField.GetDefaultWidth: Longint;
  1003. begin
  1004. result:=Size;
  1005. end;
  1006. procedure TStringField.GetText(var AText: string; ADisplayText: Boolean);
  1007. begin
  1008. AText:=GetAsString;
  1009. end;
  1010. function TStringField.GetValue(out AValue: RawByteString): Boolean;
  1011. var Buf, TBuf : TStringFieldBuffer;
  1012. DynBuf, TDynBuf : Array of AnsiChar;
  1013. begin
  1014. if DataSize <= dsMaxStringSize then
  1015. begin
  1016. Result:=GetData(@Buf);
  1017. Buf[DataSize-1]:=#0; //limit string to Size
  1018. If Result then
  1019. begin
  1020. if Transliterate then
  1021. begin
  1022. DataSet.Translate(Buf,TBuf,False);
  1023. AValue:=TBuf;
  1024. end
  1025. else
  1026. AValue:=Buf
  1027. end
  1028. end
  1029. else
  1030. begin
  1031. SetLength(DynBuf,DataSize);
  1032. Result:=GetData(@DynBuf[0]);
  1033. DynBuf[DataSize-1]:=#0; //limit string to Size
  1034. If Result then
  1035. begin
  1036. if Transliterate then
  1037. begin
  1038. SetLength(TDynBuf,DataSize);
  1039. DataSet.Translate(@DynBuf[0],@TDynBuf[0],False);
  1040. AValue:=PAnsiChar(TDynBuf);
  1041. end
  1042. else
  1043. AValue:=PAnsiChar(DynBuf);
  1044. end
  1045. end;
  1046. SetCodePage(AValue, FCodePage, False);
  1047. end;
  1048. procedure TStringField.SetAsBoolean(AValue: Boolean);
  1049. begin
  1050. If AValue Then
  1051. SetAsString('T')
  1052. else
  1053. SetAsString('F');
  1054. end;
  1055. procedure TStringField.SetAsDateTime(AValue: TDateTime);
  1056. begin
  1057. SetAsString(DateTimeToStr(AValue));
  1058. end;
  1059. procedure TStringField.SetAsFloat(AValue: Double);
  1060. begin
  1061. SetAsString(FloatToStr(AValue));
  1062. end;
  1063. procedure TStringField.SetAsInteger(AValue: Longint);
  1064. begin
  1065. SetAsString(IntToStr(AValue));
  1066. end;
  1067. procedure TStringField.SetAsLargeInt(AValue: Largeint);
  1068. begin
  1069. SetAsString(IntToStr(AValue));
  1070. end;
  1071. procedure TStringField.SetAsLongWord(AValue: LongWord);
  1072. begin
  1073. SetAsString(IntToStr(AValue));
  1074. end;
  1075. procedure TStringField.SetValue(AValue: RawByteString);
  1076. var Buf : TStringFieldBuffer;
  1077. DynBuf : array of AnsiChar;
  1078. begin
  1079. if AValue='' then
  1080. begin
  1081. Buf := #0;
  1082. SetData(@Buf);
  1083. end
  1084. else
  1085. begin
  1086. if StringCodePage(AValue) <> FCodePage then
  1087. SetCodePage(AValue, FCodePage, FCodePage<>CP_NONE);
  1088. if DataSize <= dsMaxStringSize then
  1089. begin
  1090. if FTransliterate then
  1091. DataSet.Translate(@AValue[1],Buf,True)
  1092. else
  1093. // The data is copied into the buffer, since some TDataset descendents copy
  1094. // the whole buffer-length in SetData. (See bug 8477)
  1095. StrPLCopy(PAnsiChar(Buf), AValue, DataSize-1);
  1096. // If length(AValue) > Size the buffer isn't terminated properly ?
  1097. Buf[DataSize-1] := #0;
  1098. SetData(@Buf);
  1099. end
  1100. else
  1101. begin
  1102. SetLength(DynBuf, DataSize);
  1103. if FTransliterate then
  1104. DataSet.Translate(@AValue[1],@DynBuf[0],True)
  1105. else
  1106. StrPLCopy(PAnsiChar(DynBuf), AValue, DataSize-1);
  1107. SetData(@DynBuf[0]);
  1108. end;
  1109. end;
  1110. end;
  1111. procedure TStringField.SetAsString(const AValue: String);
  1112. begin
  1113. {$IFDEF UNICODE}
  1114. SetAsAnsiString(AValue);
  1115. {$ELSE}
  1116. SetValue(AValue);
  1117. {$ENDIF}
  1118. end;
  1119. procedure TStringField.SetAsAnsiString(const AValue: AnsiString);
  1120. begin
  1121. SetValue(AValue);
  1122. end;
  1123. procedure TStringField.SetAsUTF8String(const AValue: UTF8String);
  1124. begin
  1125. SetValue(AValue);
  1126. end;
  1127. procedure TStringField.SetVarValue(const AValue: Variant);
  1128. begin
  1129. SetAsString(AValue);
  1130. end;
  1131. { ---------------------------------------------------------------------
  1132. TWideStringField
  1133. ---------------------------------------------------------------------}
  1134. class procedure TWideStringField.CheckTypeSize(AValue: Integer);
  1135. begin
  1136. // A size of 0 is allowed, since for example Firebird allows
  1137. // a query like: 'select '' as fieldname from table' which
  1138. // results in a string with size 0.
  1139. If (AValue<0) Then
  1140. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  1141. end;
  1142. constructor TWideStringField.Create(AOwner: TComponent);
  1143. begin
  1144. inherited Create(AOwner);
  1145. SetDataType(ftWideString);
  1146. FCodePage := CP_UTF16;
  1147. end;
  1148. procedure TWideStringField.SetFieldType(AValue: TFieldType);
  1149. begin
  1150. if AValue in [ftWideString, ftFixedWideChar] then
  1151. SetDataType(AValue);
  1152. end;
  1153. function TWideStringField.GetValue(out AValue: UnicodeString): Boolean;
  1154. var
  1155. FixBuffer : array[0..dsMaxStringSize div 2] of UnicodeChar;
  1156. DynBuffer : array of UnicodeChar;
  1157. Buffer : PUnicodeChar;
  1158. begin
  1159. if DataSize <= dsMaxStringSize then begin
  1160. Result := GetData(@FixBuffer, False);
  1161. FixBuffer[Size]:=#0; //limit string to Size
  1162. AValue := FixBuffer;
  1163. end else begin
  1164. SetLength(DynBuffer, Succ(Size));
  1165. Buffer := PUnicodeChar(DynBuffer);
  1166. Result := GetData(Buffer, False);
  1167. Buffer[Size]:=#0; //limit string to Size
  1168. if Result then
  1169. AValue := Buffer;
  1170. end;
  1171. end;
  1172. function TWideStringField.GetAsString: string;
  1173. begin
  1174. {$IFDEF UNICODE}
  1175. if not GetValue(Result) then
  1176. Result := '';
  1177. {$ELSE}
  1178. Result := GetAsUnicodeString;
  1179. {$ENDIF}
  1180. end;
  1181. procedure TWideStringField.SetAsString(const AValue: string);
  1182. begin
  1183. SetAsUnicodeString(AValue);
  1184. end;
  1185. function TWideStringField.GetAsUnicodeString: UnicodeString;
  1186. begin
  1187. if not GetValue(Result) then
  1188. Result := '';
  1189. end;
  1190. procedure TWideStringField.SetAsUnicodeString(const AValue: UnicodeString);
  1191. const
  1192. NullUnicodeChar : UnicodeChar = #0;
  1193. var
  1194. Buffer : PUnicodeChar;
  1195. begin
  1196. if Length(AValue)>0 then
  1197. Buffer := PUnicodeChar(@AValue[1])
  1198. else
  1199. Buffer := @NullUnicodeChar;
  1200. SetData(Buffer, False);
  1201. end;
  1202. function TWideStringField.GetAsVariant: Variant;
  1203. var us: UnicodeString;
  1204. begin
  1205. if GetValue(us) then
  1206. Result := us
  1207. else
  1208. Result := Null;
  1209. end;
  1210. procedure TWideStringField.SetVarValue(const AValue: Variant);
  1211. begin
  1212. SetAsWideString(AValue);
  1213. end;
  1214. function TWideStringField.GetAsWideString: WideString;
  1215. var us: UnicodeString;
  1216. begin
  1217. if GetValue(us) then
  1218. Result := us
  1219. else
  1220. Result := '';
  1221. end;
  1222. procedure TWideStringField.SetAsWideString(const AValue: WideString);
  1223. begin
  1224. SetAsUnicodeString(AValue);
  1225. end;
  1226. function TWideStringField.GetAsUTF8String: UTF8String;
  1227. begin
  1228. Result := GetAsUnicodeString;
  1229. end;
  1230. procedure TWideStringField.SetAsUTF8String(const AValue: UTF8String);
  1231. begin
  1232. SetAsUnicodeString(AValue);
  1233. end;
  1234. function TWideStringField.GetDataSize: Integer;
  1235. begin
  1236. Result := (Size + 1) * 2;
  1237. end;
  1238. { ---------------------------------------------------------------------
  1239. TNumericField
  1240. ---------------------------------------------------------------------}
  1241. constructor TNumericField.Create(AOwner: TComponent);
  1242. begin
  1243. Inherited Create(AOwner);
  1244. AlignMent:=taRightJustify;
  1245. end;
  1246. class procedure TNumericField.CheckTypeSize(AValue: Longint);
  1247. begin
  1248. // This procedure is only added because some TDataset descendents have the
  1249. // but that they set the Size property as if it is the DataSize property.
  1250. // To avoid problems with those descendents, allow values <= 16.
  1251. If (AValue>16) Then
  1252. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  1253. end;
  1254. procedure TNumericField.RangeError(AValue, Min, Max: Double);
  1255. begin
  1256. DatabaseErrorFmt(SFieldError+SRangeError2,[DisplayName,AValue,Min,Max]);
  1257. end;
  1258. procedure TNumericField.SetDisplayFormat(const AValue: string);
  1259. begin
  1260. If FDisplayFormat<>AValue then
  1261. begin
  1262. FDisplayFormat:=AValue;
  1263. PropertyChanged(True);
  1264. end;
  1265. end;
  1266. procedure TNumericField.SetEditFormat(const AValue: string);
  1267. begin
  1268. If FEditFormat<>AValue then
  1269. begin
  1270. FEditFormat:=AValue;
  1271. PropertyChanged(True);
  1272. end;
  1273. end;
  1274. function TNumericField.GetAsBoolean: Boolean;
  1275. begin
  1276. Result:=GetAsInteger<>0;
  1277. end;
  1278. procedure TNumericField.SetAsBoolean(AValue: Boolean);
  1279. begin
  1280. SetAsInteger(ord(AValue));
  1281. end;
  1282. { ---------------------------------------------------------------------
  1283. TLongintField
  1284. ---------------------------------------------------------------------}
  1285. constructor TLongintField.Create(AOwner: TComponent);
  1286. begin
  1287. Inherited Create(AOwner);
  1288. SetDataType(ftInteger);
  1289. FMinRange:=Low(LongInt);
  1290. FMaxRange:=High(LongInt);
  1291. FValidchars:=['+','-','0'..'9'];
  1292. end;
  1293. function TLongintField.GetAsFloat: Double;
  1294. begin
  1295. Result:=GetAsInteger;
  1296. end;
  1297. function TLongintField.GetAsLargeInt: Largeint;
  1298. begin
  1299. Result:=GetAsInteger;
  1300. end;
  1301. function TLongintField.GetAsInteger: Longint;
  1302. begin
  1303. If Not GetValue(Result) then
  1304. Result:=0;
  1305. end;
  1306. function TLongintField.GetAsLongWord: LongWord;
  1307. begin
  1308. Result:=GetAsInteger;
  1309. end;
  1310. function TLongintField.GetAsVariant: Variant;
  1311. var L : Longint;
  1312. begin
  1313. If GetValue(L) then
  1314. Result:=L
  1315. else
  1316. Result:=Null;
  1317. end;
  1318. function TLongintField.GetAsString: string;
  1319. var L : Longint;
  1320. begin
  1321. If GetValue(L) then
  1322. Result:=IntTostr(L)
  1323. else
  1324. Result:='';
  1325. end;
  1326. function TLongintField.GetDataSize: Integer;
  1327. begin
  1328. Result:=SizeOf(Longint);
  1329. end;
  1330. procedure TLongintField.GetText(var AText: string; ADisplayText: Boolean);
  1331. var l : longint;
  1332. fmt : string;
  1333. begin
  1334. AText:='';
  1335. If Not GetValue(l) then exit;
  1336. If ADisplayText or (FEditFormat='') then
  1337. fmt:=FDisplayFormat
  1338. else
  1339. fmt:=FEditFormat;
  1340. If length(fmt)<>0 then
  1341. AText:=FormatFloat(fmt,L)
  1342. else
  1343. Str(L,AText);
  1344. end;
  1345. function TLongintField.GetValue(var AValue: Longint): Boolean;
  1346. var L : Longint;
  1347. P : PLongint;
  1348. begin
  1349. L:=0;
  1350. P:=@L;
  1351. Result:=GetData(P);
  1352. If Result then
  1353. Case DataType of
  1354. ftInteger,ftAutoInc : AValue:=PLongint(P)^;
  1355. ftWord : AValue:=PWord(P)^;
  1356. ftSmallint : AValue:=PSmallint(P)^;
  1357. end;
  1358. end;
  1359. procedure TLongintField.SetAsLargeInt(AValue: Largeint);
  1360. begin
  1361. if (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1362. SetAsInteger(AValue)
  1363. else
  1364. RangeError(AValue,FMinRange,FMaxRange);
  1365. end;
  1366. procedure TLongintField.SetAsFloat(AValue: Double);
  1367. begin
  1368. SetAsInteger(Round(AValue));
  1369. end;
  1370. procedure TLongintField.SetAsInteger(AValue: Longint);
  1371. begin
  1372. If CheckRange(AValue) then
  1373. SetData(@AValue)
  1374. else
  1375. if (FMinValue<>0) or (FMaxValue<>0) then
  1376. RangeError(AValue,FMinValue,FMaxValue)
  1377. else
  1378. RangeError(AValue,FMinRange,FMaxRange);
  1379. end;
  1380. procedure TLongintField.SetAsLongWord(AValue: LongWord);
  1381. begin
  1382. SetAsInteger(AValue);
  1383. end;
  1384. procedure TLongintField.SetVarValue(const AValue: Variant);
  1385. begin
  1386. SetAsInteger(AValue);
  1387. end;
  1388. procedure TLongintField.SetAsString(const AValue: string);
  1389. var L,Code : longint;
  1390. begin
  1391. If length(AValue)=0 then
  1392. Clear
  1393. else
  1394. begin
  1395. Val(AValue,L,Code);
  1396. If Code=0 then
  1397. SetAsInteger(L)
  1398. else
  1399. DatabaseErrorFmt(SFieldError+SNotAnInteger,[DisplayName,AValue]);
  1400. end;
  1401. end;
  1402. Function TLongintField.CheckRange(AValue : longint) : Boolean;
  1403. begin
  1404. if (FMinValue<>0) or (FMaxValue<>0) then
  1405. Result := (AValue>=FMinValue) and (AValue<=FMaxValue)
  1406. else
  1407. Result := (AValue>=FMinRange) and (AValue<=FMaxRange);
  1408. end;
  1409. Procedure TLongintField.SetMaxValue (AValue : longint);
  1410. begin
  1411. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1412. FMaxValue:=AValue
  1413. else
  1414. RangeError(AValue,FMinRange,FMaxRange);
  1415. end;
  1416. Procedure TLongintField.SetMinValue (AValue : longint);
  1417. begin
  1418. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1419. FMinValue:=AValue
  1420. else
  1421. RangeError(AValue,FMinRange,FMaxRange);
  1422. end;
  1423. { TSmallintField }
  1424. function TSmallintField.GetDataSize: Integer;
  1425. begin
  1426. Result:=SizeOf(SmallInt);
  1427. end;
  1428. constructor TSmallintField.Create(AOwner: TComponent);
  1429. begin
  1430. inherited Create(AOwner);
  1431. SetDataType(ftSmallInt);
  1432. FMinRange:=-32768;
  1433. FMaxRange:=32767;
  1434. end;
  1435. { TWordField }
  1436. function TWordField.GetDataSize: Integer;
  1437. begin
  1438. Result:=SizeOf(Word);
  1439. end;
  1440. constructor TWordField.Create(AOwner: TComponent);
  1441. begin
  1442. inherited Create(AOwner);
  1443. SetDataType(ftWord);
  1444. FMinRange:=0;
  1445. FMaxRange:=65535;
  1446. FValidchars:=['+','0'..'9'];
  1447. end;
  1448. { TAutoIncField }
  1449. constructor TAutoIncField.Create(AOwner: TComponent);
  1450. begin
  1451. Inherited Create(AOWner);
  1452. SetDataType(ftAutoInc);
  1453. end;
  1454. Procedure TAutoIncField.SetAsInteger(AValue: Longint);
  1455. begin
  1456. // Some databases allows insertion of explicit values into identity columns
  1457. // (some of them also allows (some not) updating identity columns)
  1458. // So allow it at client side and leave check for server side
  1459. //if not(FDataSet.State in [dsFilter,dsSetKey,dsInsert]) then
  1460. // DataBaseError(SCantSetAutoIncFields);
  1461. inherited;
  1462. end;
  1463. { ---------------------------------------------------------------------
  1464. TLongWordField
  1465. ---------------------------------------------------------------------}
  1466. constructor TLongWordField.Create(AOwner: TComponent);
  1467. begin
  1468. Inherited Create(AOwner);
  1469. SetDataType(ftLongWord);
  1470. FValidchars:=['+','-','0'..'9'];
  1471. end;
  1472. function TLongWordField.CheckRange(AValue: LargeInt): Boolean;
  1473. begin
  1474. if (FMinValue<>0) or (FMaxValue<>0) then
  1475. Result := (AValue>=FMinValue) and (AValue<=FMaxValue)
  1476. else
  1477. Result := (AValue>=0) and (AValue<=High(LongWord));
  1478. end;
  1479. procedure TLongWordField.SetMinValue(AValue: LongWord);
  1480. begin
  1481. FMinValue:=AValue
  1482. end;
  1483. procedure TLongWordField.SetMaxValue(AValue: LongWord);
  1484. begin
  1485. FMaxValue:=AValue
  1486. end;
  1487. function TLongWordField.GetAsFloat: Double;
  1488. begin
  1489. Result:=GetAsLongWord;
  1490. end;
  1491. function TLongWordField.GetAsInteger: Longint;
  1492. begin
  1493. Result:=GetAsLongWord;
  1494. end;
  1495. function TLongWordField.GetAsLargeInt: Largeint;
  1496. begin
  1497. Result:=GetAsLongWord;
  1498. end;
  1499. function TLongWordField.GetAsLongWord: LongWord;
  1500. begin
  1501. if not GetValue(Result) then
  1502. Result:=0;
  1503. end;
  1504. function TLongWordField.GetAsString: string;
  1505. begin
  1506. Result:=IntToStr(GetAsLongWord);
  1507. end;
  1508. function TLongWordField.GetAsVariant: variant;
  1509. var L: LongWord;
  1510. begin
  1511. If GetValue(L) then
  1512. Result:=L
  1513. else
  1514. Result:=Null;
  1515. end;
  1516. function TLongWordField.GetDataSize: Integer;
  1517. begin
  1518. Result:=SizeOf(LongWord);
  1519. end;
  1520. procedure TLongWordField.GetText(var AText: string; ADisplayText: Boolean);
  1521. var
  1522. L : LongWord;
  1523. fmt : string;
  1524. begin
  1525. if GetValue(L) then
  1526. begin
  1527. if ADisplayText or (FEditFormat='') then
  1528. fmt:=FDisplayFormat
  1529. else
  1530. fmt:=FEditFormat;
  1531. if fmt<>'' then
  1532. AText:=FormatFloat(fmt,L)
  1533. else
  1534. Str(L,AText);
  1535. end
  1536. else
  1537. AText:='';
  1538. end;
  1539. function TLongWordField.GetValue(var AValue: LongWord): Boolean;
  1540. begin
  1541. Result:=GetData(@AValue);
  1542. end;
  1543. procedure TLongWordField.SetAsFloat(AValue: Double);
  1544. begin
  1545. SetAsLargeInt(Round(AValue));
  1546. end;
  1547. procedure TLongWordField.SetAsInteger(AValue: Longint);
  1548. begin
  1549. SetAsLargeInt(AValue);
  1550. end;
  1551. procedure TLongWordField.SetAsLargeInt(AValue: Largeint);
  1552. begin
  1553. if (AValue>=0) and (AValue<=High(LongWord)) then
  1554. SetAsLongWord(AValue)
  1555. else
  1556. RangeError(AValue,0,High(LongWord));
  1557. end;
  1558. procedure TLongWordField.SetAsLongWord(AValue: LongWord);
  1559. begin
  1560. if CheckRange(AValue) then
  1561. SetData(@AValue)
  1562. else
  1563. RangeError(AValue,FMinValue,FMaxValue);
  1564. end;
  1565. procedure TLongWordField.SetAsString(const AValue: string);
  1566. begin
  1567. if AValue='' then
  1568. Clear
  1569. else
  1570. SetAsLongWord(StrToDWord(AValue));
  1571. end;
  1572. procedure TLongWordField.SetVarValue(const AValue: Variant);
  1573. begin
  1574. SetAsLongWord(AValue);
  1575. end;
  1576. { ---------------------------------------------------------------------
  1577. TLargeintField
  1578. ---------------------------------------------------------------------}
  1579. constructor TLargeintField.Create(AOwner: TComponent);
  1580. begin
  1581. Inherited Create(AOwner);
  1582. SetDataType(ftLargeint);
  1583. FMinRange:=Low(Largeint);
  1584. FMaxRange:=High(Largeint);
  1585. FValidchars:=['+','-','0'..'9'];
  1586. end;
  1587. function TLargeintField.GetAsFloat: Double;
  1588. begin
  1589. Result:=GetAsLargeInt;
  1590. end;
  1591. function TLargeintField.GetAsLargeInt: Largeint;
  1592. begin
  1593. If Not GetValue(Result) then
  1594. Result:=0;
  1595. end;
  1596. function TLargeintField.GetAsLongWord: LongWord;
  1597. begin
  1598. Result:=GetAsLargeInt;
  1599. end;
  1600. function TLargeIntField.GetAsVariant: Variant;
  1601. var L : Largeint;
  1602. begin
  1603. If GetValue(L) then
  1604. Result:=L
  1605. else
  1606. Result:=Null;
  1607. end;
  1608. function TLargeintField.GetAsInteger: Longint;
  1609. begin
  1610. Result:=GetAsLargeInt;
  1611. end;
  1612. function TLargeintField.GetAsString: string;
  1613. var L : Largeint;
  1614. begin
  1615. If GetValue(L) then
  1616. Result:=IntTostr(L)
  1617. else
  1618. Result:='';
  1619. end;
  1620. function TLargeintField.GetDataSize: Integer;
  1621. begin
  1622. Result:=SizeOf(Largeint);
  1623. end;
  1624. procedure TLargeintField.GetText(var AText: string; ADisplayText: Boolean);
  1625. var l : Largeint;
  1626. fmt : string;
  1627. begin
  1628. Atext:='';
  1629. If Not GetValue(l) then exit;
  1630. If ADisplayText or (FEditFormat='') then
  1631. fmt:=FDisplayFormat
  1632. else
  1633. fmt:=FEditFormat;
  1634. If length(fmt)<>0 then
  1635. AText:=FormatFloat(fmt,L)
  1636. else
  1637. Str(L,AText);
  1638. end;
  1639. function TLargeintField.GetValue(var AValue: Largeint): Boolean;
  1640. var P : PLargeint;
  1641. begin
  1642. P:=@AValue;
  1643. Result:=GetData(P);
  1644. end;
  1645. procedure TLargeintField.SetAsFloat(AValue: Double);
  1646. begin
  1647. SetAsLargeInt(Round(AValue));
  1648. end;
  1649. procedure TLargeintField.SetAsLargeInt(AValue: Largeint);
  1650. begin
  1651. If CheckRange(AValue) then
  1652. SetData(@AValue)
  1653. else
  1654. RangeError(AValue,FMinValue,FMaxValue);
  1655. end;
  1656. procedure TLargeintField.SetAsLongWord(AValue: LongWord);
  1657. begin
  1658. SetAsLargeInt(AValue);
  1659. end;
  1660. procedure TLargeintField.SetAsInteger(AValue: Longint);
  1661. begin
  1662. SetAsLargeInt(AValue);
  1663. end;
  1664. procedure TLargeintField.SetAsString(const AValue: string);
  1665. var L : Largeint;
  1666. code : Longint;
  1667. begin
  1668. If length(AValue)=0 then
  1669. Clear
  1670. else
  1671. begin
  1672. Val(AValue,L,Code);
  1673. If Code=0 then
  1674. SetAsLargeInt(L)
  1675. else
  1676. DatabaseErrorFmt(SFieldError+SNotAnInteger,[DisplayName,AValue]);
  1677. end;
  1678. end;
  1679. procedure TLargeintField.SetVarValue(const AValue: Variant);
  1680. begin
  1681. SetAsLargeInt(AValue);
  1682. end;
  1683. Function TLargeintField.CheckRange(AValue : Largeint) : Boolean;
  1684. begin
  1685. if (FMinValue<>0) or (FMaxValue<>0) then
  1686. Result := (AValue>=FMinValue) and (AValue<=FMaxValue)
  1687. else
  1688. Result := (AValue>=FMinRange) and (AValue<=FMaxRange);
  1689. end;
  1690. Procedure TLargeintField.SetMaxValue (AValue : Largeint);
  1691. begin
  1692. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1693. FMaxValue:=AValue
  1694. else
  1695. RangeError(AValue,FMinRange,FMaxRange);
  1696. end;
  1697. Procedure TLargeintField.SetMinValue (AValue : Largeint);
  1698. begin
  1699. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1700. FMinValue:=AValue
  1701. else
  1702. RangeError(AValue,FMinRange,FMaxRange);
  1703. end;
  1704. { TFloatField }
  1705. procedure TFloatField.SetCurrency(const AValue: Boolean);
  1706. begin
  1707. if FCurrency=AValue then exit;
  1708. FCurrency:=AValue;
  1709. end;
  1710. procedure TFloatField.SetPrecision(const AValue: Longint);
  1711. begin
  1712. if (AValue = -1) or (AValue > 1) then
  1713. FPrecision := AValue
  1714. else
  1715. FPrecision := 2;
  1716. end;
  1717. function TFloatField.GetAsBCD: TBCD;
  1718. var f : Double;
  1719. begin
  1720. if GetData(@f) then
  1721. Result := DoubleToBCD(f)
  1722. else
  1723. Result := NullBCD;
  1724. end;
  1725. function TFloatField.GetAsFloat: Double;
  1726. begin
  1727. If Not GetData(@Result) Then
  1728. Result:=0.0;
  1729. end;
  1730. function TFloatField.GetAsVariant: Variant;
  1731. var f : Double;
  1732. begin
  1733. If GetData(@f) then
  1734. Result := f
  1735. else
  1736. Result:=Null;
  1737. end;
  1738. function TFloatField.GetAsLargeInt: LargeInt;
  1739. begin
  1740. Result:=Round(GetAsFloat);
  1741. end;
  1742. function TFloatField.GetAsLongWord: LongWord;
  1743. begin
  1744. Result:=Round(GetAsFloat);
  1745. end;
  1746. function TFloatField.GetAsInteger: Longint;
  1747. begin
  1748. Result:=Round(GetAsFloat);
  1749. end;
  1750. function TFloatField.GetAsString: string;
  1751. var f : Double;
  1752. begin
  1753. If GetData(@f) then
  1754. Result:=FloatToStr(f)
  1755. else
  1756. Result:='';
  1757. end;
  1758. function TFloatField.GetDataSize: Integer;
  1759. begin
  1760. Result:=SizeOf(Double);
  1761. end;
  1762. procedure TFloatField.GetText(var AText: string; ADisplayText: Boolean);
  1763. Var
  1764. fmt : string;
  1765. E : Double;
  1766. Digits : integer;
  1767. ff: TFloatFormat;
  1768. begin
  1769. AText:='';
  1770. If Not GetData(@E) then exit;
  1771. If ADisplayText or (Length(FEditFormat) = 0) Then
  1772. Fmt:=FDisplayFormat
  1773. else
  1774. Fmt:=FEditFormat;
  1775. Digits := 0;
  1776. if not FCurrency then
  1777. ff := ffGeneral
  1778. else
  1779. begin
  1780. Digits := CurrencyDecimals;
  1781. if ADisplayText then
  1782. ff := ffCurrency
  1783. else
  1784. ff := ffFixed;
  1785. end;
  1786. If fmt<>'' then
  1787. AText:=FormatFloat(fmt,E)
  1788. else
  1789. AText:=FloatToStrF(E,ff,FPrecision,Digits);
  1790. end;
  1791. procedure TFloatField.SetAsBCD(const AValue: TBCD);
  1792. begin
  1793. SetAsFloat(BCDToDouble(AValue));
  1794. end;
  1795. procedure TFloatField.SetAsFloat(AValue: Double);
  1796. begin
  1797. If CheckRange(AValue) then
  1798. SetData(@AValue)
  1799. else
  1800. RangeError(AValue,FMinValue,FMaxValue);
  1801. end;
  1802. procedure TFloatField.SetAsLargeInt(AValue: LargeInt);
  1803. begin
  1804. SetAsFloat(AValue);
  1805. end;
  1806. procedure TFloatField.SetAsLongWord(AValue: LongWord);
  1807. begin
  1808. SetAsFloat(AValue);
  1809. end;
  1810. procedure TFloatField.SetAsInteger(AValue: Longint);
  1811. begin
  1812. SetAsFloat(AValue);
  1813. end;
  1814. procedure TFloatField.SetAsString(const AValue: string);
  1815. var f : Double;
  1816. begin
  1817. If (AValue='') then
  1818. Clear
  1819. else
  1820. begin
  1821. If not TryStrToFloat(AValue,F) then
  1822. DatabaseErrorFmt(SNotAFloat, [AValue]);
  1823. SetAsFloat(f);
  1824. end;
  1825. end;
  1826. procedure TFloatField.SetVarValue(const AValue: Variant);
  1827. begin
  1828. SetAsFloat(AValue);
  1829. end;
  1830. constructor TFloatField.Create(AOwner: TComponent);
  1831. begin
  1832. Inherited Create(AOwner);
  1833. SetDataType(ftFloat);
  1834. FPrecision:=15;
  1835. FValidChars := [DecimalSeparator, '+', '-', '0'..'9', 'E', 'e'];
  1836. end;
  1837. Function TFloatField.CheckRange(AValue : Double) : Boolean;
  1838. begin
  1839. If (FMinValue<>0) or (FMaxValue<>0) then
  1840. Result:=(AValue>=FMinValue) and (AValue<=FMaxValue)
  1841. else
  1842. Result:=True;
  1843. end;
  1844. { TCurrencyField }
  1845. Constructor TCurrencyField.Create(AOwner: TComponent);
  1846. begin
  1847. inherited Create(AOwner);
  1848. SetDataType(ftCurrency);
  1849. Currency := True;
  1850. end;
  1851. { TBooleanField }
  1852. function TBooleanField.GetAsBoolean: Boolean;
  1853. var b : wordbool;
  1854. begin
  1855. If GetData(@b) then
  1856. Result := b
  1857. else
  1858. Result:=False;
  1859. end;
  1860. function TBooleanField.GetAsVariant: Variant;
  1861. var b : wordbool;
  1862. begin
  1863. If GetData(@b) then
  1864. Result := b
  1865. else
  1866. Result:=Null;
  1867. end;
  1868. function TBooleanField.GetAsString: string;
  1869. var B : wordbool;
  1870. begin
  1871. If GetData(@B) then
  1872. Result:=FDisplays[False,B]
  1873. else
  1874. result:='';
  1875. end;
  1876. function TBooleanField.GetDataSize: Integer;
  1877. begin
  1878. Result:=SizeOf(wordBool);
  1879. end;
  1880. function TBooleanField.GetDefaultWidth: Longint;
  1881. begin
  1882. Result:=Length(FDisplays[false,false]);
  1883. If Result<Length(FDisplays[false,True]) then
  1884. Result:=Length(FDisplays[false,True]);
  1885. end;
  1886. function TBooleanField.GetAsInteger: Longint;
  1887. begin
  1888. Result := ord(GetAsBoolean);
  1889. end;
  1890. procedure TBooleanField.SetAsInteger(AValue: Longint);
  1891. begin
  1892. SetAsBoolean(AValue<>0);
  1893. end;
  1894. procedure TBooleanField.SetAsBoolean(AValue: Boolean);
  1895. var b : wordbool;
  1896. begin
  1897. b := AValue;
  1898. SetData(@b);
  1899. end;
  1900. procedure TBooleanField.SetAsString(const AValue: string);
  1901. var Temp : string;
  1902. begin
  1903. Temp:=UpperCase(AValue);
  1904. if Temp='' then
  1905. Clear
  1906. else if pos(Temp, FDisplays[True,True])=1 then
  1907. SetAsBoolean(True)
  1908. else if pos(Temp, FDisplays[True,False])=1 then
  1909. SetAsBoolean(False)
  1910. else
  1911. DatabaseErrorFmt(SNotABoolean,[AValue]);
  1912. end;
  1913. procedure TBooleanField.SetVarValue(const AValue: Variant);
  1914. begin
  1915. SetAsBoolean(AValue);
  1916. end;
  1917. constructor TBooleanField.Create(AOwner: TComponent);
  1918. begin
  1919. Inherited Create(AOwner);
  1920. SetDataType(ftBoolean);
  1921. DisplayValues:='True;False';
  1922. end;
  1923. Procedure TBooleanField.SetDisplayValues(const AValue : String);
  1924. var I : longint;
  1925. begin
  1926. If FDisplayValues<>AValue then
  1927. begin
  1928. I:=Pos(';',AValue);
  1929. If (I<2) or (I=Length(AValue)) then
  1930. DatabaseErrorFmt(SFieldError+SInvalidDisplayValues,[DisplayName,AValue]);
  1931. FdisplayValues:=AValue;
  1932. // Store display values and their uppercase equivalents;
  1933. FDisplays[False,True]:=Copy(AValue,1,I-1);
  1934. FDisplays[True,True]:=UpperCase(FDisplays[False,True]);
  1935. FDisplays[False,False]:=Copy(AValue,I+1,Length(AValue)-i);
  1936. FDisplays[True,False]:=UpperCase(FDisplays[False,False]);
  1937. PropertyChanged(True);
  1938. end;
  1939. end;
  1940. { TDateTimeField }
  1941. procedure TDateTimeField.SetDisplayFormat(const AValue: string);
  1942. begin
  1943. if FDisplayFormat<>AValue then begin
  1944. FDisplayFormat:=AValue;
  1945. PropertyChanged(True);
  1946. end;
  1947. end;
  1948. function TDateTimeField.GetAsDateTime: TDateTime;
  1949. begin
  1950. If Not GetData(@Result,False) then
  1951. Result:=0;
  1952. end;
  1953. procedure TDateTimeField.SetVarValue(const AValue: Variant);
  1954. begin
  1955. SetAsDateTime(AValue);
  1956. end;
  1957. function TDateTimeField.GetAsVariant: Variant;
  1958. var d : tDateTime;
  1959. begin
  1960. If GetData(@d,False) then
  1961. Result := d
  1962. else
  1963. Result:=Null;
  1964. end;
  1965. function TDateTimeField.GetAsFloat: Double;
  1966. begin
  1967. Result:=GetAsdateTime;
  1968. end;
  1969. function TDateTimeField.GetAsString: string;
  1970. begin
  1971. GetText(Result,False);
  1972. end;
  1973. function TDateTimeField.GetDataSize: Integer;
  1974. begin
  1975. Result:=SizeOf(TDateTime);
  1976. end;
  1977. procedure TDateTimeField.GetText(var AText: string; ADisplayText: Boolean);
  1978. var R : TDateTime;
  1979. F : String;
  1980. begin
  1981. If Not GetData(@R,False) then
  1982. AText:=''
  1983. else
  1984. begin
  1985. If (ADisplayText) and (Length(FDisplayFormat)<>0) then
  1986. F:=FDisplayFormat
  1987. else
  1988. Case DataType of
  1989. ftTime : F:=LongTimeFormat;
  1990. ftDate : F:=ShortDateFormat;
  1991. else
  1992. F:='c'
  1993. end;
  1994. AText:=FormatDateTime(F,R);
  1995. end;
  1996. end;
  1997. procedure TDateTimeField.SetAsDateTime(AValue: TDateTime);
  1998. begin
  1999. SetData(@AValue,False);
  2000. end;
  2001. procedure TDateTimeField.SetAsFloat(AValue: Double);
  2002. begin
  2003. SetAsDateTime(AValue);
  2004. end;
  2005. procedure TDateTimeField.SetAsString(const AValue: string);
  2006. var R : TDateTime;
  2007. begin
  2008. if AValue<>'' then
  2009. begin
  2010. R:=StrToDateTime(AValue);
  2011. SetData(@R,False);
  2012. end
  2013. else
  2014. SetData(Nil);
  2015. end;
  2016. constructor TDateTimeField.Create(AOwner: TComponent);
  2017. begin
  2018. Inherited Create(AOwner);
  2019. SetDataType(ftDateTime);
  2020. end;
  2021. { TDateField }
  2022. constructor TDateField.Create(AOwner: TComponent);
  2023. begin
  2024. Inherited Create(AOwner);
  2025. SetDataType(ftDate);
  2026. end;
  2027. { TTimeField }
  2028. constructor TTimeField.Create(AOwner: TComponent);
  2029. begin
  2030. Inherited Create(AOwner);
  2031. SetDataType(ftTime);
  2032. end;
  2033. procedure TTimeField.SetAsString(const AValue: string);
  2034. var R : TDateTime;
  2035. begin
  2036. if AValue='' then
  2037. Clear // set to NULL
  2038. else
  2039. begin
  2040. R:=StrToTime(AValue);
  2041. SetData(@R,False);
  2042. end;
  2043. end;
  2044. { TBinaryField }
  2045. class procedure TBinaryField.CheckTypeSize(AValue: Longint);
  2046. begin
  2047. // Just check for really invalid stuff; actual size is
  2048. // dependent on the record...
  2049. If AValue<0 then // MSSQL can have a null/0 field length in a view
  2050. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  2051. end;
  2052. function TBinaryField.GetAsBytes: TBytes;
  2053. begin
  2054. if not GetValue(Result) then
  2055. SetLength(Result, 0);
  2056. end;
  2057. function TBinaryField.GetAsString: string;
  2058. var B: TBytes;
  2059. begin
  2060. if not GetValue(B) then
  2061. Result := ''
  2062. else
  2063. SetString(Result, @B[0], length(B) div SizeOf(Char));
  2064. end;
  2065. function TBinaryField.GetAsVariant: Variant;
  2066. var B: TBytes;
  2067. P: Pointer;
  2068. begin
  2069. if not GetValue(B) then
  2070. Result := Null
  2071. else
  2072. begin
  2073. Result := VarArrayCreate([0, length(B)-1], varByte);
  2074. P := VarArrayLock(Result);
  2075. try
  2076. Move(B[0], P^, length(B));
  2077. finally
  2078. VarArrayUnlock(Result);
  2079. end;
  2080. end;
  2081. end;
  2082. function TBinaryField.GetValue(var AValue: TBytes): Boolean;
  2083. var B: TBytes;
  2084. begin
  2085. SetLength(B, DataSize);
  2086. Result := assigned(B) and GetData(Pointer(B), True);
  2087. if Result then
  2088. if DataType = ftVarBytes then
  2089. begin
  2090. SetLength(AValue, PWord(B)^);
  2091. Move(B[sizeof(Word)], AValue[0], Length(AValue));
  2092. end
  2093. else // ftBytes
  2094. AValue := B;
  2095. end;
  2096. procedure TBinaryField.SetAsBytes(const AValue: TBytes);
  2097. var Buf: array[0..dsMaxStringSize] of byte;
  2098. DynBuf: TBytes;
  2099. Len: Word;
  2100. P: PByte;
  2101. begin
  2102. Len := Length(AValue);
  2103. if Len >= DataSize then
  2104. P := @AValue[0]
  2105. else begin
  2106. if DataSize <= dsMaxStringSize then
  2107. P := @Buf[0]
  2108. else begin
  2109. SetLength(DynBuf, DataSize);
  2110. P := @DynBuf[0];
  2111. end;
  2112. if DataType = ftVarBytes then begin
  2113. PWord(P)^ := Len;
  2114. Move(AValue[0], P[sizeof(Word)], Len);
  2115. end
  2116. else begin // ftBytes
  2117. Move(AValue[0], P^, Len);
  2118. FillChar(P[Len], DataSize-Len, 0); // right pad with #0
  2119. end;
  2120. end;
  2121. SetData(P, True)
  2122. end;
  2123. procedure TBinaryField.SetAsString(const AValue: string);
  2124. var B : TBytes;
  2125. begin
  2126. If Length(AValue) = DataSize then
  2127. SetData(PChar(AValue))
  2128. else
  2129. begin
  2130. SetLength(B, Length(AValue) * SizeOf(Char));
  2131. Move(AValue[1], B[0], Length(B));
  2132. SetAsBytes(B);
  2133. end;
  2134. end;
  2135. procedure TBinaryField.SetVarValue(const AValue: Variant);
  2136. var P: Pointer;
  2137. B: TBytes;
  2138. Len: integer;
  2139. begin
  2140. if VarIsArray(AValue) then
  2141. begin
  2142. P := VarArrayLock(AValue);
  2143. try
  2144. Len := VarArrayHighBound(AValue, 1) + 1;
  2145. SetLength(B, Len);
  2146. Move(P^, B[0], Len);
  2147. finally
  2148. VarArrayUnlock(AValue);
  2149. end;
  2150. SetAsBytes(B);
  2151. end
  2152. else
  2153. SetAsString(AValue);
  2154. end;
  2155. constructor TBinaryField.Create(AOwner: TComponent);
  2156. begin
  2157. Inherited Create(AOwner);
  2158. end;
  2159. { TBytesField }
  2160. function TBytesField.GetDataSize: Integer;
  2161. begin
  2162. Result:=Size;
  2163. end;
  2164. constructor TBytesField.Create(AOwner: TComponent);
  2165. begin
  2166. Inherited Create(AOwner);
  2167. SetDataType(ftBytes);
  2168. Size:=16;
  2169. end;
  2170. { TVarBytesField }
  2171. function TVarBytesField.GetDataSize: Integer;
  2172. begin
  2173. Result:=Size+2;
  2174. end;
  2175. constructor TVarBytesField.Create(AOwner: TComponent);
  2176. begin
  2177. INherited Create(AOwner);
  2178. SetDataType(ftVarBytes);
  2179. Size:=16;
  2180. end;
  2181. { TBCDField }
  2182. class procedure TBCDField.CheckTypeSize(AValue: Longint);
  2183. begin
  2184. If not (AValue in [0..4]) then
  2185. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  2186. end;
  2187. function TBCDField.GetAsBCD: TBCD;
  2188. Var
  2189. c:system.Currency;
  2190. begin
  2191. If GetData(@c) then
  2192. Result:=CurrToBCD(c)
  2193. else
  2194. Result:=NullBCD;
  2195. end;
  2196. function TBCDField.GetAsCurrency: Currency;
  2197. begin
  2198. if not GetData(@Result) then
  2199. result := 0;
  2200. end;
  2201. function TBCDField.GetAsVariant: Variant;
  2202. var c : system.Currency;
  2203. begin
  2204. If GetData(@c) then
  2205. Result := c
  2206. else
  2207. Result:=Null;
  2208. end;
  2209. function TBCDField.GetAsFloat: Double;
  2210. begin
  2211. result := GetAsCurrency;
  2212. end;
  2213. function TBCDField.GetAsInteger: Longint;
  2214. begin
  2215. result := round(GetAsCurrency);
  2216. end;
  2217. function TBCDField.GetAsString: string;
  2218. var c : system.currency;
  2219. begin
  2220. If GetData(@C) then
  2221. Result:=CurrToStr(C)
  2222. else
  2223. Result:='';
  2224. end;
  2225. function TBCDField.GetValue(var AValue: Currency): Boolean;
  2226. begin
  2227. Result := GetData(@AValue);
  2228. end;
  2229. function TBCDField.GetDataSize: Integer;
  2230. begin
  2231. result := sizeof(system.currency);
  2232. end;
  2233. function TBCDField.GetDefaultWidth: Longint;
  2234. begin
  2235. if Precision > 0 then Result := Precision+1
  2236. else Result := 10;
  2237. end;
  2238. procedure TBCDField.GetText(var AText: string; ADisplayText: Boolean);
  2239. var
  2240. c : system.currency;
  2241. fmt: String;
  2242. begin
  2243. if GetData(@C) then begin
  2244. if ADisplayText or (FEditFormat='') then
  2245. fmt := FDisplayFormat
  2246. else
  2247. fmt := FEditFormat;
  2248. if fmt<>'' then
  2249. AText := FormatFloat(fmt,C)
  2250. else if fCurrency then begin
  2251. if ADisplayText then
  2252. AText := FloatToStrF(C, ffCurrency, FPrecision, 2{digits?})
  2253. else
  2254. AText := FloatToStrF(C, ffFixed, FPrecision, 2{digits?});
  2255. end else
  2256. AText := FloatToStrF(C, ffGeneral, FPrecision, 0{digits?});
  2257. end else
  2258. AText := '';
  2259. end;
  2260. procedure TBCDField.SetAsBCD(const AValue: TBCD);
  2261. var
  2262. c:system.currency;
  2263. begin
  2264. if BCDToCurr(AValue,c) then
  2265. SetAsCurrency(c);
  2266. end;
  2267. procedure TBCDField.SetAsCurrency(AValue: Currency);
  2268. begin
  2269. If CheckRange(AValue) then
  2270. SetData(@AValue)
  2271. else
  2272. RangeError(AValue,FMinValue,FMaxValue);
  2273. end;
  2274. procedure TBCDField.SetVarValue(const AValue: Variant);
  2275. begin
  2276. SetAsCurrency(AValue);
  2277. end;
  2278. Function TBCDField.CheckRange(AValue : Currency) : Boolean;
  2279. begin
  2280. If (FMinValue<>0) or (FMaxValue<>0) then
  2281. Result:=(AValue>=FMinValue) and (AValue<=FMaxValue)
  2282. else
  2283. Result:=True;
  2284. end;
  2285. procedure TBCDField.SetAsFloat(AValue: Double);
  2286. begin
  2287. SetAsCurrency(AValue);
  2288. end;
  2289. procedure TBCDField.SetAsInteger(AValue: Longint);
  2290. begin
  2291. SetAsCurrency(AValue);
  2292. end;
  2293. procedure TBCDField.SetAsString(const AValue: string);
  2294. begin
  2295. if AValue='' then
  2296. Clear // set to NULL
  2297. else
  2298. SetAsCurrency(strtocurr(AValue));
  2299. end;
  2300. constructor TBCDField.Create(AOwner: TComponent);
  2301. begin
  2302. Inherited Create(AOwner);
  2303. FMaxValue := 0;
  2304. FMinValue := 0;
  2305. FValidChars := [DecimalSeparator, '+', '-', '0'..'9'];
  2306. SetDataType(ftBCD);
  2307. Precision := 18;
  2308. Size := 4;
  2309. end;
  2310. { TFMTBCDField }
  2311. class procedure TFMTBCDField.CheckTypeSize(AValue: Longint);
  2312. begin
  2313. If AValue > MAXFMTBcdFractionSize then
  2314. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  2315. end;
  2316. constructor TFMTBCDField.Create(AOwner: TComponent);
  2317. begin
  2318. Inherited Create(AOwner);
  2319. FMaxValue := 0;
  2320. FMinValue := 0;
  2321. FValidChars := [DecimalSeparator, '+', '-', '0'..'9'];
  2322. SetDataType(ftFMTBCD);
  2323. // Max.precision for NUMERIC,DECIMAL datatypes supported by some databases:
  2324. // Firebird-18; Oracle,SqlServer-38; MySQL-65; PostgreSQL-1000
  2325. Precision := 18; //default number of digits
  2326. Size := 4; //default number of digits after decimal place
  2327. end;
  2328. function TFMTBCDField.GetDataSize: Integer;
  2329. begin
  2330. Result := sizeof(TBCD);
  2331. end;
  2332. function TFMTBCDField.GetDefaultWidth: Longint;
  2333. begin
  2334. if Precision > 0 then Result := Precision+1
  2335. else Result := inherited GetDefaultWidth;
  2336. end;
  2337. function TFMTBCDField.GetAsBCD: TBCD;
  2338. begin
  2339. if not GetData(@Result) then
  2340. Result := NullBCD;
  2341. end;
  2342. function TFMTBCDField.GetAsCurrency: Currency;
  2343. var bcd: TBCD;
  2344. begin
  2345. if GetData(@bcd) then
  2346. BCDToCurr(bcd, Result)
  2347. else
  2348. Result := 0;
  2349. end;
  2350. function TFMTBCDField.GetAsVariant: Variant;
  2351. var bcd: TBCD;
  2352. begin
  2353. If GetData(@bcd) then
  2354. Result := VarFMTBcdCreate(bcd)
  2355. else
  2356. Result := Null;
  2357. end;
  2358. function TFMTBCDField.GetAsFloat: Double;
  2359. var bcd: TBCD;
  2360. begin
  2361. If GetData(@bcd) then
  2362. Result := BCDToDouble(bcd)
  2363. else
  2364. Result := 0;
  2365. end;
  2366. function TFMTBCDField.GetAsLargeInt: LargeInt;
  2367. var bcd: TBCD;
  2368. begin
  2369. if GetData(@bcd) then
  2370. Result := BCDToInteger(bcd)
  2371. else
  2372. Result := 0;
  2373. end;
  2374. function TFMTBCDField.GetAsInteger: Longint;
  2375. begin
  2376. Result := round(GetAsFloat);
  2377. end;
  2378. function TFMTBCDField.GetAsString: string;
  2379. var bcd: TBCD;
  2380. begin
  2381. If GetData(@bcd) then
  2382. Result:=BCDToStr(bcd)
  2383. else
  2384. Result:='';
  2385. end;
  2386. procedure TFMTBCDField.GetText(var AText: string; ADisplayText: Boolean);
  2387. var
  2388. bcd: TBCD;
  2389. fmt: String;
  2390. begin
  2391. if GetData(@bcd) then begin
  2392. if ADisplayText or (FEditFormat='') then
  2393. fmt := FDisplayFormat
  2394. else
  2395. fmt := FEditFormat;
  2396. if fmt<>'' then
  2397. AText := FormatBCD(fmt,bcd)
  2398. else if fCurrency then begin
  2399. if ADisplayText then
  2400. AText := BcdToStrF(bcd, ffCurrency, FPrecision, 2)
  2401. else
  2402. AText := BcdToStrF(bcd, ffFixed, FPrecision, 2);
  2403. end else
  2404. AText := BcdToStrF(bcd, ffGeneral, FPrecision, FSize);
  2405. end else
  2406. AText := '';
  2407. end;
  2408. function TFMTBCDField.GetMaxValue: string;
  2409. begin
  2410. Result:=BCDToStr(FMaxValue);
  2411. end;
  2412. function TFMTBCDField.GetMinValue: string;
  2413. begin
  2414. Result:=BCDToStr(FMinValue);
  2415. end;
  2416. procedure TFMTBCDField.SetMaxValue(const AValue: string);
  2417. begin
  2418. FMaxValue:=StrToBCD(AValue);
  2419. end;
  2420. procedure TFMTBCDField.SetMinValue(const AValue: string);
  2421. begin
  2422. FMinValue:=StrToBCD(AValue);
  2423. end;
  2424. Function TFMTBCDField.CheckRange(AValue: TBCD) : Boolean;
  2425. begin
  2426. If (FMinValue<>0) or (FMaxValue<>0) then
  2427. Result:=(AValue>=FMinValue) and (AValue<=FMaxValue)
  2428. else
  2429. Result:=True;
  2430. end;
  2431. procedure TFMTBCDField.SetAsBCD(const AValue: TBCD);
  2432. begin
  2433. if CheckRange(AValue) then
  2434. SetData(@AValue)
  2435. else
  2436. RangeError(AValue, BCDToDouble(FMinValue), BCDToDouble(FMaxValue));
  2437. end;
  2438. procedure TFMTBCDField.SetAsCurrency(AValue: Currency);
  2439. var bcd: TBCD;
  2440. begin
  2441. if CurrToBCD(AValue, bcd, 32, Size) then
  2442. SetAsBCD(bcd);
  2443. end;
  2444. procedure TFMTBCDField.SetVarValue(const AValue: Variant);
  2445. begin
  2446. SetAsBCD(VarToBCD(AValue));
  2447. end;
  2448. procedure TFMTBCDField.SetAsFloat(AValue: Double);
  2449. begin
  2450. SetAsBCD(DoubleToBCD(AValue));
  2451. end;
  2452. procedure TFMTBCDField.SetAsLargeInt(AValue: LargeInt);
  2453. begin
  2454. SetAsBCD(IntegerToBCD(AValue));
  2455. end;
  2456. procedure TFMTBCDField.SetAsInteger(AValue: Longint);
  2457. begin
  2458. SetAsBCD(IntegerToBCD(AValue));
  2459. end;
  2460. procedure TFMTBCDField.SetAsString(const AValue: string);
  2461. begin
  2462. if AValue='' then
  2463. Clear // set to NULL
  2464. else
  2465. SetAsBCD(StrToBCD(AValue));
  2466. end;
  2467. { TBlobField }
  2468. constructor TBlobField.Create(AOwner: TComponent);
  2469. begin
  2470. Inherited Create(AOwner);
  2471. SetDataType(ftBlob);
  2472. end;
  2473. function TBlobField.GetBlobStream(Mode: TBlobStreamMode): TStream;
  2474. begin
  2475. Result:=FDataset.CreateBlobStream(Self,Mode);
  2476. end;
  2477. function TBlobField.GetBlobType: TBlobType;
  2478. begin
  2479. Result:= TBlobType(DataType);
  2480. end;
  2481. procedure TBlobField.SetBlobType(AValue: TBlobType);
  2482. begin
  2483. SetFieldType(TFieldType(AValue));
  2484. end;
  2485. procedure TBlobField.FreeBuffers;
  2486. begin
  2487. end;
  2488. function TBlobField.GetAsBytes: TBytes;
  2489. var
  2490. Stream : TStream;
  2491. Len : Integer;
  2492. begin
  2493. Stream := GetBlobStream(bmRead);
  2494. if Stream <> nil then
  2495. try
  2496. Len := Stream.Size;
  2497. SetLength(Result, Len);
  2498. if Len > 0 then
  2499. Stream.ReadBuffer(Result[0], Len);
  2500. finally
  2501. Stream.Free;
  2502. end
  2503. else
  2504. SetLength(Result, 0);
  2505. end;
  2506. function TBlobField.GetAsString: string;
  2507. begin
  2508. {$IFDEF UNICODE}
  2509. Result := GetAsUnicodeString;
  2510. {$ELSE}
  2511. Result := GetAsAnsiString;
  2512. {$ENDIF}
  2513. end;
  2514. function TBlobField.GetAsAnsiString: AnsiString;
  2515. var
  2516. Stream : TStream;
  2517. Len : Integer;
  2518. S : AnsiString;
  2519. begin
  2520. Stream := GetBlobStream(bmRead);
  2521. if Stream <> nil then
  2522. with Stream do
  2523. try
  2524. Len := Size;
  2525. SetLength(S, Len);
  2526. if Len > 0 then
  2527. begin
  2528. ReadBuffer(S[1], Len);
  2529. if not Transliterate then
  2530. Result := S
  2531. else
  2532. begin
  2533. SetLength(Result, Len);
  2534. DataSet.Translate(@S[1],@Result[1],False);
  2535. end;
  2536. end
  2537. else
  2538. Result := '';
  2539. finally
  2540. Free;
  2541. end
  2542. else
  2543. Result := '';
  2544. end;
  2545. function TBlobField.GetAsUnicodeString: UnicodeString;
  2546. var
  2547. Stream : TStream;
  2548. Len : Integer;
  2549. begin
  2550. Stream := GetBlobStream(bmRead);
  2551. if Stream <> nil then
  2552. with Stream do
  2553. try
  2554. Len := Size;
  2555. SetLength(Result, (Len+1) div 2);
  2556. if Len > 0 then
  2557. ReadBuffer(Result[1] ,Len);
  2558. finally
  2559. Free
  2560. end
  2561. else
  2562. Result := '';
  2563. end;
  2564. function TBlobField.GetAsVariant: Variant;
  2565. begin
  2566. if not GetIsNull then
  2567. Result := GetAsString
  2568. else
  2569. Result := Null;
  2570. end;
  2571. function TBlobField.GetBlobSize: Longint;
  2572. var
  2573. Stream: TStream;
  2574. begin
  2575. Stream := GetBlobStream(bmRead);
  2576. if Stream <> nil then
  2577. with Stream do
  2578. try
  2579. Result:=Size;
  2580. finally
  2581. Free;
  2582. end
  2583. else
  2584. Result := 0;
  2585. end;
  2586. function TBlobField.GetIsNull: Boolean;
  2587. begin
  2588. if Not Modified then
  2589. Result:= inherited GetIsNull
  2590. else
  2591. with GetBlobStream(bmRead) do
  2592. try
  2593. Result:=(Size=0);
  2594. finally
  2595. Free;
  2596. end;
  2597. end;
  2598. procedure TBlobField.GetText(var AText: string; ADisplayText: Boolean);
  2599. begin
  2600. AText := inherited GetAsString;
  2601. end;
  2602. procedure TBlobField.SetAsBytes(const AValue: TBytes);
  2603. var
  2604. Len : Integer;
  2605. begin
  2606. with GetBlobStream(bmWrite) do
  2607. try
  2608. Len := Length(AValue);
  2609. if Len > 0 then
  2610. WriteBuffer(AValue[0], Len);
  2611. finally
  2612. Free;
  2613. end;
  2614. end;
  2615. procedure TBlobField.SetAsString(const AValue: string);
  2616. begin
  2617. {$IFDEF UNICODE}
  2618. SetAsUnicodeString(AValue);
  2619. {$ELSE}
  2620. SetAsAnsiString(AValue);
  2621. {$ENDIF}
  2622. end;
  2623. procedure TBlobField.SetAsAnsiString(const AValue: AnsiString);
  2624. var
  2625. Len : Integer;
  2626. S : AnsiString;
  2627. begin
  2628. with GetBlobStream(bmWrite) do
  2629. try
  2630. Len := Length(AValue);
  2631. if (Len>0) then
  2632. begin
  2633. if Not Transliterate then
  2634. S:=AValue
  2635. else
  2636. begin
  2637. SetLength(S,Len);
  2638. Len:=DataSet.Translate(@AValue[1],@S[1],True);
  2639. end;
  2640. WriteBuffer(S[1], Len);
  2641. end;
  2642. finally
  2643. Free;
  2644. end;
  2645. end;
  2646. procedure TBlobField.SetAsUnicodeString(const AValue: UnicodeString);
  2647. var
  2648. Len : Integer;
  2649. begin
  2650. with GetBlobStream(bmWrite) do
  2651. try
  2652. Len := Length(AValue) * SizeOf(UnicodeChar);
  2653. if Len > 0 then
  2654. WriteBuffer(AValue[1], Len);
  2655. finally
  2656. Free;
  2657. end;
  2658. end;
  2659. procedure TBlobField.SetVarValue(const AValue: Variant);
  2660. begin
  2661. SetAsString(AValue);
  2662. end;
  2663. procedure TBlobField.Clear;
  2664. begin
  2665. GetBlobStream(bmWrite).Free;
  2666. end;
  2667. class function TBlobField.IsBlob: Boolean;
  2668. begin
  2669. Result:=True;
  2670. end;
  2671. procedure TBlobField.LoadFromFile(const FileName: string);
  2672. var S : TFileStream;
  2673. begin
  2674. S:=TFileStream.Create(FileName,fmOpenRead or fmShareDenyWrite);
  2675. try
  2676. LoadFromStream(S);
  2677. finally
  2678. S.Free;
  2679. end;
  2680. end;
  2681. procedure TBlobField.LoadFromStream(Stream: TStream);
  2682. begin
  2683. with GetBlobStream(bmWrite) do
  2684. try
  2685. CopyFrom(Stream,0);
  2686. finally
  2687. Free;
  2688. end;
  2689. end;
  2690. procedure TBlobField.SaveToFile(const FileName: string);
  2691. var S : TFileStream;
  2692. begin
  2693. S:=TFileStream.Create(FileName,fmCreate);
  2694. try
  2695. SaveToStream(S);
  2696. finally
  2697. S.Free;
  2698. end;
  2699. end;
  2700. procedure TBlobField.SaveToStream(Stream: TStream);
  2701. var S : TStream;
  2702. begin
  2703. S:=GetBlobStream(bmRead);
  2704. Try
  2705. If Assigned(S) then
  2706. Stream.CopyFrom(S,0);
  2707. finally
  2708. S.Free;
  2709. end;
  2710. end;
  2711. procedure TBlobField.SetFieldType(AValue: TFieldType);
  2712. begin
  2713. if AValue in ftBlobTypes then
  2714. SetDataType(AValue);
  2715. end;
  2716. { TMemoField }
  2717. constructor TMemoField.Create(AOwner: TComponent);
  2718. begin
  2719. inherited Create(AOwner);
  2720. SetDataType(ftMemo);
  2721. end;
  2722. function TMemoField.GetAsAnsiString: AnsiString;
  2723. begin
  2724. Result := inherited GetAsAnsiString;
  2725. SetCodePage(RawByteString(Result), FCodePage, False);
  2726. SetCodePage(RawByteString(Result), CP_ACP, True);
  2727. end;
  2728. procedure TMemoField.SetAsAnsiString(const AValue: AnsiString);
  2729. var s: RawByteString;
  2730. begin
  2731. s := AValue;
  2732. SetCodePage(s, FCodePage, FCodePage<>CP_NONE);
  2733. inherited SetAsAnsiString(s);
  2734. end;
  2735. function TMemoField.GetAsUnicodeString: UnicodeString;
  2736. begin
  2737. Result:=GetAsAnsiString;
  2738. end;
  2739. procedure TMemoField.SetAsUnicodeString(const AValue: UnicodeString);
  2740. begin
  2741. SetAsAnsiString(AValue);
  2742. end;
  2743. function TMemoField.GetAsUTF8String: UTF8String;
  2744. var s: RawByteString;
  2745. begin
  2746. s := inherited GetAsAnsiString;
  2747. SetCodePage(s, FCodePage, False);
  2748. SetCodePage(s, CP_UTF8, True);
  2749. Result := s;
  2750. end;
  2751. procedure TMemoField.SetAsUTF8String(const AValue: UTF8String);
  2752. begin
  2753. SetAsAnsiString(AValue);
  2754. end;
  2755. { TWideMemoField }
  2756. constructor TWideMemoField.Create(AOwner: TComponent);
  2757. begin
  2758. inherited Create(AOwner);
  2759. SetDataType(ftWideMemo);
  2760. end;
  2761. function TWideMemoField.GetAsString: string;
  2762. begin
  2763. Result := GetAsUnicodeString;
  2764. end;
  2765. procedure TWideMemoField.SetAsString(const AValue: string);
  2766. begin
  2767. SetAsUnicodeString(AValue);
  2768. end;
  2769. function TWideMemoField.GetAsAnsiString: AnsiString;
  2770. begin
  2771. Result := GetAsUnicodeString;
  2772. end;
  2773. procedure TWideMemoField.SetAsAnsiString(const AValue: AnsiString);
  2774. begin
  2775. SetAsUnicodeString(AValue);
  2776. end;
  2777. function TWideMemoField.GetAsUTF8String: UTF8String;
  2778. begin
  2779. Result := GetAsUnicodeString;
  2780. end;
  2781. procedure TWideMemoField.SetAsUTF8String(const AValue: UTF8String);
  2782. begin
  2783. SetAsUnicodeString(AValue);
  2784. end;
  2785. function TWideMemoField.GetAsVariant: Variant;
  2786. begin
  2787. if not GetIsNull then
  2788. Result := GetAsUnicodeString
  2789. else
  2790. Result := Null;
  2791. end;
  2792. procedure TWideMemoField.SetVarValue(const AValue: Variant);
  2793. begin
  2794. SetAsUnicodeString(AValue);
  2795. end;
  2796. { TGraphicField }
  2797. constructor TGraphicField.Create(AOwner: TComponent);
  2798. begin
  2799. Inherited Create(AOwner);
  2800. SetDataType(ftGraphic);
  2801. end;
  2802. { TGuidField }
  2803. constructor TGuidField.Create(AOwner: TComponent);
  2804. begin
  2805. Size := 38;
  2806. inherited Create(AOwner);
  2807. SetDataType(ftGuid);
  2808. end;
  2809. class procedure TGuidField.CheckTypeSize(AValue: LongInt);
  2810. begin
  2811. if AValue <> 38 then
  2812. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  2813. end;
  2814. function TGuidField.GetAsGuid: TGUID;
  2815. const
  2816. nullguid: TGUID = '{00000000-0000-0000-0000-000000000000}';
  2817. var
  2818. S: string;
  2819. begin
  2820. S := GetAsString;
  2821. if S = '' then
  2822. Result := nullguid
  2823. else
  2824. Result := StringToGuid(S);
  2825. end;
  2826. function TGuidField.GetDefaultWidth: LongInt;
  2827. begin
  2828. Result := 38;
  2829. end;
  2830. procedure TGuidField.SetAsGuid(const AValue: TGUID);
  2831. begin
  2832. SetAsString(GuidToString(AValue));
  2833. end;
  2834. { TVariantField }
  2835. constructor TVariantField.Create(AOwner: TComponent);
  2836. begin
  2837. inherited Create(AOwner);
  2838. SetDataType(ftVariant);
  2839. end;
  2840. class procedure TVariantField.CheckTypeSize(aValue: Integer);
  2841. begin
  2842. { empty }
  2843. end;
  2844. function TVariantField.GetDefaultWidth: Integer;
  2845. begin
  2846. Result := 15;
  2847. end;
  2848. function TVariantField.GetAsBoolean: Boolean;
  2849. begin
  2850. Result := GetAsVariant;
  2851. end;
  2852. function TVariantField.GetAsDateTime: TDateTime;
  2853. begin
  2854. Result := GetAsVariant;
  2855. end;
  2856. function TVariantField.GetAsFloat: Double;
  2857. begin
  2858. Result := GetAsVariant;
  2859. end;
  2860. function TVariantField.GetAsInteger: Longint;
  2861. begin
  2862. Result := GetAsVariant;
  2863. end;
  2864. function TVariantField.GetAsString: string;
  2865. begin
  2866. Result := VarToStr(GetAsVariant);
  2867. end;
  2868. function TVariantField.GetAsWideString: WideString;
  2869. begin
  2870. Result := VarToWideStr(GetAsVariant);
  2871. end;
  2872. function TVariantField.GetAsVariant: Variant;
  2873. begin
  2874. if not GetData(@Result) then
  2875. Result := Null;
  2876. end;
  2877. procedure TVariantField.SetAsBoolean(aValue: Boolean);
  2878. begin
  2879. SetVarValue(aValue);
  2880. end;
  2881. procedure TVariantField.SetAsDateTime(aValue: TDateTime);
  2882. begin
  2883. SetVarValue(aValue);
  2884. end;
  2885. procedure TVariantField.SetAsFloat(aValue: Double);
  2886. begin
  2887. SetVarValue(aValue);
  2888. end;
  2889. procedure TVariantField.SetAsInteger(AValue: Longint);
  2890. begin
  2891. SetVarValue(aValue);
  2892. end;
  2893. procedure TVariantField.SetAsString(const aValue: string);
  2894. begin
  2895. SetVarValue(aValue);
  2896. end;
  2897. procedure TVariantField.SetAsWideString(const aValue: WideString);
  2898. begin
  2899. SetVarValue(aValue);
  2900. end;
  2901. procedure TVariantField.SetVarValue(const aValue: Variant);
  2902. begin
  2903. SetData(@aValue);
  2904. end;
  2905. { TFieldsEnumerator }
  2906. function TFieldsEnumerator.GetCurrent: TField;
  2907. begin
  2908. Result := FFields[FPosition];
  2909. end;
  2910. constructor TFieldsEnumerator.Create(AFields: TFields);
  2911. begin
  2912. inherited Create;
  2913. FFields := AFields;
  2914. FPosition := -1;
  2915. end;
  2916. function TFieldsEnumerator.MoveNext: Boolean;
  2917. begin
  2918. inc(FPosition);
  2919. Result := FPosition < FFields.Count;
  2920. end;
  2921. { TFields }
  2922. constructor TFields.Create(ADataset: TDataset);
  2923. begin
  2924. FDataSet:=ADataset;
  2925. FFieldList:=TFpList.Create;
  2926. FValidFieldKinds:=[fkData..fkInternalcalc];
  2927. end;
  2928. destructor TFields.Destroy;
  2929. begin
  2930. if Assigned(FFieldList) then
  2931. Clear;
  2932. FreeAndNil(FFieldList);
  2933. inherited Destroy;
  2934. end;
  2935. procedure TFields.ClearFieldDefs;
  2936. Var
  2937. i : Integer;
  2938. begin
  2939. For I:=0 to Count-1 do
  2940. Fields[i].FFieldDef:=Nil;
  2941. end;
  2942. procedure TFields.Changed;
  2943. begin
  2944. // Removed FDataSet.Active check, needed for Persistent fields (see bug ID 30954)
  2945. if (FDataSet <> nil) and not (csDestroying in FDataSet.ComponentState) then
  2946. FDataSet.DataEvent(deFieldListChange, 0);
  2947. If Assigned(FOnChange) then
  2948. FOnChange(Self);
  2949. end;
  2950. procedure TFields.CheckfieldKind(Fieldkind: TFieldKind; Field: TField);
  2951. begin
  2952. If Not (FieldKind in ValidFieldKinds) Then
  2953. DatabaseErrorFmt(SInvalidFieldKind,[Field.DisplayName]);
  2954. end;
  2955. function TFields.GetCount: Longint;
  2956. begin
  2957. Result:=FFieldList.Count;
  2958. end;
  2959. function TFields.GetField(Index: Integer): TField;
  2960. begin
  2961. Result:=Tfield(FFieldList[Index]);
  2962. end;
  2963. procedure TFields.SetField(Index: Integer; Value: TField);
  2964. begin
  2965. Fields[Index].Assign(Value);
  2966. end;
  2967. procedure TFields.SetFieldIndex(Field: TField; Value: Integer);
  2968. var Old : Longint;
  2969. begin
  2970. Old := FFieldList.indexOf(Field);
  2971. If Old=-1 then
  2972. Exit;
  2973. // Check value
  2974. If Value<0 Then Value:=0;
  2975. If Value>=Count then Value:=Count-1;
  2976. If Value<>Old then
  2977. begin
  2978. FFieldList.Delete(Old);
  2979. FFieldList.Insert(Value,Field);
  2980. Field.PropertyChanged(True);
  2981. Changed;
  2982. end;
  2983. end;
  2984. procedure TFields.Add(Field: TField);
  2985. begin
  2986. CheckFieldName(Field.FieldName);
  2987. FFieldList.Add(Field);
  2988. Field.FFields:=Self;
  2989. Changed;
  2990. end;
  2991. procedure TFields.CheckFieldName(const Value: String);
  2992. begin
  2993. If FindField(Value)<>Nil then
  2994. DataBaseErrorFmt(SDuplicateFieldName,[Value],FDataset);
  2995. end;
  2996. procedure TFields.CheckFieldNames(const Value: String);
  2997. var
  2998. N: String;
  2999. StrPos: Integer;
  3000. begin
  3001. if Value = '' then
  3002. Exit;
  3003. StrPos := 1;
  3004. repeat
  3005. N := ExtractFieldName(Value, StrPos);
  3006. // Will raise an error if no such field...
  3007. FieldByName(N);
  3008. until StrPos > Length(Value);
  3009. end;
  3010. procedure TFields.Clear;
  3011. var
  3012. AField: TField;
  3013. begin
  3014. while FFieldList.Count > 0 do
  3015. begin
  3016. AField := TField(FFieldList.Last);
  3017. AField.FDataSet := Nil;
  3018. AField.Free;
  3019. FFieldList.Delete(FFieldList.Count - 1);
  3020. end;
  3021. Changed;
  3022. end;
  3023. function TFields.FindField(const Value: String): TField;
  3024. var S : String;
  3025. I : longint;
  3026. begin
  3027. S:=UpperCase(Value);
  3028. For I:=0 To FFieldList.Count-1 do
  3029. begin
  3030. Result:=TField(FFieldList[I]);
  3031. if S=UpperCase(Result.FieldName) then
  3032. begin
  3033. {$ifdef dsdebug}
  3034. Writeln ('Found field ',Value);
  3035. {$endif}
  3036. Exit;
  3037. end;
  3038. end;
  3039. Result:=Nil;
  3040. end;
  3041. function TFields.FieldByName(const Value: String): TField;
  3042. begin
  3043. Result:=FindField(Value);
  3044. If result=Nil then
  3045. DatabaseErrorFmt(SFieldNotFound,[Value],FDataset);
  3046. end;
  3047. function TFields.FieldByNumber(FieldNo: Integer): TField;
  3048. var i : Longint;
  3049. begin
  3050. For I:=0 to FFieldList.Count-1 do
  3051. begin
  3052. Result:=TField(FFieldList[I]);
  3053. if FieldNo=Result.FieldNo then
  3054. Exit;
  3055. end;
  3056. Result:=Nil;
  3057. end;
  3058. function TFields.GetEnumerator: TFieldsEnumerator;
  3059. begin
  3060. Result:=TFieldsEnumerator.Create(Self);
  3061. end;
  3062. procedure TFields.GetFieldNames(Values: TStrings);
  3063. var i : longint;
  3064. begin
  3065. Values.Clear;
  3066. For I:=0 to FFieldList.Count-1 do
  3067. Values.Add(Tfield(FFieldList[I]).FieldName);
  3068. end;
  3069. function TFields.IndexOf(Field: TField): Longint;
  3070. begin
  3071. Result:=FFieldList.IndexOf(Field);
  3072. end;
  3073. procedure TFields.Remove(Value : TField);
  3074. begin
  3075. FFieldList.Remove(Value);
  3076. Value.FFields := nil;
  3077. Changed;
  3078. end;