Such an open assignment is not my cup of tea. By everything i do, i have my doubts (will it be enough to pass the exam). So i read some posts on this excellent forum and more doubts come up, so reading some more posts,... and so i get in neverending circle (and that's not so good for my productivity )
So after lots of thinking i finally started developing, but i have some doubts and questions:
1. i decided to use a randomaccessfile in each db-method (read, update, delete), so you can open and close the file when appropriate and you don't have to worry about filepointers getting wrong, because local variables are not shared. But what happens if 2 clients want to create record at the end of file or 2 clients update a different record (same record is impossible if i make a good implementation of lock and unlock methods )? Will file contents not get mixed up, because 2 different file handlers are writing at same time? Or will second file handler throw error because it can't open file for writing (because first file handler already opened file for writing)?
2. i was planning to hard-code my db-scheme (so lengths of different fields, start position of the records section,...) because the design is available in the instructions (but also in the header and thus could be read dynamically). But i don't think that's a valid reason to mention in my choices.txt and nor is mentioning it's a lot easier then getting everything from header What did you guys (and girls too of course) give as reason to make such a design decision?
1. As you have seen, one whole read operation should be considered atomic, as should whole write, delete, update, and create operations should be. Otherwise as you've mentioned, there is a chance that two concurrent calls will mess each other up especially because a class like RandomAccessFile has a piece of state (the current seek location). Thus, I synchronized all of these methods.
2. I read in the schema dynamically (not that hard once you start writing it, and then you get all the field information automatically, which is good if you want to verify field lengths) on the database side but hardcoded in the fields on the business+client sides. Justification? Hm... you could argue that the main database interface you're given does not have any methods to access schema data and thus that is not the role of the database.
I decided to cache all records, that is, when the application starts, I read the database content and put it in a HashMap<Integer, Room>, where the key is the record number and the Room object is the record itself. I thought this would be easier to deal with the records. For instance, I don't have to deal with IOExceptions in the read or find method. But note that your approach has its pros and cons, and my approach also has its pros and cons.
I created an interface called DBConstants, where I have all database schema there, and my Data class also implements it. I justified that the specs don't mention anything about the database schema changing, so I thought it would be ok to "hardcode" it.
Thanks for your reply and best wishes for 2009 (and the scjd-assignment (and result) )
So you have just one instance of your data-access class (the one that's accessing to the RAF) because otherwise 2 calls to 2 different data-access classes may mess up each other although you have synchronized all the methods. or did i miss something? and because you made all your methods synchronized you loose a bit of performance/concurrency. so that's the con of this solution?
reading out the schema isn't that hard (i have done it - to know position of first record), so i could store everything and not hard code my schema. but how did you implement locking with this one? do you have 1 method doing it all where you lock at start and unlock at the end, or do you use small pieces of code between a synchronized block? because you will need locking on different objects (e.g. you need to lock db and lock the object containing schema-info when reading in schema-info), so that may turn in a dead-lock situation.
I realize - after thinking a whole lot about all those different approaches of reading/handling the data file - that each approach has it own pros and cons You made nice argument for hardcoding the schema. But i think i will listen to the little voice in my head that keeps shouting "don't hard code, don't hard code" every time when i think about hard coding and pressing his mute button isn't working at all :lol: