fields.inc 77 KB

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