Changeset 158
Legend:
- Unmodified
- Added
- Removed
-
devel/web/UBill.pas
r142 r158 17 17 { TBillItem } 18 18 19 TBillItem = class(TDbObject) 19 TBillItem = class 20 Id: Integer; 20 21 Description: string; 21 22 Quantity: Integer; 22 23 Price: Double; 23 procedure Load; override;24 procedure Store; override;25 end; 26 27 TBillItemList = class (TDbList)24 procedure Load; 25 procedure Store; 26 end; 27 28 TBillItemList = class 28 29 end; 29 30 30 31 { TBill } 31 32 32 TBill = class (TDbObject)33 TBill = class 33 34 private 34 35 function CreateBill: Integer; 35 36 public 37 Id: Integer; 36 38 Items: TBillItemList; 37 39 User: TUser; … … 43 45 TimeDue: TDateTime; 44 46 function GenerateBill: string; 45 procedure Load; override;46 procedure Store; override;47 procedure Load; 48 procedure Store; 47 49 end; 48 50 … … 59 61 T: TUser; 60 62 begin 63 (* 61 64 T.FirstName:= 'ss'; 62 65 63 66 DbRows := Database.Select('finance_bills', '*', 'id=' + IntToStr(Id)); 64 LoadFromDbRecord(DbRows[0]);67 // LoadFromDbRecord(DbRows[0]); 65 68 DbRows.Free; 66 69 … … 74 77 BillItem := TBillItem.Create; 75 78 // BillItem.LoadFromDbRecord(DbRows[I]); 76 Items.Add(BillItem);79 // Items.Add(BillItem); 77 80 end; 78 81 … … 132 135 '<tr><td colspan="2"><hr></td></tr>' + 133 136 '</table>'; 137 *) 134 138 end; 135 139 136 140 procedure TBill.Load; 137 141 begin 142 (* 138 143 Id := StrToInt(DbRow.Values['id']); 139 144 BillCode := DbRow.Values['BillCode']; … … 143 148 TimeCreate := UnixToDateTime(StrToInt(DbRow.Values['time_create'])); 144 149 UserId := StrToInt(DbRow.Values['user_id']); 150 *) 145 151 end; 146 152 … … 158 164 Database.Update('finance_bills', Data, 'id=' + IntToStr(Id)); 159 165 Data.Free; 160 inherited Store;161 166 end; 162 167 -
devel/web/UDatabase.pas
r142 r158 1 1 unit UDatabase; 2 2 3 {$mode objfpc}{$H+}3 {$mode delphi}{$H+} 4 4 5 5 interface 6 6 7 7 uses 8 Classes, SysUtils, USqlDatabase;8 SysUtils, Variants, Classes, TypInfo, USqlDatabase, RTLConsts, Contnrs, Dialogs; 9 9 10 10 type 11 11 TDatabase = class; 12 13 { TDbObject } 14 12 TDbList = class; 13 TDbListClass = class of TDbList; 14 TDbObject = class; 15 TDbObjectClass = class of TDbObject; 16 17 {$M+} 15 18 TDbObject = class 16 Id: Integer; 17 Loaded: Boolean; 18 Database: TDatabase; 19 procedure Store; virtual; 20 procedure Load; virtual; 19 private 20 FDatabase: TDatabase; 21 FId: Integer; 22 FRow: TAssocArray; 23 procedure WriteProperty(Instance: TDbObject; PropInfo: PPropInfo; Data: TAssocArray; Depth: Integer); 24 procedure DeleteProperty(Instance: TDbObject; PropInfo: PPropInfo); 25 procedure DestroyProperty(Instance: TDbObject; PropInfo: PPropInfo; Depth: Integer); 26 procedure ReadProperty(Instance: TObject; PropInfo: PPropInfo; Data: TAssocArray; Depth: Integer); 27 function SearchPropertyByPointer(P: Pointer): string; 28 public 29 constructor Create(ADatabase: TDatabase); virtual; 30 procedure Init; 31 procedure Store(Depth: Integer = 1); virtual; 21 32 procedure Delete; 33 procedure LoadById(Id: Integer; Depth: Integer = 1); 34 procedure Load(Depth: Integer = 1); 35 procedure LoadFromRow(Row: TAssocArray; Depth: Integer = 1); 36 destructor Destroy(Depth: Integer = 100); virtual; 37 property Database: TDatabase read FDatabase write FDatabase; 38 published 39 property Id: Integer read FId write Fid; 40 end; 41 42 // TList with RTTI information 43 TPersistentList = class 44 private 45 FList: PPointerList; 46 FCount: Integer; 47 FCapacity: Integer; 48 protected 49 function Get(Index: Integer): Pointer; 50 procedure Grow; virtual; 51 procedure Put(Index: Integer; Item: Pointer); 52 procedure Notify(Ptr: Pointer; Action: TListNotification); virtual; 53 procedure SetCapacity(NewCapacity: Integer); 54 procedure SetCount(NewCount: Integer); 55 public 56 destructor Destroy; override; 57 function Add(Item: Pointer): Integer; 58 procedure Clear; virtual; 59 procedure Delete(Index: Integer); 60 class procedure Error(const Msg: string; Data: Integer); overload; virtual; 61 class procedure Error(Msg: PResStringRec; Data: Integer); overload; 62 procedure Exchange(Index1, Index2: Integer); 63 function Expand: TPersistentList; 64 function Extract(Item: Pointer): Pointer; 65 function First: Pointer; 66 function IndexOf(Item: Pointer): Integer; 67 procedure Insert(Index: Integer; Item: Pointer); 68 function Last: Pointer; 69 procedure Move(CurIndex, NewIndex: Integer); 70 function Remove(Item: Pointer): Integer; 71 procedure Pack; 72 procedure Sort(Compare: TListSortCompare); 73 procedure Assign(ListA: TPersistentList; AOperator: TListAssignOp = laCopy; ListB: TPersistentList = nil); 74 property Capacity: Integer read FCapacity write SetCapacity; 75 property Count: Integer read FCount write SetCount; 76 property Items[Index: Integer]: Pointer read Get write Put; default; 77 property List: PPointerList read FList; 78 end; 79 80 TDbList = class(TObjectList) 81 private 82 FId: Integer; 83 FItemId: Integer; 84 FDatabase: TDatabase; 85 FItemsClass: TDbObjectClass; 86 procedure Put(Index: Integer; const Value: TDbObject); virtual; 87 function Get(Index: Integer): TDbObject; virtual; 88 procedure CheckId; 89 public 90 procedure Store(Depth: Integer = 1); 91 procedure Load(Depth: Integer = 1); 92 procedure Delete; 93 constructor Create(ADatabase: TDatabase; Id: Integer); virtual; 94 destructor Destroy(Depth: Integer = 100); 95 // property Id: Integer read FId write Fid; 96 property Items[Index: Integer]: TDbObject read Get write Put; default; 97 property ItemsClass: TDbObjectClass read FItemsClass write FItemsClass; 98 published 99 property ListId: Integer read FId write Fid; 100 property ItemId: Integer read FItemId write FItemId; 101 end; 102 {$M-} 103 104 TDatabase = class(TSqlDatabase) 105 private 106 FOnError: TNotifyEvent; 107 procedure HandleError(Sender: TObject); 108 public 109 ProcessedClass: TObject; 110 DbObject: TDbObject; 22 111 constructor Create; 112 property OnError: TNotifyEvent read FOnError write FOnError; 113 procedure CheckTable; 23 114 destructor Destroy; override; 24 115 end; 25 116 26 TDbObjectClass = class of TDbObject; 27 28 { TDbList } 29 30 TDbList = class 31 Id: Integer; 32 Database: TDatabase; 33 ItemClassType: TDbObjectClass; 34 Items: TList; 35 constructor Create; 36 destructor Destroy; override; 37 function Add: TDbObject; 38 procedure Store; 39 procedure Load; 40 end; 41 42 { TDbResultSet } 43 44 TDbResultSet = class 45 Items: TList; 46 procedure Delete; 47 end; 48 49 { TDatabase } 50 51 TDatabase = class(TSqlDatabase) 52 BaseObject: TDbObject; 53 constructor Create; 54 destructor Destroy; override; 55 procedure Init; 56 end; 117 procedure LogMessage(Text: string); 57 118 58 119 implementation 59 120 60 procedure TDbObject.Store; 61 begin 62 63 end; 64 65 procedure TDbObject.Load; 66 begin 67 68 end; 69 70 procedure TDbObject.Delete; 71 begin 72 73 end; 74 75 constructor TDbObject.Create; 76 begin 77 end; 78 79 destructor TDbObject.Destroy; 80 begin 121 procedure LogMessage(Text: string); 122 begin 123 124 end; 125 126 { TDbObject } 127 128 procedure TDbObject.WriteProperty(Instance: TDbObject; PropInfo: PPropInfo; Data: TAssocArray; Depth: Integer); 129 var 130 PropType: PTypeInfo; 131 // AncestorValid: Boolean; 132 133 procedure WriteSet(Value: Longint); 134 // var 135 // I: Integer; 136 // BaseType: PTypeInfo; 137 begin 138 (* 139 BaseType := GetTypeData(PropType)^.CompType^; 140 WriteValue(vaSet); 141 for I := 0 to SizeOf(TIntegerSet) * 8 - 1 do 142 if I in TIntegerSet(Value) then WriteStr(GetEnumName(BaseType, I)); 143 WriteStr(''); 144 *) 145 end; 146 147 procedure WriteIntProp(IntType: PTypeInfo; Value: Longint); 148 var 149 Ident: string; 150 IntToIdent: TIntToIdent; 151 begin 152 IntToIdent := FindIntToIdent(IntType); 153 if Assigned(IntToIdent) and IntToIdent(Value, Ident) then 154 //WriteIdent(Ident) 155 else 156 Data.AddKeyValue(PropInfo.Name, IntToStr(Value)); 157 end; 158 159 procedure WriteOrdProp; 160 var 161 Value: Longint; 162 begin 163 Value := GetOrdProp(Instance, PropInfo); 164 case PropType^.Kind of 165 tkInteger: 166 WriteIntProp(PPropInfo(PropInfo)^.PropType, Value); 167 tkChar: 168 Data.AddKeyValue(PropInfo.Name, Chr(Value)); 169 tkSet: 170 LogMessage('Unsupported writer persistent type: Set'); 171 // WriteSet(Value); 172 tkEnumeration: 173 Data.AddKeyValue(PropInfo.Name, IntToStr(Value)); 174 end; 175 end; 176 177 procedure WriteFloatProp; 178 var 179 Value: Extended; 180 begin 181 Value := GetFloatProp(Instance, PropInfo); 182 Data.AddKeyValue(PropInfo.Name, MysqlFloatToStr(Value)); 183 end; 184 185 procedure WriteInt64Prop; 186 // var 187 // Value: Int64; 188 begin 189 (* 190 Value := GetInt64Prop(Instance, PropInfo); 191 WritePropPath; 192 WriteInteger(Value); 193 *) 194 end; 195 196 procedure WriteStrProp; 197 begin 198 Data.AddKeyValue(PropInfo.Name, GetWideStrProp(Instance, PropInfo)); 199 end; 200 201 procedure WriteObjectProp; 202 var 203 Value: TObject; 204 // OldAncestor: TPersistent; 205 // SavePropPath, ComponentValue: string; 206 begin 207 Value := TObject(GetOrdProp(Instance, PropInfo)); 208 if Value = nil then begin 209 Data.AddKeyValue(PropInfo.Name, IntToStr(0)); 210 end else if Value is TDbObject then begin 211 TDbObject(Value).Store(Depth-1); 212 Data.AddKeyValue(PropInfo.Name, IntToStr(TDbObject(Value).Id)); 213 end else if Value is TDbList then begin 214 if Value = nil then raise Exception.Create('WriteObjectProp: Unbelievable! Value is nil!'); 215 TDbList(Value).Store(Depth-1); 216 Data.AddKeyValue(PropInfo.Name, IntToStr(TDbList(Value).FId)); 217 end; 218 end; 219 220 221 begin 222 // Using IsDefaultPropertyValue will tell us if we should write out 223 // a given property because it was different from the default or 224 // different from the Ancestor (if applicable). 225 if (PropInfo^.GetProc <> nil) and 226 ((PropInfo^.SetProc <> nil) or 227 ((PropInfo^.PropType^.Kind = tkClass) and 228 (TObject(GetOrdProp(Instance, PropInfo)) is TComponent) and 229 (csSubComponent in TComponent(GetOrdProp(Instance, PropInfo)).ComponentStyle))) then 230 begin 231 LogMessage('Write property: '+Instance.ClassName+'.'+PropInfo.Name); 232 //if not IsDefaultPropertyValue(Instance, PropInfo, GetLookupInfo) then 233 begin 234 //AncestorValid := AncestorIsValid(Ancestor, Root, RootAncestor); 235 PropType := PropInfo^.PropType; 236 case PropType^.Kind of 237 tkInteger, tkChar, tkEnumeration, tkSet: 238 WriteOrdProp; 239 tkFloat: 240 WriteFloatProp; 241 tkString, tkLString, tkWString: 242 WriteStrProp; 243 tkClass: 244 WriteObjectProp; 245 //tkMethod: 246 // WriteMethodProp; 247 //tkVariant: 248 // WriteVariantProp; 249 tkInt64: 250 WriteInt64Prop; 251 //tkInterface: 252 // WriteInterfaceProp; 253 else 254 raise Exception.Create('Not supported class property '+GetEnumName(PropType, Integer(PropType^.Kind))); 255 end; 256 end; 257 end; 258 end; 259 260 261 procedure TDbObject.ReadProperty(Instance: TObject; PropInfo: PPropInfo; Data: TAssocArray; Depth: Integer); 262 const 263 NilMethod: TMethod = (Code: nil; Data: nil); 264 var 265 PropType: PTypeInfo; 266 // Method: TMethod; 267 268 procedure SetIntIdent(Instance: TPersistent; PropInfo: Pointer; 269 const Ident: string); 270 var 271 V: Longint; 272 IdentToInt: TIdentToInt; 273 begin 274 IdentToInt := FindIdentToInt(PPropInfo(PropInfo)^.PropType); 275 if Assigned(IdentToInt) and IdentToInt(Ident, V) then 276 SetOrdProp(Instance, PropInfo, V) 277 else 278 //PropValueError; 279 end; 280 281 procedure ProcessObjectProp; 282 var 283 Setter: Longint; 284 Value: TObject; 285 TypeData: PTypeData; 286 TargetObject: ^TObject; 287 TargetClass: TClass; 288 DbListClass: TDbListClass; 289 DbObjectClass: TDbObjectClass; 290 begin 291 if Depth > 0 then begin 292 // List := TDbList.Create(AClass, FDatabase, FId); 293 Value := TObject(GetOrdProp(Instance, PropInfo)); 294 TypeData := GetTypeData(PropInfo.PropType); 295 // ShowMessage(PropInfo.Name+' '+TypeData.ClassType.ClassName); 296 if Value = nil then begin 297 Setter := Longint(PropInfo^.SetProc); 298 if (Setter and $FF000000) = $FF000000 then 299 begin // field - Setter is the field's offset in the instance data 300 TargetObject := Pointer(Integer(Instance) + (Setter and $00FFFFFF)); 301 TargetClass := TypeData.ClassType; 302 // TargetClass := TargetClass.ClassParent; 303 // ShowMessage(TargetClass.ClassName); 304 if TargetClass.ClassParent = TDbObject then begin 305 DbObjectClass := TDbObjectClass(TargetClass); 306 TargetObject^ := DbObjectClass.Create(FDatabase); // auto ref count 307 end else 308 if TargetClass.ClassParent = TDbList then begin 309 DbListClass := TDbListClass(TargetClass); 310 //ShowMessage(DbListClass.ClassName); 311 312 TargetObject^ := DbListClass.Create(FDatabase, StrToInt(FRow.Values[PropInfo.Name])); // auto ref count 313 end else TargetObject^ := TargetClass.Create; // auto ref count 314 Value := TObject(GetOrdProp(Instance, PropInfo)); 315 end else raise Exception.Create('Object property '+PropInfo.Name+' in object '+Instance.ClassName+' is not mapped directly to variable!'); 316 end; 317 //ShowMessage(IntToStr(Integer(Value.ClassInfo))); 318 if Value is TDbObject then begin 319 (Value as TDbObject).LoadById(StrToInt(FRow.Values[PropInfo.Name]), Depth-1); 320 //ShowMessage(Value.ClassName); 321 end else if Value is TDbList then begin 322 (Value as TDbList).Load(Depth); 323 //ShowMessage(Value.ClassName); 324 end; 325 end; 326 end; 327 328 begin 329 LogMessage('Read property: ' + Instance.ClassName + '.' + PropInfo.Name); 330 // if PPropInfo(PropInfo)^.SetProc = nil then 331 // if not ((PPropInfo(PropInfo)^.PropType^.Kind = tkClass) and 332 // (TObject(GetOrdProp(Instance, PropInfo)) is TComponent) and 333 // (csSubComponent in TComponent(GetOrdProp(Instance, PropInfo)).ComponentStyle)) then 334 // ReadError(@SReadOnlyProperty); 335 PropType := PPropInfo(PropInfo)^.PropType; 336 try 337 case PropType^.Kind of 338 tkInteger: 339 // if NextValue = vaIdent then 340 // SetIntIdent(Instance, PropInfo, Data) 341 // else 342 SetOrdProp(Instance, PropInfo, StrToInt(Data.Values[PropInfo.Name])); 343 tkChar: 344 SetOrdProp(Instance, PropInfo, Ord(Data.Values[PropInfo.Name][1])); 345 tkEnumeration: 346 SetOrdProp(Instance, PropInfo, StrToInt(Data.Values[PropInfo.Name])); 347 tkFloat: 348 SetFloatProp(Instance, PropInfo, MySqlStrToFloat(Data.Values[PropInfo.Name])); 349 tkString, tkLString: 350 SetStrProp(Instance, PropInfo, Data.Values[PropInfo.Name]); 351 tkWString: 352 SetWideStrProp(Instance, PropInfo, Data.Values[PropInfo.Name]); 353 tkSet: 354 LogMessage('Unsupported reader property type: Set'); 355 //SetOrdProp(Instance, PropInfo, ReadSet(PropType)); 356 tkClass: ProcessObjectProp; 357 (* 358 case NextValue of 359 vaNil: 360 begin 361 ReadValue; 362 SetOrdProp(Instance, PropInfo, 0); 363 end; 364 vaCollection: 365 begin 366 ReadValue; 367 ReadCollection(TCollection(GetOrdProp(Instance, PropInfo))); 368 end 369 else 370 SetObjectIdent(Instance, PropInfo, ReadIdent); 371 end; 372 *) 373 (* tkMethod: 374 if NextValue = vaNil then 375 begin 376 ReadValue; 377 SetMethodProp(Instance, PropInfo, NilMethod); 378 end 379 else 380 begin 381 Method.Code := FindMethod(Root, ReadIdent); 382 Method.Data := Root; 383 if Method.Code <> nil then SetMethodProp(Instance, PropInfo, Method); 384 end; 385 tkVariant: 386 SetVariantReference; 387 tkInt64: 388 SetInt64Prop(Instance, PropInfo, ReadInt64); 389 tkInterface: 390 SetInterfaceReference; 391 *) 392 end; 393 finally 394 end; 395 end; 396 397 procedure TDbObject.Init; 398 begin 399 end; 400 401 destructor TDbObject.Destroy(Depth: Integer = 100); 402 var 403 I, Count: Integer; 404 PropInfo: PPropInfo; 405 PropList: PPropList; 406 // Name: string; 407 begin 408 LogMessage('Destroy class: ' + Self.ClassName); 409 if Depth >= 0 then begin 410 Store(0); 411 if Self.ClassInfo = nil then raise Exception.Create('Class ' + Self.ClassName + ' doesn''t provide RTTI information!'); 412 Count := GetTypeData(Self.ClassInfo)^.PropCount; 413 if Count > 0 then with FDatabase do begin 414 ProcessedClass := Self; 415 GetMem(PropList, Count * SizeOf(Pointer)); 416 try 417 GetPropInfos(Self.ClassInfo, PropList); 418 for I := 0 to Count - 1 do 419 begin 420 PropInfo := PropList^[I]; 421 if PropInfo = nil then 422 Break; 423 if IsStoredProp(Self, PropInfo) then 424 DestroyProperty(Self, PropInfo, Depth); 425 end; 426 finally 427 FreeMem(PropList, Count * SizeOf(Pointer)); 428 end; 429 end; 81 430 inherited Destroy; 431 end; 432 end; 433 434 procedure TDbObject.Store(Depth: Integer = 1); 435 var 436 Data: TAssocArray; 437 I, Count: Integer; 438 PropInfo: PPropInfo; 439 PropList: PPropList; 440 // Name: string; 441 begin 442 LogMessage('Write class: ' + Self.ClassName); 443 if Depth >= 0 then begin 444 Data := TAssocArray.Create; 445 if Self.ClassInfo = nil then raise Exception.Create('Trida '+Self.ClassName+' neposkytuje RTTI informace!'); 446 Count := GetTypeData(Self.ClassInfo)^.PropCount; 447 if Count > 0 then with FDatabase do begin 448 GetMem(PropList, Count * SizeOf(Pointer)); 449 try 450 GetPropInfos(Self.ClassInfo, PropList); 451 for I := 0 to Count - 1 do 452 begin 453 PropInfo := PropList^[I]; 454 if PropInfo = nil then 455 Break; 456 if IsStoredProp(Self, PropInfo) then 457 WriteProperty(Self, PropInfo, Data, Depth); 458 end; 459 460 ProcessedClass := Self; 461 repeat 462 Replace(Self.ClassName, Data); 463 until not RepeatLastAction; 464 FId := FDatabase.LastInsertId; 465 finally 466 FreeMem(PropList, Count * SizeOf(Pointer)); 467 end; 468 end; 469 // Instance.DefineProperties(Self); 470 end; 471 end; 472 473 function TDbObject.SearchPropertyByPointer(P: Pointer): string; 474 var 475 // Data: TAssocArray; 476 I, Count: Integer; 477 PropInfo: PPropInfo; 478 PropList: PPropList; 479 Instance: TObject; 480 // Name: string; 481 begin 482 Instance := Self; 483 if Self.ClassInfo = nil then raise Exception.Create('Trida '+Self.ClassName+' neposkytuje RTTI informace!'); 484 Count := GetTypeData(Self.ClassInfo)^.PropCount; 485 if Count > 0 then with FDatabase do begin 486 ProcessedClass := Self; 487 GetMem(PropList, Count * SizeOf(Pointer)); 488 try 489 GetPropInfos(Self.ClassInfo, PropList); 490 for I := 0 to Count - 1 do 491 begin 492 PropInfo := PropList^[I]; 493 if PropInfo = nil then 494 Break; 495 if IsStoredProp(Instance, PropInfo) then 496 if GetObjectProp(Self,PropInfo) = P then begin 497 Result := PropInfo.Name; 498 Break; 499 end; 500 end; 501 finally 502 FreeMem(PropList, Count * SizeOf(Pointer)); 503 end; 504 end; 82 505 end; 83 506 84 507 { TDbList } 85 508 86 constructor TDbList.Create; 87 begin 88 Items := TList.Create; 89 end; 90 91 destructor TDbList.Destroy; 509 procedure TDbList.CheckId; 510 var 511 Rows: TDbRows; 512 begin 513 if FId = 0 then begin 514 FDatabase.ProcessedClass := Self; 515 Rows := FDatabase.Select(Self.ClassName, 'MAX(ListId)'); 516 // ShowMessage(Rows[0].Values['MAX(ListId)']); 517 if Rows.Count > 0 then begin 518 if Rows[0].Values['MAX(ListId)'] = '' then FId := 1 else 519 FId := StrToInt(Rows[0].Values['MAX(ListId)']) + 1; 520 end else FId := 1; 521 Rows.Free; 522 end; 523 end; 524 525 constructor TDbList.Create(ADatabase: TDatabase; Id: Integer); 526 begin 527 FId := Id; 528 FDatabase := ADatabase; 529 // inherited Create(FDatabase); 530 //Load; 531 end; 532 533 procedure TDbList.Delete; 92 534 var 93 535 I: Integer; 94 536 begin 95 for I := 0 to Items.Count - 1 do 96 TDbObject(Items[I]).Free; 97 Items.Free; 98 inherited Destroy; 99 end; 100 101 function TDbList.Add: TDbObject; 102 var 103 Data: TAssocArray; 104 begin 105 Result := ItemClassType.Create; 106 Data := TAssocArray.Create; 107 Data.AddKeyValue('id', ''); 108 Database.Insert(ClassName, Data); 109 Result.Id := Database.LastInsertId;; 110 Items.Add(Result); 111 end; 112 113 procedure TDbList.Store; 537 for I := 0 to Count-1 do Items[I].Delete; 538 FDatabase.Select(Self.ClassName, 'ListId=' + IntToStr(FId)) 539 end; 540 541 destructor TDbList.Destroy(Depth: Integer = 100); 542 var 543 I: Integer; 544 begin 545 LogMessage('Destroy DbList: ' + Self.ClassName); 546 Store(0); 547 if Depth >= 0 then begin 548 if Depth > 0 then for I := 0 to Count-1 do if Assigned(Items[I]) then TDbObject(Items[I]).Destroy(Depth); 549 inherited Destroy; 550 end; 551 end; 552 553 function TDbList.Get(Index: Integer): TDbObject; 554 begin 555 Result := inherited Get(Index); 556 end; 557 558 procedure TDbList.Load(Depth: Integer = 1); 559 var 560 // B: TObject; 561 DbRows: TDbRows; 562 I: Integer; 563 // d: TPersistentList; 564 begin 565 // d:= TPersistentList.Create; 566 // ShowMessage(IntToStr(Integer(d.ClassInfo))); 567 FDatabase.ProcessedClass := Self; 568 //ShowMessage(IntToStr(Integer(FDatabase.ProcessedClass.ClassInfo))); 569 FDatabase.Table := Self.ClassName; 570 DbRows := FDatabase.Select(FDatabase.Table, '*', 'ListId=' + IntToStr(FId) + ' ORDER BY id'); 571 Count := DbRows.Count; 572 for I := 0 to DbRows.Count-1 do begin 573 Items[I] := ItemsClass.Create(FDatabase); 574 if Depth > 0 then Items[I].LoadById(StrToInt(DbRows.Data[I].Values['ItemId']), Depth-1); 575 // FromRow(Items[I], DbRows.Data[I]); 576 end; 577 end; 578 579 procedure TDbList.Put(Index: Integer; const Value: TDbObject); 580 begin 581 inherited Put(Index, Value); 582 end; 583 584 procedure TDbList.Store(Depth: Integer = 1); 114 585 var 115 586 I: Integer; 116 587 Data: TAssocArray; 117 588 begin 589 if Depth >= 0 then begin 590 CheckId; 591 FDatabase.ProcessedClass := Self; 592 FDatabase.Delete(Self.ClassName, 'ListId='+IntToStr(FId)); 593 if Self.ClassName = 'tmeasurepointsetlist' then LogMessage('d'); 118 594 Data := TAssocArray.Create; 119 Database.Insert(ClassName, Data); 120 for I := 0 to Items.Count - 1 do begin 121 Database.Insert(ClassName, Data); 122 end; 123 end; 124 125 procedure TDbList.Load; 126 begin 127 128 end; 129 130 { TDbResultSet } 131 132 procedure TDbResultSet.Delete; 595 Data.AddKeyValue('ListId', IntToStr(FId)); 596 Data.AddKeyValue('ItemId', '0'); 597 for I := 0 to Count-1 do 598 if Assigned(Items[I]) then begin 599 if Depth > 0 then Items[I].Store(Depth); 600 Data.Values['ItemId'] := IntToStr(TDbObject(Items[I]).FId); 601 FDatabase.ProcessedClass := Self; 602 FDatabase.Insert(Self.ClassName, Data); 603 end else raise Exception.Create('Item '+IntToStr(I)+' in '+Self.ClassName+' is nil!'); 604 Data.Free; 605 // inherited StoreClassName(FItemsClass.ClassName+'_list', Depth); 606 end; 607 end; 608 609 { TDatabase } 610 611 procedure TDatabase.CheckTable; 612 begin 613 614 end; 615 616 constructor TDatabase.Create; 617 begin 618 inherited; 619 inherited OnError := HandleError; 620 end; 621 622 destructor TDatabase.Destroy; 623 begin 624 Disconnect; 625 inherited; 626 end; 627 628 procedure TDbObject.LoadFromRow(Row: TAssocArray; Depth: Integer = 1); 629 var 630 I, Count: Integer; 631 PropInfo: PPropInfo; 632 PropList: PPropList; 633 begin 634 LogMessage('Load class: ' + Self.ClassName); 635 // ShowMessage(Row.GetAllValues); 636 FRow := Row; 637 if Self.ClassInfo = nil then raise Exception.Create('Trida '+Self.ClassName+' neposkytuje RTTI informace!'); 638 Count := GetTypeData(Self.ClassInfo)^.PropCount; 639 if Count > 0 then with FDatabase do begin 640 ProcessedClass := Self; 641 GetMem(PropList, Count * SizeOf(Pointer)); 642 try 643 GetPropInfos(Self.ClassInfo, PropList); 644 for I := 0 to Count - 1 do 645 begin 646 PropInfo := PropList^[I]; 647 if PropInfo = nil then 648 Break; 649 if IsStoredProp(Self, PropInfo) then 650 ReadProperty(Self, PropInfo, Row, Depth); 651 end; 652 finally 653 FreeMem(PropList, Count * SizeOf(Pointer)); 654 end; 655 end; 656 // Instance.DefineProperties(Self); 657 // Data.Free; 658 FRow := nil; 659 end; 660 661 procedure TDatabase.HandleError(Sender: TObject); 662 var 663 Name: string; 664 PropInfo: PPropInfo; 665 begin 666 if LastErrorNumber = 1146 then begin // Table doesn't exist 667 CreateTable(Table); 668 RepeatLastAction := True; 669 end else 670 if LastErrorNumber = 1054 then begin // Unknown column 671 Name := Copy(LastErrorMessage, Pos('''', LastErrorMessage) + 1, Length(LastErrorMessage)); 672 Name := Copy(Name, 1, Pos('''', Name)-1); 673 //ShowMessage(IntToStr(Integer(ProcessedClass.ClassInfo))); 674 //ShowMessage(ProcessedClass.ClassName); 675 PropInfo := GetPropInfo(ProcessedClass.ClassInfo, Name); 676 if PropInfo = nil then 677 raise Exception.Create('Missing published property '+Name+' in class '+ProcessedClass.ClassName) 678 else CreateColumn(Table, PropInfo.Name, PropInfo.PropType^.Kind); 679 RepeatLastAction := True; 680 end else begin 681 if Assigned(FOnError) then FOnError(Self); 682 end; 683 end; 684 685 constructor TDbObject.Create(ADatabase: TDatabase); 686 begin 687 FDatabase := ADatabase; 688 FId := 0; 689 end; 690 691 procedure TDbObject.LoadById(Id: Integer; Depth: Integer = 1); 692 var 693 Rows: TDbRows; 694 begin 695 FId := Id; 696 Rows := FDatabase.Select(Self.ClassName, '*', 'id=' + IntToStr(FId)); 697 if Rows.Count > 0 then LoadFromRow(Rows[0], Depth) else begin 698 Store; 699 Rows.Free; 700 Rows := FDatabase.Select(Self.ClassName, '*', 'id=' + IntToStr(FId)); 701 LoadFromRow(Rows[0], Depth); 702 end; 703 Rows.Free; 704 end; 705 706 { TPersistentList } 707 708 destructor TPersistentList.Destroy; 709 begin 710 Clear; 711 end; 712 713 function TPersistentList.Add(Item: Pointer): Integer; 714 begin 715 Result := FCount; 716 if Result = FCapacity then 717 Grow; 718 FList^[Result] := Item; 719 Inc(FCount); 720 if Item <> nil then 721 Notify(Item, lnAdded); 722 end; 723 724 procedure TPersistentList.Clear; 725 begin 726 SetCount(0); 727 SetCapacity(0); 728 end; 729 730 procedure TPersistentList.Delete(Index: Integer); 731 var 732 Temp: Pointer; 733 begin 734 if (Index < 0) or (Index >= FCount) then 735 Error(@SListIndexError, Index); 736 Temp := Items[Index]; 737 Dec(FCount); 738 if Index < FCount then 739 System.Move(FList^[Index + 1], FList^[Index], 740 (FCount - Index) * SizeOf(Pointer)); 741 if Temp <> nil then 742 Notify(Temp, lnDeleted); 743 end; 744 745 class procedure TPersistentList.Error(const Msg: string; Data: Integer); 746 747 (* 748 function ReturnAddr: Pointer; 749 asm 750 MOV EAX,[EBP+4] 751 end; 752 *) 753 754 begin 755 // raise EListError.CreateFmt(Msg, [Data]) at ReturnAddr; 756 end; 757 758 class procedure TPersistentList.Error(Msg: PResStringRec; Data: Integer); 759 begin 760 TPersistentList.Error(LoadResString(Msg), Data); 761 end; 762 763 procedure TPersistentList.Exchange(Index1, Index2: Integer); 764 var 765 Item: Pointer; 766 begin 767 if (Index1 < 0) or (Index1 >= FCount) then 768 Error(@SListIndexError, Index1); 769 if (Index2 < 0) or (Index2 >= FCount) then 770 Error(@SListIndexError, Index2); 771 Item := FList^[Index1]; 772 FList^[Index1] := FList^[Index2]; 773 FList^[Index2] := Item; 774 end; 775 776 function TPersistentList.Expand: TPersistentList; 777 begin 778 if FCount = FCapacity then 779 Grow; 780 Result := Self; 781 end; 782 783 function TPersistentList.First: Pointer; 784 begin 785 Result := Get(0); 786 end; 787 788 function TPersistentList.Get(Index: Integer): Pointer; 789 begin 790 if (Index < 0) or (Index >= FCount) then 791 Error(@SListIndexError, Index); 792 Result := FList^[Index]; 793 end; 794 795 procedure TPersistentList.Grow; 796 var 797 Delta: Integer; 798 begin 799 if FCapacity > 64 then 800 Delta := FCapacity div 4 801 else 802 if FCapacity > 8 then 803 Delta := 16 804 else 805 Delta := 4; 806 SetCapacity(FCapacity + Delta); 807 end; 808 809 function TPersistentList.IndexOf(Item: Pointer): Integer; 810 begin 811 Result := 0; 812 while (Result < FCount) and (FList^[Result] <> Item) do 813 Inc(Result); 814 if Result = FCount then 815 Result := -1; 816 end; 817 818 procedure TPersistentList.Insert(Index: Integer; Item: Pointer); 819 begin 820 if (Index < 0) or (Index > FCount) then 821 Error(@SListIndexError, Index); 822 if FCount = FCapacity then 823 Grow; 824 if Index < FCount then 825 System.Move(FList^[Index], FList^[Index + 1], 826 (FCount - Index) * SizeOf(Pointer)); 827 FList^[Index] := Item; 828 Inc(FCount); 829 if Item <> nil then 830 Notify(Item, lnAdded); 831 end; 832 833 function TPersistentList.Last: Pointer; 834 begin 835 Result := Get(FCount - 1); 836 end; 837 838 procedure TPersistentList.Move(CurIndex, NewIndex: Integer); 839 var 840 Item: Pointer; 841 begin 842 if CurIndex <> NewIndex then 843 begin 844 if (NewIndex < 0) or (NewIndex >= FCount) then 845 Error(@SListIndexError, NewIndex); 846 Item := Get(CurIndex); 847 FList^[CurIndex] := nil; 848 Delete(CurIndex); 849 Insert(NewIndex, nil); 850 FList^[NewIndex] := Item; 851 end; 852 end; 853 854 procedure TPersistentList.Put(Index: Integer; Item: Pointer); 855 var 856 Temp: Pointer; 857 begin 858 if (Index < 0) or (Index >= FCount) then 859 Error(@SListIndexError, Index); 860 if Item <> FList^[Index] then 861 begin 862 Temp := FList^[Index]; 863 FList^[Index] := Item; 864 if Temp <> nil then 865 Notify(Temp, lnDeleted); 866 if Item <> nil then 867 Notify(Item, lnAdded); 868 end; 869 end; 870 871 function TPersistentList.Remove(Item: Pointer): Integer; 872 begin 873 Result := IndexOf(Item); 874 if Result >= 0 then 875 Delete(Result); 876 end; 877 878 procedure TPersistentList.Pack; 133 879 var 134 880 I: Integer; 135 881 begin 136 for I := 0 to Items.Count - 1 do 137 TDbObject(Items[I]).Free; 138 Items.Free; 139 end; 140 141 { TDatabase } 142 143 constructor TDatabase.Create; 144 begin 145 BaseObject := TDbObject.Create;; 146 end; 147 148 destructor TDatabase.Destroy; 149 begin 150 BaseObject.Free; 151 end; 152 153 procedure TDatabase.Init; 154 begin 155 BaseObject.Id := 1; 156 BaseObject.Database := Self; 157 BaseObject.Load; 882 for I := FCount - 1 downto 0 do 883 if Items[I] = nil then 884 Delete(I); 885 end; 886 887 procedure TPersistentList.SetCapacity(NewCapacity: Integer); 888 begin 889 if (NewCapacity < FCount) or (NewCapacity > MaxListSize) then 890 Error(@SListCapacityError, NewCapacity); 891 if NewCapacity <> FCapacity then 892 begin 893 ReallocMem(FList, NewCapacity * SizeOf(Pointer)); 894 FCapacity := NewCapacity; 895 end; 896 end; 897 898 procedure TPersistentList.SetCount(NewCount: Integer); 899 var 900 I: Integer; 901 begin 902 if (NewCount < 0) or (NewCount > MaxListSize) then 903 Error(@SListCountError, NewCount); 904 if NewCount > FCapacity then 905 SetCapacity(NewCount); 906 if NewCount > FCount then 907 FillChar(FList^[FCount], (NewCount - FCount) * SizeOf(Pointer), 0) 908 else 909 for I := FCount - 1 downto NewCount do 910 Delete(I); 911 FCount := NewCount; 912 end; 913 914 procedure QuickSort(SortList: PPointerList; L, R: Integer; 915 SCompare: TListSortCompare); 916 var 917 I, J: Integer; 918 P, T: Pointer; 919 begin 920 repeat 921 I := L; 922 J := R; 923 P := SortList^[(L + R) shr 1]; 924 repeat 925 while SCompare(SortList^[I], P) < 0 do 926 Inc(I); 927 while SCompare(SortList^[J], P) > 0 do 928 Dec(J); 929 if I <= J then 930 begin 931 T := SortList^[I]; 932 SortList^[I] := SortList^[J]; 933 SortList^[J] := T; 934 Inc(I); 935 Dec(J); 936 end; 937 until I > J; 938 if L < J then 939 QuickSort(SortList, L, J, SCompare); 940 L := I; 941 until I >= R; 942 end; 943 944 procedure TPersistentList.Sort(Compare: TListSortCompare); 945 begin 946 if (FList <> nil) and (Count > 0) then 947 QuickSort(FList, 0, Count - 1, Compare); 948 end; 949 950 function TPersistentList.Extract(Item: Pointer): Pointer; 951 var 952 I: Integer; 953 begin 954 Result := nil; 955 I := IndexOf(Item); 956 if I >= 0 then 957 begin 958 Result := Item; 959 FList^[I] := nil; 960 Delete(I); 961 Notify(Result, lnExtracted); 962 end; 963 end; 964 965 procedure TPersistentList.Notify(Ptr: Pointer; Action: TListNotification); 966 begin 967 end; 968 969 procedure TPersistentList.Assign(ListA: TPersistentList; AOperator: TListAssignOp; ListB: TPersistentList); 970 var 971 I: Integer; 972 LTemp, LSource: TPersistentList; 973 begin 974 // ListB given? 975 if ListB <> nil then 976 begin 977 LSource := ListB; 978 Assign(ListA); 979 end 980 else 981 LSource := ListA; 982 983 // on with the show 984 case AOperator of 985 986 // 12345, 346 = 346 : only those in the new list 987 laCopy: 988 begin 989 Clear; 990 Capacity := LSource.Capacity; 991 for I := 0 to LSource.Count - 1 do 992 Add(LSource[I]); 993 end; 994 995 // 12345, 346 = 34 : intersection of the two lists 996 laAnd: 997 for I := Count - 1 downto 0 do 998 if LSource.IndexOf(Items[I]) = -1 then 999 Delete(I); 1000 1001 // 12345, 346 = 123456 : union of the two lists 1002 laOr: 1003 for I := 0 to LSource.Count - 1 do 1004 if IndexOf(LSource[I]) = -1 then 1005 Add(LSource[I]); 1006 1007 // 12345, 346 = 1256 : only those not in both lists 1008 laXor: 1009 begin 1010 LTemp := TPersistentList.Create; // Temp holder of 4 byte values 1011 try 1012 LTemp.Capacity := LSource.Count; 1013 for I := 0 to LSource.Count - 1 do 1014 if IndexOf(LSource[I]) = -1 then 1015 LTemp.Add(LSource[I]); 1016 for I := Count - 1 downto 0 do 1017 if LSource.IndexOf(Items[I]) <> -1 then 1018 Delete(I); 1019 I := Count + LTemp.Count; 1020 if Capacity < I then 1021 Capacity := I; 1022 for I := 0 to LTemp.Count - 1 do 1023 Add(LTemp[I]); 1024 finally 1025 LTemp.Free; 1026 end; 1027 end; 1028 1029 // 12345, 346 = 125 : only those unique to source 1030 laSrcUnique: 1031 for I := Count - 1 downto 0 do 1032 if LSource.IndexOf(Items[I]) <> -1 then 1033 Delete(I); 1034 1035 // 12345, 346 = 6 : only those unique to dest 1036 laDestUnique: 1037 begin 1038 LTemp := TPersistentList.Create; 1039 try 1040 LTemp.Capacity := LSource.Count; 1041 for I := LSource.Count - 1 downto 0 do 1042 if IndexOf(LSource[I]) = -1 then 1043 LTemp.Add(LSource[I]); 1044 Assign(LTemp); 1045 finally 1046 LTemp.Free; 1047 end; 1048 end; 1049 end; 1050 end; 1051 1052 procedure TDbObject.DeleteProperty(Instance: TDbObject; PropInfo: PPropInfo); 1053 var 1054 PropType: PTypeInfo; 1055 1056 procedure WriteObjectProp; 1057 var 1058 Value: TObject; 1059 // OldAncestor: TPersistent; 1060 // SavePropPath, ComponentValue: string; 1061 Setter: Longint; 1062 TargetObject: ^TObject; 1063 begin 1064 Value := TObject(GetOrdProp(Instance, PropInfo)); 1065 if Value = nil then begin 1066 end else begin 1067 if Value is TDbObject then begin 1068 TDbObject(Value).Delete; 1069 end else if Value is TDbList then begin 1070 TDbList(Value).Delete; 1071 end; 1072 1073 // Set object reference to nil 1074 Setter := Longint(PropInfo^.SetProc); 1075 if (Setter and $FF000000) = $FF000000 then 1076 begin // field - Setter is the field's offset in the instance data 1077 TargetObject := Pointer(Integer(Instance) + (Setter and $00FFFFFF)); 1078 TargetObject^ := nil; // auto ref count 1079 end; 1080 end; 1081 end; 1082 1083 1084 begin 1085 // Using IsDefaultPropertyValue will tell us if we should write out 1086 // a given property because it was different from the default or 1087 // different from the Ancestor (if applicable). 1088 if (PropInfo^.GetProc <> nil) and 1089 ((PropInfo^.SetProc <> nil) or 1090 ((PropInfo^.PropType^.Kind = tkClass) and 1091 (TObject(GetOrdProp(Instance, PropInfo)) is TComponent) and 1092 (csSubComponent in TComponent(GetOrdProp(Instance, PropInfo)).ComponentStyle))) then 1093 begin 1094 LogMessage('Destroy property: '+Instance.ClassName+'.'+PropInfo.Name); 1095 //if not IsDefaultPropertyValue(Instance, PropInfo, GetLookupInfo) then 1096 begin 1097 //AncestorValid := AncestorIsValid(Ancestor, Root, RootAncestor); 1098 PropType := PropInfo^.PropType; 1099 case PropType^.Kind of 1100 tkClass: 1101 WriteObjectProp; 1102 end; 1103 end; 1104 end; 1105 end; 1106 1107 procedure TDbObject.DestroyProperty(Instance: TDbObject; PropInfo: PPropInfo; Depth: Integer); 1108 var 1109 PropType: PTypeInfo; 1110 1111 procedure WriteObjectProp; 1112 var 1113 Value: TObject; 1114 // OldAncestor: TPersistent; 1115 // SavePropPath, ComponentValue: string; 1116 Setter: Longint; 1117 TargetObject: ^TObject; 1118 begin 1119 Value := TObject(GetOrdProp(Instance, PropInfo)); 1120 if Value = nil then begin 1121 end else begin 1122 if Value is TDbObject then begin 1123 TDbObject(Value).Destroy(Depth - 1); 1124 end else if Value is TDbList then begin 1125 TDbList(Value).Destroy(Depth - 1); 1126 end; 1127 1128 // Set object reference to nil 1129 Setter := Longint(PropInfo^.SetProc); 1130 if (Setter and $FF000000) = $FF000000 then 1131 begin // field - Setter is the field's offset in the instance data 1132 TargetObject := Pointer(Integer(Instance) + (Setter and $00FFFFFF)); 1133 TargetObject^ := nil; // auto ref count 1134 end; 1135 end; 1136 end; 1137 1138 1139 begin 1140 // Using IsDefaultPropertyValue will tell us if we should write out 1141 // a given property because it was different from the default or 1142 // different from the Ancestor (if applicable). 1143 if (PropInfo^.GetProc <> nil) and 1144 ((PropInfo^.SetProc <> nil) or 1145 ((PropInfo^.PropType^.Kind = tkClass) and 1146 (TObject(GetOrdProp(Instance, PropInfo)) is TComponent) and 1147 (csSubComponent in TComponent(GetOrdProp(Instance, PropInfo)).ComponentStyle))) then 1148 begin 1149 LogMessage('Destroy property: '+Instance.ClassName+'.'+PropInfo.Name); 1150 //if not IsDefaultPropertyValue(Instance, PropInfo, GetLookupInfo) then 1151 begin 1152 //AncestorValid := AncestorIsValid(Ancestor, Root, RootAncestor); 1153 PropType := PropInfo^.PropType; 1154 case PropType^.Kind of 1155 tkClass: 1156 WriteObjectProp; 1157 end; 1158 end; 1159 end; 1160 end; 1161 1162 procedure TDbObject.Load(Depth: Integer); 1163 begin 1164 LoadById(Id, Depth); 1165 end; 1166 1167 procedure TDbObject.Delete; 1168 var 1169 I, Count: Integer; 1170 PropInfo: PPropInfo; 1171 PropList: PPropList; 1172 // Name: string; 1173 begin 1174 LogMessage('Delete class: '+Self.ClassName); 1175 if Self.ClassInfo = nil then raise Exception.Create('Class '+Self.ClassName+' doesn''t provide RTTI information!'); 1176 Count := GetTypeData(Self.ClassInfo)^.PropCount; 1177 if Count > 0 then with FDatabase do begin 1178 ProcessedClass := Self; 1179 GetMem(PropList, Count * SizeOf(Pointer)); 1180 try 1181 GetPropInfos(Self.ClassInfo, PropList); 1182 for I := 0 to Count - 1 do 1183 begin 1184 PropInfo := PropList^[I]; 1185 if PropInfo = nil then 1186 Break; 1187 if IsStoredProp(Self, PropInfo) then 1188 DeleteProperty(Self, PropInfo); 1189 end; 1190 finally 1191 FreeMem(PropList, Count * SizeOf(Pointer)); 1192 end; 1193 end; 1194 Database.Delete(Self.ClassName, 'id=' + IntToStr(Id)); 1195 inherited Destroy; 158 1196 end; 159 1197 160 1198 end. 161 -
devel/web/UFinancePage.pas
r138 r158 4 4 5 5 interface 6 7 uses 8 UDatabase, UConfig; 9 10 type 11 12 { TBaseObject } 13 14 TBaseObject = class(TDbObject) 15 private 16 FName: string; 17 published 18 property Name: string read FName write FName; 19 end; 6 20 7 21 function FinanceOverviewPage: string; … … 94 108 end; 95 109 110 function Test: string; 111 var 112 Base: TBaseObject; 113 begin 114 Result := ShowHeader('<strong>ZděchovNET</strong> - komunitní počítačová síť', 'Finance'); 115 Base := TBaseObject.Create(nil); 116 Base.Database := TDatabase.Create; 117 Base.Database.Hostname := DatabaseHostname; 118 Base.Database.Database := 'centrala'; 119 Base.Database.UserName := DatabaseUserName; 120 Base.Database.Password := DatabasePassword; 121 Base.Database.Connect; 122 //Base.Store; 123 124 Result := Result + ShowFooter; 125 end; 126 127 { TBaseObject } 128 96 129 begin 97 130 RegisterPage('finance', @FinanceOverviewPage); 98 RegisterPage('finance-clenove', @FinanceClientList); 131 RegisterPage('finance-clenove', @FinanceClientList); 132 RegisterPage('test', @Test); 99 133 end. -
devel/web/UNews.pas
r139 r158 12 12 { TNewsCategory } 13 13 14 TNewsCategory = class(TDbObject) 14 TNewsCategory = class 15 Id: Integer; 15 16 Title: string; 16 17 Permission: Integer; 17 18 procedure LoadFromDbRecord(DbRow: TAssocArray); 18 procedure Store; override;19 procedure Store; 19 20 end; 20 21 21 22 { TNewsItem } 22 23 23 TNewsItem = class(TDbObject) 24 TNewsItem = class 25 Id: Integer; 24 26 Title: string; 25 27 Content: string; … … 29 31 Category: Integer; 30 32 procedure LoadFromDbRecord(DbRow: TAssocArray); 31 procedure Store; override;33 procedure Store; 32 34 end; 33 35 -
devel/web/UUser.pas
r142 r158 12 12 { TUser } 13 13 14 TUser = class(TDbObject) 14 TUser = class 15 Id: Integer; 15 16 SubjectName: string; 16 17 FirstName: string; … … 26 27 DIC: string; 27 28 procedure LoadFromDbRecord(DbRow: TAssocArray); 28 procedure Store; override;29 procedure Store; 29 30 end; 30 31 -
devel/web/index.lpi
r142 r158 12 12 <MainUnit Value="0"/> 13 13 <TargetFileExt Value=".exe"/> 14 <ActiveEditorIndexAtStart Value=" 3"/>14 <ActiveEditorIndexAtStart Value="5"/> 15 15 </General> 16 16 <VersionInfo> … … 29 29 </local> 30 30 </RunParams> 31 <Units Count="2 4">31 <Units Count="25"> 32 32 <Unit0> 33 33 <Filename Value="index.pas"/> 34 34 <IsPartOfProject Value="True"/> 35 35 <UnitName Value="Index"/> 36 <CursorPos X=" 44" Y="7"/>37 <TopLine Value="1"/> 38 <EditorIndex Value=" 4"/>39 <UsageCount Value="9 0"/>36 <CursorPos X="64" Y="17"/> 37 <TopLine Value="1"/> 38 <EditorIndex Value="5"/> 39 <UsageCount Value="95"/> 40 40 <Loaded Value="True"/> 41 41 </Unit0> … … 46 46 <CursorPos X="80" Y="21"/> 47 47 <TopLine Value="1"/> 48 <EditorIndex Value="6"/> 49 <UsageCount Value="90"/> 50 <Loaded Value="True"/> 48 <UsageCount Value="95"/> 51 49 </Unit1> 52 50 <Unit2> … … 57 55 <TopLine Value="197"/> 58 56 <EditorIndex Value="0"/> 59 <UsageCount Value="9 0"/>57 <UsageCount Value="95"/> 60 58 <Loaded Value="True"/> 61 59 </Unit2> … … 63 61 <Filename Value="UXmlClasses.pas"/> 64 62 <IsPartOfProject Value="True"/> 65 <UsageCount Value="9 0"/>63 <UsageCount Value="95"/> 66 64 </Unit3> 67 65 <Unit4> … … 71 69 <CursorPos X="10" Y="96"/> 72 70 <TopLine Value="76"/> 73 <EditorIndex Value=" 9"/>74 <UsageCount Value="9 0"/>71 <EditorIndex Value="7"/> 72 <UsageCount Value="95"/> 75 73 <Loaded Value="True"/> 76 74 </Unit4> … … 81 79 <CursorPos X="1" Y="1"/> 82 80 <TopLine Value="81"/> 83 <UsageCount Value="9 0"/>81 <UsageCount Value="95"/> 84 82 </Unit5> 85 83 <Unit6> … … 87 85 <IsPartOfProject Value="True"/> 88 86 <UnitName Value="UFinancePage"/> 89 <CursorPos X=" 31" Y="19"/>90 <TopLine Value=" 11"/>91 <EditorIndex Value=" 11"/>92 <UsageCount Value="9 0"/>87 <CursorPos X="42" Y="101"/> 88 <TopLine Value="90"/> 89 <EditorIndex Value="8"/> 90 <UsageCount Value="95"/> 93 91 <Loaded Value="True"/> 94 92 </Unit6> … … 99 97 <CursorPos X="34" Y="30"/> 100 98 <TopLine Value="17"/> 101 <UsageCount Value="9 0"/>99 <UsageCount Value="95"/> 102 100 </Unit7> 103 101 <Unit8> … … 105 103 <IsPartOfProject Value="True"/> 106 104 <UnitName Value="UNews"/> 107 <CursorPos X="15" Y="49"/> 108 <TopLine Value="34"/> 109 <EditorIndex Value="10"/> 110 <UsageCount Value="90"/> 111 <Loaded Value="True"/> 105 <CursorPos X="1" Y="16"/> 106 <TopLine Value="12"/> 107 <UsageCount Value="95"/> 112 108 </Unit8> 113 109 <Unit9> … … 117 113 <CursorPos X="28" Y="149"/> 118 114 <TopLine Value="109"/> 119 <EditorIndex Value=" 8"/>120 <UsageCount Value="9 0"/>115 <EditorIndex Value="6"/> 116 <UsageCount Value="95"/> 121 117 <Loaded Value="True"/> 122 118 </Unit9> … … 143 139 <Filename Value="../../../../other/powtils/main/pwmain.pas"/> 144 140 <UnitName Value="pwmain"/> 145 <CursorPos X=" 24" Y="364"/>146 <TopLine Value=" 351"/>141 <CursorPos X="30" Y="2342"/> 142 <TopLine Value="2320"/> 147 143 <UsageCount Value="19"/> 148 144 </Unit13> … … 153 149 <CursorPos X="56" Y="16"/> 154 150 <TopLine Value="1"/> 155 <EditorIndex Value="12"/> 156 <UsageCount Value="78"/> 157 <Loaded Value="True"/> 151 <UsageCount Value="83"/> 158 152 </Unit14> 159 153 <Unit15> … … 173 167 <IsPartOfProject Value="True"/> 174 168 <UnitName Value="UConfig"/> 175 <CursorPos X=" 28" Y="14"/>176 <TopLine Value="1"/> 177 <EditorIndex Value=" 5"/>178 <UsageCount Value=" 65"/>169 <CursorPos X="3" Y="14"/> 170 <TopLine Value="1"/> 171 <EditorIndex Value="9"/> 172 <UsageCount Value="70"/> 179 173 <Loaded Value="True"/> 180 174 </Unit17> … … 184 178 <CursorPos X="1" Y="134"/> 185 179 <TopLine Value="108"/> 186 <UsageCount Value=" 65"/>180 <UsageCount Value="70"/> 187 181 <SyntaxHighlighter Value="None"/> 188 182 </Unit18> … … 192 186 <CursorPos X="1" Y="1"/> 193 187 <TopLine Value="1"/> 194 <UsageCount Value=" 65"/>188 <UsageCount Value="70"/> 195 189 <SyntaxHighlighter Value="JScript"/> 196 190 </Unit19> … … 199 193 <IsPartOfProject Value="True"/> 200 194 <UnitName Value="UDatabase"/> 201 <CursorPos X=" 26" Y="52"/>202 <TopLine Value=" 23"/>195 <CursorPos X="17" Y="1129"/> 196 <TopLine Value="1107"/> 203 197 <EditorIndex Value="1"/> 204 <UsageCount Value=" 59"/>198 <UsageCount Value="64"/> 205 199 <Loaded Value="True"/> 206 200 </Unit20> … … 209 203 <IsPartOfProject Value="True"/> 210 204 <UnitName Value="UUser"/> 211 <CursorPos X=" 41" Y="34"/>212 <TopLine Value="1 6"/>213 <EditorIndex Value=" 7"/>214 <UsageCount Value=" 59"/>205 <CursorPos X="31" Y="36"/> 206 <TopLine Value="14"/> 207 <EditorIndex Value="3"/> 208 <UsageCount Value="64"/> 215 209 <Loaded Value="True"/> 216 210 </Unit21> … … 219 213 <IsPartOfProject Value="True"/> 220 214 <UnitName Value="UUserPage"/> 221 <CursorPos X=" 55" Y="23"/>215 <CursorPos X="69" Y="19"/> 222 216 <TopLine Value="1"/> 223 217 <EditorIndex Value="2"/> 224 <UsageCount Value=" 55"/>218 <UsageCount Value="60"/> 225 219 <Loaded Value="True"/> 226 220 </Unit22> … … 229 223 <IsPartOfProject Value="True"/> 230 224 <UnitName Value="UBill"/> 231 <CursorPos X="2 5" Y="156"/>232 <TopLine Value=" 136"/>233 <EditorIndex Value=" 3"/>234 <UsageCount Value="5 2"/>225 <CursorPos X="26" Y="75"/> 226 <TopLine Value="39"/> 227 <EditorIndex Value="4"/> 228 <UsageCount Value="57"/> 235 229 <Loaded Value="True"/> 236 230 </Unit23> 231 <Unit24> 232 <Filename Value="../../../../../../../usr/share/fpcsrc/packages/fv/src/dialogs.pas"/> 233 <UnitName Value="Dialogs"/> 234 <CursorPos X="19" Y="4"/> 235 <TopLine Value="1"/> 236 <UsageCount Value="10"/> 237 </Unit24> 237 238 </Units> 238 <JumpHistory Count=" 30" HistoryIndex="29">239 <JumpHistory Count="29" HistoryIndex="28"> 239 240 <Position1> 240 <Filename Value="U Database.pas"/>241 <Caret Line=" 28" Column="1" TopLine="1"/>241 <Filename Value="UBill.pas"/> 242 <Caret Line="146" Column="51" TopLine="136"/> 242 243 </Position1> 243 244 <Position2> 244 <Filename Value="U Database.pas"/>245 <Caret Line=" 63" Column="1" TopLine="27"/>245 <Filename Value="UBill.pas"/> 246 <Caret Line="28" Column="24" TopLine="3"/> 246 247 </Position2> 247 248 <Position3> 248 <Filename Value="U Database.pas"/>249 <Caret Line=" 97" Column="34" TopLine="79"/>249 <Filename Value="UBill.pas"/> 250 <Caret Line="25" Column="21" TopLine="6"/> 250 251 </Position3> 251 252 <Position4> 252 <Filename Value="U Database.pas"/>253 <Caret Line="3 2" Column="23" TopLine="14"/>253 <Filename Value="UBill.pas"/> 254 <Caret Line="37" Column="17" TopLine="28"/> 254 255 </Position4> 255 256 <Position5> 256 <Filename Value="U Database.pas"/>257 <Caret Line=" 12" Column="14" TopLine="1"/>257 <Filename Value="UBill.pas"/> 258 <Caret Line="33" Column="16" TopLine="19"/> 258 259 </Position5> 259 260 <Position6> 260 <Filename Value="U Database.pas"/>261 <Caret Line=" 98" Column="35" TopLine="80"/>261 <Filename Value="UBill.pas"/> 262 <Caret Line="66" Column="3" TopLine="48"/> 262 263 </Position6> 263 264 <Position7> 264 <Filename Value="U User.pas"/>265 <Caret Line=" 16" Column="1" TopLine="1"/>265 <Filename Value="UBill.pas"/> 266 <Caret Line="78" Column="3" TopLine="60"/> 266 267 </Position7> 267 268 <Position8> 268 269 <Filename Value="UBill.pas"/> 269 <Caret Line="1 51" Column="57" TopLine="141"/>270 <Caret Line="137" Column="7" TopLine="105"/> 270 271 </Position8> 271 272 <Position9> 272 <Filename Value="U Database.pas"/>273 <Caret Line="1 17" Column="25" TopLine="96"/>273 <Filename Value="UBill.pas"/> 274 <Caret Line="151" Column="1" TopLine="124"/> 274 275 </Position9> 275 276 <Position10> 276 <Filename Value="U Database.pas"/>277 <Caret Line=" 83" Column="5" TopLine="47"/>277 <Filename Value="UFinancePage.pas"/> 278 <Caret Line="9" Column="50" TopLine="1"/> 278 279 </Position10> 279 280 <Position11> 280 <Filename Value="U Database.pas"/>281 <Caret Line=" 138" Column="20" TopLine="108"/>281 <Filename Value="UFinancePage.pas"/> 282 <Caret Line="8" Column="1" TopLine="1"/> 282 283 </Position11> 283 284 <Position12> 284 <Filename Value="U Database.pas"/>285 <Caret Line="1 39" Column="18" TopLine="108"/>285 <Filename Value="UFinancePage.pas"/> 286 <Caret Line="14" Column="3" TopLine="1"/> 286 287 </Position12> 287 288 <Position13> 288 <Filename Value="U Database.pas"/>289 <Caret Line=" 49" Column="27" TopLine="36"/>289 <Filename Value="UFinancePage.pas"/> 290 <Caret Line="16" Column="3" TopLine="14"/> 290 291 </Position13> 291 292 <Position14> 292 <Filename Value="U Database.pas"/>293 <Caret Line="1 05" Column="8" TopLine="87"/>293 <Filename Value="UFinancePage.pas"/> 294 <Caret Line="117" Column="10" TopLine="90"/> 294 295 </Position14> 295 296 <Position15> 296 <Filename Value="U Database.pas"/>297 <Caret Line=" 48" Column="34" TopLine="35"/>297 <Filename Value="UFinancePage.pas"/> 298 <Caret Line="123" Column="45" TopLine="91"/> 298 299 </Position15> 299 300 <Position16> 300 <Filename Value="U Database.pas"/>301 <Caret Line="1 06" Column="24" TopLine="88"/>301 <Filename Value="UFinancePage.pas"/> 302 <Caret Line="12" Column="1" TopLine="8"/> 302 303 </Position16> 303 304 <Position17> 304 <Filename Value="U Database.pas"/>305 <Caret Line="1 37" Column="1" TopLine="105"/>305 <Filename Value="UFinancePage.pas"/> 306 <Caret Line="116" Column="34" TopLine="96"/> 306 307 </Position17> 307 308 <Position18> 308 <Filename Value="U Database.pas"/>309 <Caret Line="1 33" Column="17" TopLine="105"/>309 <Filename Value="UFinancePage.pas"/> 310 <Caret Line="118" Column="45" TopLine="96"/> 310 311 </Position18> 311 312 <Position19> 312 <Filename Value="U Database.pas"/>313 <Caret Line=" 48" Column="27" TopLine="30"/>313 <Filename Value="UFinancePage.pas"/> 314 <Caret Line="8" Column="21" TopLine="1"/> 314 315 </Position19> 315 316 <Position20> 316 <Filename Value="U Bill.pas"/>317 <Caret Line=" 292" Column="26" TopLine="265"/>317 <Filename Value="UFinancePage.pas"/> 318 <Caret Line="17" Column="17" TopLine="1"/> 318 319 </Position20> 319 320 <Position21> 320 <Filename Value="U Bill.pas"/>321 <Caret Line=" 304" Column="5" TopLine="268"/>321 <Filename Value="UFinancePage.pas"/> 322 <Caret Line="122" Column="10" TopLine="95"/> 322 323 </Position21> 323 324 <Position22> 324 <Filename Value="U Bill.pas"/>325 <Caret Line=" 312" Column="44" TopLine="278"/>325 <Filename Value="UDatabase.pas"/> 326 <Caret Line="1164" Column="10" TopLine="1129"/> 326 327 </Position22> 327 328 <Position23> 328 <Filename Value=" UBill.pas"/>329 <Caret Line=" 72" Column="3" TopLine="54"/>329 <Filename Value="index.pas"/> 330 <Caret Line="14" Column="16" TopLine="1"/> 330 331 </Position23> 331 332 <Position24> 332 333 <Filename Value="UBill.pas"/> 333 <Caret Line=" 310" Column="49" TopLine="282"/>334 <Caret Line="166" Column="1" TopLine="282"/> 334 335 </Position24> 335 336 <Position25> 336 <Filename Value="U Bill.pas"/>337 <Caret Line=" 313" Column="15" TopLine="281"/>337 <Filename Value="UUserPage.pas"/> 338 <Caret Line="6" Column="31" TopLine="1"/> 338 339 </Position25> 339 340 <Position26> 340 <Filename Value="U SqlDatabase.pas"/>341 <Caret Line=" 369" Column="15" TopLine="337"/>341 <Filename Value="UUser.pas"/> 342 <Caret Line="29" Column="21" TopLine="1"/> 342 343 </Position26> 343 344 <Position27> 344 345 <Filename Value="UDatabase.pas"/> 345 <Caret Line=" 114" Column="5" TopLine="78"/>346 <Caret Line="442" Column="35" TopLine="434"/> 346 347 </Position27> 347 348 <Position28> 348 349 <Filename Value="UDatabase.pas"/> 349 <Caret Line="1 24" Column="5" TopLine="88"/>350 <Caret Line="1132" Column="25" TopLine="1110"/> 350 351 </Position28> 351 352 <Position29> 352 <Filename Value="U Bill.pas"/>353 <Caret Line="1 33" Column="21" TopLine="97"/>353 <Filename Value="UDatabase.pas"/> 354 <Caret Line="1131" Column="7" TopLine="1109"/> 354 355 </Position29> 355 <Position30>356 <Filename Value="UDatabase.pas"/>357 <Caret Line="38" Column="17" TopLine="27"/>358 </Position30>359 356 </JumpHistory> 360 357 </ProjectOptions> … … 374 371 </Parsing> 375 372 <CodeGeneration> 376 <SmartLinkUnit Value="True"/>377 373 <Checks> 378 374 <IOChecks Value="True"/> … … 383 379 <VerifyObjMethodCallValidity Value="True"/> 384 380 </CodeGeneration> 385 <Linking>386 <LinkSmart Value="True"/>387 </Linking>388 381 <Other> 382 <Verbosity> 383 <ShoLineNum Value="True"/> 384 </Verbosity> 389 385 <CompilerPath Value="$(CompPath)"/> 390 386 </Other>
Note:
See TracChangeset
for help on using the changeset viewer.