Need to do Versioning of existing system - c#

I am working on a system which now requires versions to be maintained.
Will explain you the project in brief.
We have a CMS in which there are three users 1. Super Admin, 2. Editor, 3. Approver.
Editor add's data from CMS and send it to approver if he approves the data only in that case it is visible on the front end. Now if the editor edits the same data then its disapproved and removed from the frontend and agian he will send it to the approver and the same process will follow. This is how its working now.
The client has now changed the requirement and now what he wants is that once the data is approved and visible in the site i.e frontend and the editor now edits the data it should not be removed from the frontend and new edited data should be send for approval and when the approver approves the data the old one should be replaced with new one in the front end.
The database design is real bad so it's going to be difficult to achieve this.
The solution that we have thought of is...
For example the Editor can add some kind of news in the front end. All the data w.r.t news is added in news table. Editor add's the news sends it for approval and then he approves. Till here there are no issues. Now suppose that for some reason he wants to edit the same news which is approved. The moment he clicks on edits button it is removed from front end so what we thought is like maintain another table something like temp_news with the same structure and the moment he clicks on edit news after its being approved a new record should be inserted in temp_news table with the values from news table added in this table. Till then in frontend we will display the news from news table. So now we have the same news data in two tables. Approver and editor can now do all the changes and we will update the temp_news table. The moment approver approves this changed data we will update the new's table with values from temp_news table. so now in front end we have the updated new's.
The problem with this solution is that once the changed is approved both tables news and temp_news have the latest data. This not versioning.
Need a solution for this.
I am just a beginner.

I would just have one table that you use to store multiple versions of the same data
news
----
ID int
newsItem int
dateCreated datetime
IsApproved boolean
content text
Then for display on the front end. Just
SELECT top(1) * FROM news where IsApproved = true orderby dateCreated desc
So the front will only show the most recently approved version.
and newer version will just get a new ID and dateCreated but the isApproved would be false
so say if you had 3 version of the same news item. it would look like
ID newsitem dateCreated IsApproved
1 1 2011-4-26 false
2 1 2011-3-20 true
3 1 2011-1-6 true

How about a version control system like Git? Keep the versions, including the one to be approved in Git and the approved one in database table ( only one .) When a new one is approved, move it to the db. Since you are using C# and ASP.NET, something like git# might be helpful for you
People are already doing this:
This is a django website with a twist:
all content is stored in text files. I
manage those files with git. A little
script loads those files into the
database and then django serves them.
In fact, all of the content and its
history is actually publicly available
(but you don't have to make your
history available in order to use this
system). You can all see this an
example of how to use django-gitcms.
http://luispedro.org/software/git-cms
http://nestacms.com/docs/creating-content/publishing-articles-with-git
Git-based content management?

Related

ASP.NET Sorting Multiple SQL Database Tables By Date Range

This past week I was tasked with moving a PHP based database to a new SQL database. There are a handful of requirements, but one of those was using ASP.Net MVC to connect to the SQL database...and I have never used ASP.Net or MVC.
I have successfully moved the database to SQL and have the foundation of the ASP site set up (after spending many hours pouring through tutorials). The issue I am having now is that one of the pages is meant to display a handful of fields (User_Name, Work_Date, Work_Description, Work_Location, etc) but the only way of grabbing all of those fields is by combining two of the tables. Furthermore, I am required to allow the user to search the combined table for any matching rows between a user inputted date range.
I have tried having a basic table set up that displays the correct fields and have implemented a search bar...but that only allows me to search by a single date, not a range. I have also tried to use GridView with its Query Builder feature to grab the data fields I needed (which worked really well), but I can't figure out how to attach textboxes/buttons to the newly made GridView. Using a single table with GridView works perfectly and using textboxes/buttons is very intuitive. I just can't seem to make the same connection with a joined view.
So I suppose my question is this: what is the best way for me to combine these two tables while also still having the ability to perform searches on the displayed data? If I could build this database from scratch I would have just made a table with the relevant data attached to it, but because this is derived from a previously made database it has 12+ years of information that I need to dump into it.
Any help would be greatly appreciated. I am kind of dead in the water here. My inexperience with these systems is getting the better of me. I could post the code that I have, but I am mainly interested in my options and then I can do the research on my own.
Thanks!
It's difficult to offer definitive answers to your questions due to the need for guesswork.
But here are some hints.
You can say WHERE datestamp >= '2017-01-01' AND datestamp < '2018-01-01' to filter all the rows in calendar year 2017. Many variations on this sort of date range filter are available.
Your first table probably has some kind of ID number on each row. Let's call it first.first_id. Your second table probably has its own id, let's call it second.second_id. And, it probably has another id that identifies a row in your first table, let's call it second.first_id. That second.first_id is called a foreign key in the second table to the first table. There can be any number of rows in your second table corresponding to your first table via this foreign key.
If this is the case you can do something like this:
SELECT first.datestamp, first.val1, first.val2, second.val1, second.val2
FROM first
JOIN second ON first.first_id = second.first_id
WHERE first.datestamp >= '2018-06-01' AND first.datestamp < '2018-07-01'
AND (first.val1 = 'some search term' OR second.val1 = 'some search term')
ORDER BY first.datestamp
This makes a virtual table by joining together your two physical tables (FROM...JOIN...).
Then it filters the rows you want from that virtual table (FROM ...).
Then it puts them in the order you want (ORDER BY...).
Finally, it chooses the columns from the virtual table you want in your result set (SELECT ...).
SQL database servers (MySQL, SQL Server, postgreSQL, Oracle and the rest) are very smart about doing this sort of thing efficiently.

