Login ProductsSalesSupportDownloadsAbout |
Home » Technical Support » DBISAM Technical Support » Support Forums » DBISAM Client/Server » View Thread |
Messages 1 to 10 of 12 total |
Best Startup approach |
Thu, May 10 2007 2:21 PM | Permanent Link |
Mark C | Is there a correct or efficient way of starting an applications session/database/tables reagrding opened or closed.
At design-time compile is it best to have everything in-active and then on the main application formCreate, activate session / database then... 1. open ALL the tables and leave open throughout system until application terminates 2. Have NO tables open, but open them use them THEN close them. 3. Or any other methods. The application I am using is a 5 user works order system using one main form that drives all other input forms All my datasets and session/database componets are in one datamodule. Just was hoping for some BEST PRACTICE advice. Regards Mark. |
Fri, May 11 2007 1:08 AM | Permanent Link |
Dave M | Mark C wrote:
> Just was hoping for some BEST PRACTICE advice. At the risk of sounding like a wise guy, it might be a little after the fact to ask for best practice. It seems to me that your questions stem from treating data as global and once your data is no longer treated as global, your questions are answered. If you are using datamodules (which OOP wise aren't really best practice anyway), you can first design what you want. Then remove the var declaration (and remove from the autocreate list) and create in code. You can have the form, (which is removed from the autocreate list and created in code) create the datamodule in code. For instance, the customer form creates a customer datamodule, which could create job datamodules, etc. Only the form or creating datamodule can access a datamodule, since all var declarations are removed. (This also allows the creation, for instance, of many customer or job windows.) If you actually mean just one unit for the whole app, keeping everything in one datamodule or unit means the unit could eventually become thousands or tens of thousands of lines. Each time you edit something, how do you know you haven't broken something else? I have many times done so. It's true you can start off an app this way, but you may eventually have to rip it apart and do it over, if it gets big enough. Also, depending on the complexity of your app, globally accessible vars may end up making some other problems. For instance, you may end up assuming a table is on one record one place and on on another elsewhere. (Yes, I have done this and it makes for hard to find bugs and an undependable app.) This approach means when all forms (other than the main) are closed, all tables are closed. BTW, you can put your database and session in one globally available unit and have various datamodules use it. Dave M |
Fri, May 11 2007 2:44 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Mark
>Is there a correct or efficient way of starting an applications session/database/tables reagrding opened or closed. No >At design-time compile is it best to have everything in-active and then on the main application formCreate, activate session / database then... Its best to have all tables, sessions, databases etc closed before you compile - this prevents some potential problems. >1. open ALL the tables and leave open throughout system until application terminates That's how one of my apps works. The only problem is the time taken to open all the tables. >2. Have NO tables open, but open them use them THEN close them. >3. Or any other methods. I would go with open when needed and leave open until the app closes. The overhead is low and its probably the most efficient. The only potential danger is corruption if a pc crashes with the tables open and before the OS has written stuff to disk, but with DBISAM I've very rarely encountered this.. Roy Lambert |
Fri, May 11 2007 3:34 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Dave
>If you are using datamodules (which OOP wise aren't really best practice anyway), you can >first design what you want. Then remove the var declaration (and remove from the >autocreate list) and create in code. You can have the form, (which is removed from the >autocreate list and created in code) create the datamodule in code. For instance, the >customer form creates a customer datamodule, which could create job datamodules, etc. Only >the form or creating datamodule can access a datamodule, since all var declarations are >removed. (This also allows the creation, for instance, of many customer or job windows.) I leave the var declaration in, have the datamodule autocreated BUT with all the tables closed. There is a public procedure which I call from my main form to open the tables. Apart from the time spent opening tables it works very well and hasn't yet caused a problem. >If you actually mean just one unit for the whole app, keeping everything in one datamodule >or unit means the unit could eventually become thousands or tens of thousands of lines. Many of which will be simple table or field declarations unless there are some very complex business rules which have to live in the datamodule. I don't know about others but the vast (and I do mean vast) majority of my code deals with user interaction and is distributed over the forms in the app that the user works with, there are some generic procedures that are called from several apps which live in various units. I've just had a look in one app. The data module is 2259 lines but the declarations are 1207 lines. >Each time you edit something, how do you know you haven't broken something else? I have >many times done so. Same applies where ever the code lives. I>Also, depending on the complexity of your app, globally accessible vars may end up making >some other problems. For instance, you may end up assuming a table is on one record one >place and on on another elsewhere. (Yes, I have done this and it makes for hard to find >bugs and an undependable app.) But there's nothing to prevent several instances of a table on a datamodule. Also,depending on the design of the app it can be far better to have just one instance of the table and manage the cursor, especially if you define the fields in the ide and use the persistent variables rather than fieldbyname to access them. Roy Lambert |
Fri, May 11 2007 10:25 AM | Permanent Link |
Mark C | Thanks For your comments.
|
Fri, May 11 2007 8:48 PM | Permanent Link |
Dave M | Roy Lambert wrote:
>it works very well and hasn't yet caused a problem. The question I tried to answer was about best practice. There exists lots of ways of doing things that may not create problems for some and are also not best practice. I tried to answer working within the existing Delphi datamodule framework, which itself is not best practice. Therefore my answer also isn't best practice. So I guess if someone is going to use datamodules, it is a matter of how close one wants to get to best practice in a framework that isn't engineered for best practice. >The data module is 2259 lines but the declarations are 1207 lines. I would call that size hard to manage. I have a number of files that size and larger and I don't even like to open them. If it is big, it's hard to follow. It then involves retesting pretty much everything in the file, especially if you have set properties in the designer. Basically, you may end up with a situation where you are never sure if things that you have already debugged work. Of course if all testing is completely automated and thorough, then no problem, sort of. >>Each time you edit something, how do you know you haven't broken something else? >Same applies where ever the code lives. Generally not true, because when organized correctly, very seldom will you be editing all of the code. Isn't this is one of the reasons for organizing debugged routines in libraries and removing them from source code, so as to provide for some kind of reliable version? The issue here is reducing complexity of code maintenance by removing as much code as possible from a given editing cycle or event. >But there's nothing to prevent several instances of a table on a datamodule. This reminds me of having repeating data in a tuple, sometimes it works, sometimes it comes back to haunt you. In some situations, no problem. The way I recommended, you can for instance have 1 job or 100. You can use the datamodule (or an ancestor) for lookup, display, or data entry. No side effects, other than normal multiple user issues. On the other hand, for a simple app, it can be overkill. >Also,depending on the design of the app it can be far better to have just one instance of the table and manage the cursor, especially if you define the fields in the ide and use the persistent variables rather than fieldbyname to access them. Isn't the need to manage the cursor the result of an undesirable side effect? I used to do this with Clipper years ago. At the time, it always seemed wrong or lacking, and that there should have been a better way. The whole persistent variable/fieldbyname issue is part of the problems with Delphi's native code database access. It should have been changed years ago to allow binding to objects. That would be much better than what I suggested. As it is, the whole datamodule implementation breaks encapsulation. Years ago I had questions like what the OP had. It seems to me that the questions are a symptom of an antiquated design and that these questions will resolve once the design is updated. Dave M |
Sat, May 12 2007 3:55 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Dave
>The question I tried to answer was about best practice. Often that's a matter of opinion >I tried to >answer working within the existing Delphi datamodule framework, which itself is not best >practice. I'm always willing to learn - why isn't it best practice? >>The data module is 2259 lines but the declarations are 1207 lines. > >I would call that size hard to manage. I wouldn't <vbg> >>Same applies where ever the code lives. > >Generally not true, because when organized correctly, very seldom will you be editing all >of the code. Isn't this is one of the reasons for organizing debugged routines in >libraries and removing them from source code, so as to provide for some kind of reliable >version? The issue here is reducing complexity of code maintenance by removing as much >code as possible from a given editing cycle or event. That one reads to me like total gibberish. Maybe we're talking at cross purposes. I don't have any procedures that are 1000 lines long. If I'm editing a simple standalone procedure in a unit no matter how large the unit is why should it have any impact on other procedures or fuctions eg procedure TDM.CompaniesNewRecord(DataSet: TDataSet); begin Companies_Turnover.Value := '?'; Companies_Staffing.Value := '?'; Companies_Created.AsDateTime := Date; end; This is going to impact the companies table, and will do so even if I put it in a unit all its own. More importantly it will impact the companies table wherever its used. I don't want to have to stick it on every form. Editing it is rather unlikely to affect any other code don't you think even though the unit is 2259 lines long? >>But there's nothing to prevent several instances of a table on a datamodule. > >This reminds me of having repeating data in a tuple, sometimes it works, sometimes it >comes back to haunt you. We obviously program in different styles it certainly doesn't haunt me - a whip and a chair are all you need to tame it >Isn't the need to manage the cursor the result of an undesirable side effect? I used to do >this with Clipper years ago. At the time, it always seemed wrong or lacking, and that >there should have been a better way. I would say that all you're doing is an alternative way of managing the cursor. I (in some apps) use a single table, you're using multiple tables. Using a single table is a bit more tricky, but for an app that started life under Paradox & W95 I had to use every trick I could to keep the number of file handles in use down. As I change it for ElevateDB I'm altering the architecture to some degree. >The whole persistent variable/fieldbyname issue is part of the problems with Delphi's >native code database access. Don't see that please educate me. >Years ago I had questions like what the OP had. It seems to me that the questions are a >symptom of an antiquated design and that these questions will resolve once the design is >updated. Just cos its newer don't mean its better! I have major issues with coding and development practices that require ever more CPU and RAM just to work at an acceptable speed. Roy Lambert |
Sat, May 12 2007 7:56 AM | Permanent Link |
Dave M | Roy Lambert wrote:
>Often that's a matter of opinion >I'm always willing to learn - why isn't it best practice? Unfortunately you'll have to read to the end of this post. >That one reads to me like total gibberish. Maybe we're talking at cross purposes. I don't have any >procedures that are 1000 lines long. If I'm editing a simple standalone procedure in a unit no matter >how large the unit is why should it have any impact on other procedures or fuctions eg Ideally it wouldn't but...first of all, we were talking about Delphi datamodules. This includes the visual designer which is subject to accidental changes (not to mention bugs). Have you ever accidentally deleted events from a table when editing? Haven't you ever introduced bugs by global search and replace? Unless you check differences in the pas and dfm, you can't be sure of what is changed. The more things in the file, the more things called into question. Again, this is one of the reasons code is place in a library. Code I don't have access to (or haven't accessed), I can't mess up. How is this gibberish? >procedure TDM.CompaniesNewRecord(DataSet: TDataSet); >begin >Companies_Turnover.Value := '?'; >Companies_Staffing.Value := '?'; >Companies_Created.AsDateTime := Date; >end; >This is going to impact the companies table, and will do so even if I put it in a unit all its own. More >importantly it will impact the companies table wherever its used. I don't want to have to stick it on >every form. Your above comments and related code look to me like an illustration of the effects of passing around global data. It's also one of the same problems that datamodules have. Wouldn't it be better to have the company create its own new record? That might lead to a company object and would cause you to bump up against a native Delphi “data access issue”, specifically, how do you bind your objects to controls? It's either directly binding to datasets (and bypassing the objects), doing it manually, or coming up with a workaround. >We obviously program in different styles Maybe, but I have lots of “less than best practice” code of the type I have criticized. Right now I am considering rewriting some of it. Part of Delphi's native code database access architecture doesn't lend itself to easily writing good OO code. Maybe a year ago, I read somewhere that changes in data binding were planned for vcl.net in Highlander. I had hoped that it might also end up in native, but I'm not too sure it will. >Don't see that please educate me. See above. It's all part of the “how do you bind controls if you want to build business objects problem.” Also, how about the inability to maintain a clear delineation between UI, business objects, and data access? Having Tfields/fieldbyname show up in your forms doesn't help with this. These issues have been written about many times over the years. Maybe you don't see a need for what I have discussed. These issues have become more prominent as the code I am maintaining has gotten larger and harder to maintain. Dave M |
Sat, May 12 2007 8:23 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Dave
>Unfortunately you'll have to read to the end of this post. Nothing unfortunate about it - just a fact of life - and I did. >Ideally it wouldn't but...first of all, we were talking about Delphi datamodules. This >includes the visual designer which is subject to accidental changes (not to mention bugs). >Have you ever accidentally deleted events from a table when editing? Haven't you ever >introduced bugs by global search and replace? OK I see where you're coming from now. I first learnt (the hard way) about global search and replace when programming in APL back around 1978 and also learnt that its not a two way street. >Your above comments and related code look to me like an illustration of the effects of >passing around global data. It's also one of the same problems that datamodules have. >Wouldn't it be better to have the company create its own new record? That might lead to a >company object and would cause you to bump up against a native Delphi “data access issue”, >specifically, how do you bind your objects to controls? It's either directly binding to >datasets (and bypassing the objects), doing it manually, or coming up with a workaround. This is obviously where we start to differ. I'm sufficiently old school not to care overmuch (I was going to use a stronger expression but this is a public NG and I wouldn't want to embarrass Tim) about the purities of OO. I am as happy, probably happier, writing a function and passing it a few parameters as I am creating a class and altering its properties. I'm old enough to have seen a lot of passing ideas all of which were going to mean bug free and easy to maintain code. In the words of Catweasel "nothing works" >Maybe, but I have lots of “less than best practice” code of the type Again I would make the point that this is often a matter of opinion. One thing that seems to have fallen out of favour in judging how good code is is its performance. The attitude now is sling more hardware at it. Someday pure OO will reach an acceptable performance level, databases will move on from flat file or relational to OO. Not sure if I'll be alive to see that though. >See above. It's all part of the “how do you bind controls if you want to build business >objects problem.” Also, how about the inability to maintain a clear delineation between >UI, business objects, and data access? Having Tfields/fieldbyname show up in your forms >doesn't help with this. These issues have been written about many times over the years. > >Maybe you don't see a need for what I have discussed. These issues have become more >prominent as the code I am maintaining has gotten larger and harder to maintain. You've guessed right there However, one thing I've learnt over the years is that code you're happy with is easier to maintain and anyone else's code not matter how well written is a nightmare. Thanks for sharing your views, but as you can tell no convert Roy Lambert |
Mon, May 14 2007 5:58 PM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. timyoung@elevatesoft.com | Dave,
<< Isn't the need to manage the cursor the result of an undesirable side effect? I used to do this with Clipper years ago. At the time, it always seemed wrong or lacking, and that there should have been a better way. >> It depends upon what you mean by "manage the cursor". If you mean navigation, searching, etc. then there really isn't any way around that. Every access to a cursor on any dataset is going to require cursor management to some degree. MS has tried to remove this type of access with respect to .NET and the way that they handle data retrieval, but it is really counter-intuitive in many ways because it tries to make datasets that are from a database (and can be quite large) behave like in-memory datasets. This basically eliminates the ability to ever look at the dataset in its entirety for any practical purpose without resorting to pagination schemes that effectively force the end developer to recreate the code that the client interface layer has managed *for them* for years. IOW, eliminating the pagination and scrollable cursor support that ODBC and other standard CLI access layers have always had in the past didn't get rid of the requirements for such things, it simply moved the responsibility out of the hands of the database engine developers and into those with the least amount of experience in coping with such issues - the application developer. Now with .NET the application developer has to come up with all sorts of pagination schemes to work around the fact that the data access layer does not provide scrollable cursors. -- Tim Young Elevate Software www.elevatesoft.com |
Page 1 of 2 | Next Page » | |
Jump to Page: 1 2 |
This web page was last updated on Tuesday, September 17, 2024 at 04:19 AM | Privacy PolicySite Map © 2024 Elevate Software, Inc. All Rights Reserved Questions or comments ? E-mail us at info@elevatesoft.com |