ארכיון חודשי: נובמבר 2014

Firebird 3.0

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

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

לFirebird יש מספר תחבירי SQL, וחשוב להבין אותם לפני הבנה של התכונות החדשות. סוג התחבירים הם:

  • DSQL
  • ESQL
  • PSQL

DSQL – הם בעצם השאילתות שכותבים ומריצים בצורה דינאמית באמצעות API. המקדם D מייצג את המילה Dynamic.
ESQL – הם בעצם שאילתות עם preprocessor, כאלו שכותבים למשל דרך תוכנה שלנו. ההבדל בינה לבין DSQL היא שבשפה זו משתמשים בפקודה EXEC. הפירוש של המקדם E מייצג את המילה Embedded.
PSQL – השפה שבה כותבים stored procedure וטריגרים. המקדם של P מייצג את המילה Procedural.

בנוסף ישנה שפה בשם DDL – ‏Data Definition Language. זו השפה בה עושים פעולות כדוגמת create table או create database.

לאחר הסבר קצר על התחביר, ניתן להבין פיטצ'רים שונים ולאן הם שייכים.

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

SQL – כלל השפות:

  • Merge Syntax
  • פונקציות window
  • תמיכה ב regex בביצוע SUBSTRING
  • נכנס סוג נתונים בשם Boolean
  • יכולת לשמור גרסאות עם RDB$RECORD_VERSION
  • cursor יציב

PSQL:

  • פונקציות SQL
  • פרוצדורות
  • טריגרים, פונקציות ופרוצדורות משפות חיצוניות
  • חבילות
  • חריגות עם פרמטרים
  • SQLSTAT במצב של WHEN
  • שימוש ב continue בתוך לולאות.
  • cursor יכול להחזיר התייחסות כמשתנה מסוג רשומה
  • cursor דו כיווני

DDL‏:

  • תמיכה במצב null של עמודה ו domain
  • היכולת לשנות קידוד ברירת המחדל של מסד הנתונים
  • הוספה של Identity Column – המקביל ל serial בPG ו Auto Increment של SQLITE ו MySQL
  • תחביר עבור RECREATE SEQUENCE/GENERATOR
  • טריגרים עבור DDL
  • תמיכה ב DATABASE LINGER

אבטחה:

  • תמיכה database encryption
  • תמיכה מורחבת יותר בהרשאות Object
  • הרשאות לעבודה עם DDL
  • הרשאות ברמת מסד הנתונים
  • תוספות לעבודה עם Roles

פיקוח:

  • הוספת יכולות נוספות לסטטיסטיקה אודות שאילתות ומסד הנתונים בכלל

אז מה זה כל הסעיפים האלו ? להמשיך לקרוא

יחידות בדיקה, כן, לא, אולי

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

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

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

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

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

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

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

יחידות בדיקה (מיד יצעקו הבודקים), לא נועדו לכך, ואני אומר להם כי הם טועים !

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

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

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

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

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

האם בדקת באמצעות ‎ /dev/full האם המערכת שלך יודעת להתמודד עם מצב בו אין מקום יותר לשמור מידע ?
רק השבוע סידרתי את MySQL שהרס טבלה כי מערכת הקבצים הגיעה ל 100% ולא היה מקום לרשום את הרשומה, אז הטבלה נהרסה.

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

יותר מזה, אתה בודק את הקוד שלך על 10,000 רשומות, הלקוח קצה שלך אבל משתמש ב10,500 רשומות, ואז יש איטיות (ב10,499 עדיין אין), איך לא ידעת להוסיף עוד רק 500 רשומות לבדיקה ? זה מה שמנהל מסוים יצעק עליך, לא ?

ומה אם האיטיות הזו נגרמת בגלל שלאותו לקוח אין מספיק זיכרון לשלוף 10,500 רשומות, אבל לך יש ? האם יכולת בכלל לחזות שימוש וכמה זיכרון להגיד ללקוח להחזיק ? ומה אם אצלו זה נגרם כי יש לו עוד תוכנה שרצה, לא קשורה אליך שבזמן השליפה, למרות שאתה בדקת בדיוק לפני כן אם יש מספיק זיכרון והיה, תפסה את הזיכרון הזה שאתה רוצה להקצות לעצמך ?

האם בכלל יש פתרון למקרי קצה כאלו ?

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

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

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

אז עכשיו חלק מהקוראים כאן (שעוד נשארו ולא עזבו בזעם או שיעמום) יגידו "כן, אבל תראה את סוג הבעיות ב X מול סוג הבעיות של Y".

אבל התשובה היא שזה לא משנה.
בדיקה מוכיחה כי היא מסוגלת לעבור (או לא), אבל היא לא מוכיחה העדר בעיות, אלא רק שהיא עוברת (או לא).

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

