Jump to content

David Schwartz

Members
  • Content Count

    1229
  • Joined

  • Last visited

  • Days Won

    25

David Schwartz last won the day on September 9

David Schwartz had the most liked content!

Community Reputation

426 Excellent

1 Follower

Technical Information

  • Delphi-Version
    Delphi 10.4 Sydney

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. David Schwartz

    VCL DB App. To Cloud

    Yes, this is rather vague. But if you're using D10.4 and it's a VCL DB app, then I'm guessing you're using some kind of TDatabase component to connect to your local DB? If so, it may be as simple as changing your provider interface and connecting to that. If you're using MySQL or SQL Server locally, you can connect to the same DBs remotely. But you could also be asking a more generic question, like what's involved replacing a local DB with a REST-based service API? I mean, you mentioned RadServer, so maybe that's what you're looking for instead? That's a whole nuther can of worms! But if that's what you want, then you need to start shifting how you think about your DB. In Delphi, using DB-aware controls, you're using a traditional client/server model where the app is simply connecting to a DB server and issuing queries and processing the responses. However, those queries tend to be invisible unless you're using explicit SQL queries. Issuing SQL queries for tables and rows is often a lot more overhead than what you want to do if you have a REST-based API -- in that case you need the queries to be more granular. A lot of client/server apps issue things like, "SELECT * FROM ...." and get back thousands and thousands of records, then filter them down. Using a REST-based API, it's best to issue extremely specific queries. Like if you're using a grid to show some data, you'd issue queries that only request to get the number of rows and columns in the grid. If it's a master/detail list, then when the user clicks a row, you'd issue a request to get the data for that specific row. Client/Server stuff often pulls everythign into memory when you open the tables. That is way to inefficient for remote services. If your app IS more of a traditional client/server app, they're you're going to need to re-do the forms and logic that's used to populate the forms, rather than relying on the underlying DB-aware components. There are some provider components that you can replace your existing ones with that add some level of intelligence to the underlying data management without needing a lot of rework on your part, but that would be more of a stop-gap IMHO. Another approach you can use retains the current providers but you'd want to lean more heavily on SQL and stored procs. If you plan it out correctly, the stored procs can be replaced by API calls to a back-end service with endpoints that call the same stored procs. Whatever approach you take, you MUST get away from the traditional client/server practices that simply open the tables and load the entire dataset into local memory.
  2. David Schwartz

    Buying a mini pc to install Delphi

    That's why I prefer to buy stuff that's out-of-warranty and do my own upgrades. It's WAY CHEAPER that way! Most of what we're talking about is purely mechanical work; very little soldering is needed. Besides, I can't recall the last time I had any piece of electronics that failed and I was able to get it fixed under warranty. Seriously. FWIW, I spent most of today at a car dealer. I got a new car on Friday and while going through the paperwork yesterday (Sunday) I found that a few things that I kept telling them I wanted and hearing them say, "Ok, that's what you've got" -- but that ended up being far different than what was in the agreement they had me sign. It all had to do with warranties. If you want to find an industry that has figured out how to leverage people's fear of things breaking down vs. the cost to get it fixed, the automotive industry has perfected this to the max. My experience with electronics is they either fail in the first few hours of use, or they don't. That applies especially to computers and peripherals. I don't know how many dozens of computers are contained in the newest cars, but no matter what they say, most of them are NOT covered under ANY warranties. But they'll tell you they are -- or they'll say they're NOT just to get you to buy an extended warranty plan that you don't need, and when they fail they'll tell you they're NOT covered. I got this new car because my last car had a problem that originated with the previous owner. In spite of all of all the warranties and assurances that I didn't have to worry about ANY problems that might arise with my electrical system (it's an EV) they were all just a big pack of lies. My fast charge port stopped working, and they wanted $6500 to replace the entire wiring harness in it -- even though the warranty I paid $5k for was supposedly designed to cover things like this -- "from stem to stern" they said. "Anything that goes wrong" they said. Just not "pre-existing conditions". Oops. Now they tell me that after 3+ years! I'm the wrong person to talk to about the perceived value of warranties -- to me, they're utterly worthless. And if you ask most people who've had any kind of insurance policy on things that failed and then their "warranty" denied coverage (esp. health care plans!) they'll say the same thing. I put zero faith in warranties. It's easier to get things "fixed" by filing a dispute with your charge card company than to deal with warranties! Thankfully, most companies are easier to manipulate via social media than the useless warranties they offer.
  3. David Schwartz

    Buying a mini pc to install Delphi

    You're welcome to spend your time however you want. Just like some people love to constantly tinker on their own cars, and won't own anything built after 1990. That's perfectsly fine! I'm just as uninterested in futzing with my car as I am with constantly futzing with my OS and computer hardwere. There was a time when I totally LOVED futzing with the OS and hardware. Today I just want it to run. Apple's OS is basically Unix, and I can get at it via the Terminal app any time I want; I do that very rarely any more. It's not about the cost to me, but how little I have to actually think about it and am forced to deal with it. Some people prefer to clean their own homes, and some prefer to have someone clean it for them. Arguments can be made on both sides. But saying you do your own cleaning just because you think "the cost [to have someone else do it] is outrageous", then it's not about the cleaning any more, is it? Neither one is "right" or "better". I just find that Apple's ecosystem takes far less of my time and attention to maintain than Windows. That's priceless to me. YMMV.
  4. David Schwartz

    Buying a mini pc to install Delphi

    I didn't realize this forum caters to "average consmers".
  5. David Schwartz

    Buying a mini pc to install Delphi

    "the Apple Tax"? I've got a 2014 Mac Mini and a 2018 Mac Mini, as well as a 2014 MacBook Pro. They all still run just fine. I use the Mac Minis pretty much every single day. I have yet to own a Windows PC that lasts more than 3-4 years. My suggestion is to buy an Intel-based Mac Mini with an i7, 256GB or more of SSD. These devices let you upgrade the RAM, so you could get one with just 8GB and put in a couple of 16GB DRAMs. Also, you can get more SSD, but it's cheaper to get a Samsung T5, T7, or T9 external SSD (USB 3.2) rather than pay the cost of adding more SSD to the base machine. A 512 GB SSD + a 2TB T7 may be an optimal choice. Set it up with a VM and load Delphi into that. I use VirtualBox, but I just read where VMWare just announced that Workstation and Fusion are now FREE. Be sure to back them up; mine take up 100GB or so, which only takes a few minutes to copy to a T5 and less on the faster ones. As far as connecting to whatever you get, I access my 2014 Mac Mini via the 2018 one using an RDP connection (shared desktop). That would work as well for Windows as Macs. I'm looking at getting a new Mac Mini with the M4 chip ... does anybody know how well VMs running Windows work on Apples Mx series chips? Does the Intel CPU emulation layer slow things down very much?
  6. David Schwartz

    Meta-Delphi question about web hosting..

    I second the recommendation for TMS WEB Core. It's just like building a VCL or FMX app, but it runs in the web browser. The language has been enhanced a bit to deal with async issues, but it's easy to learn. (Once you do, you wonder why it's not in Delphi's core.)
  7. I'd suggest TMS Software's various Cloud Packs. The most challenging thing in using ANY REST-based service is that they're inherintely asynchronous in nature. Delphi has nothing built-in to handle that. A lot of people use tasks or multi-threading, but a lot of libraries provide a way to have callbacks so they look more like ordinary TEvents. I've switched to using something from TMS called WEB Core that lets you write code in the Delphi IDE and it's transpiled into javascript. They've extended the language with some things to make accessing async services much easier. They've got something in beta that will add a WYSIWYG HTML form designer that integrates into the Delphi IDE to use with WEB Core, so you're not stuck doing design work in one window and having to see how it looks at run-time in another window. Any latency and security issues you have will depend on the services you're using, not so much your app -- there's nothing you can do in your app to address latency issues, and you can only use the secure interfaces the services offer, but they tend to offer the latest security options.
  8. David Schwartz

    Minimum Viable Product (MVP)

    IOW, use ChatGPT as an SME. That might be somewhat informative, but not a very smart approach for a start-up. TBH, if you don't already know most of this information and/or you don't have an SME involved in your project, then this is a waste of time and money because nobody is going to buy it. Keep in mind that ChatGPT only looks backward. It's not going to inform you of anything users would like to see in the future, which is what you're going to need to deliver if you want to gain a foot-hold over incumbant providers who are failing to deliver on what their users have been requesting for months if not years because the exising backlog is so huge. These AI systems are trained on what's known. The generative parts are not likely to take you in a direction that a creative person with decades of experience in one or more fields might propose. I'm building a meditation app. There are literally thousands of them available today, and if you asked ChatGPT to describe the structure, it's easy because they're all the same: they're like an MP3 player loaded up with some pre-recorded materials. Mine is NOT THAT. ChatGPT is never going to offer an example of what MY app's design is like. Why? Because it does not exist anywhere! What's worse is when I talk to potential investors and explain everything that makes mine unique, they come back to me later and say, "Well, I had my team look into this and they said they don't see any differences between yours and the others they found." What I have taken away from that is that Steve Jobs' infamous quote has a lot of merit: "Sometimes people don't know what they want until you show it to them." And even then it might take them a while to figure out it's really different. Back in the 80's I'd go to a big annual trade show called COMDEX and ask phone vendors how I could get access to their SDK to write apps that run on their phones. Some said they don't do that, and some said things like "it's $50k plus I'd have to pay them a licensing fee to keep the app included on the phone", plus I'd have to update it for each new phone release. But all of them were of the opinion that they could not see a world where anybody would want to waste time developing apps to run on cell phones. Which is perhaps why all of them lost their dominance as leaders in the cell phone industry believing that Apple's approach would never succeed. ChatGPT would only give you suggestions on how to build a better cell phone. It would never suggest adding apps and an app-store; focusing on the built-in camera's features; and make it so people can use it to create pro-quality videos. When was the last time you saw an ad for a phone that touts a bunch of new features for the PHONE part? Today they replace what a PC in 2000 did with 40 apps and a dozen hardware accessories!
  9. David Schwartz

    What are you using AI code-gen tools for that's working well?

    "Yes!" to all of these. I've also used it to do refactoring that's too complex to do with RegEx patterns. Like if you have "a.x := b.x" and you want to change everything to "b.x := a.x", or changing a Case statement into cascaded if..then..else or the other way around. You could give it a class with just variables and have it write all of the properties using either in place vars or methods. If you have a particular structure you want to follow, you can say, "create a class like xyz using this list of fields instead".
  10. I've been playing around with ChatGPT to help with certain Delphi coding tasks and I find it's really great at coding import/export routines between classes where the field names and types are the same. It's also great for generating template code for large Case statements, and certain kinds of refactoring. Coming up with functions to do specific things is not something it's very good at. I think with more popular languages, it would do a better job. But it makes up lots of stuff and if you try drilling-down it will eventually go in circles explaining how to implement things that don't really exist. I'm curious what sorts of things others are successfully using some AI tools for that help with Delphi code?
  11. David Schwartz

    Minimum Viable Product (MVP)

    You are facing the wrong direction in asking this question. You can only get the answer to "what belongs in our MVP" by asking prospective users of your software. In fact, you need to ask Subject Matter Experts (SMEs) in that domain who have a deep understanding of how your prospective users work and what kinds of functions and services they need to do their jobs better than what's already available. For a Corporate-level CRM package, you're going to be fighting a huge investment in their current solution, and a TON of resistance to change. You can minimize the latter by making your solution as compatible with whatever turnkey solution they might be using. But most of them are customized, and the companies pay a LOT of money in maintenance fees to keep them moving forward. First, you'd have to duplicate what they've already got, then you'd have to figure out what their 3-5 year backlog of change requests is and implement the most significant of them, then get that into the hands of their Corporate IT people so far ahead of what their expectations of the current platform are that it's enough for them to go to their CIO and say, "We need to jump ship and go with this other product!" at which point they're likely to be fired. Facebook did not start out as a better MySpace. But it wasn't long before they put MySpade out of business. You need to find a small specific niche and start building something that's simple yet unique that solves a glaring problem, as laid out by an SME in that niche. Make it available cheaply or free and then listen to your customers and build new features they're looking for, but in a more abstract way. If you're lucky, in 10 years you'll have something that one of the elephants in the field will want to buy you out for 9 figures. But asking a bunch of people who are SMEs for writing software in Dephi about what they think should go into an MVP targeted at Corporate Sales, Marketing, Support, and Management is not going to get you anywhere. Reach out to SMEs in THAT domain, and the first thing you should ask is, "What's it going to take to get a typical Corporation to adopt a new and unproven CRM product? You're not going to like their answer.
  12. David Schwartz

    swagger help needed

    This looks great, although it's 4 years after I created this thread and I am long gone from that employer. The article says a command-line version is "coming soon". Generally that would be sufficient for my typical needs. Is there any way to get updates on its progress?
  13. David Schwartz

    ifthen strange return value !

    @bravesofts Tell me, if you go to a restaurant and they don't use a dishwasher, but instead simply wipe off dishes that people use and then use them again, what do you get served a drink in? You'd call it a "dirty cup". The cup or dish itself is there -- it's intact, it's complete, it's ready to go. But it's "dirty" -- its contents have not been set to "clean", initialized as it were, or NIL if it's an object. A variable in Delphi is a pointer. The assumption is that it points to an object somewhere. The language requires you to set it to a known initial state -- that's called INITIALIZATION. You can initialize it to either NIL or a valid pointer. Just leaving it uninitialized raises a compiler warning and usually leads to bugs if ignored. Declaring a variable as an object allocates a pointer and you don't know until run-time if what it's pointing at is a valid object or not. If you're lucky it throws a memory error; if you're unlucky, it goes off into the weeds because the data appears valid and eventually crashes on something unrelated, sending you down a rabbit hole that's unrelated to the REAL error. Your code is correct as far as Delphi's syntax and semantics go. Only it's not reflecting what you think it is. You're testing the contents of the pointer var itself, not the OBJECT. There's a built-in function called Assigned(x) that you should be using, not your own method, IsAllocated, because all Delphi knows is if the reference is NIL or not. If it's not, then it assumes it's a pointer to a valid instance of said object. It has no way of knowing if it's allocated or not, or even if it's valid or not. If your code NEVER INITIALIZES it, then local variables take on whatever value is in the memory allocated on the stack for that variable. You need to INITIALIZE IT BEFORE USING IT. Usually, that means you say: myVar := NIL; You can also say something like: myVar := TMyObject.Create(); In C++ you can specify initialization values for specific fields in the class IN THE DEFINITION so that when you DECLARE AN INSTANCE then those fields are AUTO-INITIALIZED. This is not possible in Delphi. Declaring a variable for an object does not create an instance of it; the value of that pointer is not auto-initialized -- you have to do it yourself, usually by setting it to NIL.
  14. David Schwartz

    array

    Don't re-invent the wheel. Use a TClientDataSet or some other in-memory table with indices set up on the columns and it should run like greased lightning. (That's what adding an index to a column is for!)
  15. David Schwartz

    Issue with dynamic panel creation

    It would help a lot if you'd explain the problem you're having. Looking at the code, I'm _guessing_ that you only have a single vertical list of panels on that scrollbox. However, I can't tell if you have horizontal scrolling active or not. Assuming you don't want the panels resized, then they should all have the same relative positioning. I'm doing something similar with some panels on a scrollbox that does not do horizontal scrolling. It put three across and unlimited rows. I have a list of things and I go through the list and display them like this: 1 ---- 2 ---- 3 4 ---- 5 ---- 6 7 ---- 8 ---- 9 . . . I have a row_count and col_count, and position them with a gutter above and to the left, and derive the Top and Left position of each one with simple math based on curr_row and curr_col that I track as I'm laying them down. I save the Top, Left, Height, and Width in the objects in the list. The Height and Width are always constant, but the Top and Left change based on whether I want to show or hide them based on filtering. I have no problem scrolling vertically. I don't want or need horizontal scrolling. And the form isn't sizeable. But there's no reason this approach shouldn't work. When the form size changes, check the dimensions and if the number per row changes, then hide then reset the panels on the scrollbox area to maximize the number you can have with the given gutter size you're using. (I'm using 20 for both, but you seem to be using 5 for Vertical and you're ignoring Horizontal.) But if there was a problem based on this code, I'd say it's because you're calculating the positions by deriving them by SUMMING things up while scanning through your list. If you do allow horizontal scrolling, then that's just not going to work. The summing approach you're using will ONLY work properly if there's JUST ONE COLUMN. If there are multiple columns, you're going to get a steadily growing gap between rows in increments of the panel.Height+5. That might be happening simply because you have horizontal scrolling enabled. You need to use indices and calculate the TOP and LEFT based on a panel's index, the number of columns and rows you have, the gutter size between them, and current row and column.
×