Can we start?

Apr 10, 2008 at 10:36 PM
I am ready to begin.

I would like to work on the implemetation of models so as soon as we have a DB schema and a general model interface I would love to start coding

Untill then I can do anyhting else needed.
Coordinator
Apr 11, 2008 at 1:12 AM
Edited Apr 11, 2008 at 3:37 AM
Yea I say we get started before we all start to loose interest.. Clive, you appear to be the most seasoned in DB Schema designs, want to kick us off with a discussion on what you think would be best? Or just whip up a schema :)
Apr 11, 2008 at 4:52 AM

ChanceUSC wrote:
Clive, you appear to be the most seasoned in DB Schema designs, want to kick us off with a discussion on what you think would be best? Or just whip up a schema :)

Can we agree on a bullet-list of fields required? Plus a good name for it - at the moment all I can think of is Basic.
Also can we agree an outline solution framework for version 0.1 from the mvcms.makelog, mvcms.utility, utility.nunit, mvcms.data and mvcms.data.nunit .... mvcms.filter, mvcms.filter.nunit? Once this is done, we can start to fill code in.
I also suggest $/0.1/mvcms.data and not $/mvcms.data. That way we can go from 0.1 to 0.2 and in doing so rename and prune as required before the first check-in of 0.2. This means we do need to get the names absolutely right first time.
Apr 11, 2008 at 5:00 AM
I am very much into using error/diagnostic logging via custom event log. Since my common data routines can control this from a config file, it can be turned on or off as required. Hence for development, commercial use and any other case where you have local administrator access. There is code posted at http://forums.asp.net/p/1207886/2255745.aspx#2255745
Apr 11, 2008 at 5:25 AM
Here is a quick bullet list columns for the Basic table plus some others

Id - Identity integer primary key
ApprovePersonId - Integer FK to Person who approved publication - default null
CreatePersonId - Integer FK to Id of Person who created record - default 1
UpdatePersonId - Integer FK to Id of Person who last updated record - default 1
Content - NVARCHAR(MAX) Non-null
Header - NVARCHAR(100) Non-null
LogAdd - DATETIME non-null default getutcdate() - datetime in UTC record was added
LogCount - Integer non-null default 0 - Incremented by 1 for every update
LogUpdate - Datetime record was last updated

The BasicEdit table would be:
Id - Identity integer primary key
CreatePersonId - Integer FK to Id of Person who created record - default 1
EditNote - NVARCHAR(MAX) Non-null
LogAdd - DATETIME non-null default getutcdate() - datetime in UTC record was added

The Person table would be
Id - Identity integer primary key
CreatePersonId - Integer FK to Id of Person who created record - default 1
UpdatePersonId - Integer FK to Id of Person who last updated record - default 1
Email - NVARCHAR(128)
IsAdmin - Boolean default 0 - 1=Can approve for release
LogAdd - DATETIME non-null default getutcdate() - datetime in UTC record was added
LogCount - Integer non-null default 0 - Incremented by 1 for every update
LogUpdate - Datetime record was last updated
Name - NVARCHAR(100) non-null name of user
NTDomain - NVARCHAR(128) non-null default ''
NTUser - NVARCHAR(128) non-null default ''
UserName - Nvarchar(50) non-null default ''
UserPassword - NVARCHAR(100) non-null default ''


Apr 11, 2008 at 6:02 AM
Now why three tables when we need to keep it simple!

1) The Person table will have a dummy record in it with default of id=1. The UI should have a session variable set at a fixed 1 for version 0.1.
2) The BasicLog will be used to log edit notes, approval ect. - the stored procedures and data layer will take care of it. The Basic.Insert and Basic.Edit will have an additional EditNote field which can just be left blank.
3) NVARCHAR whilst less efficient than VARCHAR does allow any character set to be used.
4) For any update the UI/BL will need to keep the Id and LogCount of the record - if both match the update goes ahead and the record will updated including incrementing LogCount.
5) The User record will need to be refined but it allows use both in Intranet or Extranet or without any authentication. I have assumed that ASPNETDB will not be used - this does mean in a later version we will need to roll our own logon pages. We will need to discuss User record requirement separately.
6) I have assumed that times will be stored in UTC not local time. It will therefore be the UI/BLL responsibility to adjust for the time zone of the user. Perhaps MVCMS will provide a function to take datetime, timezone and return a local datetime.
7) There is the tricky question of approval mechanism - for 0.1 the BLL can just pass in 1 for the approval
id and the post will appear on the approved list so that a public user can see it.
8) **** This is the wrong thread, but like the source code licence, we should have a model posting policy or at least a firm requirement on the installer of MVCMS to have such a policy **** Perhaps the posting policy on this site or the ASP.NET forum would suffice. *** The UI designers should have the display of this on the wish list for 0.2
9) Basic.Header will describe the content and will appear on lists of content
10) Basic.Content is the content to display
11) I have not included images as I want to keep 0.1 simple!
Coordinator
Apr 11, 2008 at 6:10 AM
Edited Apr 11, 2008 at 6:37 AM

TATWORTH wrote:
Here is a quick bullet list columns for the Basic table plus some others

Id - Identity integer primary key
ApprovePersonId - Integer FK to Person who approved publication - default null
CreatePersonId - Integer FK to Id of Person who created record - default 1
UpdatePersonId - Integer FK to Id of Person who last updated record - default 1
Content - NVARCHAR(MAX) Non-null
Header - NVARCHAR(100) Non-null
LogAdd - DATETIME non-null default getutcdate() - datetime in UTC record was added
LogCount - Integer non-null default 0 - Incremented by 1 for every update
LogUpdate - Datetime record was last updated



The BasicEdit table would be:
Id - Identity integer primary key
CreatePersonId - Integer FK to Id of Person who created record - default 1
EditNote - NVARCHAR(MAX) Non-null
LogAdd - DATETIME non-null default getutcdate() - datetime in UTC record was added

The Person table would be
Id - Identity integer primary key
CreatePersonId - Integer FK to Id of Person who created record - default 1
UpdatePersonId - Integer FK to Id of Person who last updated record - default 1
Email - NVARCHAR(128)
IsAdmin - Boolean default 0 - 1=Can approve for release
LogAdd - DATETIME non-null default getutcdate() - datetime in UTC record was added
LogCount - Integer non-null default 0 - Incremented by 1 for every update
LogUpdate - Datetime record was last updated
Name - NVARCHAR(100) non-null name of user
NTDomain - NVARCHAR(128) non-null default ''
NTUser - NVARCHAR(128) non-null default ''
UserName - Nvarchar(50) non-null default ''
UserPassword - NVARCHAR(100) non-null default ''


I really like your approach to users, but heres my 2 cents:

Id - Identity uniqueidentifier primary key <-- better suited for multiple sites running under 1 database
ApprovePersonId - Integer FK to Person who approved publication - default null
CreatePersonId - Integer FK to Id of Person who created record - default 1
UpdatePersonId - Integer FK to Id of Person who last updated record - default 1
Content - NVARCHAR(MAX) Non-null
LogAdd - DATETIME non-null default getutcdate() - datetime in UTC record was added
LogCount - Integer non-null default 0 - Incremented by 1 for every update
LogUpdate - Datetime record was last updated

Path - NVARCHAR(25) <-- not sure if you guys will like this approach but I used it on a recent MVC based CMS.
Title - NVARCHAR(25)
Keywords - UniqueIdentifier NVARCHAR(100) (or FK Keywords Table )
Parent - UniqueIdentifier FK to Page (Nullable)




Header <--changed this in an edit (needs a better name..)
-------------------------------------
Id - UniqueIdentifier Primary Key
Page - UID FK to Page.ID
File - UID FK to HeaderFiles



HeaderFiles
---------------------
Id - UniqueIdentifier Primary Key
Name - NVARCHAR(10) Non-null
FileName - NVARCHAR(20) Non-null
Content - NVARCHAR(MAX) Non-null
FileType - int non-null (1 = JS / 2 = CSS... )
ApprovePersonId - Integer FK to Person who approved publication - default null
CreatePersonId - Integer FK to Id of Person who created record - default 1
UpdatePersonId - Integer FK to Id of Person who last updated record - default 1
LogAdd - DATETIME non-null default getutcdate() - datetime in UTC record was added
LogCount - Integer non-null default 0 - Incremented by 1 for every update
LogUpdate - Datetime record was last updated
Apr 11, 2008 at 6:12 AM
There is also the issues of parameter tables. It is best to have a few configuration items in the web.config - these are:

1) Connection string (however I would prefer to put this in a separate config file that just the Data layer has access to)
2) force HTTPS - redirects to HTTPS any HTTP request.
3) AuthenticateBy 0=Nothing, 1=NT, 2=User name/password

All the rest of the content and parameters would be stored in the database, including the content posting text I referred to earlier. The database would provide Param.GetString(Id), Param.GetInt(id) where the Ids would be enumerations defined in the data layer.

Well there are my thoughts for today - Shalom to our member in Israel and I will pick up your responses in about 12 hous time.
Coordinator
Apr 11, 2008 at 6:21 AM
Edited Apr 11, 2008 at 6:30 AM
Clive, I edited what I posted (I violated 3rd norm form.. kinda tired over here) after you responded - sorry!

Thanks for the initial schema, goodnight and shalom.
Apr 11, 2008 at 7:37 AM
>Id - Identity uniqueidentifier primary key <-- better suited for multiple sites running under 1 database

All that is necessary to have multiple sites on one database is to have a site table and hold the Id in the config file. I know ASPNETDB uses them, however the only advantage is their unpredictability.

Regarding the header, css and javascript tables, I can add them, Path will have to be longer than 25 unless it is a generated filename from an uploaded file. It should be a relative not absolute path, with the folder path stored in either the config file or as a parameter I had not considered the aspect of uplods. Do we want both at 0.1 ? We certainly can make provision for both.

There is a question about content; is it
A) Pure text no HTML allowed
B) Limited HTML e.g. <i>....</i> ect.
C) Free for all text, which means hyperlinks and all potential issues that raises.

While it is the BLL's job to call the function to filter the text and the data layer will just store and retrieve it, it should be considered. If our final result is to be product that a user can install, configure and use, then it would be irresponsible not to allow for a selectable restriction.

Some further thoughts while I was having breakfast:
1) All copyright headers enclosed in a region
2) All using in alphabetical sequence and enclosed in a region.
3) All constants, custom exceptions and enums for the whole application to be in MVCMS.Common (or Utility)
4) Odd point versions to be development. Even point versions to be a release version (which means possibly dropping/disabling features from the preceding point version, so that what is released is stable.
5) Next week I will write up a note on the System supplied exception to be used.
6) Except by special agreement no code to be checked in containing errors or fixable warnings.
7) If contributors have their own solution file, they must include all unit test projects up to their level, and those tests must be run successfully.
8) XML documentation to be on for all class projects and the documentation to be filled in for all release code.
9) Initial unit tests should follow the class they are testing so CommonDataTest tests CommonData - so if you are working on CommonData you check out CommonDataTest as well.
10) Certain large classes like CommonData will be physically separated files using the partial keyword with the unit tests similarly split. This will give a rich library which will simple to use, yet can be updated piece by piece rather than a whole.
11) Blocks of code not necessarily to the individual function (unless large) to be enclosed in regions so that those working with laptops can look at just the code they need.
12) Depending on the level, a convention needs to be established for what level of unit testing is necessary prior to a new function being checked in. Certainly for the common and data levels, testing will be extensive.
Apr 11, 2008 at 7:54 AM
Edited Apr 11, 2008 at 7:56 AM
For CommonDataTest it may be better to have CommonDataFixture (some OO guys/people in ivory towers like that) and it leaves the word Test free for other things so that can be a CommonTest namespace of functions to help testing with it own CommonTestFixture to test the test helper!

We also need to work out what does and does not need translating - all user -visible strings need translating. At 0.3 I will set up a bogus tranlation so that OK gets translated to _OK_ which soon finds out what is not covered by translatable strings and if there is room for translations!
Coordinator
Apr 11, 2008 at 11:27 AM
Man, you guys are great! I love how fast everyone's jumping in, and I have no comments / complaints about where you're going.

THe only comment I want to address is where Clive said that he would like to use the event log for logging. Can I recommend not doing that, so that we keep this solution usable on shared hosting sites?
Apr 11, 2008 at 2:02 PM


pvencill wrote:
THe only comment I want to address is where Clive said that he would like to use the event log for logging. Can I recommend not doing that, so that we keep this solution usable on shared hosting sites?


I agree. we should keep this shared hosting friendly
Coordinator
Apr 11, 2008 at 7:50 PM

TATWORTH wrote:
>Id - Identity uniqueidentifier primary key <-- better suited for multiple sites running under 1 database

All that is necessary to have multiple sites on one database is to have a site table and hold the Id in the config file. I know ASPNETDB uses them, however the only advantage is their unpredictability.

Regarding the header, css and javascript tables, I can add them, Path will have to be longer than 25 unless it is a generated filename from an uploaded file. It should be a relative not absolute path, with the folder path stored in either the config file or as a parameter I had not considered the aspect of uplods. Do we want both at 0.1 ? We certainly can make provision for both.

There is a question about content; is it
A) Pure text no HTML allowed
B) Limited HTML e.g. <i>....</i> ect.
C) Free for all text, which means hyperlinks and all potential issues that raises.

While it is the BLL's job to call the function to filter the text and the data layer will just store and retrieve it, it should be considered. If our final result is to be product that a user can install, configure and use, then it would be irresponsible not to allow for a selectable restriction.

Some further thoughts while I was having breakfast:
1) All copyright headers enclosed in a region
2) All using in alphabetical sequence and enclosed in a region.
3) All constants, custom exceptions and enums for the whole application to be in MVCMS.Common (or Utility)
4) Odd point versions to be development. Even point versions to be a release version (which means possibly dropping/disabling features from the preceding point version, so that what is released is stable.
5) Next week I will write up a note on the System supplied exception to be used.
6) Except by special agreement no code to be checked in containing errors or fixable warnings.
7) If contributors have their own solution file, they must include all unit test projects up to their level, and those tests must be run successfully.
8) XML documentation to be on for all class projects and the documentation to be filled in for all release code.
9) Initial unit tests should follow the class they are testing so CommonDataTest tests CommonData - so if you are working on CommonData you check out CommonDataTest as well.
10) Certain large classes like CommonData will be physically separated files using the partial keyword with the unit tests similarly split. This will give a rich library which will simple to use, yet can be updated piece by piece rather than a whole.
11) Blocks of code not necessarily to the individual function (unless large) to be enclosed in regions so that those working with laptops can look at just the code they need.
12) Depending on the level, a convention needs to be established for what level of unit testing is necessary prior to a new function being checked in. Certainly for the common and data levels, testing will be extensive.


The way I used path in my last MVC was relative, when someone added a page, the path was generated by crawling up the tree and generating the string. For instance, say someone added a page under Personal-Information title email. The path would be "Personal-Information/Email" <-- thats a bad example but it is the most generic I could come up with atm. The way I handled routes was, I had predefined routes in place (manage for the CMS, blog for blog content, ect) and then a catchall so if someone visits "www.thesite.com/Personal-Information/Email/" the catchall route is triggered and "Personal-Information/E-mail/" is passed to the controller. The controller then simply has a hash (custom dictionary) with keys defined by the path.
Apr 11, 2008 at 8:37 PM

The only comment I want to address is where Clive said that he would like to use the event log for logging. Can I recommend not doing that, so that we keep this solution usable on shared hosting sites?


That is not quite the problem you might imagine, there are two alternatives, either the log is redirected to a log table or simply turned off in the configuration file. Having worked with a variety of applications, adequate error logging is essential.
Apr 12, 2008 at 2:33 PM
there has got to be a better way to coordinate. how about checking in the documentation in the source control?
Coordinator
Apr 13, 2008 at 1:41 AM
Clive - did you happen to get that schema done by any chance?
Apr 15, 2008 at 5:06 PM
anyone come up with a schema yet?
Coordinator
Apr 15, 2008 at 7:08 PM
Edited Apr 16, 2008 at 1:24 AM
Clive (TATWORTH) was going to make it for us but he hasn't been around in a few days. I'll give him a few more days and if he doesn't come back I'll come up with them. I'd rather he do it though because he's a better DBA than I am, plus he has tools to generate SP / wrapper classes (wish I had those..).
Coordinator
Apr 17, 2008 at 1:13 AM
Edited Apr 17, 2008 at 7:21 PM
Does anyone know if Clive plans to return to the project? He said his availability was Sunday - Thursday but his last post was almost a week ago. Are there any other DBAs out there that want to take a swing at this or should I make plans to do it this weekend? Unfortunately it has been a crazy week for me so I won't be able to touch it until then. If Clive (TATWORTH) doesn't return and no one else wants to do it, I'll get it hammered out by Monday.
Apr 22, 2008 at 9:09 PM
Chance, Clive, did someone get a schema put together?
Coordinator
Apr 23, 2008 at 5:55 PM
No I worked through the weekend, I'll have it done tonight.. sorry about the delay

(delivering to a client on the week of final projects for college = fun time)
Coordinator
Apr 25, 2008 at 2:23 AM
I have the db schema done (well somewhat.. the stored procs arent done) but I havent had a chance to figure out how to use TortoiseMerge or one of these other goofy source control apps.. wish i could just use SVN..
Apr 25, 2008 at 11:35 AM
Great! As soon as you get it up we can start to get some work done.

Thanks :)