Sorry if the question seems vague, please let me explain.
I have two datasets, called, say, Master and Extensions. They have a same primary key, but not all Master records have an Extensions record (this is the important point).
The UI are the usual data aware controls linked by datasources, placed in a TPageControl, with a page/tab for each dataset. A TDBNavigator linked to the Master dataset allows the user to browse through the records.
The user could be on the Extensions page/tab while browsing, and may want to edit the Extensions record data. If an Extension record already exists, all's well and good because the AutoEdit property of the datasource will automatically place the dataset into edit mode.
But what if there is no Extensions record? I suppose I need the equivalent of an 'AutoInsert' property, that would automatically place the dataset in Insert mode if the user starts to typing in one of the controls. (and I can always set up the primary key in the BeforeInsert event).
Any thoughts how I would achieve this?
Thanks for any advice, and thanks for reading a long question,
Regards
PhilW.
I would programmatically insert the record when the user enters any of the editable controls, and remove it afterwards if it's not needed. You should be able to do that without hitting the database at all, so the only real cost is a little code.
I don't think it's really autoinsert when you're inserting a new row into the middle of a sparse table like this.
Related
I'm planning a new app that will handle multiple text fields on many projects for many users. ie, there will be a lot of text fields to manage.
A key feature will be the ability to "roll back" to view and update to previous versions of each and every text field.
Can anyone give me some advice on how best to handle this?
It seems like there would be a huge amount of data if each and every version of each and every potential text field was stored in the same table. But it may be the only way, and there is nothing wrong with storing each and every version in it's entirety?
I thought there might be a smart approach to this though?
I would suggest using a versioning library like paper_trail. It will log all the changes to the fields you tell it to track. If you're really concerned with the amount of data that needs to be stored you might prefer a library like vestal_versions, which only stores the changes you made, not a complete copy of each version.
I'm developing a business web application which will maintain a database with several tables. One of the requirements are that one should be able to "save your work" without affecting the database and then later pick it up and continue working. Multiple "savings" must be supported.
This administration tool will be developed in ASP.NET MVC4 or Microsoft's LightSwitch, I haven't decided yet.
The problem I have is that I don't know how to solve this structurally, are there any known techniques to this problem? I need help by someone to point me in the right direction, I'm stuck here..
EDIT: I'll try to explain further with a scenario
I make a change to one row and save, but the change should only be visible to me (not affect the main database).
I realize the change in 1. is bad and choose to start over with changing the data in the same row, I also make a change to another row. I save these changes (but only for me)
Now I have two savings (from step 1 and 2), I change my mind and the changes made in 1. is correct and I open that "savefile" and commit the changes to main databse. I'll then delete the "savefile" from step 2.
Hope that makes the situation more clear.
Thanks
The easiest way that I can think of is to let the database do the work for you.
You could:
Just add some type of a "status" column ("committed", "uncommitted" etc) to the table, & filter out any "uncommitted" records in any grid that displays "real" data. You can then also filter
a different way in your editing grid, that only shows you
"uncommitted" records, or if you could save an ID instead of a status, if you
only want to see your own records.
Add another table to hold the uncommitted records, rather than
"pollute" the actual table with extra columns.
Does that make sense?
if you are really going to build a transactional type version control system, then you have a huge job ahead.
look at some popular tools like SVN and see the level of complication and features they support.
Rolling back a partial transaction inside a database - especially one with constraints and triggers will be very difficult. almost everything would run into an issue somewhere.
you may also consider storing uncommitted transactions outside the database - like in some local XML structure - then committing the components only once when desired.
either way, the interface for finding all the records and determining which ones to do what with will be a challenge - nevermind the original application.
I'm planning to write an un-do feature for use in a TDBGrid hooked up to a TTable (BDE). I want it to work at the grid cell level.
I'd like some suggestions on a good way to implement this.
I plan to keep a list of records that changed, the field name, and their former values.
What I need, I believe, are an OnEnter and OnExit for cells.
TDataSet.BeforeEdit is half of what I need, I think. But, TDataSet.AfterEdit is a bit misnamed -- it's called not after the edit is completed, but "after the TDataSet enters the edit mode" (to quote the help system.)
TField.OnChange would work though... I think ...
My thinking is that AfterEdit will grab the contents of the cell. And TField.OnChange will log the change to a stack I keep. (Thank goodness for Delphi's Generics. I never knew what I was missing before we had them!)
Any suggestions on how my thinking, caveats, or better ways to do this?
PS Standard mea culpa: Yes, yes: the BDE is deprecated, I shouldn't be using it, yada, yada, yada. Tell that to my boss who has me maintaining 1.5 million lines of legacy code. Yes, yes: someday the BDE will go away and we should be proactive and make the move now. We know. Thank you.
As per Robert's request, my comment(s) rewritten as an asnwer.
Don't cells already support undo by typing Ctrl-Z or Esc?
Or if you want to keep a stack of edits to multiple cells and have "undo" revert them one by one then you could combine dataset and field events. The dataset OnBeforeEdit will give you the base for all cells, each field's onchange will give you its OnAfterEdit which would render the same value as an (imaginary) Field.OnBeforeEdit when the user comes back to edit the same cell again.
If to implement Undo / Redo functionality for BDE datasets, then best will be to inherit your own datasets, and there override some methods, instead of to hook events. Then replace all TQuery with TYourQuery.
More simple is to use TClientDataSet + TDataSetProvider in the places where Undo / Redo is needed. Set TClientDataSet.LogChanges to True. To Undo editing call UndoLastChange. Sorry, you cannot Redo, although.
Migration from BDE to some 3d party data access components may be simple and straightforward. Eg, AnyDAC has API compatible with BDE, well documented migration procedure, tool for automating migration. Also, after migration you will get (2) right out of the box.
I use disablecontrols method for master/detail tables and I am looking for a way to change the record position internally (while within disable controls) in the component level (IBDAC) without using bookmarks or locate
Thanks
Try RecNo and check out Navigating Data in Client Datasets
Apart from that, I think this is probably a design issue you need to address, but I'm not sure. I normally fetch all the data I need, then a single unidirectional pass through the dataset is usually enough. If necessary, make a second pass (rarely), but I've never had to move back and forth several times within a dataset. There is probably a better way. Hope that helps.
I came across this a few times in my career and never really found an answer. My question is in regards to a web form that contains multiple controls that the user can update, and then saves the data to a database (easiest example I can think of right now is a user profile form - see SO profile edit screen).
So far, I have always just saved every control's value to the database. To me, it seems easier to have one method that calls one stored procedure, passing all the page's form values in.
I have seen pages that seem to save the individual control's value, rather than the entire set of controls. It can definitely look nice (if the page is doing it through AJAX), but is it better? I would think you would need more overhead to get this done, like one (or many?) DTO, more methods, and more stored procedures?
Which way is better? And are there any examples of how the individual control way is done?
Thanks!
I'd generally recommend using the individual control method; it provides for much greater granularity of design.
Depends what you mean by better.
"one method, stored procedure" - quicker to code, easier to maintain. "save the individual control's value" - more optimized? I'd leave optimization to last. Looks nicer? Is usability actually a problem on this page? YAGNI - fix performance/usability only if they are broken.
Some thoughts
It's one call to the database whether it's 25 columns or a single column
(Similar) If you update 6 controls in one edit session, you do it in one call rather than 6 separate ones
You may have forms with dependent or linked controls or disallowed value combinations: The general case would be "multiple control" changes in one edit session: so code for this
The general idea of auditing/timestamping is at the unique *row *level, not column.