איך בונים פורום?

‏ • 13 באפריל, 2002

העיקרון בפורום הוא שיש הודעת אב ולה יש הודעות ילדים. הודעות האב מסודרות בסדר כרונולוגי הפוך והודעות הילדים מסודרות ביניהן לפי סדר יורד. אבל בואו נתחיל מהתחלה.
בד"כ אני נוהג לצייר לי סכמה של התהליך ושל הטפסים על מנת שיהיה לי יותר קל אח"כ להבין מה עשיתי.

בניית בסיס הנתונים

קודם כל אני נבנה את טבלת המשתמשיםץ הדברים החשובים ביותר הם:

שם משתמש [כינוי], סיסמא , אמייל , ורצוי גם תאריך. אני הוספתי עוד כמה שדות לשימושי האישי. לטבלה נקרא לה members.


שם שדה סוג DATATYPE תפקיד ערך ראשוני
Id מספור אוטומטי מפתח ראשי 
UserID מספר המספר של המשתמש 
Nick מחרוזת הכינוי 
Pass מחרוזת הסיסמא  
Email מחרוזת אימייל 
DateAdd Date תאריך הוספה Date()
Fname מחרוזת שם פרטי 
Lname מחרוזת שם משפחה 
Address מחרוזת כתובת 
Sex כן/לא זכר/נקבה 
Qut מחרוזת ציטוט 
WordDes תזכיר תיאור עצמי 
Homepage מחרוזת הטקסט שיופיע כדף בית 
Link מחרוזת הקישור לדף הבית 
Age מספר הגיל 




השלב הבא הוא לבנות את הטבלה של ההודעות. אצלי היא בפורמט הבא:

שם שדה סוג DATATYPE תפקיד ערך ראשוני
MessageID מספור אוטומטי מפתח ראשי  /td>
ForumID מספר מספר הפורום  
Parented מספר המספר של הודעת האב  
levelID מספר מה הסדר של ההודעות  
MsgSubject מחרוזת הנושא  
MessageBody מחרוזת גוף ההודעה  
Uname מחרוזת הכינוי  
Uid מספר המספר של המשתמש  
link1 מחרוזת קישורים  
Link1des מחרוזת הטקסט שיוציע  
IsFile כן/לא האם יש קבצים מצורפים  
Filename מחרוזת    
fileDES מחרוזת    
DateAdd תאריך תאריך הוספה Date()



ניתן כמובן להוסיף עוד קישורים ותאורי קישורים [ורצוי גם לחלק את הטבלה לשתי טבלאות של קבצים ושאר הודעות ולחבר בעזרת ה-MessageID] אבל בינתיים זה מספיק. נקרא לטבלה Messages.

איך יודעים מהי הודעת האב ?

מכיון שלכל הודעה חדשה אנו צריכים מספור כלשהו, עומדות לפנינו כמה אפשרויות:

האפשרות הראשונה היא להכניס איזה שהוא מספור שאנחנו יוצרים לתוך ה parentID. החיסרון בשיטה הזו היא שאם יש לנו כמה משתמשים בו זמנית אנו עלולים להרוס את הסדר.

הפתרון הפשוט ביותר הוא להשתמש במשתנה Session.SessionID ולהכניס אותו לתוך הודעת האב. לכל הבנים שיבואו מתחתיו אנו ניתן כבר את ה parentID הקיים, וניתן levelID שגדל באחד כל פעם. [רצוי להתחיל ב-1 ולא ב-0].

לאחר שנוסיף את ההודעה נסגור את ה Session ונחליף אותה בחדשה בעזרת Session.Abandon().
ככה אנו פותרים שתי בעיות – בעיית מספור ההודעות, ובעיית הכנסה. כי הרי לכל משתמש יש מספר מזהה משלו, ואין שום סיכוי שבעולם ששני אנשים שונים יכניסו שתי הודעות עם אותו parentID . אם היינו ממספרים את ההודעות בזמן ההכנסה היה סיכוי גדול יותר שתקלה כזו תתרחש‎.


אם ישנן שתי הודעות בן לאותו אב – מי תבוא קודם?


זאת שנכתבה קודם כמובן ואת זה נדע לפי השדה של התאריך.

איך עושים את ההזחה של ההודעות?


בעזרת הlevelID. כל הודעה תהיה טבלה בפני עצמה שהרוחב שלה הוא 100% מינוס ה-levelID. כל זה יהיה באחוזים ומיושר לשמאל ככה שתהיה לנו הזחה לכל הודעה.


טוב, אז איך עושים את זה?

ישנן כל מני דרכים לשלוף את הנתונים מתוך הDB. מכיוון שזהו בעצם עץ, ניתן לשלוף את הנתונים בכמה דרכים:

  • בעזרת DataShape
  • בעזרת שני RecordSet
  • בעזרת עמודת מונה שתסדר לנו את ההודעות.

הקוד הבא מדגים את הצגת הפורום באמצעות recordSet כפול:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20  

<%
DSN="Provider=Microsoft.Jet.OLEDB.4.0;
    Data Source="
+Server.MapPath ("theBD.mdb") +";
    User Id=admin; Password="

SQL1="select parentID from Messages where levelID=1 order by dateAdd DESC"
SQL2="select * from Messages where parentID="&
    oRss(0).value & "order by levelID;"

Set oConnection=Server.CreateObject("ADODB.connection")
OConnection.open (DSb)
Set oRecordset==Server.CreateObject("ADODB. Recordset")
ORecordset.open (SQL1, oConnection,3,1)

While not oRecordset.eof
    ORecordsetMasege=oConection.execute (SQL2)
    While not OrecordsetMasege.eof
    'כאן תיכנס הטבלה של כל הודעה והודעה
    OrecordsetMasege.movenext()
Wend
%>


איך זה עובד?

בהתחלה אנו שולפים את כל הרשומות שה-parentID שלהם הוא 1 , כלומר הן הודעות אב. אח"כ בלולאה השנייה אנו שולפים לכל הודעת אב את הבנים שלה, מסודרים לפי ה-levelID.

אבל השיטה הזאת לא יעילה וממש לא נוחה. אם היינו יכולים להכניס איזה ממספר שהיה עוזר לי למיין את כולם מצבנו היה יותר טוב. השיטה הטובה ביותר לממספר שחשבתי עליה היא מן מחרוזת שהחלק השמאלי שלה מורכב מה-ParentID ,והחלק הימני ה-levelID.

אבל למה לעבוד קשה? למה אנחנו צריכים להתאמץ לסדר את ההודעות כאשר אנו יכולים להשתמש ב-DB למיון וסידור ההודעות?

לא רק זה, אפילו יש לנו Wizard שעושה את כל העבודה השחורה. אם נסתכל על הטבלה שלנו [וגם כל הקוד שרשמנו מקודם ] נוכל לראות שבעצם יש לנו המון כפילויות בעמודה של ה-parentID. ופה קבור הכלב!

נפתח את האקסס [או כל DB אחר אבל זה יהיה בלי ה-Wizard …] נלך לשאילתות ונבחר את השאילתא הבאה – שאילתת חיפוש כפילויות.





נלחץ על אישור ובחלון הבא נבחר את הטבלה שלנו Messages .






לחיצה על הבא כמובן תוביל אותנו לשאלה – איזה עמודה אנו רוצים לסנן?

parentID , כמובן, תהיה התשובה. לא לשכוח ללחוץ "הבא" אחר כך.






עכשיו בא הקטע המגניב – איזה עוד שדות אנו רוצים בשאילתה? את כל השאר.






ניתן שם לשאילתה, ונלחץ על "סיום".





עכשו כשנפתח את הטבלה/שאילתה חדשה, נקבל טובלה ממש דומה ל-MessageS אולם זה עדיין לא הסוף. אנו עדיין צריכים למיין את הכל. תצוגת העיצוב תיתן לנו את התמונה הבאה. השתמשו בגרירות השונות על מנת להביא את הטבלה למצב הקיים ושנו את הסדר לפי התמונה.






כאשר נפעיל את השאילתה נקבל את הטבלה ממויינת. כל מה שאנחנו צריכים לעשות עכשיו הוא לשלוף את הנתונים. היתרון בשיטה זו היא שאנו שולפים את הנתונים מתוך שאילתה אך מכניסים אותה לתוך הטבלה. הנתונים תמיד יהיו ממוינים, ללא צורך באיז שהיא טרנספורמציה על העמודה המסדרת [שבעצם לא קיימת]. למעשה אם היינו צריכים ליצור את השאילת הזו ביד זה היה נראה בערך כך:


1
2
3
4
5
6
7
8
9
10
11  

SELECT Message.parentID, Message.dateAdd,
   Message.levelID, Message.messageID,
   Message.forumID, Message.Uname, Message.Uid,
   Message.msgSubject, Message.link1, Message.Link1des,
   Message.link2, Message.Link2des, Message.link3,
   Message.Link3des, Message.isFile, Message.IP,
   Message.fileName, Message.fileDES
FROM Message
WHERE (((Message.parentID) In (SELECT [parentID] FROM [Message] As Tmp
GROUP BY [parentID] HAVING Count(*)>1 )))
ORDER BY Message.parentID DESC , Message.dateAdd, Message.levelID;

לא סימפטי אה? בדיוק בשביל זה יש לנו את ה- Query Analyser. עכשו הכל כבר מסודר וכל מה שנשאר זה לשלוף את הכל בעזרת:

Select * from ForumMSG

ואם ישנם כמה פורומים, פשוט לשים WHERE… איפה שצריך.
עכשו ה-ASP שלנו ניראה כך:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15  

<%DSN="Provider=Microsoft.Jet.OLEDB.4.0;
    Data Source="
+Server.MapPath ("theBD.mdb") +";
    User Id=admin; Password="

SQL1=" Select * from ForumMSG"

Set oConnection=Server.CreateObject("ADODB.connection")
OConnection.open (DSN)
Set oRecordset==Server.CreateObject("ADODB. Recordset")
ORecordset.open (SQL1, oConnection,3,1)

While not oRecordset.eof
       ' כאן תיכנס הטבלה של כל הודעה והודעה
         oRecordset.movenext()
Wend
%>


ופה בעצם אנו מקבלים את כל הפורום מסודר ומאורגן. על זה כמובן אפשר לעשות חלוקה לדפים, וכמובן לעשות את החלקים שמראים ומסתירים את ההודעה.


תכנות נעים ובהצלחה!

תגיות: ,

תגובות בפייסבוק