קלט/פלט · מחלקות ותכנות מונחה־עצמים
dbmopen#
קושר קובץ DBM בדיסק להאש כך שקריאות וכתיבות להאש הופכות לחיפושים ולאחסונים במסד הנתונים.
dbmopen הוא הדרך הישנה לקשור האש לקובץ dbm, ndbm, sdbm, gdbm, או Berkeley DB. הוא הוחלף ברובו על־ידי tie עם מודול backend מפורש של DBM (DB_File, GDBM_File, SDBM_File, NDBM_File, AnyDBM_File), שנותן שליטה על המימוש שבו משתמשים ועל אפשרויות לכל־backend. יש להושיט יד ל־dbmopen בקריאת קוד מורשת או כאשר תמציתיות ה־one-liner חשובה יותר מבחירת ה־backend.
בניגוד ל־open, הארגומנט הראשון אינו מטפל קובץ - הוא ההאש שיקושר. HASH נכתב עם ה־sigil של %.
תקציר#
dbmopen %HASH, $DBNAME, $MASK
dbmopen(%HASH, $DBNAME, 0) # open existing only; never create
dbmclose %HASH # or: untie %HASH
מה מקבלים בחזרה#
ערך אמת בהצלחה, ערך שקרי בכישלון. בכישלון, $! נקבע לשגיאת המערכת שמנעה את הקישור. מקרי הכישלון הנפוצים הם ״מסד הנתונים אינו קיים ו־MASK הוא 0״ ושגיאות הרשאה על קבצי הגיבוי.
dbmopen(%cache, $path, 0)
or die "cache $path missing or unreadable: $!";
לאחר קריאה מוצלחת, %HASH מתנהג כמו כל האש אחר: $HASH{key} = $value כותב למסד הנתונים, $HASH{key} קורא ממנו, delete מסיר רשומה, exists בודק חברות, ו־each / keys / values עוברים על הרשומות. הנתונים חיים בדיסק; ההאש הוא רק מבט.
ארגומנטים#
HASH- משתנה ההאש לקשירה. חייב להיכתב עם%. כל תוכן קיים מושלך. ההאש נשאר קשור עד שנקראים עליוdbmcloseאוuntie, או עד שהוא יוצא מהתחום.DBNAME- נתיב מסד הנתונים ללא סיומת הקובץ של ה־backend. אחסוניdbm/sdbmמסורתיים משתמשים בשני קבצים בשם`DBNAME.dir`ו־`DBNAME.pag`;gdbmו־Berkeley DB משתמשים בקובץ יחיד. העברת"/var/lib/app/cache"פותחת את/var/lib/app/cache.dir+/var/lib/app/cache.pagתחתsdbm, או את/var/lib/app/cacheתחתgdbm.MASK- מצב יצירה לכל קבצים שצריכים להיווצר, באותה צורה כמו הארגומנט השלישי שלchmod(בדרך כלל ליטרל אוקטלי כמו0666או0644). ה־umaskהפעיל מוחל עלMASK, ולכן ההרשאות האמיתיות בדיסק הןMASK & ~umask.MASKשל0מדכא יצירה: אם מסד הנתונים אינו קיים כבר,dbmopenמחזיר שקרי ו־$!נקבע.
מצב גלובלי שהוא נוגע בו#
דוגמאות#
פתיחת מסד נתוני היסטוריה, מעבר עם each, ולאחר מכן סגירה:
dbmopen(%HIST, '/usr/lib/news/history', 0666)
or die "open history: $!";
while (my ($key, $val) = each %HIST) {
print $key, ' = ', unpack('L', $val), "\n";
}
dbmclose %HIST;
פתיחה לקריאה־בלבד, סירוב ליצור את מסד הנתונים:
dbmopen(%cache, "$ENV{HOME}/.app/cache", 0)
or die "no cache at $ENV{HOME}/.app/cache: $!";
my $hit = $cache{$key};
dbmclose %cache;
בחירת backend ספציפי על־ידי טעינת המודול שלו לפני קריאה ל־dbmopen. AnyDBM_File מתייעץ עם @AnyDBM_File::ISA כדי להחליט באיזה מימוש dbmopen משתמש:
use DB_File;
dbmopen(%NS_Hist, "$ENV{HOME}/.netscape/history.db", 0644)
or die "open netscape history: $!";
מסד נתונים מוגן־כתיבה - השמה נכשלת בשקט (או croak בהתאם ל־backend); יש להגן עם eval כאשר צריך לבחון:
dbmopen(%db, $path, 0) or die $!;
my $writable = eval { $db{__probe__} = 1; delete $db{__probe__}; 1 };
warn "read-only\n" unless $writable;
מסד נתונים גדול - יש להימנע מ־keys / values, שמממשים את הרשימה כולה בזיכרון. יש להשתמש ב־each במקום:
dbmopen(%big, $path, 0) or die $!;
while (my ($k, $v) = each %big) {
process($k, $v);
}
dbmclose %big;
מקרי קצה#
ה־sigil של ההאש נדרש.
dbmopen %h, $name, 0666- כתיבת$hאו\%hלא עובדת. החריץ הראשון הוא שם ההאש כהאש, לא כהפניה.MASK = 0הוא המטבע של ״פתיחת קיים בלבד״.0666נראה־סביר יוצר בשקט מסד נתונים ריק רענן אם הקובץ חסר, מה שכמעט אף פעם אינו מה שקורא רוצה בנתיב חיפוש של מטמון.הסיומות מנוהלות על־ידי ה־backend. אין להעביר
"cache.dir"או"cache.pag"- יש להעביר"cache".sdbmמצרף.dir/.pag;gdbmכותב לשם החשוף.פתיחה אחת לכל תהליך עבור DBM ישן יותר. אם ה־backend הוא ספריית
dbm(3)המסורתית (נדיר כיום), לתהליך יכולה להיות רק פתיחת DBM אחת בכל זמן נתון. ל־sdbmול־gdbmאין מגבלה זו.מגבלות גודל ערך.
sdbmתוחם מפתחות + ערכים בערך 1008 בתים לכל רשומה; כתיבות חורגות בגודל נקטעות או נדחות. ל־gdbmול־Berkeley DB יש מגבלות גבוהות בהרבה. במקרה של ספק, יש להשתמש ב־tieעםDB_Fileולבדוק את המגבלות של ה־backend עצמו.ערכים מספריים הם בתים בדיסק. אחסון
$h{k} = 42כותב את המחרוזת"42", לא מספר שלם. יש לבצע pack במפורש עםpack/unpackכאשר השדה זקוק לפריסה בינארית קבועה (כמו בדוגמת news-history לעיל).סגירה היא אופציונלית אך מומלצת. הקישור משוחרר כאשר ההאש יוצא מהתחום, אך
dbmcloseאוuntieמפורש מבצע flush לכתיבות ממתינות וחושף שגיאות בזמן הסגירה.קישור מחדש של האש שכבר קשור. קריאה ל־
dbmopenעל האש שכבר קשור סוגרת קודם את הקישור הקודם.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
dbmclose- שחרור קישורdbmopenו־flush של כתיבות ממתינותtie- התחליף המודרני; יש לשלב עםDB_File,GDBM_File,SDBM_File, אוAnyDBM_Fileכדי לבחור backend במפורשuntie- שחרור קישור שנעשה עםdbmopenאוtieeach- שידור רשומות בלי לממש את מסד הנתונים כולו בזיכרוןumask- ממסך את הארגומנטMASKכאשר קבצי גיבוי נוצריםopen- ה־built-in הרגיל לפתיחת קובץ, שלוקח מטפל קובץ ולא האש