fields.inc 63 KB

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