גם אם הקוד שלכם 100% נקי מבאגים (ואין כזה קוד באמת), וגם יחידות הבדיקה שלכם ללא באגים (שוב זה קוד, ומי אמר ששם אין בעיות ?), לפעמים החיבור למשהו נוסף, לפעמים בשליטה שלכם ולפעמים לא יכול לגרום לנפילה.
לפעמים מסך שלא מכוייל כמו שצריך יגרום בעיה חדשה, שאותה אתם לא יכולים לבדוק ביחידת בדיקה ומעולם לא חשבתם על הנושא.

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

מוגש כחומר למחשבה.

אריקסון ו webrtc

כבר כתבתי בעבר על webrtc, אך זה עולם שכל הזמן משתנה ולא רק טכנולוגית.

אחד הדברים שמאוד נחמדים בעולם ה webrtc, זה היענות של מרבית החברות הגדולות בשוק בשביל לאמץ אותו.

גוגל היא החברה הכי מפורסמת שמנסה לקדם את webrtc, ויש לה אתר שהיא פתחה בנושא, והיא משחררת מימוש (בראש ובראשונה נועד עבור כרום) ברישיון MIT.

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

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

החברה פתחה אתר בנושא, ושמה את הקוד שלה ב github, וגם הוא ברישיון פתוח – BSD.
הכלים שהיא משתמשת גם הם פתוחים, כדוגמת Gstreamer .
הם גם משתמשים במימוש של סיסקו – מימוש קוד פתוח עבור H.264, למעשה זה משהו שהם מספקים שגוגל בכלל לא.

הם גם משחררים דפדפן עבור iOS בשם bowser אשר מאפשר בעצם לקבל תמיכה ב webrtc, ובכך הם הופכים להיות הדפדפן הראשון במערכת הפעלה זו שתומך בזה.
הדפדפן נועד לקדם דווקא את H.264, אבל בנתיים גם מאפשר להשתמש ב webrtc.

הסיבה לכך שאין דפדפנים אחרים, נעוצה באפל, אשר אינה אוהבת את webrtc ורוצה שהטכנולוגיה שלה תתקדם במקום (משהו שאף אחד אחר בתעשייה לא רוצה), אך מתרצים את הנושא, בכך שהם מעדיפים מערכת טבעית ולא משהו בדפדפן, ולכן מוזילה וגוגל, אינם תומכים ב webrtc כאשר מדובר ב iOS.

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

כרגע יש קרב גדול על בחירת קודקים לוידאו, כאשר הקרב הוא בין H.264 לבין VP8 ובעתיד גם VP9.

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

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

knockout.js

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

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

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

ניסיתי מספר כלים בנושא של data binding כדוגמת Rivets.js ועוד מספר ספריות פשוטות נוספות. אבל אף אחת מהן לא סיפקה את הצרכים שלי, תמיד הייתי צריך לעקם את עצמי בשביל פיתרון, במקום שהפתרון יהיה מתאים לצורת העבודה שלי.
העניין הוא שכל כלי מבקש צורת חשיבה לגמרי שונה, כלומר זה לא שיש דרך אחת נכונה ואני עושה אותה לא נכון, אלא המון דרכים וצורות, שאף אחת מהן לא מתאימה לי אישית.

אז החלטתי לפנות לכלים כדוגמת Backbone, Angular.js ו Ember.js. אבל גיליתי כי עבור הצרכים שלי הן מפלצות – ביחוד אנגולר ואמבר. הכלי שניסיתי היה ד"א אנגולר.

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

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

הכלי נקרא knockout.js. הכלי הזה בנוי בגישה של "תשאיר לי את ה data binding, השאר שלך לעשות מה שתרצה".

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

הגישה של konockout.js קיבלה את השם Model-View-ViewModel אשר מאוד מוכרת לי מעולם הדלפי, רק בצורה שונה.

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

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

זה נעשה בצורה די פשוטה בג'אווהסקריפט נקי:

function observable() {
   if (arguments.length > 0) {
      //write stuff
   } else {
      // read stuff
   }
}

למעשה arguments זה המקביל ל var_args של C או open array של פסקל, רק שהוא מכיל בתוכו אוביקטים כי זו שפת javascript.

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

הנה קוד מאוד פשוט ב knockout:

<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
function ViewModel() {
    this.firstName = ko.observable("Joe");
    this.lastName = ko.observable("Bloggs");
 
    this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();
    }, this);
}
 
ko.applyBindings(new ViewModel());

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

זהו, זה כל מה שהיה צריך. אין צורך בשיריון של namespace, איזורים וכיוב' … בלי לבחור סוג של template וכיוב'.
במקום שבו משתמשים בשדות, אז נכנסים לתוך ה namespace של אותו אובייקט, ואז במידה ורוצים לצאת החוצה משתמשים ב ‎$parent ובמידה ורוצים להתחיל מההתחלה, משתמשים ב ‎$root כלומר בנקודה שבה קראנו ל applyBindings.
אם אתם רוצים את האובייקט עצמו שאנחנו משתמשים בשדה מסוים (למשל כאשר משתמשים במערך), משתמשים ב‎$data וישנם עוד סוגי משתנים. הנה הסבר פשוט בנושא.

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