Jump to content

David Schwartz

  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by David Schwartz

  1. David Schwartz

    End of licence Comunity edition.

    Ok, thanks. Good to know.
  2. David Schwartz

    Help with Delphi Community Edition

    ummm ... you do know you can have more than one email address in your life, right? I know folks with 50 or 60 emails just on GMail (although I don't know how they keep track of them). I've got a ton of domains, and over a dozen of them have email set up. Why would you impose on somebody else like that? Just grab another email address from somewhere! Do you have a domain with web hosting? If so, you can easily go into your hosting control panel and set up another mailbox. EMBT is not going to match it up with the one you used to register your product even if its the same domain because ... how many people do you think have registered using a @gmail_com address??? Probably THOUSANDS! Just say'n. Anyway, the download and installtion takes way more time than activation.
  3. David Schwartz

    End of licence Comunity edition.

    One of the "features" of Delphi is the committment that the company has to backwards compatibility. Meaning, you could probably load up a Delphi 2 database app that uses BDE and have it recompiled and running fairly quickly, assuming it isn't using any 3rd-party components. I would not worry about anything built in 10.x that didn't work just fine in 10.x+n . If you had some code built for D6 or D7, then yes, you'd probably run into some problems, but even they wouldn't be very hard to get past -- again, assuming no 3rd-party components are involved. (I don't think you can load any components into the CE versions, so this shouldn't be a problem. However, I also can't imagine being constrained to work with ONLY the default components -- I had to do it at one place I worked, and it was a horrible PITA.)
  4. I'm using TMS WEB core to build a web app, and it's talking with a dedicated REST-based service (built with XData). I have several back-end services that I'm using and the XData service interfaces with them itself. In most cases, it's also doing stuff that makes it more of a middle-tier app -- things that I simply don't want to do on the Client side. I see where TMS just came out with support for Google's Firebase using some DB-specific components in WEB Core that work on the Client side to connect directly to a Firebase DB remotely. In my mind, I tend to think of my back-end service as a class where I get and set things as needed, and I don't have to worry about how they're implemented or where they're stored. But putting logic in the Client that now knows these implementation details creates complications and dependencies that can affect future changes. I'm curious what others who've built some web apps think of the pros and cons of accessing back-end services directly from the Client app vs. through their dedicated service back-end? Do you mix it up, or prefer to hide everything behind your back-end service?
  5. David Schwartz

    Remote Delphi developer position

    Actually, I think it's far better than most job reqs I've seen that all look like they were copy-pasted from a book of generic job descriptions. I think it would help if it mentioned the application domain(s) that they're hiring for, along with some typical tasks they expect to accompany some of the skill requirements. (Apache, Linux, Windows ... beyond writing code ... sounds like an IT role.)
  6. David Schwartz

    How do I know if the click is an actual user click ?

    csUpdating is for use within components, and it's not just used for initialization. Using it to manage initialization in forms is ill-advised. There are three "levels" of initialization in forms: FormCreate, FormShow, and FormActivate. They occur at different times, and afford a lot of control over timing issues. If you want to see some really unpredictable timing issues with events, take a look at TTreeView and TListView controls. If you put some trace logic in the event handlers, you'll notice that several are called twice for every change. That can cause really strange things to happen if the handler does anything other than update a spot in the control.
  7. David Schwartz

    Direct vs. Indirect access of service by a Client?

    I'm asking for YOUR opinion, and you just asked me some questions. YOUR opinion seems to be, "Unless I'm running something with the bursty traffic of a Superbowl ad, then I don't care." That's fine. Thanks.
  8. David Schwartz

    Direct vs. Indirect access of service by a Client?

    Sorry, I'm not following you at all. This isn't an ad on the SuperBowl. It's a fairly nondescript membership-based service -- something like this forum, where the choice here might be whether the script talks directly to the service storing the data you're reading right now, or does it access it through a service (ie, a middle-tier) that might talk to different datastores and, for most purposes, introduces an unnoticeable delay?
  9. David Schwartz

    Direct vs. Indirect access of service by a Client?

    @Fr0sT.Brutal I don't think you're understanding the gist of my question. I can't recall ever seeing anybody recommend that it's a Good Idea to write an app that connects directly to the IP:Port# of a back-end DB like, say, MySQL. Why? Because everybody who has been working in the industry for any length of time says it's a HUGE security risk to expose the local DB access port to the entire internet. There used to be this terrific, and inexpensive, DB management tool called SQLYog that had a proxy layer that completely insulated the front-end GUI from the back-end MySQL DB. (I think they expanded it to work with other DBs over time, but I only used it with MySQL.) You had to install a script on your server that it talked to via a secure connection so you didn't have to expose the MySQL port to the entire world. That was the only MySQL DB maintenance tool that was affordable that operated securely. It got bought up and now it's as expensive as the others. Did you write your own secure proxy layer for your remote DB applications? Given that you think it depends mainly on the number of API calls you need, I'm guessing you aren't really dealing with the underlying risks. It doesn't matter if you have just one or thousands of APIs -- all it takes is one a-hole and lots of time on his/her hands to swamp your server with direct requests to your IP:Port# in an effort to break into your back-end DB. It's not like most DBs don't have a well-known port# they're configured to use, right? MySQL uses port 3306 by default. How many apps have you built where you put the DB logic on the front-end and made port 3306 public on the back-end servier just so you didn't need to bother with any kind of API layer for security, eh? For most folks it's an all-or-nothing proposition -- you don't build it for just a few then throw it away as your API needs grow. And you don't take the easy way out and pretend it's not an issue until you get your system hacked and have to report it to your users and the authorities as a breech. In this case, if you have a web app (as opposed to a typical client/server app that runs on a intranet LAN), it's probably designed to access most logic through your own back-end service. Even if the API itself is published (and many public services are; eg., Amazon and Google, among many others), the security is set up so nobody knows how the services themselves are implemented. It's like OOP -- you've got some "encapsulation" going on that hides the underlying implementation, with all of the corresponding benefits. One of the biggest consumers of such public APIs is Zapier, and they don't seem at all concerned with the quantity of calls each of their services might support. But if you DO have a dedicated service layer on the back-end, and then decide to implement some UI features that access something like Firebase directly from the front-end, you've now exposed an implementation detail to the world that can be easily detected that people might try to hack. Sure, it's more secure than just a raw IP:Port#, but ... I'm wondering how many people who've built apps partitioned this way think it's a risk or not. Are they inclined to hide everything behind their own services API? Or add-on UI services that expose some of their back-end service providers directly?
  10. David Schwartz

    Firebase options?

    what options exist to access Firebase from a VCL app?
  11. David Schwartz

    Some REST help please.

    In my limited experience with APIs and REST interfaces, it seems the API says whether it's a GET, POST, or some other HTTP request type, regardless if it follows typical REST protocols. Recently I had an encounter with a REST interface that's not just a POST request (due to the size of the payload) but it also allows optional querystring parameters on the URL. It sends data back in a RESTResponse packet. It took me quite a while to figure this out since it's not even clearly documented. Whaddaydo?
  12. David Schwartz

    Some REST help please.

    There are plenty of Delphi examples that could be cited as guides. Google this: "how to query a rest api using delphi" Even asking ChatGPT can elicit a decent response
  13. David Schwartz

    Type within a class

    If I understand what you're saying, I think it's a big problem that renders Google practically useless if you don't know the proper term to use, or if there even is one. You can give a code sample to google and ask, "what is this?" and you'll probably get a bunch of gibberish that does not include what you're looking for. ChatGPT might do a better job. But if you don't know what something is called, it's hard to ask anybody anything about it. Telling someone to RTFM isn't helpful b/c they don't even know what to look for. Case in point: where can you find the entire set of % parameters that can be used in a Format statement? if you go to the Help topic for Format, it doesn't say. You have to find a link buried in commentary to bring up that info. I still don't know what they're actually called.
  14. David Schwartz

    How do I know if the click is an actual user click ?

    I have a var in the form class named 'ignore_this' and set it to true before doing something that will fire an event automatically that I want ignored, then set it false afterwards, and I put "if ignore_this then Exit;" at the top of the event handler. Sometimes there's so much stuff like that in the OnFormCreate that I just have a 'creating_form' variable that's set True at the top and False at the bottom of OnFormCreate so event handlers can get bypassed.
  15. David Schwartz

    Testing zlib compression in Delphi

    It has been a while since I used these, but they work as intended. They let you compress and decompress a string or chunk of data in memory or a stream. It's not a "zip file" with a directory b/c ... what would it put in the directory if. say, there were 30 strings you were compressing? It takes a chunk of data and either compresses it or decompresses it. If you don't know the length of the uncompressed data, then it needs to figure it out. But chances are it's either quite small (ie, the overhead needed to figure it out is minimal) or you're going to save uncompressed size in your data record along with the compressed data so you know how much data it's going to take when it's uncompressed. Maybe think of it the same way as encoding and decoding data to/from Base64, only in that case the sizes are easy to calculate. I don't find any of this puzzling. Including the reference to ChangeFileExt -- although when I started using it (going back to DOS days), I thought it was odd that it assumed the dot '.' was part of the extension. But over time, it makes more sense that way so you can say ChangeFileExt( fn, '' ) to remove it AND the dot to get the BaseName that doesn't include the dot either. Coming from the c / Unix world, extensions are superflous, like in Macs (which are Unix-based), so it was weird to me that DOS (and later Windows) depended upon them to identify file types. In Unix, everything has some kind of file header in it, and there's even a command (file <filename>) that does a really good job of figuring out what type of file something is by reading a chunk of bytes from the beginning of the file. I think *nix allows file extensions simply as a courtesy to DOS / Windows, but doesn't hold them as having any significance. When I first started working with Unix in the mid-80s, file names rarely had extensions on them as they simply weren't needed. However, things that transformed an input file to a different format output file did tend to use an extension, so a C source file had a .c extension; the output of the cpp command (rarely used to save files) used a .cpp extension; the output of the c compiler used a .o extension. But the output of the linker used no extension. In fact, just typing a filename on the command line would run it using whatever it needed: it could run as an executable, or via sh, bash, ksh, csh, etc, if it was a shell script; and so on. Unix just figured it out, and totally ignored any extension that might be present. AFAIK, Linux systems still do that today. I suppose it just depends on your background? DOS and Windows still have a lot of vestiges hanging around from their Unix roots. (I just never figured out why DOS used backslashes instead of forward slashes in file paths, other than simply to look different. In Unix, backslashes are used universally as an escape character. Also, single and double quotes (' vs. ") are interpreted differently in a lot of contexts, unlike in DOS and Windows where they're typically equivalent.)
  16. David Schwartz


    TMS has a scripting tool.
  17. David Schwartz

    Type within a class

    Delphi supports nested types. This binds the type name TIterateAction to TDataContainer in case anybody wants to refer to it outside of TDataContainer class. Usually I see nested types declared as Private, which basically means they're intended for the exclusive use of that class, as nobody outside of the class can even see them.
  18. David Schwartz

    How do I upgrade an old 2007 project ?

    I had a lot of problems with D2009, so I stuck with D2007 until D2010 came out. But D2010 was also where they introduced generics, so it bridges two major inflection points in the language.
  19. I just got this from somebody who claims to have found my resume somewhere. This is pretty much the same as every other job req I've been seeing for the past few years. Other than mentioning Delphi, I have no clue what skills they are looking for, or even what the application domain is. And since they client is asking for 3-5 years of experience, I cannot imagine them hiring someone with even 10 years of experience. Why is this guy even sending this to someone like me? I'm guessing they're just harvesting resumes. I don't know about anybody else, but after 40 years, my resume doesn't change a whole lot from one year to the next. I can't cover more than 10 years without making it too long; sadly, the projects I worked on in the 90's were the most fun but nobody wants to hear about things I did when they were kids. So there's not much in an updated resume that's they don't already have, maybe one or two more lines about my latest endeavors. One red-flag to me is the CMMI Level 3. This means you're not changing any line of code that isn't tied back to a change request somewhere in Jira. --------------------------------------------------------- Hi, Hope you are doing great. My name is Naga Devi and I work for Ameriinfo Inc. I have come across your impressive credentials from one of the job boards and wanted to check your availability. If you are available, I have included a job description below and would appreciate your response along with your latest resume, best number, and a time to connect. If you are not interested or the job is not suitable, please accept my apology and I request your support with references. Position: Delphi Developer Location: Remote The Challenge: The Delphi multi-tiered Desktop Application Developer supports the client’s mission by developing quality software within a structured and mature software development life-cycle environment, preferably an agile development environment. This position works closely with the customer and team members, especially the Functional Analyst, SQA (Software Quality Assurance), and other developers to ensure that modifications and enhancements to existing software and development of new software products provide efficient and effective solutions for the customer. The applicant for this position will be involved in all aspects of application development, including analysis, requirements documentation, design, development and test site deployment and issue tracking and resolution. The applicant will work closely and take direction from the lead Delphi Developer and the Project Manager. Required Education: Bachelor’s (or higher) in Computer Science or similar field of study with an application development focus preferred. Required Years of Experience: 3 years, or 5 years of additional relevant experience may be substituted for education Responsibilities: • Designing, developing, testing, deploying software. • Defect resolution and issue tracking. • Development of new functionality and modification to existing applications. • Participating in agile development life-cycle to include daily scrum calls, sprint planning and build planning. • Assisting and working with other Delphi developers as well as Mumps developers. • Work in Jira to track and update status on work activities. Minimum Qualifications: • The applicant must possess written and verbal communication skills required to work with team members and assist with documentation to include but not limited to software documentation, work activities, issue tracking, technical manuals, and other work processes. • Has high standards, results oriented, and a commitment to delivering high quality production time • Although rarely required, applicants must also be willing to travel occasionally. • Preferred Qualifications: • 6+ months of experience working with VistA integration development. • Prior experience working with tools such as Jira, Service Now and GitHub • CMMI (Capability Maturity Model Integration) Maturity Level 3, ISO (International Organization for Standardization) 9001:2015 or 9001:2001, and ITIL experience a plus
  20. David Schwartz

    Delphi job req I just got

    Thankfully, my days of working for large corporations with their policies aimed at micromanaging programmer activities are over. I don't have an issue with Traceability. What i have an issue with is when you're working for a company and they put you through a few days of formal training in something like Agile that goes through things in detail, then you get back to your project and are told things aren't really the way you were taught. Such as, while Development owns the Backlog, Developers aren't allowed to write up Change Tickets or submit anything into the Backlog, only the Client is, and that requires a detailed documentation of the errors and how to reproduce them. Which is fine unless the errors are not reproducible because of existing bugs that the Client won't ever see, but Devs can and do find them. We're hired as "experts" and then managed like monkeys. I'm done with it. Got my own stuff to play with now. 🙂
  21. David Schwartz

    Delphi job req I just got

    I found an exact copy of this same job req on LinkedIn from someone else. The real client is Booze-Allen-Hamilton (or whatever their name is these days) and it's for the VA, who probably wrote the copy itself. I used to work for a company on a similar project.
  22. I've got this file I'm trying to attach to a POST request in TMS WEB Core as follows: procedure TFile.Upload(AAction: string); var f: TJSHTMLFile; fd: TJSFormData; ptrProgress, ptrComplete, ptrError, ptrAbort: pointer; begin f := FileObject; fd := TJSFormData.new; fd.Append('file1',f); <-------- the file is Base64 encoded FReq := TJSXMLHttpRequest.new; . . . event handler assignments . . . FReq.Open('POST',AAction, true); FReq.Send(fd); end; procedure TFile.Upload(AAction: string); var f: TJSHTMLFile; fd: TJSFormData; ptrProgress, ptrComplete, ptrError, ptrAbort: pointer; begin f := FileObject; fd := TJSFormData.new; fd.Append('file1',f); <-------- FReq := TJSXMLHttpRequest.new; . . . event handler assignments . . . FReq.Open('POST',AAction, true); FReq.Send(fd); end; This is using javascript under the hood. It's being put into a JSFormData object, which is being imported from a standard JS file. I have this code in a PHP script to receive it: $fn = $destinationFolder . $_GET['filename']; $data = base64_decode($_FILES['file1']); <------- $file = fopen($fn, 'w'); fwrite($file, $data); fclose($file); It _seems_ to be getting uploaded, but it's not getting delivered. My web console debugger shows this: First, that attachment looks empty. Or maybe the file itself is attached separately. I don't know. Does this look correct for a JS upload like this? Second, is $_FILES['file1'] the right way to refer to it on the server side in PHP? Would it be the same in, say, Python?
  23. David Schwartz

    is this a valid, complete JSFormData attachment?

    The Mystery has been SOLVED!!! <?php // a lot of safety and security checks go here, along with the folder: $destinationFolder = 'dest/folder/goes/here/'; $data = file_get_contents( $_FILES['file1']['tmp_name'] ); $fn = $destinationFolder . $_FILES['file1']['name']; $file = fopen($fn, 'w'); fwrite($file, $data); fclose($file); http_response_code(200); echo 'File ' . $_FILES['file1']['name'] . ' uploaded to: ' . $fn; ?> file_get_contents apparently tells the client to send the file to the server (this script) and it gets saved into $data, which is done in another thread or session or something, because it does not appear as part of the upload payload with the request. It boiled down to getting just two lines of code correct!
  24. as I said: "... and proceed from there" It's in a new folder so there shouldn't be any initial conflict. But you always have to rename a new project and the initial unit(s), right?
  25. I've seen apps hang on disconnecting from DBs. I've never known why, tho. Is there an unterminated transaction that's waiting to time-out, perhaps?