אינדקס ישויות עבור כל המודולים
להחזיק בזיכרון (RAM) פעם אחת, עותק אחד, של כל הישויות במערכת ואז לאפשר לכל מודול לחפש (מהר) לפי מספר טלפון / כתובת דוא"ל / מספר זהות / שם.המנוע הוא א-סינכרוני ! יישום הלקוח שולח בקשת חיפוש כהודעה (ערוץ 12) וממתין לתשובה שבד"כ מגיעה תוך 0.1 שניות כולל זמני התקשורת.
להלן דוגמאות בולטות לשימוש במודול הזה: חיפוש מהיר בהייפר, תיוק דוא"ל, תיוק מסרון (SMS), ממשק whatsapp, זיהוי שיחת טלפון ובדיקת כפילויות בקליטת לידים.
העמוד הזה הוא טכני ומיועד עבור מנהלי המערכת, נפרט כאן את מבני הנתונים של המודול ואת דרך פענוח התשובות.
להזכירך, בממשק ה webAPI של הייפר קיימת הפונקציה Does_Entity_Exist_json אשר מבצעת את הבדיקה הזאת בממשק http / json, עבור מערכות חיצוניות להייפר (אבל לא מכילה את כל המידע שכאן).
התיעוד כאן משרת בעיקר כתיבת תסריטים או פיתוח בעזרת הסיפרייה (components) של הייפר (ראו קטע קוד בסוף).
עדכון ישות בזמן ריצה
כאשר מודול כלשהו מעדכן שדה הקשור באינדקס (למשל טלפון, רשימת שדות בהמשך), עליו לשלוח הודעת עדכון ברשת - לאחר העדכון עצמו.הממשק א-סינכרוני, כל בקשה נכנסת לתור ומבוצעת מהר. האינדקס ממשיך להיות זמין לחיפושים גם בזמן העדכון.
// MsgType = 13; async into "Update_Queue"
TYPE
Thyper_ServerApp_Refresh_Index_Request = PACKED RECORD
Reload_Entity_Number: Integer; // for example 500123 for client; 10123 for supplier;
Contacts_Table: Boolean; // simple flag to reload all contacts of that entity
From_Storage: Char; // must be filled (N/A/D)
Moved_To_Storage: Char; // (#0/N/A/D/T) only when moving to a different storage
End;
Procedure Update_Index(CONST Req: Thyper_ServerApp_Refresh_Index_Request); // use inside 'server side app'; THREAD SAFE
// this is how to send the message; use record helper to clear etc
Server.SendMessage(Server_Side_Username, 13, RecVar, sizeof(Thyper_ServerApp_Refresh_Index_Request));
-
עדכון אינדקס מלא (כל הטבלאות מחדש) רץ בכל 6 שעות מאז ההצלחה האחרונה. במקרה של כישלון, מנסה שוב לאחר 2 דקות.
בתחילת תהליך העדכון, תור הבקשות מבוטל לכן במקרה שבו התהליך נכשל אז כל העדכונים נתקעים. - במקרה של עדכון/הוספה אז השדה From_Storage מציין את מקום האחסון של הרשומה המעודכנת.
- רק במקרה של מחיקה / העברה מארכיון להווה (או להיפך) יש למלא גם את הפרמטר Moved_To_Storage. אחרת יש להעביר אותו ריק.
- כרגע הקוד של מוצר המדף לוכד את העדכונים הנ"ל ושולח בעצמו את הבקשות לעדכון. עליך להתערב רק אם ראית שתסריט שהרצת אינו מעדכן את האינדקס.
בקשת חיפוש מהאינדקס
כאשר מודול כלשהו רוצה לחפש ישות, עליו לשלוח בקשה ולהמתין לתשובה. הממשק א-סינכרוני, לכל בקשה יש unique ID והלקוח המאזין צריך לנתב את התשובה (עם אותו ID) למודול הקורא.השאילתה על ישויות שיש להן טלפון או דוא"ל או מספר מזהה מטעם הרשויות
TYPE
Thyper_ServerApp_Index_Request = PACKED RECORD // MsgType = 12
Req_Unique_ID: Double; // UTC
Random_ID: Word; // help to indentify in case of multiple requests in the same time
Reply_To_Username: String[50]; // this field will be removed soon
//===//
ID_Number: Array [0..1] OF String[20]; // same value, maybe without zeros in prefix
ID_Number_Type: Array [0..1] OF Byte; // value > 0 will activate the filter
Phone: Array [0..2] OF String[20];
Email: String[150]; // ansi string length = store UTF8 inside it !
Deleted_Storage, Archive_Storage: Boolean; // Do you want to search in this storages ?
End;
Thyper_ServerApp_Index_Response = PACKED RECORD // MsgType = 12
Req_Unique_ID: Double; // values copied from request
Random_ID: Word; // help to indentify in case of multiple requests in the same time
Result_Rowcount: Word; // MAX 100 (best) results
End;
Function Search_Index(Req: Thyper_ServerApp_Index_Request): ThPrvTable; // use inside 'server side app'; THREAD SAFE
// this is how to send the message; use record helper to clear etc
Server.SendMessage(Server_Side_Username, 12, RecVar, sizeof(Thyper_ServerApp_Index_Request));
מבנה טבלת התשובות
Field Name | Data Type | Description | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Entity Number | Integer | מספר ישות. בהייפר אין הקבלה בין הטווחים של המספרים. כל ישות נחשבת לחשבון במודול הכספים. | ||||||||||||||||||||||||
Match by | Integer |
|
||||||||||||||||||||||||
Storage | String [1] |
|
||||||||||||||||||||||||
Contact | Bool | האם מדובר באיש קשר ? | ||||||||||||||||||||||||
Full Name | String [200] | שדה שם מלא בשפה המקומית. במקרה של איש קשר אז מוסיף תגית BR ואחריה את השם המלא של הישות המכילה (דוגמאות: שם חברה מסחרית, שם פרויקט). | ||||||||||||||||||||||||
String [100] | כתובת דוא"ל מתוך הרשומה של הישות (לקוח/ספק/עובד) או מהרשומה של איש הקשר. | |||||||||||||||||||||||||
1st Phone 2nd Phone 3rd Phone |
String [20] | טלפונים מתוך הרשומה של הישות (לקוח/ספק/עובד) או מהרשומה של איש הקשר. | ||||||||||||||||||||||||
Gender | Integer |
|
||||||||||||||||||||||||
Agency | Integer | קיים רק ברשומה של הישות, לכן במקרה של איש קשר - השדה מועתק מהישות המכילה | ||||||||||||||||||||||||
Country | String [40] | שדה ארץ מתוך הרשומה של הישות (לקוח/ספק/עובד) או מהרשומה של איש הקשר. | ||||||||||||||||||||||||
Handling Status | Integer |
השדה קיים רק ברשומה של לקוח או ספק. במקרה של איש קשר - השדה מועתק מהישות המכילה. עבור פרויקט או עובד/משתמש ישלח ערך אפס.
|
||||||||||||||||||||||||
Role | Integer |
|
||||||||||||||||||||||||
Business | Integer |
|
||||||||||||||||||||||||
Legal Status | String list [200] | שדה מסוג רשימת ערכים, מאוחסן כטקסט בשפה שבה מילאו את הרשומה (יתכנו שפות שונות באותו מסד נתונים). |
לאחר בניית רשימת תוצאות, המודול מבצע את המיון הבא ואז מקצץ את הרשימה (אם היו מעל 100 תוצאות).
Result.Sort(['Storage','Match By','Contact','Full Name','Entity Number']);
הקוד לקליטת התשובה
עבור מערכת התסריטים בהייפר תהיה פונקציה בדיוק כמו Search_Index לעיל, היא תעשה block לקוד עד לקבלת התשובה. הפונקציה תפורסם בקרוב.להלן הקוד עבור פיתוח ב- RAD Studio:
בהודעה נכנסת בערוץ 12, הטבלה מוחזרת ב stream מיד אחרי הרשומה Thyper_ServerApp_Index_Response כך שאם רשום לך בשדה שיש תוצאות, עליך להריץ את הקוד הבא:
IF Index_Response.Result_Rowcount = 0 Then EXIT;
Temp_MS:= ThMemoryStream.Create;
Temp_MS.CopyFrom_MS(Source, Source.Size); // stream from last position after "Thyper_ServerApp_Index_Response"
Temp_MS.DeCompress;
TempTable:= Build_Hyper_ServerApp_Index_Response_Table;
TempTable.LoadFromMemoryStream(Temp_MS);
Free_And_NIL(Temp_MS);
IF NOT TempTable.Empty(0) Then
RUN_YOUR_CODE_HERE(TempTable);
Free_And_NIL(TempTable);