How to design ASP.NET Core - SQL application where user should be able to create forms of different input items and store values in database

I've started working on a web application project, where a feature is: the admin user can create/update few custom forms choosing different input types from the database and the end users can update the form data in a repetitive fashion/sometimes daily and the data stores in the database for further use cases. To elaborate, the admin user can choose any of "checkbox", "textbox", "textarea", "datetime", "temperature" etc. input types and create a form. The end user then can read the form and input the values that is to be saved in the database for reporting to admin.
I need to use ASP.NET Core MVC, SQL, EF, code first migration at the back-end of the project.
I am thinking maybe (as an example) a Form model with Id and Name properties, TextBox model with Id, Name, FormId, DateTime model with Id, Name, FormId etc. for creating the forms and then when user inputs values that can be updated using other models/tables in the database like TextBoxRecord model with Id, TextBoxId, Value, UserId, DateEntered etc. But then it will be too many tables to update and read every time when entering values and displaying reports to the admin.
I appreciate any help with a good design idea of the data model or how to attain this kind of logic. Also feel free ask, if you have any questions. Thanks.
Some time ago, I was working on some simular project. We don't store each of our form field in DB, because we don't want to update DB each time we need to add some new-kind-of-form-field. We believe it's up to HTML+JS to decide what kind of input to use with particular object property.
We create a serializer, that serialize form structure in xml and store it in DB. In this xml we keep a TableName (EF DataSet<> name) and ColumnName (name of model property) for each FormField.
When we need to show a form to user, we deserialize it from DB, pack in ViewModel (because we don't want to show to user real names of our DB tables) and send it to JavaScript code as JSON. JS then constructs the form element and show it to user. When user submits the data, we again deserialize corresponding form from DB and update actual models in db with data from user input.
Hope this will help.
To all the, eurhm, people, who find this an interesting question and "would like to know the answer too", there's an interesting article to read at
https://www.red-gate.com/simple-talk/opinion/opinion-pieces/bad-carma/
That story started with (at least as good as) exactly the same kind of user requirement as the OP's here.
(And to those who want to downvote this because "not an answer" : it is MORE of an answer because it shows in intimate detail WHY you NEVER want to even start going down that alley.)

Design of queryable web based results

I'm trying to accomplish something like a facebook news feed wall, loading N number of results from the overall dataset, starting with the most recent, date descending. When you click “more”, it displays the next N underneath and so on until you finish the dataset.
I’m struggling to come up with the best design to accomplish this. Ive always been told that stateless web services are the only way to build a scalable enterprise application, which means that as I understand it, keeping the whole results object cached serverside on the first call to the page, and just taking N results from it with each subsequent web service call is a no no?
If that’s the case, then something like GetResults(int pageindex, int pagesize) would work.... and thats how I WAS going to do it but then I realised it would not work if someone added a new DB record in between calls. Eg you start with 23 wall feed items in the DB and want to display them 10 at a time.
First call, page 1, page size 10 will return results 14-23 (most recent first)
Someone then adds 2 new posts, so you have 25 now in the DB
Second call, page 2, page size 10 will return results 6-15, two of which were already returned in the first call.
So this offsetting approach doesn’t work because you can’t guarantee the underlying dataset will remain the same between calls.
Im confused, how do I accomplish this?
Edit: Sorry a little more info. To avoid the problem of huge data table lookups, I had considered the option of pre-populating a "transient" table with the last few days data for that user when you first load the screen, then just reading the results a page at a time from that transient table to make it faster reading, with a slightly slower load time. Then when you exhaust that data, you bring in the next period (say 2 weeks) into the transient table and continue reading.
The difficulty is that users will "Post" items which then automatically will be picked up by users who match their search criteria. Eg if your criteria state you want to meet people between 25 and 32 and within 50 miles of you, then when you load up your news feed, you want it to show posts from all users who match your criteria. Kindof like a dynamic friends list.
How I was going to achieve this was at time of login, a stored proc would run which would populate a transient table in the DB by selecting all users and filtering down based on age and location criteria which I have in static lookup tables (postcode distances etc), then it will save the list of Users who match your criteria to this transient table for use whenever you then need to filter posts or search users. If you update your preferences, it will also recalculate this but only when you update prefs or re-login. So any new users signing up won't appear until you next login, which is fine I think.
Then when it comes time to display your news feed, all it does is retrieves this list of User Ids from the DB who match your criteria, then brings back all NewsFeedPosts which were posted by those users. Hey presto, dynamic news feed!
But obviously this is a subset of the entire NewsFeedPost table which is generated on the fly, so it doesn't make sense to recalculate this every time a user clicks "more", so this was how I was thinking about implementing it.
Tables - NewsFeedCurrent, NewsFeedRecent, NewsFeedArchive
New posts are created in the current table. Every night a batch job runs that moves all data from current that is 2 days old, to the recent table, and any data in the recent table that is a week old to the archive table.
The thinking being that 90% of the time, the user will only be interested in the last 2 days of data. So keep table small for access time. Another 9% of the time the user may want the last weeks data. So keep that separate in a secondary table. Then only 1% of the time the user wants data more than a week old so keep that in a larger, slow archive table that will be slower, but gives you performance boost by keeping current and recent tables small.
So when you first hit the news feed page, what it was going to do is take the pre-generated user list for your account and pull out all NewsFeedCurrent items and put them in a transient table, say TempNewsFeed under your user ID. You can then work with this resultset just by pulling back everything for your user id, no filtering required for items you arent interested in as they are pre-filtered. this will add a second or so to the page load but will improve response time when fetching results. Then when that data is exhausted, it will then - again using the list of users matching your criteria - pull out all relevant data from the Recent table, adding it to the TempNewsFeed table, allowing you to continue fetching data up to a week old. When thats exhausted, it will finally go to the archive table and using the user id list, pull out all data matching this and put in the temp table, allowing you to continue navigating the remaining data. This will give a fairly significant delay as it populates the archive data but if you are going back a week, then you will have to accept 5-10 seconds wait while it populates the data and says "loading data...". Once it has though, navigating historical data will be just as quick as recent data as it will all be in the transient table.
If you refresh the screen or go back onto it from another screen, it clears out the transient table and starts again from the Current table data.
Hope my answer makes sense, makes the right assumptions ...
I would divide the news feed into two sections. The first is for incoming news - which would be powered with AJAX calls. It is constantly saying "What is new?" The second section is for older news, where the user can lazily load more news by scrolling down.
Newest News Items
The important point is to make note of the maximum news feed id on your page. Let's imagine that is 10000. When the user loaded the page, news feed id 10000 was the latest news item.
When the new section is updated with AJAX, we simply ask, "What is newer than id 10000?" and we load those items onto the page. After we load them, we also increment the id on the page. For example, if we start with id 10000 and we load five new news items, the new id would be 10005. The next call would ask, "What is newer than 10005?"
Older News Items
The older section would keep track of the oldest news item on the page. Let's imagine they scroll back for a weeks worth of news. The minimum news item id would be 9000. When they want to scroll back further, we simply ask, "What is older than 9000?"
The idea then is to maintain on the page the maximum news item id and the minimum news item id and then keep loading from that reference point.

Maker-Checker functionality for asp.net

I'm creating a maker-checker functionality where, maker creates a record and it is reviewed by the checker. The record creation will not happen until the checker approves it. If the checker rejects it then it should be rolled back.
The idea which i know is create a temporary table of records which will hold the records to be created until the checker approves it. But this method will have 2X number of tables to be created to cover all functionalities.
What are the best practices to achieve this?
Is it something which can be done using Windows Work Flow.? (WWF)
Just add a few more columns to your db.
Status : Current status of record ( Waiting for approval, Approved,
Declined . etc)
Maker : Username or id
Checker : Username or id
Checker Approval/Rejection Time
Alternatively if you have lots of tables like this needs to maker/checker workflow you can add another table and reference all other record to this table.
Windows workflow foundation also could work for you but i persnoally find it difficult to use
If you want revisions for the recored you also need more columns. Such as Revision Number and IsLastRevision.
I dont know what you are using for accessing db and modifiying records. If you are using OR/M you might override Update and do revisions on all saves . For Example
void Update(Entity e )
{
Entity n = new Entity();
// Create a copy of e ( With AutoMapper for example or manually )
e.Current = true;
e.RevisionNumber += 1;
Update(e);
Insert(n);
}
In this case you will have two options:
Create two identical tables and use one table for approved data and one for requested data.
OR
You can create two rows for a user with TypeID(requested/approved). in this case user will create a request with typeID = requested when approver approved that request you simply override current approved record with new one otherwise simply mark requested row with rejected status.

How to save a list of recent text entries in isolated storage.?

In my app I have a textbox named "msgBox" and a button named "sendBtn".
When the user taps the Button, the text typed in the msgBox is sent to a server.
I want to save and display the last 15-20 sent items.
How can I do that..??
Please help.
If you want to display the most recent items, you could include the current date with the submission of the form. Then, when accessing the server, sort the items by their date, and only display the first 15-20. This method would be simpler than creating another table dedicated to recent entries. Also, browsing through archives by date would be much easier as the date would be tagged to the entries.
As a mySQL statement (being the server language I know the most), inserting a message would be the following (where [message] is the sanitized MsgBox value):
INSERT INTO `messages` (`msg`,`date`) VALUES ('[message]',NOW());
Retrieval would look like so:
SELECT `msg` FROM `messages` ORDER BY `date` DESC LIMIT 15;
This method would be simpler than creating another table dedicated to recent entries. Also, browsing through archives by date would be much easier as the date would be tagged to the entries.
Hope this helps!

Categories

Resources