Giter Site home page Giter Site logo

exilon / quicklib Goto Github PK

View Code? Open in Web Editor NEW
597.0 597.0 177.0 54.77 MB

Quick development library (AutoMapper, LinQ, IOC Dependency Injection, MemoryCache, Scheduled tasks, Json and Yml Config and Options pattern, Serializers, etc) with crossplatform support for Delphi/Firemonkey (Windows,Linux,OSX/IOS/Android) and freepascal (Windows/Linux).

License: Apache License 2.0

Pascal 100.00%
automapper azure chronometer config console delphi dependency-injection firemonkey freepascal ioc json linq linux monitor scheduled-tasks serializer service thread yaml

quicklib's People

Contributors

corneliusdavid avatar exilon avatar jeppe712 avatar jkour avatar jonahzheng avatar loris-f avatar turric4n avatar vldgeorgiev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

quicklib's Issues

Memory leak in Quick.Process.GetProcessList

Quick.Process.GetProcessList creates a memory leak.

To avoid a memory-leak, implement a var parameter for an existing StringList, for example:

procedure GetProcessList (var MyStringList: TStringList);

This would allow freeing the String-List manually after use.

FireMonkey Fix Suggestion

Hi,
I see you fixed the code in Quick.Commons to compile in other platforms.

I was thinking that this code is more suitable:

{$ELSE}
var
{$IFDEF NEXTGEN}
plogin : MarshaledAString;
{$ELSE}
plogin : PAnsiChar;
{$ENDIF}
begin
{$IFDEF POSIX}

rather than string in NEXTGEN

This is what is suggested in the docs too.

What do you think?

QuickLib can not compiler with directive:'5023'

uses Quicklib units,and complie project,then debug message outpu message is:
[dcc32 Error] quicklib.pas(7): E1030 Invalid compiler directive: '5023' [dcc32 Fatal Error] Quick.Console.pas(204): F2063 Could not compile used unit 'Quick.Log.pas'
delphi version is 10.2 25.0.29899.2631

Improvement request: Serialization Dataset to Json / Json to Dataset

The great QuickLib already contain nearly everything to serialize from dataset to json (and back) which would be useful for transferring a dataset from server to client in JSON format. The tricky part is from JSON to DATASET as ideally it should create the field from a memory table. I had a quick look and Rest Dataware does have it (https://sourceforge.net/projects/rest-dataware-componentes/) but it is part of their component set and therefore it is linked to a lot of units and not straightforward to use it without their specific framework

BUG in Quick.Commons

//checks if need include signs // signs!
if pfIncludeNumbers in Complexity then // pfIncludeNumbers!

// QuickLib 2.1

Here is the bug-fix:

image

Improvement request: Scheduled Task start time based on cron

I know it might not be easy to implement now because the way it was created, but it would be interesting if the TScheduledTasks could start and repeat at specific time similar to cron expression
Examples:
5 4 * * * : every day at 4:05am
0 22 * * 1-5 : At 22:00 on every day-of-week from Monday through Friday
*/5 * * * * : At every 5th minute
The not so good part from traditional cron is that it start in minute interval and ideally it would be good having second intervals (adding one additional number/expression).
0 0 * * * * : every day and hour when min = 0 and second = 0
*/5 * * * * * : every 5th second (e.g. 0, 5, 10, 15, ...)

Little issue - the .pas source files should be encoded in utf8

Thanks again for this great, feature-rich library! I'm checking out the pooling feature and the thread pool feature, after getting QuickLogger compiled.

One little, not-critical suggestion - please consider save the .pas source file in utf8 instead of the default ANSI encoding, otherwise when they are opened in other locals the unicode characters won't be displayed correctly, as shown in the attached screenshot.

The issue is minor when the character displaying issue happens inside the comments, but it will cause it unable to be compiled if it happens inside string constants.
QuickLibPasFileShouldBeUtf8

could Quick.Process add a function that can redirect output?

thanks for your awsome delphi lib.
i use it in my work.
now , i wanna to write a function that could redirect the program ouput to my program.
i wrote a function like my words long before,but it works bad.
so , could quicklib provide this function that can wait for terminate and get output with callback.
thans again.
and sorry for my pool english

From not set

Mail.From := fMail.From;

Mail.From := fMail.From; // Not set if calling this method directly ? Exception / check now ? Or just allow exception on sending ?

SAML AzureAD Single Sign-on Support - Feature Request

https://docs.microsoft.com/en-us/azure/active-directory/develop/single-sign-on-saml-protocol

https://docs.microsoft.com/en-us/azure/active-directory/saas-apps/saml-toolkit-tutorial

The link below has a BASIC implementation of SAML for ASP.NET. (323 lines of c# code):

https://github.com/jitbit/AspNetSaml

How SAML works?
SAML workflow has 2 steps:

User is redirected to the SAML provider (where he authenticates)
User is redirected back to your app, where you validate the payload
Here's how you do it (this example is for ASP.NET MVC:

  1. Redirecting the user to the saml provider:
    //this example is an ASP.NET MVC action method
    public ActionResult Login()
    {
    //TODO: specify the SAML provider url here, aka "Endpoint"
    var samlEndpoint = "http://saml-provider-that-we-use.com/login/";

    var request = new AuthRequest(
    "http://www.myapp.com", //TODO: put your app's "entity ID" here
    "http://www.myapp.com/SamlConsume" //TODO: put Assertion Consumer URL (where the provider should redirect users after authenticating)
    );

    //redirect the user to the SAML provider
    return Redirect(request.GetRedirectUrl(samlEndpoint));
    }

  2. User has been redirected back
    User is sent back to your app - you need to validate the SAML response ("assertion") that you recieved via POST.

Here's an example of how you do it in ASP.NET MVC

//ASP.NET MVC action method... But you can easily modify the code for Web-forms etc.
public ActionResult SamlConsume()
{
// 1. TODO: specify the certificate that your SAML provider gave you
string samlCertificate = @"-----BEGIN CERTIFICATE-----
BLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAH123543==
-----END CERTIFICATE-----";

// 2. Let's read the data - SAML providers usually POST it into the "SAMLResponse" var
Saml.Response samlResponse = new Response(samlCertificate, Request.Form["SAMLResponse"]);

// 3. We're done!
if (samlResponse.IsValid())
	username = samlResponse.GetNameID();

}
Reading more attributes from the provider
SAML providers usually send more data with their response: username, first/last names etc. Here's how to get it:

if (samlResponse.IsValid())
{
//WOOHOO!!! user is logged in

//Some more optional stuff for you
//let's extract username/firstname etc
string username, email, firstname, lastname;
try
{
	username = samlResponse.GetNameID();
	email = samlResponse.GetEmail();
	firstname = samlResponse.GetFirstName();
	lastname = samlResponse.GetLastName();
}
catch(Exception ex)
{
	//insert error handling code
	//no, really, please do
	return null;
}

//user has been authenticated, put your code here, like set a cookie or something...
//or call FormsAuthentication.SetAuthCookie() or something

}

Quick.Config

It cannot be compiled in FreePascal. FPC version 3.0.4, Lazarus 2.0.2.

1st error: QuickFiles line#412
Result := Result + [rec.Name]

I have replaced it with SetLength(Result, length(Result) + 1); Result[High(Result)] := rec.Name;

then 2nd error:
Quick.Config.Json
line#43
Rtti
I have replaced it with rttiutils

then 3rd error:
Quick.Commons
line#816
loUserLocale - identificator not found

How to use Factory and inject value in constructor in IOC?

Hi,
I am looking at the IOC and I want to do the following:

Say I have TBase class and TClassA and TClassB inheriting from TBase.

Now I want a factory to produce either classA or classB. Can I use Abstract Factory for this?

Thanks

Syntax error in DebugUtils (D10.0)

function TCalculator.Divide(a, b: Int64): Double;
begin
{$IFDEF DEBUG}
var crono := TDebugger.TimeIt(Self,'Divide',Format('Divide %d / %d',[a,b]));
...

Memory Leak on ConfigToJson

Hi,

Just run sample and click Load From file and close app, you will see memory leak!


Unexpected Memory Leak

An unexpected memory leak has occurred. The unexpected small block leaks are:

25 - 40 bytes: TJSONObject x 1

73 - 88 bytes: TList<System.JSON.TJSONPair> x 1

Delphi 10.4
Path: \QuickLib\samples\delphi\QuickConfig\ConfigToJSON

Improvement request: Database Connection Pool

If I am not wrong, according to description, it might be easy to use the Quick.Pooling to creste a database connection pool. An example to accomplish this (e.g. with ZeosDBO) would be great

Quick.Azure

function ListContainers(const azContainersStartWith : string; azResponseInfo : TAzureResponseInfo) : TStrings;

Should be

function ListContainers(const azContainersStartWith : string; out azResponseInfo : TAzureResponseInfo) : TStrings;

Very nice Lib BTW

Regards,
Pascal

Compile errors on Linux

I'm testing QuickLib on Linux, and i get many compile errors on units Quick.Commons, it seems that it want to compile some parts that belongs to IOS.

I'm using Delphi 10.4 Sydney with 2 patches applied

[DCC Error] Quick.Commons.pas(946): E2003 Undeclared identifier: 'GetDeviceModel'
[DCC Error] Quick.Commons.pas(1144): E2003 Undeclared identifier: 'NSBundle'
[DCC Error] Quick.Commons.pas(1145): E2003 Undeclared identifier: 'NSString'
[DCC Error] Quick.Commons.pas(1148): E2003 Undeclared identifier: 'StrToNSStr'
[DCC Error] Quick.Commons.pas(1148): E2003 Undeclared identifier: 'ILocalObject'
[DCC Error] Quick.Commons.pas(1148): E2015 Operator not applicable to this operand type
[DCC Error] Quick.Commons.pas(1149): E2003 Undeclared identifier: 'TNSBundle'
[DCC Error] Quick.Commons.pas(1149): E2066 Missing operator or semicolon
[DCC Error] Quick.Commons.pas(1149): E2125 EXCEPT or FINALLY expected
[DCC Error] Quick.Commons.pas(1155): E2029 '.' expected but ';' found
[DCC Error] Quick.Commons.pas(1248): E2003 Undeclared identifier: 'NSBundle'
[DCC Error] Quick.Commons.pas(1249): E2003 Undeclared identifier: 'NSString'
[DCC Error] Quick.Commons.pas(1251): E2003 Undeclared identifier: 'StrToNSStr'
[DCC Error] Quick.Commons.pas(1251): E2003 Undeclared identifier: 'ILocalObject'
[DCC Error] Quick.Commons.pas(1251): E2015 Operator not applicable to this operand type
[DCC Error] Quick.Commons.pas(1252): E2003 Undeclared identifier: 'TNSBundle'
[DCC Error] Quick.Commons.pas(1252): E2066 Missing operator or semicolon
[DCC Error] Quick.Commons.pas(1252): E2029 'END' expected but ')' found
[DCC Fatal Error] Quick.SysInfo.pas(226): F2063 Could not compile used unit 'Quick.Commons.pas'

Quick.AppService Starting with Param

Hi,

I install the Application with a parameter.
Example: MyApplicaiton MyParam1 /install

After the installation, When i try to start the application ParamStr(1) gives me empty value.

When i make a normal service application without using Quick.AppService, ParamStr(1) gives me the parameter which i give on installation.

How can i get params on start?

Best Regards,
Serhan.

QuickLib.Expression have bug and Some advice

First, it was found that priority processing was not supported, causing some partial errors:
Assert(true, TExpressionParser.Validate(5, '(0.3 < 8) or (5 < 4) and (2 = 1)')); //false is err
Assert(true, TExpressionParser.Validate(5, '(8 > 3) or (5 > 4) and (2 = 1)')); //false is err

Some statements cannot be executed
// PRN(TExpressionParser.Validate(5,'8<1'));
// PRN(TExpressionParser.Validate(5,'8 < 1 or 5 > 4 '));

Unable to support addition, subtraction, multiplication and division. Hope to support common functions as well as custom functions

Quick.Azure TQuickAzure.ListContainers

Line 797

if Assigned(AzContainer) then begin //frees ContainerList objects for AzContainer in AzContainers do AzContainer.Free; AzContainers.Free; end;

Should be

if Assigned(AzContainers) then begin //frees ContainerList objects for AzContainer in AzContainers do AzContainer.Free; AzContainers.Free; end;

ScheduledJobs synchronization

First of all, good job with developing and publishing those sets of useful classes. They are a big time-saver and there are several very useful ones.

I was interested in the scheduled tasks and made a test, which worked nicely. However, I didn't see any way to wait for the tasks or to stop them. If it exists and I have missed it, sorry.

Here is what I mean: Let's say that there is a scheduled task, which has a long execution time and it starts. If I want to close the application, I will have to signal the task to end and to wait for it to do it gracefully.
It would be handy to have a set of methods like scheduledtasks.Terminate(and a flag that can be checked by the task) to signal any running task to interrupt, and a scheduledtasks.Wait to wait for any running one to finish.
Of course this can be achieved by doing the sync manually, but it will be useful to have it integrated.

Btw, some of your interface like ITask are named the same as the ones in System.Threading. These are the best names, but it creates an inconvenience when having a lot of code using the System ITask, and trying to integrate your classes gradually :)
I have to go over the code and add prefixes or reorder the units under uses...

Quick Config Return for Load or new Event when file is corrupted

I know that Quick Config does not generate any error if the configuration file is corrupted or not well formatted.
As an improvement suggestion, it would be great to know (after executing the load procedure) if the config file was read without error or if it contained errors.

Compiler Error in Quick.Json.Serializer

Delphi 10 Seattle

[dcc32 Error] Quick.Json.Serializer.pas(390): E2003 Undeclared identifier: 'JsonString'

Line:
if rField.FieldType.TypeKind in [tkString, tkLString, tkWString, tkUString] then
{$IFDEF DELPHIRX103_UP}
rValue := DeserializeType(aObject,rField.FieldType.TypeKind,rField.FieldType.Handle,TJsonValue(member).value)
{$ELSE}
rValue := DeserializeType(aObject,rField.FieldType.TypeKind,rField.FieldType.Handle,member.JsonString.ToString)
{$ENDIF}
else rValue := DeserializeType(aObject,rField.FieldType.TypeKind,rField.FieldType.Handle,member.ToJSON);

Quick.SMTP - TLS (GMail/Office365)

     Self.UseTLS := utUseExplicitTLS;   // REQUIRED for GMAIL / Office365

Line 236 (above) needs to be uncommented for GMAIL and Office365 to send email.

Not sure why this is commented out in the code ???

Memory leak in Quick.Commons.GetSpecialFolderPath

Using Delphi 10.3 in Windows 10, setting ReportMemoryLeaksOnShutdown to True detects a memory leak in GetSpecialFolderPath function.
As stated in https://www.experts-exchange.com/questions/10206340/Locating-special-folder.html, maybe you could consider a solution like:

implementation
uses
Winapi.ActiveX;
...
function GetSpecialFolderPath(folderID : Integer) : string;
var
malloc : IMalloc;
ppidl: PItemIdList;
begin
if (SHGetMalloc(malloc)=NOERROR) then
begin
SHGetSpecialFolderLocation(0, folderID, ppidl);
SetLength(Result, MAX_PATH);
if not SHGetPathFromIDList(ppidl,{$IFDEF FPC}PAnsiChar(Result){$ELSE}PChar(Result){$ENDIF}) then
begin
malloc.Free(ppidl);
raise EShellError.create(Format('GetSpecialFolderPath: Invalid PIPL (%d)',[folderID]));
end;
SetLength(Result, lStrLen({$IFDEF FPC}PAnsiChar(Result){$ELSE}PChar(Result){$ENDIF}));
malloc.Free(ppidl);
end;
end;

In my test, that solved the problem.

Regards,

Paolo

Quick.Console

Feature :
CoutXY() -> Event type is not supported. Would be fantastic to add this feature.

TJsonUtils.JsonFormat range error beyond end of string

I believe I found a bug with the JsonFormat command. The for loop iterates through the supplied json string, but when the last character is a '}', the case statement checks beyond the end of the string json[i+1].

  for i := 1 to json.Length do
  begin
    c := json[i];
    ...
      case c of
        ...
        '}',']' :
          begin
            Delete(LIndent, 1, Length(INDENT));
            if not isEOL then Result := Result + EOL;
            if json[i+1] = ',' then Result := Result + LIndent + c
              else if json[i-1] in ['{','['] then Result := Result + c + EOL
                else Result := Result + LIndent + c + EOL;
            isEOL := True;
          end;

if json[i+1] (Quick.JSON.Utils.pas line 112) causes an index out of range (unless there is a space or newline at the end of the json string).

My input looked like this:

{"Config":{"foo":"bar"}}

Adding a length check corrects the problem:

 if (i<json.Length) and (json[i+1] = ',') then Result := Result + LIndent + c

Thank you for this wonderful project!

any plan TDateTime convert mongodb $date type in JsonSerializer??

Hi, exilon.

thanks for QuickLib.
always i used quicklib with mongodb and IJsonSerializer.
but, TDateTime is changed to string type into mongodb.
TJson.ObjectToJsonString(Object, [joDateFormatMongo]) it can make mongo datetime type json.

however, do you have any plan support convert tdatetime to $date options?

error in linux

Hello,

actually, i test QuikcLogger in Ubuntu 18.04 with QuickLib. (latest version 2.0 and 1.43)
just include Quick.Logger, Quick.Logger.Provider.Files.
(few months ago, i reported this error. but it's not fixed)
i try execute in linux machine after than result is show this error.

realloc(): invalid next size
중지됨 (core dumped)

i patch source code in Quick.Commons.pas like this.
(in GetComputerName procedure .. line 948)
{$IFDEF DELPHILINUX}
var
phost : PAnsiChar;
begin
try
phost := AllocMem(256);
if gethostname(phost,_SC_HOST_NAME_MAX) = 0 then
begin
{$IFDEF DEBUG}
Result := Copy(Trim(phost),1,Length(Trim(phost)));
{$ELSE}
Result := Copy(phost,1,Length(phost));
{$ENDIF}
end
else Result := 'N/A.';
FreeMem(phost);
except
Result := 'N/A';
end;
end;

gethostname need allocated buffer. but phost not allocation error.
i hope it helps.

Problem in class TQuickAmazon.PutObject ( StreamToArray )

Problem in class TQuickAmazon.PutObject

The "StreamToArray" function is not converting the STREAM to ARRAY correctly. At the end of the file, null characters (<0x00>) are remaining.
To solve the problem I had to replace the function with the code below:

function ByteContent(DataStream: TStream): TBytes;
var
  Buffer: TBytes;
begin
  if not Assigned(DataStream) then
    exit(nil);

  SetLength(Buffer, DataStream.Size);
  // the content may have been read
  DataStream.Position := 0;
  if DataStream.Size > 0 then
    DataStream.Read(Buffer[0], DataStream.Size);

  Result := Buffer;
end;

image (118)

loadFromJSON error?

Hi,
it sounds like the properties of any object are unchanged after loadFromJSON. I'm using Delphi 10.3.2 (not yet tested with FPC). Here is may program:

program QuickCloneTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Quick.Commons,
  Quick.Console,
  Quick.JSON.Helper;

type
  TMyObject = class
  public
    caption: string;
  end;

var
  jsonOutput: string;
  myObject, myOtherObject: TMyObject;

begin
  try
    myObject := TMyObject.Create;
    try
      myOtherObject := TMyObject.Create;
      try
        myOtherObject.caption := 'Second object''s caption';
        myObject.caption := 'First object''s caption';
        jsonOutput := myObject.ToJson;
        cout('Json is: ', ccYellow);
        cout(jsonOutput, etInfo);
        cout('', ccWhite);

        myOtherObject.FromJson(jsonOutput);
        cout('MyOtherObject''s caption is: ', ccYellow);
        cout(myOtherObject.caption, etInfo);
        cout('', ccWhite);

        myOtherObject.Clone(myObject);
        cout('After cloning, myOtherObject''s caption is: ', ccYellow);
        cout(myOtherObject.caption, etInfo);
        cout('', ccWhite);

        myObject.caption := 'Changed';
        myObject.FromJson(jsonOutput);
        cout('MyObject''s caption is: ', ccYellow);
        cout(myObject.caption, etInfo);

      finally
        myOtherObject.Free;
      end;
    finally
      myObject.Free;
    end;
    ConsoleWaitForEnterKey;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

and here is its output

Json is:
{
    "caption": "First object's caption"
}

MyOtherObject's caption is:
Second object's caption

After cloning, myOtherObject's caption is:
Second object's caption

MyObject's caption is:
Changed

where I expected always "First object's caption".

install with delphinus error!

hi,i am install QuickLib in delphinus, but it report an error!
Downloading QuickLib
Version: HEAD
Error: Delphinus.Install.json seems to be invalid json
deleting tempfiles
Error: Installation failed

can you help me?

TAppConfig.JsonIndent property is ignored

The Config json provider calls its serializer with a constant aIndent parameter (for TJsonSerializer.ObjectToJson) instead of using TAppConfig's JsonIndent property.

Quick.Config.Json, line 220:

json.Text := serializer.ObjectToJson(cConfig,True);

Should be:

json.Text := serializer.ObjectToJson(cConfig,cConfig.JsonIndent);

I was trying to set this property to overcome the range check error reported in #63.

suggestion in FaultControl

Hi, exilon.

in TRunTask and TScheduledTasks with WaitAndRetry,
parameter is 'aMaxRetries', 'aWaitTimeBetweenRetriesMs' and 'aWaitTimeMultiplierFactor'

for example --
aMaxRetires is -1 or INFINITE, aWaitTimeBetweenRetriesMs is 5000
and aWaitTimeMultiplierFactor is 0.
I think this is every 5 seconds retry. but it's not.
i think that cases MultiplierFactor is 0 means just follow aWaitTimeBetweenRetriesMS interval.

next is original code

if IsEmptyArray(fWaitTimeArray) then waitretryMS := fWaitTimeBetweenRetries *   Round(fNumRetries * fWaitTimeMultiplierFactor)
else waitretryMS := fWaitTimeArray[fNumRetries - 1];
if waitretryMS > 0 then WaitBeforeRetry(waitretryMS);

how about this...

          if fWaitTimeMultiplierFactor = 0 then
          begin
            if IsEmptyArray(fWaitTimeArray) then waitretryMS := fWaitTimeBetweenRetries
              else waitretryMS := fWaitTimeArray[fNumRetries - 1];
            if waitretryMS > 0 then WaitBeforeRetry(waitretryMS);
          end
          else
          begin
            if IsEmptyArray(fWaitTimeArray) then waitretryMS := fWaitTimeBetweenRetries * Round(fNumRetries * fWaitTimeMultiplierFactor)
              else waitretryMS := fWaitTimeArray[fNumRetries - 1];
            if waitretryMS > 0 then WaitBeforeRetry(waitretryMS);
          end;

TQuickAzure.PutBlob Filesize Issue

Hi,

When you upload a file to Azure using PutBlob function then the filesize is wrong on Azure. When you download this file again, tested with an excel file, it will be damaged (it will ask for a repair).
The reason is the way the local var Content is handled. I found a fix in the Embarcadero 10.3.3 Demos on GitHub, filename CloudPopulator.pas (Trunk\Object Pascal\Database\CloudAPI\CloudExplorer).

`function TQuickAzure.PutBlob(const azContainer : string; cStream : TStream; const azBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
var
BlobService : TAzureBlobService;
//Content : TArray;
Content: TBytes;
CloudResponseInfo : TCloudResponseInfo;
container : string;
blobname : string;
begin
azResponseInfo.StatusCode := 500;
if cStream.Size = 0 then
begin
azResponseInfo.StatusMsg := 'Stream is empty';
Exit;
end;

container := CheckContainer(azContainer);
blobname := RemoveFirstSlash(azBlobName);
try
BlobService := TAzureBlobService.Create(fconAzure);
try
BlobService.Timeout := fTimeout;
CloudResponseInfo := TCloudResponseInfo.Create;
try
// Content := StreamToArray(cStream);
Content := ByteContent(cStream);
Result := BlobService.PutBlockBlob(container,blobname,Content,EmptyStr,nil,nil,CloudResponseInfo);
azResponseInfo := GetResponseInfo(CloudResponseInfo);
finally
CloudResponseInfo.Free;
end;
finally
BlobService.Free;
end;
except
on E : Exception do
begin
azResponseInfo.StatusCode := 500;
azResponseInfo.StatusMsg := e.message;
Result := False;
end;
end;
end;`

and added (copied from the Embarcadero Demos on GitHub, CloudPopulator.pas)

`function TQuickAzure.ByteContent(DataStream: TStream): TBytes;
var
Buffer: TBytes;
begin
if not Assigned(DataStream) then
exit(nil);

SetLength(Buffer, DataStream.Size);
// the content may have been read
DataStream.Position := 0;
if DataStream.Size > 0 then
DataStream.Read(Buffer[0], DataStream.Size);

Result := Buffer;
end;`

Regards,
Pascal

Bug in Quick.AppService.

Hi, exilon.

i'll try AppService in console application.
in help text contain 'console' option.
but, in 'CheckParams' procedure not working with 'console' option.
only show 'Unknown parameter specified'.

i think should be
-->

if (ParamFindSwitch('h')) or (ParamFindSwitch('help')) then Self.Help
    else if ParamFindSwitch('install') then
    begin
      if (fCanInstallWithOtherName) and (ParamGetSwitch('instance',svcname)) then
      begin
        fServiceName := svcname;
        fDisplayName := svcname;
      end;
      Self.Install;
    end
    else if ParamFindSwitch('remove') then
    begin
      if (fCanInstallWithOtherName) and (ParamGetSwitch('instance',svcname)) then
      begin
        fServiceName := svcname;
        fDisplayName := svcname;
      end;
      Self.Remove;
    end
    else if ParamFindSwitch('console') then
    begin
    end
    else
      Writeln('Unknow parameter specified!');

ScheduledTasks RemoveTaskAfterExpiration not working...

First of all many thanks for this great library.
I'm using ScheduledTasks with RemoveTaskAfterExpiration option true.
After expiration ScheduledTasks dont remove task from its task list.

When I check the code I see that TScheduler.Execute cannot remove task from list because TScheduledTask.DoExpire method sets task's enabled property to false.

What's the lowest supported Delphi compiler?

Thanks for this excellent, versatile library!

A quick question - Delphi XE4 emits the following error when it is compiling Quick.Commons.TArrayOfStringHelper.Remove:
[dcc32 Error] Quick.Commons.pas(1617): E2008 Incompatible types

It seems that System.Delete doesn't support TArray in this version of Delphi.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.