باگی که فقط با اسکیمای کپیشده خودش رو نشون داد
خلاصهٔ کاملتر
نویسنده، نگهدارنده Truss (یه نمایشدهنده اسکیمای دیتابیس برای لاراول)، میگه مردم همیشه یه سوال رو میپرسیدن: «روی اسکیمای من چه شکلیه؟» دموی قبلی فقط یه دیتابیس نمونه داشت. برای همین یه صفحه اضافه کرد که فایل mysqldump کپیشده رو همون تو مرورگر پارس میکنه و با همون داشبورد پکیج رسم میکنه؛ بدون نصب و بدون آپلود. به گفتهاش بخش جالب ماجرا خود صفحه نبود، بلکه چیزهایی بود که کد تا اون روز از زیرشون در میرفت، چون تا قبلش هر اسکیمایی از یه کانکشن دیتابیس میومد که خود کاربر تنظیمش کرده بود.
فرض اول این بود که اسمها فقط رشتهان. داشبورد اسم جدول و ستون رو مستقیم مینوشت تو تعریف دیاگرام. وقتی اسم از information_schema میاد اشکالی نداره، چون دیتابیس خودش قواعد شناسه رو اعمال کرده. ولی یه فایل کپیشده میتونه اسم ستون رو چیزی بذاره که اصلا شناسه دیتابیس نیست و برای موتور رسم، تکهای از مارکآپ حساب میشه. فیکسش هوشمندانه نبود: هر شناسه قبل از نوشته شدن به چیزی که فرمت دیاگرام قبول میکنه کاهش پیدا میکنه. حرف اصلی نویسنده اینه که کد درست بود، فرضش غلط بود.
فرض دوم این بود که یه حالت هندلنشده میتونه ساکت بمونه. یه دامپ اسکیما گرامر ثابتی نداره؛ شناسهها ممکنه با بکتیک باشن یا نه، CREATE INDEX ممکنه جدا بیاد یا داخل تعریف جدول، و فارنکیها ممکنه بعدا با ALTER TABLE اضافه بشن. وسوسه اینه که خط ناشناس رو رد کنی و بری جلو، ولی نویسنده میگه یه کانسترینت گمشده دیاگرام رو خراب نشون نمیده، کامل و غلط نشون میده. الان هر استیتمنت یکی از سه سرنوشت رو داره که همه دیده میشن: رسمشده، آگاهانه ردشده و شمردهشده، یا فلگشده با شماره خط.
فرض سوم این بود که یه رابطه بینام، رابطه واقعی نیست. Truss یه حالت inference داره که از قراردادهای نامگذاری رابطهها رو حدس میزنه، مثلا user_id احتمالا به users اشاره میکنه. اون حالت وقتی خودت فعالش کردی و اسکیما رو میشناسی مفیده، ولی به گفته نویسنده برای صفحهای که اولین چیزیه که یه غریبه میبینه دیفالت بدیه، چون یه یال حدسی غلط شبیه حدس به نظر نمیرسه. پس این پارسر فقط چیزی رو رسم میکنه که صریحا با FOREIGN KEY اعلام شده باشه.
آخرین مورد اصلا به ورودی غیرقابلاعتماد ربط نداشت. موقع بازبینی صفحه، هر کلیکی روی هر جایی آدم رو میبرد به ریپوی گیتهاب پروژه. دلیلش یه تگ بستهنشده چند خط بالاتر بود که کل بقیه قالب رو داخل یه لینک برده بود. تستهای اون صفحه با رجکس رشته مچ میکردن و رجکس مفهوم «این تگ ده خط بعد هنوز بازه» رو نمیفهمه. چیزی که باگ رو گرفت یه چک ساختاری بود که واقعا HTML رو پارس میکنه. درس کلیتر اینه که تست پترنمحور فقط وجود چند رشته رو چک میکنه، نه اینکه خروجی شکل درستی داره.
نکات کلیدی:
- پارس کل دامپ تو خود صفحه انجام میشه و هیچ چیزی آپلود نمیشه
- هر شناسه قبل از نوشتن تو دیاگرام نرمالسازی میشه، روی هر ارجاع
- سه سرنوشت برای هر استیتمنت: رسمشده، ردشده و شمردهشده، یا فلگشده با شماره خط
- حالت inference برای این صفحه خاموشه؛ فقط FOREIGN KEY صریح یال میسازه
- هر INSERT شمرده و دور ریخته میشه، نه خونده؛ قولش ساختاره، نه داده
- تنها چیزی که تو sessionStorage نوشته میشه، بعد از اولین خوندن پاک میشه
- چک ساختاری HTML باگی رو گرفت که تست رجکسی سبز ردش کرده بود




