- Timestamp:
- Oct 30, 2010, 7:43:01 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Network/MysqlClient/USqlDatabase.pas
r35 r81 2 2 3 3 {$mode Delphi}{$H+} 4 // Upraveno: 16.12.2009 4 5 // Upraveno: 28.10.2010 5 6 6 7 interface 7 8 8 9 uses 9 SysUtils, Classes, Dialogs, mysql50, TypInfo; 10 SysUtils, Classes, Dialogs, mysql50, TypInfo, UStringListEx, 11 ListObject, DictionaryStringString; 10 12 11 13 type 12 EQueryError = Exception;14 EQueryError = class(Exception); 13 15 14 16 TClientCapabilities = (_CLIENT_LONG_PASSWORD, _CLIENT_FOUND_ROWS, … … 19 21 TSetClientCapabilities = set of TClientCapabilities; 20 22 21 T AssociativeArray = class(TStringList)23 TDbRows = class(TListObject) 22 24 private 23 function GetValues(Index: string): string; 24 function GetValuesAtIndex(Index: Integer): string; 25 procedure SetValues(Index: string; const Value: string); 25 function GetData(Index: Integer): TDictionaryStringString; 26 procedure SetData(Index: Integer; const Value: TDictionaryStringString); 26 27 public 27 constructor Create; 28 destructor Destroy; override; 29 function GetAllValues: string; 30 procedure AddKeyValue(Key, Value: string); 31 property ValuesAtIndex[Index: Integer]: string read GetValuesAtIndex; 32 property Values[Index: string]: string read GetValues write SetValues; default; 33 end; 34 35 TDbRows = class(TList) 36 private 37 function GetData(Index: Integer): TAssociativeArray; 38 procedure SetData(Index: Integer; const Value: TAssociativeArray); 39 public 40 property Data[Index: Integer]: TAssociativeArray read GetData write SetData; default; 28 property Data[Index: Integer]: TDictionaryStringString read GetData write SetData; default; 41 29 destructor Destroy; override; 42 30 end; … … 51 39 function GetLastErrorMessage: string; 52 40 function GetLastErrorNumber: Integer; 53 function CheckError: Boolean;54 41 function GetCharset: string; 55 42 procedure SetDatabase(const Value: string); 56 { Private declarations }57 43 public 58 44 Hostname: string; … … 69 55 function Select(ATable: string; Filter: string = '*'; Condition: string = '1'): TDbRows; 70 56 procedure Delete(ATable: string; Condition: string = '1'); 71 procedure Insert(ATable: string; Data: T AssociativeArray);72 procedure Update(ATable: string; Data: T AssociativeArray; Condition: string = '1');73 procedure Replace(ATable: string; Data: T AssociativeArray);57 procedure Insert(ATable: string; Data: TDictionaryStringString); 58 procedure Update(ATable: string; Data: TDictionaryStringString; Condition: string = '1'); 59 procedure Replace(ATable: string; Data: TDictionaryStringString); 74 60 procedure Connect; 75 61 procedure Disconnect; … … 86 72 function MySQLFloatToStr(F: Real): string; 87 73 function MySQLStrToFloat(S: string): Real; 74 function SQLToDateTime(Value: string): TDateTime; 75 function DateTimeToSQL(Value: TDateTime): string; 88 76 89 77 implementation 90 78 91 uses DateUtils, Math; 79 uses 80 DateUtils, Math; 81 82 resourcestring 83 SDatabaseQueryError = 'Database query error: "%s"'; 92 84 93 85 const … … 106 98 CLIENT_TRANSACTIONS = 8192; // Client knows about transactions 107 99 108 { TDataModule2 }109 110 100 function MySQLFloatToStr(F: Real): string; 111 101 var … … 113 103 begin 114 104 S := FloatToStr(F); 115 if Pos(',', S) > 0 then S[Pos(',', S)] := '.';105 if Pos(',', S) > 0 then S[Pos(',', S)] := '.'; 116 106 Result := S; 117 107 end; … … 119 109 function MySQLStrToFloat(S: string): Real; 120 110 begin 121 if Pos('.', S) > 0 then S[Pos('.', S)] := ',';111 if Pos('.', S) > 0 then S[Pos('.', S)] := ','; 122 112 Result := StrToFloat(S); 123 113 end; 114 115 function SQLToDateTime(Value: string): TDateTime; 116 var 117 Parts: TStringListEx; 118 DateParts: TStringListEx; 119 TimeParts: TStringListEx; 120 begin 121 try 122 Parts := TStringListEx.Create; 123 DateParts := TStringListEx.Create; 124 TimeParts := TStringListEx.Create; 125 126 Parts.Explode(' ', Value); 127 DateParts.Explode('-', Parts[0]); 128 Result := EncodeDate(StrToInt(DateParts[0]), StrToInt(DateParts[1]), 129 StrToInt(DateParts[2])); 130 if Parts.Count > 1 then begin 131 TimeParts.Explode(':', Parts[1]); 132 Result := Result + EncodeTime(StrToInt(TimeParts[0]), StrToInt(TimeParts[1]), 133 StrToInt(TimeParts[2]), 0); 134 end; 135 finally 136 DateParts.Free; 137 TimeParts.Free; 138 Parts.Free; 139 end; 140 end; 141 142 function DateTimeToSQL(Value: TDateTime): string; 143 begin 144 Result := FormatDateTime('yyyy-mm-dd hh.nn.ss', Value); 145 end; 146 147 { TSqlDatabase } 124 148 125 149 procedure TSqlDatabase.Connect; … … 138 162 FSession := NewSession; 139 163 end else FConnected := False; 140 CheckError; 141 Rows := Query('SET NAMES ' + Encoding); 142 Rows.Free; 143 end; 144 145 procedure TSqlDatabase.Insert(ATable: string; Data: TAssociativeArray); 164 165 if LastErrorNumber <> 0 then 166 raise EQueryError.Create(Format(SDatabaseQueryError, [LastErrorMessage])); 167 168 try 169 Rows := Query('SET NAMES ' + Encoding); 170 finally 171 Rows.Free; 172 end; 173 end; 174 175 procedure TSqlDatabase.Insert(ATable: string; Data: TDictionaryStringString); 146 176 var 147 177 DbNames: string; … … 155 185 DbValues := ''; 156 186 for I := 0 to Data.Count - 1 do begin 157 Value := Data. ValuesAtIndex[I];187 Value := Data.Items[I].Value; 158 188 StringReplace(Value, '"', '\"', [rfReplaceAll]); 159 189 if Value = 'NOW()' then DbValues := DbValues + ',' + Value 160 190 else DbValues := DbValues + ',"' + Value + '"'; 161 DbNames := DbNames + ',`' + Data. Names[I] + '`';191 DbNames := DbNames + ',`' + Data.Keys[I] + '`'; 162 192 end; 163 193 System.Delete(DbNames, 1, 1); 164 194 System.Delete(DbValues, 1, 1); 165 DbResult := Query('INSERT INTO `' + Table + '` (' + DbNames + ') VALUES (' + DbValues + ')'); 166 DbResult.Free; 195 try 196 DbResult := Query('INSERT INTO `' + Table + '` (' + DbNames + ') VALUES (' + DbValues + ')'); 197 finally 198 DbResult.Free; 199 end; 167 200 end; 168 201 … … 176 209 RepeatLastAction := False; 177 210 LastQuery := Data; 178 //if not Connected then NastaveniPripojeni.ShowModal;179 211 Result := TDbRows.Create; 180 //repeat181 212 mysql_query(FSession, PChar(Data)); 182 //until not183 CheckError;184 //if not CheckError then185 begin 186 187 188 189 190 191 Result[I] := TAssociativeArray.Create;192 193 194 Add(mysql_fetch_field_direct(DbResult, II)^.Name +195 NameValueSeparator +PChar((DbRow + II)^));213 if LastErrorNumber <> 0 then begin 214 raise EQueryError.Create(Format(SDatabaseQueryError, [LastErrorMessage])); 215 end; 216 217 DbResult := mysql_store_result(FSession); 218 if Assigned(DbResult) then begin 219 Result.Count := mysql_num_rows(DbResult); 220 for I := 0 to Result.Count - 1 do begin 221 DbRow := mysql_fetch_row(DbResult); 222 Result[I] := TDictionaryStringString.Create; 223 with Result[I] do begin 224 for II := 0 to mysql_num_fields(DbResult) - 1 do begin 225 Add(mysql_fetch_field_direct(DbResult, II)^.Name, 226 PChar((DbRow + II)^)); 196 227 end; 197 228 end; 198 229 end; 199 end;200 230 end; 201 231 mysql_free_result(DbResult); 202 (* 203 if Assigned(DatabaseIntegrity) then 204 with DatabaseIntegrity do if not Checking then begin 205 Check; 206 DebugLog('Database integrity: Unreferenced='+IntToStr(Unreferenced)+' BadReferences='+IntToStr(BadReferences)); 207 end; 208 *) 209 end; 210 211 procedure TSqlDatabase.Replace(ATable: string; Data: TAssociativeArray); 232 end; 233 234 procedure TSqlDatabase.Replace(ATable: string; Data: TDictionaryStringString); 212 235 var 213 236 DbNames: string; … … 221 244 DbValues := ''; 222 245 for I := 0 to Data.Count - 1 do begin 223 Value := Data. ValuesAtIndex[I];246 Value := Data.Items[I].Value; 224 247 StringReplace(Value, '"', '\"', [rfReplaceAll]); 225 248 if Value = 'NOW()' then DbValues := DbValues + ',' + Value 226 249 else DbValues := DbValues + ',"' + Value + '"'; 227 DbNames := DbNames + ',`' + Data. Names[I] + '`';250 DbNames := DbNames + ',`' + Data.Keys[I] + '`'; 228 251 end; 229 252 System.Delete(DbNames, 1, 1); 230 253 System.Delete(DbValues, 1, 1); 231 DbResult := Query('REPLACE INTO `' + Table + '` (' + DbNames + ') VALUES (' + DbValues + ')'); 232 DbResult.Free; 254 try 255 DbResult := Query('REPLACE INTO `' + Table + '` (' + DbNames + ') VALUES (' + DbValues + ')'); 256 finally 257 DbResult.Free; 258 end; 233 259 end; 234 260 … … 236 262 begin 237 263 Table := ATable; 238 Result := Query('SELECT ' + Filter + ' FROM `' + Table + '` WHERE ' +Condition);239 end; 240 241 procedure TSqlDatabase.Update(ATable: string; Data: T AssociativeArray; Condition: string = '1');264 Result := Query('SELECT ' + Filter + ' FROM `' + Table + '` WHERE ' + Condition); 265 end; 266 267 procedure TSqlDatabase.Update(ATable: string; Data: TDictionaryStringString; Condition: string = '1'); 242 268 var 243 269 DbValues: string; … … 249 275 DbValues := ''; 250 276 for I := 0 to Data.Count - 1 do begin 251 Value := Data. ValuesAtIndex[I];277 Value := Data.Items[I].Value; 252 278 StringReplace(Value, '"', '\"', [rfReplaceAll]); 253 279 if Value = 'NOW()' then DbValues := DbValues + ',' + Value 254 else DbValues := DbValues + ',' + Data. Names[I] + '=' + '"' + Value + '"';280 else DbValues := DbValues + ',' + Data.Keys[I] + '=' + '"' + Value + '"'; 255 281 end; 256 282 System.Delete(DbValues, 1, 1); 257 DbResult := Query('UPDATE `' + Table + '` SET (' + DbValues + ') WHERE ' + Condition); 258 DbResult.Free; 283 try 284 DbResult := Query('UPDATE `' + Table + '` SET (' + DbValues + ') WHERE ' + Condition); 285 finally 286 DbResult.Free; 287 end; 259 288 end; 260 289 … … 264 293 end; 265 294 266 { TAssocArray }267 268 procedure TAssociativeArray.AddKeyValue(Key, Value: string);269 begin270 Add(Key + NameValueSeparator + Value);271 end;272 273 constructor TAssociativeArray.Create;274 begin275 NameValueSeparator := '|';276 end;277 278 destructor TAssociativeArray.Destroy;279 begin280 inherited;281 end;282 283 function TAssociativeArray.GetAllValues: string;284 var285 I: Integer;286 begin287 Result := '';288 for I := 0 to Count - 1 do begin289 Result := Result + Names[I] + '=' + ValuesAtIndex[I] + ',';290 end;291 end;292 293 function TAssociativeArray.GetValues(Index: string): string;294 begin295 Result := inherited Values[Index];296 end;297 298 function TAssociativeArray.GetValuesAtIndex(Index: Integer): string;299 begin300 Result := inherited Values[Names[Index]];301 end;302 303 295 procedure TSqlDatabase.Delete(ATable: string; Condition: string = '1'); 296 var 297 DbResult: TDbRows; 304 298 begin 305 299 Table := ATable; 306 Query('DELETE FROM `' + Table + '` WHERE ' + Condition); 300 try 301 DbResult := Query('DELETE FROM `' + Table + '` WHERE ' + Condition); 302 finally 303 DbResult.Free; 304 end; 307 305 end; 308 306 … … 325 323 end; 326 324 327 procedure TAssociativeArray.SetValues(Index: string; const Value: string);328 begin329 inherited Values[Index] := Value;330 end;331 332 { TDbRows }333 334 destructor TDbRows.Destroy;335 var336 I: Integer;337 begin338 for I := 0 to Count - 1 do339 Data[I].Free;340 inherited;341 end;342 343 function TDbRows.GetData(Index: Integer): TAssociativeArray;344 begin345 Result := Items[Index];346 end;347 348 procedure TDbRows.SetData(Index: Integer; const Value: TAssociativeArray);349 begin350 Items[Index] := Value;351 end;352 353 325 function TSqlDatabase.LastInsertId: Integer; 354 326 begin … … 364 336 begin 365 337 Result := mysql_errno(FSession); 366 end;367 368 function TSqlDatabase.CheckError: Boolean;369 begin370 Result := LastErrorNumber <> 0;371 if Result then372 raise EQueryError.Create('Database query error: "' + LastErrorMessage + '"');373 338 end; 374 339 … … 386 351 387 352 procedure TSqlDatabase.CreateTable(Name: string); 388 var 389 DbRows: TDbRows; 390 begin 391 DbRows := Query('CREATE TABLE `' + Name + '`' + 353 begin 354 Query('CREATE TABLE `' + Name + '`' + 392 355 ' (`Id` INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (`Id`));'); 393 DbRows.Destroy;394 356 end; 395 357 … … 420 382 end; 421 383 384 { TDbRows } 385 386 destructor TDbRows.Destroy; 387 begin 388 inherited; 389 end; 390 391 function TDbRows.GetData(Index: Integer): TDictionaryStringString; 392 begin 393 Result := TDictionaryStringString(Items[Index]); 394 end; 395 396 procedure TDbRows.SetData(Index: Integer; const Value: TDictionaryStringString); 397 begin 398 Items[Index] := Value; 399 end; 400 422 401 end. 423 402
Note:
See TracChangeset
for help on using the changeset viewer.