fields.inc 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt, member of the
  5. Free Pascal development team
  6. TFields and related components implementations.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. PRocedure DumpMem (P : Pointer;Size : Longint);
  14. Type PByte = ^Byte;
  15. Var i : longint;
  16. begin
  17. Write ('Memory dump : ');
  18. For I:=0 to Size-1 do
  19. Write (Pbyte(P)[i],' ');
  20. Writeln;
  21. end;
  22. { ---------------------------------------------------------------------
  23. TFieldDef
  24. ---------------------------------------------------------------------}
  25. Constructor TFieldDef.Create(AOwner: TFieldDefs; const AName: string;
  26. ADataType: TFieldType; ASize: Word; ARequired: Boolean; AFieldNo: Longint);
  27. begin
  28. Inherited Create(AOwner);
  29. {$ifdef dsdebug }
  30. Writeln('TFieldDef.Create : ',Aname,'(',AFieldNo,')');
  31. {$endif}
  32. FName:=Aname;
  33. FDatatype:=ADatatype;
  34. FSize:=ASize;
  35. FRequired:=ARequired;
  36. FPrecision:=-1;
  37. // Correct sizes.
  38. If FDataType=ftFloat then
  39. begin
  40. If Not (FSize in [4,8,10]) then FSize:=10
  41. end
  42. else If FDataType in [ftWord,ftsmallint,ftinteger] Then
  43. If Not (FSize in [1,2,4]) then FSize:=4;
  44. FFieldNo:=AFieldNo;
  45. AOwner.FItems.Add(Self);
  46. end;
  47. Destructor TFieldDef.Destroy;
  48. Var I : longint;
  49. begin
  50. Inherited destroy;
  51. end;
  52. Function TFieldDef.CreateField(AOwner: TComponent): TField;
  53. Var TheField : TFieldClass;
  54. begin
  55. {$ifdef dsdebug}
  56. Writeln ('Creating field '+FNAME);
  57. {$endif dsdebug}
  58. TheField:=GetFieldClass;
  59. if TheField=Nil then
  60. DatabaseErrorFmt(SUnknownFieldType,[FName]);
  61. Result:=Thefield.Create(AOwner);
  62. Try
  63. Result.Size:=FSize;
  64. Result.Required:=FRequired;
  65. Result.FieldName:=FName;
  66. Result.FFieldNo:=Self.FieldNo;
  67. Result.SetFieldType(DataType);
  68. {$ifdef dsdebug}
  69. Writeln ('TFieldDef.CReateField : Trying to set dataset');
  70. {$endif dsdebug}
  71. {$ifdef dsdebug}
  72. Writeln ('TFieldDef.CReateField : Result Fieldno : ',Result.FieldNo,' Self : ',FieldNo);
  73. {$endif dsdebug}
  74. Result.Dataset:=TFieldDefs(Owner).FDataset;
  75. If Result is TFloatField then
  76. TFloatField(Result).Precision:=FPrecision;
  77. except
  78. Result.Free;
  79. Raise;
  80. end;
  81. end;
  82. Function TFieldDef.GetFieldClass : TFieldClass;
  83. begin
  84. //!! Should be owner as tdataset but that doesn't work ??
  85. If Assigned(Owner) then
  86. Result:=TFieldDefs(Owner).FDataSet.GetFieldClass(FDataType)
  87. else
  88. Result:=Nil;
  89. end;
  90. { ---------------------------------------------------------------------
  91. TFieldDefs
  92. ---------------------------------------------------------------------}
  93. destructor TFieldDefs.Destroy;
  94. begin
  95. FItems.Free;
  96. // This will destroy all fielddefs since we own them...
  97. Inherited Destroy;
  98. end;
  99. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType);
  100. begin
  101. Add(AName,ADatatype,0,False);
  102. end;
  103. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize : Word);
  104. begin
  105. Add(AName,ADatatype,ASize,False);
  106. end;
  107. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize: Word;
  108. ARequired: Boolean);
  109. begin
  110. If Length(AName)=0 Then
  111. DatabaseError(SNeedFieldName);
  112. // the fielddef will register itself here as a owned component.
  113. // fieldno is 1 based !
  114. TFieldDef.Create(Self,AName,ADataType,ASize,Arequired,FItems.Count+1);
  115. end;
  116. function TFieldDefs.GetCount: Longint;
  117. begin
  118. Result:=FItems.Count;
  119. end;
  120. function TFieldDefs.GetItem(Index: Longint): TFieldDef;
  121. begin
  122. Result:=TFieldDef(FItems[Index]);
  123. end;
  124. constructor TFieldDefs.Create(ADataSet: TDataSet);
  125. begin
  126. Inherited Create(ADataSet);
  127. FItems:=TList.Create;
  128. FDataset:=ADataset;
  129. end;
  130. procedure TFieldDefs.Assign(FieldDefs: TFieldDefs);
  131. Var I : longint;
  132. begin
  133. Clear;
  134. For i:=0 to FieldDefs.Count-1 do
  135. With FieldDefs[i] do
  136. Add(Name,DataType,Size,Required);
  137. end;
  138. procedure TFieldDefs.Clear;
  139. Var I : longint;
  140. begin
  141. For I:=FItems.Count-1 downto 0 do
  142. TFieldDef(Fitems[i]).Free;
  143. FItems.Clear;
  144. end;
  145. function TFieldDefs.Find(const AName: string): TFieldDef;
  146. Var I : longint;
  147. begin
  148. I:=IndexOf(AName);
  149. If I=-1 Then
  150. DataBaseErrorFmt(SUnknownField,[AName,FDataSet.Name]);
  151. Result:=TFieldDef(Fitems[i]);
  152. end;
  153. function TFieldDefs.IndexOf(const AName: string): Longint;
  154. Var I : longint;
  155. begin
  156. For I:=0 to Fitems.Count-1 do
  157. If AnsiCompareText(TFieldDef(FItems[I]).Name,AName)=0 then
  158. begin
  159. Result:=I;
  160. Exit;
  161. end;
  162. Result:=-1;
  163. end;
  164. procedure TFieldDefs.Update;
  165. begin
  166. FDataSet.UpdateFieldDefs;
  167. end;
  168. Function TFieldDefs.AddFieldDef : TFieldDef;
  169. begin
  170. Result:=TFieldDef.Create(Self,'',ftUnknown,0,False,FItems.Count+1);
  171. end;
  172. { ---------------------------------------------------------------------
  173. TField
  174. ---------------------------------------------------------------------}
  175. Const
  176. SBoolean = 'Boolean';
  177. SDateTime = 'TDateTime';
  178. SFloat = 'Float';
  179. SInteger = 'Integer';
  180. SString = 'String';
  181. constructor TField.Create(AOwner: TComponent);
  182. begin
  183. Inherited Create(AOwner);
  184. FVisible:=True;
  185. FValidChars:=[#0..#155];
  186. end;
  187. destructor TField.Destroy;
  188. begin
  189. IF Assigned(FDataSet) then
  190. begin
  191. FDataSet.Active:=False;
  192. FDataSet.RemoveField(Self);
  193. end;
  194. Inherited Destroy;
  195. end;
  196. function TField.AccessError(const TypeName: string): EDatabaseError;
  197. begin
  198. Result:=EDatabaseError.CreateFmt(SinvalidTypeConversion,[TypeName,FFieldName]);
  199. end;
  200. procedure TField.Assign(Source: TPersistent);
  201. begin
  202. //!! To be implemented
  203. end;
  204. procedure TField.Change;
  205. begin
  206. If Assigned(FOnChange) Then
  207. FOnChange(Self);
  208. end;
  209. procedure TField.CheckInactive;
  210. begin
  211. If Assigned(FDataSet) then
  212. FDataset.CheckInactive;
  213. end;
  214. procedure TField.Clear;
  215. begin
  216. SetData(Nil);
  217. end;
  218. procedure TField.DataChanged;
  219. begin
  220. FDataset.DataEvent(deFieldChange,ptrint(Self));
  221. end;
  222. procedure TField.FocusControl;
  223. begin
  224. FDataSet.DataEvent(deFocusControl,ptrint(Self));
  225. end;
  226. procedure TField.FreeBuffers;
  227. begin
  228. // Empty. Provided for backward compatibiliy;
  229. // TDataset manages the buffers.
  230. end;
  231. function TField.GetAsBoolean: Boolean;
  232. begin
  233. AccessError(SBoolean);
  234. end;
  235. function TField.GetAsDateTime: TDateTime;
  236. begin
  237. AccessError(SdateTime);
  238. end;
  239. function TField.GetAsFloat: Double;
  240. begin
  241. AccessError(SDateTime);
  242. end;
  243. function TField.GetAsLongint: Longint;
  244. begin
  245. AccessError(SInteger);
  246. end;
  247. function TField.GetAsInteger: Integer;
  248. begin
  249. Result:=GetAsLongint;
  250. end;
  251. function TField.GetAsString: string;
  252. begin
  253. AccessError(SString);
  254. end;
  255. function TField.GetCanModify: Boolean;
  256. begin
  257. Result:=Not ReadOnly;
  258. If Result then
  259. begin
  260. Result:=Assigned(DataSet);
  261. If Result then
  262. Result:= DataSet.CanModify;
  263. end;
  264. end;
  265. function TField.GetData(Buffer: Pointer): Boolean;
  266. begin
  267. IF FDataset=Nil then
  268. DatabaseErrorFmt(SNoDataset,[FieldName]);
  269. If FVAlidating then
  270. begin
  271. result:=Not(FValueBuffer=Nil);
  272. If Result then
  273. Move (FValueBuffer^,Buffer^ ,DataSize);
  274. end
  275. else
  276. Result:=FDataset.GetFieldData(Self,Buffer);
  277. end;
  278. function TField.GetDataSize: Word;
  279. begin
  280. Result:=0;
  281. end;
  282. function TField.GetDefaultWidth: Longint;
  283. begin
  284. Result:=10;
  285. end;
  286. function TField.GetDisplayName : String;
  287. begin
  288. If FDisplayLabel<>'' then
  289. result:=FDisplayLabel
  290. else
  291. Result:=FFieldName;
  292. end;
  293. Function TField.IsDisplayStored : Boolean;
  294. begin
  295. Result:=(DisplayLabel<>FieldName);
  296. end;
  297. function TField.getIndex : longint;
  298. begin
  299. If Assigned(FDataset) then
  300. Result:=FDataset.FFieldList.IndexOf(Self)
  301. else
  302. Result:=-1;
  303. end;
  304. procedure TField.SetAlignment(const AValue: TAlignMent);
  305. begin
  306. if FAlignment <> AValue then
  307. begin
  308. FAlignment := Avalue;
  309. PropertyChanged(false);
  310. end;
  311. end;
  312. function TField.GetIsNull: Boolean;
  313. begin
  314. Result:=Not(GetData (Nil));
  315. end;
  316. function TField.GetParentComponent: TComponent;
  317. begin
  318. //!! To be implemented
  319. end;
  320. procedure TField.GetText(var AText: string; ADisplayText: Boolean);
  321. begin
  322. AText:=GetAsString;
  323. end;
  324. function TField.HasParent: Boolean;
  325. begin
  326. HasParent:=True;
  327. end;
  328. function TField.IsValidChar(InputChar: Char): Boolean;
  329. begin
  330. // FValidChars must be set in Create.
  331. Result:=InputChar in FValidChars;
  332. end;
  333. procedure TField.Notification(AComponent: TComponent; Operation: TOperation);
  334. begin
  335. Inherited Notification(AComponent,Operation);
  336. end;
  337. procedure TField.PropertyChanged(LayoutAffected: Boolean);
  338. begin
  339. If (FDataset<>Nil) and (FDataset.Active) then
  340. If LayoutAffected then
  341. FDataset.DataEvent(deLayoutChange,0)
  342. else
  343. FDataset.DataEvent(deDatasetchange,0);
  344. end;
  345. procedure TField.ReadState(Reader: TReader);
  346. begin
  347. //!! To be implemented
  348. end;
  349. procedure TField.SetAsBoolean(AValue: Boolean);
  350. begin
  351. AccessError(SBoolean);
  352. end;
  353. procedure TField.SetAsDateTime(AValue: TDateTime);
  354. begin
  355. AccessError(SDateTime);
  356. end;
  357. procedure TField.SetAsFloat(AValue: Double);
  358. begin
  359. AccessError(SFloat);
  360. end;
  361. procedure TField.SetAsLongint(AValue: Longint);
  362. begin
  363. AccessError(SInteger);
  364. end;
  365. procedure TField.SetAsInteger(AValue: Integer);
  366. begin
  367. SetAsLongint(AValue);
  368. end;
  369. procedure TField.SetAsString(const AValue: string);
  370. begin
  371. AccessError(SString);
  372. end;
  373. procedure TField.SetData(Buffer: Pointer);
  374. begin
  375. If Not Assigned(FDataset) then
  376. EDatabaseError.CreateFmt(SNoDataset,[FieldName]);
  377. FDataSet.SetFieldData(Self,Buffer);
  378. end;
  379. Procedure TField.SetDataset (Value : TDataset);
  380. begin
  381. {$ifdef dsdebug}
  382. Writeln ('Setting dataset');
  383. {$endif}
  384. If Value=FDataset then exit;
  385. If Assigned(FDataset) Then FDataset.CheckInactive;
  386. If Assigned(Value) then
  387. begin
  388. Value.CheckInactive;
  389. // ?? Identifier idents no member ??
  390. Value.FFieldList.CheckFieldName(FFieldName);
  391. end;
  392. If Assigned(FDataset) then
  393. FDataset.FFieldList.Remove(Self);
  394. If Assigned(Value) then
  395. Value.FFieldList.Add(Self);
  396. FDataset:=Value;
  397. end;
  398. procedure TField.SetDataType(AValue: TFieldType);
  399. begin
  400. FDataType := AValue;
  401. end;
  402. procedure TField.SetFieldType(AValue: TFieldType);
  403. begin
  404. //!! To be implemented
  405. end;
  406. procedure TField.SetParentComponent(AParent: TComponent);
  407. begin
  408. //!! To be implemented
  409. end;
  410. procedure TField.SetSize(AValue: Word);
  411. begin
  412. CheckInactive;
  413. CheckTypeSize(AValue);
  414. FSize:=AValue;
  415. end;
  416. procedure TField.SetText(const AValue: string);
  417. begin
  418. AsString:=AValue;
  419. end;
  420. procedure TField.Validate(Buffer: Pointer);
  421. begin
  422. If assigned(OnValidate) Then
  423. begin
  424. FValueBuffer:=Buffer;
  425. FValidating:=True;
  426. Try
  427. OnValidate(Self);
  428. finally
  429. FValidating:=False;
  430. end;
  431. end;
  432. end;
  433. class function Tfield.IsBlob: Boolean;
  434. begin
  435. Result:=False;
  436. end;
  437. class procedure TField.CheckTypeSize(AValue: Longint);
  438. begin
  439. If (AValue<>0) and Not IsBlob Then
  440. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  441. end;
  442. // TField private methods
  443. function TField.GetDisplayText: String;
  444. begin
  445. SetLength(Result, 0);
  446. if Assigned(OnGetText) then
  447. OnGetText(Self, Result, True)
  448. else
  449. GetText(Result, True);
  450. end;
  451. procedure TField.SetDisplayLabel(const AValue: string);
  452. begin
  453. if FDisplayLabel<>Avalue then
  454. begin
  455. FDisplayLabel:=Avalue;
  456. PropertyChanged(true);
  457. end;
  458. end;
  459. procedure TField.SetDisplayWidth(const AValue: Longint);
  460. begin
  461. if FDisplayWidth<>AValue then
  462. begin
  463. FDisplayWidth:=AValue;
  464. PropertyChanged(True);
  465. end;
  466. end;
  467. function TField.GetDisplayWidth: integer;
  468. begin
  469. if FDisplayWidth=0 then
  470. result:=GetDefaultWidth
  471. else
  472. result:=FDisplayWidth;
  473. end;
  474. procedure TField.SetReadOnly(const AValue: Boolean);
  475. begin
  476. if (FReadOnly<>Avalue) then
  477. begin
  478. FReadOnly:=AValue;
  479. PropertyChanged(True);
  480. end;
  481. end;
  482. procedure TField.SetVisible(const AValue: Boolean);
  483. begin
  484. if FVisible<>Avalue then
  485. begin
  486. FVisible:=AValue;
  487. PropertyChanged(True);
  488. end;
  489. end;
  490. { ---------------------------------------------------------------------
  491. TStringField
  492. ---------------------------------------------------------------------}
  493. constructor TStringField.Create(AOwner: TComponent);
  494. begin
  495. Inherited Create(AOwner);
  496. SetDataType(ftString);
  497. Size:=20;
  498. end;
  499. class procedure TStringField.CheckTypeSize(AValue: Longint);
  500. begin
  501. If (AValue<1) or (AValue>dsMaxStringSize) Then
  502. databaseErrorFmt(SInvalidFieldSize,[AValue])
  503. end;
  504. function TStringField.GetAsBoolean: Boolean;
  505. Var S : String;
  506. begin
  507. S:=GetAsString;
  508. result := (Length(S)>0) and (Upcase(S[1]) in ['T',YesNoChars[True]]);
  509. end;
  510. function TStringField.GetAsDateTime: TDateTime;
  511. begin
  512. Result:=StrToDateTime(GetAsString);
  513. end;
  514. function TStringField.GetAsFloat: Double;
  515. begin
  516. Result:=StrToFloat(GetAsString);
  517. end;
  518. function TStringField.GetAsLongint: Longint;
  519. begin
  520. Result:=StrToInt(GetAsString);
  521. end;
  522. function TStringField.GetAsString: string;
  523. begin
  524. If Not GetValue(Result) then
  525. Result:='';
  526. end;
  527. function TStringField.GetDataSize: Word;
  528. begin
  529. Result:=Size+1;
  530. end;
  531. function TStringField.GetDefaultWidth: Longint;
  532. begin
  533. result:=Size;
  534. end;
  535. Procedure TStringField.GetText(var AText: string; ADisplayText: Boolean);
  536. begin
  537. AText:=GetAsString;
  538. end;
  539. function TStringField.GetValue(var AValue: string): Boolean;
  540. Var Buf : TStringFieldBuffer;
  541. begin
  542. Result:=GetData(@Buf);
  543. If Result then
  544. AValue:=Buf;
  545. end;
  546. procedure TStringField.SetAsBoolean(AValue: Boolean);
  547. begin
  548. If AValue Then
  549. SetAsString('T')
  550. else
  551. SetAsString('F');
  552. end;
  553. procedure TStringField.SetAsDateTime(AValue: TDateTime);
  554. begin
  555. SetAsString(DateTimeToStr(AValue));
  556. end;
  557. procedure TStringField.SetAsFloat(AValue: Double);
  558. begin
  559. SetAsString(FloatToStr(AValue));
  560. end;
  561. procedure TStringField.SetAsLongint(AValue: Longint);
  562. begin
  563. SetAsString(intToStr(AValue));
  564. end;
  565. procedure TStringField.SetAsString(const AValue: string);
  566. Const NullByte : char = #0;
  567. begin
  568. IF Length(AValue)=0 then
  569. SetData(@NullByte)
  570. else
  571. SetData(@AValue[1]);
  572. end;
  573. { ---------------------------------------------------------------------
  574. TNumericField
  575. ---------------------------------------------------------------------}
  576. constructor TNumericField.Create(AOwner: TComponent);
  577. begin
  578. Inherited Create(AOwner);
  579. AlignMent:=taRightJustify;
  580. end;
  581. procedure TNumericField.RangeError(AValue, Min, Max: Double);
  582. begin
  583. DatabaseErrorFMT(SRangeError,[AValue,Min,Max,FieldName]);
  584. end;
  585. procedure TNumericField.SetDisplayFormat(const AValue: string);
  586. begin
  587. If FDisplayFormat<>AValue then
  588. begin
  589. FDisplayFormat:=AValue;
  590. PropertyChanged(True);
  591. end;
  592. end;
  593. procedure TNumericField.SetEditFormat(const AValue: string);
  594. begin
  595. If FEDitFormat<>AValue then
  596. begin
  597. FEDitFormat:=AVAlue;
  598. PropertyChanged(True);
  599. end;
  600. end;
  601. { ---------------------------------------------------------------------
  602. TLongintField
  603. ---------------------------------------------------------------------}
  604. constructor TLongintField.Create(AOwner: TComponent);
  605. begin
  606. Inherited Create(AOwner);
  607. SetDatatype(ftinteger);
  608. FMinRange:=Low(LongInt);
  609. FMaxRange:=High(LongInt);
  610. FValidchars:=['+','-','0'..'9'];
  611. end;
  612. function TLongintField.GetAsFloat: Double;
  613. begin
  614. Result:=GetAsLongint;
  615. end;
  616. function TLongintField.GetAsLongint: Longint;
  617. begin
  618. If Not GetValue(Result) then
  619. Result:=0;
  620. end;
  621. function TLongintField.GetAsString: string;
  622. Var L : Longint;
  623. begin
  624. If GetValue(L) then
  625. Result:=IntTostr(L)
  626. else
  627. Result:='';
  628. end;
  629. function TLongintField.GetDataSize: Word;
  630. begin
  631. Result:=SizeOf(Longint);
  632. end;
  633. procedure TLongintField.GetText(var AText: string; ADisplayText: Boolean);
  634. var l : longint;
  635. fmt : string;
  636. begin
  637. Atext:='';
  638. If Not GetValue(l) then exit;
  639. If ADisplayText or (FEditFormat='') then
  640. fmt:=FDisplayFormat
  641. else
  642. fmt:=FEditFormat;
  643. If length(fmt)<>0 then
  644. AText:=FormatFloat(fmt,L)
  645. else
  646. Str(L,AText);
  647. end;
  648. function TLongintField.GetValue(var AValue: Longint): Boolean;
  649. Type
  650. PSmallint = ^SmallInt;
  651. PLongint = ^Longint;
  652. PWord = ^Word;
  653. Var L : Longint;
  654. P : PLongint;
  655. begin
  656. P:=@L;
  657. Result:=GetData(P);
  658. If Result then
  659. Case Datatype of
  660. ftInteger,ftautoinc : AValue:=Plongint(P)^;
  661. ftword : Avalue:=Pword(P)^;
  662. ftsmallint : AValue:=PSmallint(P)^;
  663. end;
  664. end;
  665. procedure TLongintField.SetAsFloat(AValue: Double);
  666. begin
  667. SetAsLongint(Round(Avalue));
  668. end;
  669. procedure TLongintField.SetAsLongint(AValue: Longint);
  670. begin
  671. If CheckRange(AValue) then
  672. SetData(@AValue)
  673. else
  674. RangeError(Avalue,FMinrange,FMaxRange);
  675. end;
  676. procedure TLongintField.SetAsString(const AValue: string);
  677. Var L,Code : longint;
  678. begin
  679. If length(AValue)=0 then
  680. Clear
  681. else
  682. begin
  683. Val(AVAlue,L,Code);
  684. If Code=0 then
  685. SetAsLongint(L)
  686. else
  687. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  688. end;
  689. end;
  690. Function TLongintField.CheckRange(AValue : longint) : Boolean;
  691. begin
  692. result := true;
  693. if (FMaxValue=0) then
  694. begin
  695. if (AValue>FMaxRange) Then result := false;
  696. end
  697. else
  698. if AValue>FMaxValue then result := false;
  699. if (FMinValue=0) then
  700. begin
  701. if (AValue<FMinRange) Then result := false;
  702. end
  703. else
  704. if AValue<FMinValue then result := false;
  705. end;
  706. Procedure TLongintField.SetMaxValue (AValue : longint);
  707. begin
  708. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  709. FMaxValue:=AValue
  710. else
  711. RangeError(AValue,FMinRange,FMaxRange);
  712. end;
  713. Procedure TLongintField.SetMinValue (AValue : longint);
  714. begin
  715. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  716. FMinValue:=AValue
  717. else
  718. RangeError(AValue,FMinRange,FMaxRange);
  719. end;
  720. { ---------------------------------------------------------------------
  721. TLargeintField
  722. ---------------------------------------------------------------------}
  723. constructor TLargeintField.Create(AOwner: TComponent);
  724. begin
  725. Inherited Create(AOwner);
  726. SetDatatype(ftLargeint);
  727. FMinRange:=Low(Largeint);
  728. FMaxRange:=High(Largeint);
  729. FValidchars:=['+','-','0'..'9'];
  730. end;
  731. function TLargeintField.GetAsFloat: Double;
  732. begin
  733. Result:=GetAsLargeint;
  734. end;
  735. function TLargeintField.GetAsLargeint: Largeint;
  736. begin
  737. If Not GetValue(Result) then
  738. Result:=0;
  739. end;
  740. function TLargeintField.GetAsLongint: Longint;
  741. begin
  742. Result:=GetAsLargeint;
  743. end;
  744. function TLargeintField.GetAsString: string;
  745. Var L : Largeint;
  746. begin
  747. If GetValue(L) then
  748. Result:=IntTostr(L)
  749. else
  750. Result:='';
  751. end;
  752. function TLargeintField.GetDataSize: Word;
  753. begin
  754. Result:=SizeOf(Largeint);
  755. end;
  756. procedure TLargeintField.GetText(var AText: string; ADisplayText: Boolean);
  757. var l : largeint;
  758. fmt : string;
  759. begin
  760. Atext:='';
  761. If Not GetValue(l) then exit;
  762. If ADisplayText or (FEditFormat='') then
  763. fmt:=FDisplayFormat
  764. else
  765. fmt:=FEditFormat;
  766. If length(fmt)<>0 then
  767. AText:=FormatFloat(fmt,L)
  768. else
  769. Str(L,AText);
  770. end;
  771. function TLargeintField.GetValue(var AValue: Largeint): Boolean;
  772. type
  773. PLargeint = ^Largeint;
  774. Var P : PLargeint;
  775. begin
  776. P:=@AValue;
  777. Result:=GetData(P);
  778. end;
  779. procedure TLargeintField.SetAsFloat(AValue: Double);
  780. begin
  781. SetAsLargeint(Round(Avalue));
  782. end;
  783. procedure TLargeintField.SetAsLargeint(AValue: Largeint);
  784. begin
  785. If CheckRange(AValue) then
  786. SetData(@AValue)
  787. else
  788. RangeError(Avalue,FMinrange,FMaxRange);
  789. end;
  790. procedure TLargeintField.SetAsLongint(AValue: Longint);
  791. begin
  792. SetAsLargeint(Avalue);
  793. end;
  794. procedure TLargeintField.SetAsString(const AValue: string);
  795. Var L : largeint;
  796. code : longint;
  797. begin
  798. If length(AValue)=0 then
  799. Clear
  800. else
  801. begin
  802. Val(AVAlue,L,Code);
  803. If Code=0 then
  804. SetAsLargeint(L)
  805. else
  806. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  807. end;
  808. end;
  809. Function TLargeintField.CheckRange(AValue : largeint) : Boolean;
  810. begin
  811. result := true;
  812. if (FMaxValue=0) then
  813. begin
  814. if (AValue>FMaxRange) Then result := false;
  815. end
  816. else
  817. if AValue>FMaxValue then result := false;
  818. if (FMinValue=0) then
  819. begin
  820. if (AValue<FMinRange) Then result := false;
  821. end
  822. else
  823. if AValue<FMinValue then result := false;
  824. end;
  825. Procedure TLargeintField.SetMaxValue (AValue : largeint);
  826. begin
  827. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  828. FMaxValue:=AValue
  829. else
  830. RangeError(AValue,FMinRange,FMaxRange);
  831. end;
  832. Procedure TLargeintField.SetMinValue (AValue : largeint);
  833. begin
  834. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  835. FMinValue:=AValue
  836. else
  837. RangeError(AValue,FMinRange,FMaxRange);
  838. end;
  839. { TSmallintField }
  840. function TSmallintField.GetDataSize: Word;
  841. begin
  842. Result:=SizeOf(SmallInt);
  843. end;
  844. constructor TSmallintField.Create(AOwner: TComponent);
  845. begin
  846. inherited Create(AOwner);
  847. SetDataType(ftSmallInt);
  848. FMinRange:=-32768;
  849. FMaxRange:=32767;
  850. end;
  851. { TWordField }
  852. function TWordField.GetDataSize: Word;
  853. begin
  854. Result:=SizeOf(Word);
  855. end;
  856. constructor TWordField.Create(AOwner: TComponent);
  857. begin
  858. inherited Create(AOwner);
  859. SetDataType(ftWord);
  860. FMinRange:=0;
  861. FMaxRange:=65535;
  862. FValidchars:=['+','0'..'9'];
  863. end;
  864. { TAutoIncField }
  865. constructor TAutoIncField.Create(AOwner: TComponent);
  866. begin
  867. Inherited Create(AOWner);
  868. SetDataType(ftAutoInc);
  869. end;
  870. Procedure TAutoIncField.SetAsLongint(AValue : Longint);
  871. begin
  872. DataBaseError(SCantSetAutoIncfields);
  873. end;
  874. { TFloatField }
  875. function TFloatField.GetAsFloat: Double;
  876. begin
  877. If Not GetData(@Result) Then
  878. Result:=0.0;
  879. end;
  880. function TFloatField.GetAsLongint: Longint;
  881. begin
  882. Result:=Round(GetAsFloat);
  883. end;
  884. function TFloatField.GetAsString: string;
  885. Var R : Double;
  886. begin
  887. If GetData(@R) then
  888. Result:=FloatToStr(R)
  889. else
  890. Result:='';
  891. end;
  892. function TFloatField.GetDataSize: Word;
  893. begin
  894. Result:=SizeOf(Double);
  895. end;
  896. procedure TFloatField.GetText(var TheText: string; ADisplayText: Boolean);
  897. Var
  898. fmt : string;
  899. E : Double;
  900. begin
  901. text:='';
  902. If Not GetData(@E) then exit;
  903. If ADisplayText or (Length(FEditFormat) = 0) Then
  904. Fmt:=FDisplayFormat
  905. else
  906. Fmt:=FEditFormat;
  907. If fmt<>'' then
  908. TheText:=FormatFloat(fmt,E)
  909. else
  910. TheText:=FloatToStrF(E,ffgeneral,FPrecision,0);
  911. end;
  912. procedure TFloatField.SetAsFloat(AValue: Double);
  913. begin
  914. If CheckRange(AValue) then
  915. SetData(@Avalue)
  916. else
  917. RangeError(AValue,FMinValue,FMaxValue);
  918. end;
  919. procedure TFloatField.SetAsLongint(AValue: Longint);
  920. begin
  921. SetAsFloat(Avalue);
  922. end;
  923. procedure TFloatField.SetAsString(const AValue: string);
  924. Var R : Double;
  925. Code : longint;
  926. begin
  927. Val(AVAlue,R,Code);
  928. If Code<>0 then
  929. DatabaseErrorFmt(SNotAFloat,[AVAlue])
  930. Else
  931. SetAsFloat(R);
  932. end;
  933. constructor TFloatField.Create(AOwner: TComponent);
  934. begin
  935. Inherited Create(AOwner);
  936. SetDatatype(ftfloat);
  937. end;
  938. Function TFloatField.CheckRange(AValue : Double) : Boolean;
  939. begin
  940. If (FMinValue<>0) or (FmaxValue<>0) then
  941. Result:=(AValue>=FMinValue) and (AVAlue<=FMAxValue)
  942. else
  943. Result:=True;
  944. end;
  945. { TBooleanField }
  946. function TBooleanField.GetAsBoolean: Boolean;
  947. begin
  948. If not GetData(@Result) then
  949. Result:=False;
  950. end;
  951. function TBooleanField.GetAsString: string;
  952. Var B : boolean;
  953. begin
  954. If Getdata(@B) then
  955. Result:=FDisplays[False,B]
  956. else
  957. result:='';
  958. end;
  959. function TBooleanField.GetDataSize: Word;
  960. begin
  961. Result:=SizeOf(Boolean);
  962. end;
  963. function TBooleanField.GetDefaultWidth: Longint;
  964. begin
  965. Result:=Length(FDisplays[false,false]);
  966. If Result<Length(FDisplays[false,True]) then
  967. Result:=Length(FDisplays[false,True]);
  968. end;
  969. procedure TBooleanField.SetAsBoolean(AValue: Boolean);
  970. begin
  971. SetData(@AValue);
  972. end;
  973. procedure TBooleanField.SetAsString(const AValue: string);
  974. Var Temp : string;
  975. begin
  976. Temp:=UpperCase(AValue);
  977. If Temp=FDisplays[True,True] Then
  978. SetAsBoolean(True)
  979. else If Temp=FDisplays[True,False] then
  980. SetAsBoolean(False)
  981. else
  982. DatabaseErrorFmt(SNotABoolean,[AValue]);
  983. end;
  984. constructor TBooleanField.Create(AOwner: TComponent);
  985. begin
  986. Inherited Create(AOwner);
  987. SetDataType(ftBoolean);
  988. DisplayValues:='True;False';
  989. end;
  990. Procedure TBooleanField.SetDisplayValues(AValue : String);
  991. Var I : longint;
  992. begin
  993. If FDisplayValues<>AValue then
  994. begin
  995. I:=Pos(';',AValue);
  996. If (I<2) or (I=Length(AValue)) then
  997. DatabaseErrorFmt(SInvalidDisplayValues,[AValue]);
  998. FdisplayValues:=AValue;
  999. // Store display values and their uppercase equivalents;
  1000. FDisplays[False,True]:=Copy(AValue,1,I-1);
  1001. FDisplays[True,True]:=UpperCase(FDisplays[False,True]);
  1002. FDisplays[False,False]:=Copy(AValue,I+1,Length(AValue)-i);
  1003. FDisplays[True,False]:=UpperCase(FDisplays[False,False]);
  1004. PropertyChanged(True);
  1005. end;
  1006. end;
  1007. { TDateTimeField }
  1008. function TDateTimeField.GetAsDateTime: TDateTime;
  1009. begin
  1010. If Not GetData(@Result) then
  1011. Result:=0;
  1012. end;
  1013. function TDateTimeField.GetAsFloat: Double;
  1014. begin
  1015. Result:=GetAsdateTime;
  1016. end;
  1017. function TDateTimeField.GetAsString: string;
  1018. begin
  1019. GetText(Result,False);
  1020. end;
  1021. function TDateTimeField.GetDataSize: Word;
  1022. begin
  1023. Result:=SizeOf(TDateTime);
  1024. end;
  1025. procedure TDateTimeField.GetText(var TheText: string; ADisplayText: Boolean);
  1026. Var R : TDateTime;
  1027. F : String;
  1028. begin
  1029. If Not Getdata(@R) then
  1030. TheText:=''
  1031. else
  1032. begin
  1033. If (ADisplayText) and (Length(FDisplayFormat)<>0) then
  1034. F:=FDisplayFormat
  1035. else
  1036. Case DataType of
  1037. ftTime : F:=ShortTimeFormat;
  1038. ftDate : F:=ShortDateFormat;
  1039. else
  1040. F:='c'
  1041. end;
  1042. TheText:=FormatDateTime(F,R);
  1043. end;
  1044. end;
  1045. procedure TDateTimeField.SetAsDateTime(AValue: TDateTime);
  1046. begin
  1047. SetData(@Avalue);
  1048. end;
  1049. procedure TDateTimeField.SetAsFloat(AValue: Double);
  1050. begin
  1051. SetAsDateTime(AValue);
  1052. end;
  1053. procedure TDateTimeField.SetAsString(const AValue: string);
  1054. Var R : TDateTime;
  1055. begin
  1056. R:=StrToDateTime(AVAlue);
  1057. SetData(@R);
  1058. end;
  1059. constructor TDateTimeField.Create(AOwner: TComponent);
  1060. begin
  1061. Inherited Create(AOwner);
  1062. SetDataType(ftDateTime);
  1063. end;
  1064. { TDateField }
  1065. function TDateField.GetDataSize: Word;
  1066. begin
  1067. Result:=SizeOf(TDateTime);
  1068. end;
  1069. constructor TDateField.Create(AOwner: TComponent);
  1070. begin
  1071. Inherited Create(AOwner);
  1072. SetDataType(ftDate);
  1073. end;
  1074. { TTimeField }
  1075. function TTimeField.GetDataSize: Word;
  1076. begin
  1077. Result:=SizeOf(TDateTime);
  1078. end;
  1079. constructor TTimeField.Create(AOwner: TComponent);
  1080. begin
  1081. Inherited Create(AOwner);
  1082. SetDataType(ftTime);
  1083. end;
  1084. { TBinaryField }
  1085. class procedure TBinaryField.CheckTypeSize(AValue: Longint);
  1086. begin
  1087. // Just check for really invalid stuff; actual size is
  1088. // dependent on the record...
  1089. If AValue<1 then
  1090. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  1091. end;
  1092. function TBinaryField.GetAsString: string;
  1093. begin
  1094. Setlength(Result,DataSize);
  1095. GetData(Pointer(Result));
  1096. end;
  1097. procedure TBinaryField.GetText(var TheText: string; ADisplayText: Boolean);
  1098. begin
  1099. TheText:=GetAsString;
  1100. end;
  1101. procedure TBinaryField.SetAsString(const AValue: string);
  1102. Var Buf : PChar;
  1103. Allocated : Boolean;
  1104. begin
  1105. Allocated:=False;
  1106. If Length(AVAlue)=DataSize then
  1107. Buf:=PChar(Avalue)
  1108. else
  1109. begin
  1110. GetMem(Buf,DataSize);
  1111. Move(Pchar(Avalue)[0],Buf^,DataSize);
  1112. Allocated:=True;
  1113. end;
  1114. SetData(Buf);
  1115. If Allocated then
  1116. FreeMem(Buf,DataSize);
  1117. end;
  1118. procedure TBinaryField.SetText(const AValue: string);
  1119. begin
  1120. SetAsString(Avalue);
  1121. end;
  1122. constructor TBinaryField.Create(AOwner: TComponent);
  1123. begin
  1124. Inherited Create(AOwner);
  1125. end;
  1126. { TBytesField }
  1127. function TBytesField.GetDataSize: Word;
  1128. begin
  1129. Result:=Size;
  1130. end;
  1131. constructor TBytesField.Create(AOwner: TComponent);
  1132. begin
  1133. Inherited Create(AOwner);
  1134. SetDataType(ftBytes);
  1135. Size:=16;
  1136. end;
  1137. { TVarBytesField }
  1138. function TVarBytesField.GetDataSize: Word;
  1139. begin
  1140. Result:=Size+2;
  1141. end;
  1142. constructor TVarBytesField.Create(AOwner: TComponent);
  1143. begin
  1144. INherited Create(AOwner);
  1145. SetDataType(ftvarbytes);
  1146. Size:=16;
  1147. end;
  1148. { TBCDField }
  1149. class procedure TBCDField.CheckTypeSize(AValue: Longint);
  1150. begin
  1151. If not (AValue in [1..4]) then
  1152. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  1153. end;
  1154. function TBCDField.GetAsCurrency: Currency;
  1155. Var C : system.Currency;
  1156. begin
  1157. if GetData(@C) then
  1158. result := C;
  1159. end;
  1160. function TBCDField.GetAsFloat: Double;
  1161. begin
  1162. result := GetAsCurrency;
  1163. end;
  1164. function TBCDField.GetAsLongint: Longint;
  1165. begin
  1166. result := round(GetAsCurrency);
  1167. end;
  1168. function TBCDField.GetAsString: string;
  1169. var c : system.currency;
  1170. begin
  1171. If GetData(@C) then
  1172. Result:=CurrToStr(C)
  1173. else
  1174. Result:='';
  1175. end;
  1176. function TBCDField.GetDataSize: Word;
  1177. begin
  1178. result := sizeof(currency);
  1179. end;
  1180. function TBCDField.GetDefaultWidth: Longint;
  1181. begin
  1182. if precision > 0 then result := precision
  1183. else result := 10;
  1184. end;
  1185. procedure TBCDField.GetText(var TheText: string; ADisplayText: Boolean);
  1186. var c : system.currency;
  1187. begin
  1188. If GetData(@C) then
  1189. begin
  1190. if ADisplayText then
  1191. begin
  1192. if Displayformat='' then
  1193. begin
  1194. if Fcurrency then TheText := FloatToStrF(C,ffcurrency,FPrecision,0)
  1195. else TheText := FloatToStrF(C,ffgeneral,FPrecision,0);
  1196. end
  1197. else
  1198. TheText := CurrToStr(C); // ToDo: Displayformat is ignored
  1199. end
  1200. else
  1201. begin
  1202. if (Displayformat='') and (Editformat='') then
  1203. begin
  1204. if Fcurrency then TheText := FloatToStrF(C,ffcurrency,FPrecision,0)
  1205. else TheText := FloatToStrF(C,ffFixed,FPrecision,0);
  1206. end
  1207. else
  1208. TheText := CurrToStr(C); // ToDo: Displayformat is ignored
  1209. end;
  1210. end
  1211. else
  1212. TheText:='';
  1213. end;
  1214. procedure TBCDField.SetAsCurrency(AValue: Currency);
  1215. begin
  1216. If CheckRange(AValue) then
  1217. setdata(@AValue)
  1218. else
  1219. RangeError(AValue,FMinValue,FMaxvalue);
  1220. end;
  1221. Function TBCDField.CheckRange(AValue : Currency) : Boolean;
  1222. begin
  1223. If (FMinValue<>0) or (FmaxValue<>0) then
  1224. Result:=(AValue>=FMinValue) and (AVAlue<=FMaxValue)
  1225. else
  1226. Result:=True;
  1227. end;
  1228. procedure TBCDField.SetAsFloat(AValue: Double);
  1229. begin
  1230. SetAsCurrency(AValue);
  1231. end;
  1232. procedure TBCDField.SetAsLongint(AValue: Longint);
  1233. begin
  1234. SetAsCurrency(AValue);
  1235. end;
  1236. procedure TBCDField.SetAsString(const AValue: string);
  1237. begin
  1238. SetAsCurrency(strtocurr(AValue));
  1239. end;
  1240. constructor TBCDField.Create(AOwner: TComponent);
  1241. begin
  1242. Inherited Create(AOwner);
  1243. FMaxvalue := 0;
  1244. FMinvalue := 0;
  1245. SetDataType(ftBCD);
  1246. Size:=4;
  1247. end;
  1248. { TBlobField }
  1249. procedure TBlobField.AssignTo(Dest: TPersistent);
  1250. begin
  1251. //!! To be implemented
  1252. end;
  1253. Function TBlobField.GetBlobStream(Mode : TBlobStreamMode) : TStream;
  1254. begin
  1255. Result:=FDataset.CreateBlobStream(Self,Mode);
  1256. end;
  1257. procedure TBlobField.FreeBuffers;
  1258. begin
  1259. end;
  1260. function TBlobField.GetAsString: string;
  1261. var
  1262. Stream: TStream;
  1263. begin
  1264. Stream := GetBlobStream(bmRead);
  1265. if Stream<>nil then
  1266. With GetBlobStream(bmRead) do
  1267. try
  1268. SetLength(Result,Size);
  1269. ReadBuffer(Pointer(Result)^,Size);
  1270. finally
  1271. Free
  1272. end
  1273. else
  1274. Result := '(blob)';
  1275. end;
  1276. function TBlobField.GetBlobSize: Longint;
  1277. var
  1278. Stream: TStream;
  1279. begin
  1280. Stream := GetBlobStream(bmread);
  1281. if Stream <> nil then
  1282. With Stream do
  1283. try
  1284. Result:=Size;
  1285. finally
  1286. Free;
  1287. end
  1288. else
  1289. result := 0;
  1290. end;
  1291. function TBlobField.GetIsNull: Boolean;
  1292. begin
  1293. If Not Modified then
  1294. result:= inherited GetIsnull
  1295. else
  1296. With GetBlobStream(bmread) do
  1297. try
  1298. Result:=(Size=0);
  1299. Finally
  1300. Free;
  1301. end;
  1302. end;
  1303. procedure TBlobField.GetText(var TheText: string; ADisplayText: Boolean);
  1304. begin
  1305. TheText:=GetAsString;
  1306. end;
  1307. procedure TBlobField.SetAsString(const AValue: string);
  1308. begin
  1309. With GetBlobStream(bmwrite) do
  1310. try
  1311. WriteBuffer(Pointer(Avalue)^,Length(Avalue));
  1312. finally
  1313. Free;
  1314. end;
  1315. end;
  1316. procedure TBlobField.SetText(const AValue: string);
  1317. begin
  1318. SetAsString(AValue);
  1319. end;
  1320. constructor TBlobField.Create(AOwner: TComponent);
  1321. begin
  1322. Inherited Create(AOWner);
  1323. SetDataType(ftBlob);
  1324. end;
  1325. procedure TBlobField.Assign(Source: TPersistent);
  1326. begin
  1327. //!! To be implemented
  1328. end;
  1329. procedure TBlobField.Clear;
  1330. begin
  1331. GetBlobStream(bmWrite).free;
  1332. end;
  1333. class function TBlobField.IsBlob: Boolean;
  1334. begin
  1335. Result:=True;
  1336. end;
  1337. procedure TBlobField.LoadFromFile(const FileName: string);
  1338. Var S : TFileStream;
  1339. begin
  1340. S:=TFileStream.Create(FileName,fmOpenRead);
  1341. try
  1342. LoadFromStream(S);
  1343. finally
  1344. S.Free;
  1345. end;
  1346. end;
  1347. procedure TBlobField.LoadFromStream(Stream: TStream);
  1348. begin
  1349. With GetBlobStream(bmWrite) do
  1350. Try
  1351. CopyFrom(Stream,0);
  1352. finally
  1353. Free;
  1354. end;
  1355. end;
  1356. procedure TBlobField.SaveToFile(const FileName: string);
  1357. Var S : TFileStream;
  1358. begin
  1359. S:=TFileStream.Create(FileName,fmCreate);
  1360. try
  1361. SaveToStream(S);
  1362. finally
  1363. S.Free;
  1364. end;
  1365. end;
  1366. procedure TBlobField.SaveToStream(Stream: TStream);
  1367. Var S : TStream;
  1368. begin
  1369. S:=GetBlobStream(bmRead);
  1370. Try
  1371. Stream.CopyFrom(S,0);
  1372. finally
  1373. S.Free;
  1374. end;
  1375. end;
  1376. procedure TBlobField.SetFieldType(AValue: TFieldType);
  1377. begin
  1378. If AValue in [Low(TBlobType)..High(TBlobType)] then
  1379. SetDatatype(Avalue);
  1380. end;
  1381. { TMemoField }
  1382. constructor TMemoField.Create(AOwner: TComponent);
  1383. begin
  1384. Inherited Create(AOwner);
  1385. SetDataType(ftMemo);
  1386. end;
  1387. { TGraphicField }
  1388. constructor TGraphicField.Create(AOwner: TComponent);
  1389. begin
  1390. Inherited Create(AOwner);
  1391. SetDataType(ftGraphic);
  1392. end;
  1393. { TFields }
  1394. Constructor TFields.Create(ADataset : TDataset);
  1395. begin
  1396. FDataSet:=ADataset;
  1397. FFieldList:=TList.Create;
  1398. FValidFieldKinds:=[fkData..fkInternalcalc];
  1399. end;
  1400. Destructor TFields.Destroy;
  1401. begin
  1402. FFieldList.Free;
  1403. end;
  1404. Procedure Tfields.Changed;
  1405. begin
  1406. If Assigned(FOnChange) then
  1407. FOnChange(Self);
  1408. end;
  1409. Procedure TFields.CheckfieldKind(Fieldkind : TFieldKind; Field : TField);
  1410. begin
  1411. If Not (FieldKind in ValidFieldKinds) Then
  1412. DatabaseErrorFmt(SInvalidFieldKind,[Field.FieldName]);
  1413. end;
  1414. Function Tfields.GetCount : Longint;
  1415. begin
  1416. Result:=FFieldList.Count;
  1417. end;
  1418. Function TFields.GetField (Index : longint) : TField;
  1419. begin
  1420. Result:=Tfield(FFieldList[Index]);
  1421. end;
  1422. Procedure TFields.SetFieldIndex (Field : TField;Value : Integer);
  1423. Var Old : Longint;
  1424. begin
  1425. Old := FFieldList.indexOf(Field);
  1426. If Old=-1 then
  1427. Exit;
  1428. // Check value
  1429. If Value<FFieldList.Count Then Value:=0;
  1430. If Value>=Count then Value:=Count-1;
  1431. If Value<>Old then
  1432. begin
  1433. FFieldList.Delete(Old);
  1434. FFieldList.Insert(Value,Field);
  1435. Field.PropertyChanged(True);
  1436. Changed;
  1437. end;
  1438. end;
  1439. Procedure TFields.Add(Field : TField);
  1440. begin
  1441. CheckFieldName(Field.FieldName);
  1442. FFieldList.Add(Field);
  1443. Field.FFields:=Self;
  1444. Changed;
  1445. end;
  1446. Procedure TFields.CheckFieldName (Const Value : String);
  1447. Var I : longint;
  1448. S : String;
  1449. begin
  1450. If FindField(Value)<>Nil then
  1451. begin
  1452. S:=UpperCase(Value);
  1453. For I:=0 To FFieldList.Count-1 do
  1454. If S=UpperCase(TField(FFieldList[i]).FieldName) Then
  1455. DataBaseErrorFmt(SDuplicateFieldName,[Value],FDataset);
  1456. end;
  1457. end;
  1458. Procedure TFields.CheckFieldNames (Const Value : String);
  1459. Var I : longint;
  1460. S,T : String;
  1461. begin
  1462. T:=Value;
  1463. Repeat
  1464. I:=Pos(T,';');
  1465. If I=0 Then I:=Length(T);
  1466. S:=Copy(T,1,I-1);
  1467. Delete(T,1,I);
  1468. // Will raise an error if no such field...
  1469. FieldByName(S);
  1470. Until (T='');
  1471. end;
  1472. Procedure TFields.Clear;
  1473. begin
  1474. FFieldList.Clear;
  1475. end;
  1476. Function TFields.FindField (Const Value : String) : TField;
  1477. Var S : String;
  1478. I : longint;
  1479. begin
  1480. Result:=Nil;
  1481. S:=UpperCase(Value);
  1482. For I:=0 To FFieldList.Count-1 do
  1483. If S=UpperCase(TField(FFieldList[i]).FieldName) Then
  1484. Begin
  1485. {$ifdef dsdebug}
  1486. Writeln ('Found field ',Value);
  1487. {$endif}
  1488. Result:=TField(FFieldList[I]);
  1489. Exit;
  1490. end;
  1491. end;
  1492. Function TFields.FieldByName (Const Value : String) : TField;
  1493. begin
  1494. Result:=FindField(Value);
  1495. If result=Nil then
  1496. DatabaseErrorFmt(SFieldNotFound,[Value],FDataset);
  1497. end;
  1498. Function TFields.FieldByNumber(FieldNo : Integer) : TField;
  1499. Var i : Longint;
  1500. begin
  1501. Result:=Nil;
  1502. For I:=0 to FFieldList.Count-1 do
  1503. If FieldNo=TField(FFieldList[I]).FieldNo then
  1504. begin
  1505. Result:=TField(FFieldList[i]);
  1506. Exit;
  1507. end;
  1508. end;
  1509. Procedure TFields.GetFieldNames (Values : TStrings);
  1510. Var i : longint;
  1511. begin
  1512. Values.Clear;
  1513. For I:=0 to FFieldList.Count-1 do
  1514. Values.Add(Tfield(FFieldList[I]).FieldName);
  1515. end;
  1516. Function TFields.IndexOf(Field : TField) : Longint;
  1517. Var i : longint;
  1518. begin
  1519. Result:=-1;
  1520. For I:=0 To FFieldList.Count-1 do
  1521. If Pointer(Field)=FFieldList[i] Then
  1522. Exit(I);
  1523. end;
  1524. procedure TFields.Remove(Value : TField);
  1525. Var I : longint;
  1526. begin
  1527. I:=IndexOf(Value);
  1528. If I<>0 then
  1529. FFieldList.Delete(I);
  1530. end;
  1531. {
  1532. $Log$
  1533. Revision 1.19 2004-12-13 19:20:42 michael
  1534. * Patch from Joost van der Sluis
  1535. - fixed bug #3180, TFields.Clear implemented
  1536. - implemented TLargeintField
  1537. Revision 1.18 2004/12/05 00:05:38 michael
  1538. patch to enable RecNo and DisplayFormat
  1539. Revision 1.17 2004/12/04 22:43:56 michael
  1540. - implemented TBCDFields
  1541. Revision 1.16 2004/11/30 21:18:34 michael
  1542. + Fix from Jesus Reyes to fix TfieldDefs.Assign
  1543. Revision 1.15 2004/08/21 21:10:00 michael
  1544. * Patch from Joost van der Sluis
  1545. - Empty recordsets don't show any bogus data anymore
  1546. - Floatfiels.gettext fix
  1547. - SetBufListsize fix forTDBGrid
  1548. Revision 1.14 2004/08/01 13:00:29 michael
  1549. + Patch for Tlongintfield by Joost van der Sluis
  1550. Revision 1.13 2004/07/19 20:27:29 michael
  1551. + Fixes from Jesus Reyes to implement DisplayWith, DisplayLabel, Visibility
  1552. Revision 1.12 2004/07/18 13:16:50 michael
  1553. + Changed extended to double for better Delphi compatibility
  1554. Revision 1.11 2004/05/02 21:23:18 peter
  1555. * use ptrint
  1556. Revision 1.10 2004/03/25 20:43:39 michael
  1557. Some compatibility additions
  1558. Revision 1.9 2004/02/25 16:29:26 michael
  1559. + Added AsInteger to TField. Maps to AsLongint for now
  1560. Revision 1.8 2003/09/14 13:22:14 michael
  1561. + Fixed error in TField.GetCanModify reported by Andrew Johnson
  1562. Revision 1.7 2002/09/07 15:15:23 peter
  1563. * old logs removed and tabs fixed
  1564. }