کتابخانه‌ی استاندارد · پایگاه داده

اس کیو ال db/sql

خواندن، بررسی و گونه‌یابی SQL بدون پایگاه داده: تجزیه‌گر آگاه از گویش، فهرست جدول‌ها و جانگهدارهای گونه‌دار.

واردسازی دیتابیس.اس کیو ال

پرسمان یک رشته است، پس غلط املایی داخل آن را پایگاه داده پیدا می‌کند، آن هم هنگام اجرا و روی همان مسیری که کسی آزمایش نکرده بود. این بسته خود رشته را می‌خواند: SQL را برای یکی از چهار گویش واکافت و تجزیه می‌کند، و وقتی طرح جدول‌ها را هم به آن بدهید هر جدول و ستون را پیدا می‌کند، آن‌هایی که وجود ندارند را نام می‌برد و گونه‌ی هر جانگهدار و هر ستون بازگشتی را می‌گوید. هیچ‌چیز اینجا به پایگاه داده وصل نمی‌شود؛ همه‌اش ایستا است، پس جایش در آزمون یا در گام ساخت برنامه است.

همان ایده‌ی sqlc در زبان Go است، با این تفاوت که طرح از همان SQL که می‌نویسید می‌آید: دستورهای CREATE TABLE در مهاجرت‌های شما همان فهرست هستند، پس پرونده‌ی دومی نیست که باید هم‌گام نگه داشته شود.

چیزهایی که مردم را غافلگیر می‌کند:

  • گویش توصیه نیست. ? در SQLite و MySQL جانگهدار است و در PostgreSQL عملگر ساده، چون پستگرس جانگهدارهایش را با $1 شماره می‌زند؛ "name" همه‌جا نام نقل‌قول‌شده است جز در MySQL که رشته است؛ AUTOINCREMENT و AUTO_INCREMENT و GENERATED ... AS IDENTITY هر کدام به یک موتور تعلق دارند. همان گویشی را بدهید که واقعا روی آن اجرا می‌کنید.
  • بررسی نام‌ها را تنها وقتی پیدا می‌کند که دستور تجزیه شده باشد. گزارشی که خطای نگارشی دارد چیزی درباره‌ی ستون‌ها نمی‌گوید، پس نخست نگارش را درست کنید و دوباره اجرا کنید.
  • جدولی که ستون‌هایش معلوم نیست، از CREATE TABLE ... AS SELECT یا نمایی که بسته نتوانسته بخواند، باز می‌ماند: ستون‌های آن هرگز گمشده گزارش نمی‌شوند. بی‌خبری همیشه خوش‌خبری نیست.
  • اعمال دستورها را به ترتیب می‌خواند، پس نما باید پس از جدول‌هایی بیاید که از آن‌ها گزینش می‌کند، درست همان‌طور که در پایگاه داده هست.
  • متن عیب‌ها در هر دو حالت زبانی انگلیسی است؛ کدها یکی هستند، پس برنامه‌ی فارسی می‌تواند روی code تطبیق بدهد.
  • جانگهدارها یک وکتور<رشته> به شما می‌دهد که مالکش هستید: وکتور و رشته‌های داخلش را در پایان آزاد کنید.
  • سلام اجازه می‌دهد نام فاصله داشته باشد، SQL نه. SELECT نام خانوادگی FROM t یک ستون و یک نام جایگزین است، نه یک نام، و بی‌هیچ اعتراضی پذیرفته می‌شود - و چون نام‌های فارسی بیشتر دو واژه‌اند، دانستنش مهم است. در گیومه بگذاریدشان: SELECT "نام خانوادگی" FROM t.

از همین جا: یک قدم‌به‌قدم از طرح تا پرسمان بررسی‌شده

شش بخش پس از این، بسته را تکه‌تکه باز می‌کنند. این یکی آن را کنار هم می‌گذارد، به همان ترتیبی که در پروژه‌ای واقعی با آن روبه‌رو می‌شوید: پروژه‌ای که از پیش پایگاه داده دارد و انبوهی رشته‌ی پرسمان. برنامه‌ی زیر تمام مسیر است و همان‌طور که هست اجرا می‌شود - بدون سرور، بدون اتصال، بدون هیچ آماده‌سازی.

db-sql-tutorial.salam
واردسازی رشته
واردسازی دیتابیس.اس کیو ال

ناپایا طرح کلی := اس کیو ال.فهرست جداول {}

تابع عدد(ن: صحیح): رشته:
    برگشت رشته.از عدد(ن برگردان صحیح۶۴)
پایان

تابع گام(ش: صحیح، عنوان: رشته):
    سرچاپ ""
    سرچاپ "گام " + عدد(ش) + ": " + عنوان
پایان

تابع بیازما(پ: رشته):
    ناپایا ن := اس کیو ال.بررسی(پ، طرح کلی)
    اگر ن.ok و ن.warnings == ۰:
        سرچاپ "  درست   " + پ
    وگرنه:
        سرچاپ "  نادرست " + پ
        ناپایا ای := ۰
        تا ای < ن.items.طول():
            ع := ن.items.بگیر(ای)
            سرچاپ "          " + ع.code + " " + ع.message
            اگر وارونه رشته.خالی است(ع.help):
                سرچاپ "          " + ع.help
            پایان
            ای = ای + ۱
        پایان
    پایان
    اس کیو ال.آزادسازی گزارش(ن)
پایان

تابع ریشه:
    گام(۱، "طرحی که از پیش دارید")
    طرح کلی = اس کیو ال.فهرست تازه(اس کیو ال.گویش شماره(اس کیو ال.اس کیو لایت))
    دیرکن اس کیو ال.آزادسازی فهرست(طرح کلی)
    ناپایا ساخته := اس کیو ال.اعمال(طرح کلی، """
        CREATE TABLE نویسندگان (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            country TEXT
        );
        CREATE TABLE کتابها (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            author_id INTEGER NOT NULL,
            title TEXT NOT NULL,
            year INTEGER,
            price REAL
        );
    """)
    شمارش := "  " + عدد(اس کیو ال.شمار جدول(طرح کلی)) + " جدول خوانده شد، "
    سرچاپ شمارش + عدد(اس کیو ال.شمار ستون(طرح کلی، "کتابها")) + " ستون روی کتابها"
    اگر وارونه ساخته.ok:
        سرچاپ اس کیو ال.متن گزارش(ساخته)
    پایان
    اس کیو ال.آزادسازی گزارش(ساخته)

    گام(۲، "پرسمان هایی که از پیش دارید")
    بیازما("SELECT id, titles FROM کتابها WHERE author_id = ?")
    بیازما("SELECT ک.title, ن.nationality FROM کتابها ک JOIN نویسندگان ن ON ن.id = ک.author_id")
    بیازما("INSERT INTO کتابها (title) VALUES (?)")
    بیازما("SELECT id FROM کتابها WHERE year = 'recent'")
    بیازما("DELETE FROM کتابها")

    گام(۳، "همان پنج تا، درست شده")
    بیازما("SELECT id, title FROM کتابها WHERE author_id = ?")
    بیازما("SELECT ک.title, ن.country FROM کتابها ک JOIN نویسندگان ن ON ن.id = ک.author_id")
    بیازما("INSERT INTO کتابها (author_id, title) VALUES (?, ?)")
    بیازما("SELECT id FROM کتابها WHERE year = 2024")
    بیازما("DELETE FROM کتابها WHERE id = ?")

    گام(۴، "یک پرسمان چه می گیرد و چه می دهد")
    ناپایا ت := اس کیو ال.تحلیل کن("SELECT title, price FROM کتابها WHERE year > ?"، طرح کلی)
    سرچاپ "  یک " + اس کیو ال.نام دستور(ت.kind) + " روی " + ت.table
    پ := ت.params.بگیر(۰)
    سرچاپ "  می گیرد " + پ.column + " از گونه " + اس کیو ال.گونه سلام(پ.kind، پ.not_null)
    ناپایا ای := ۰
    تا ای < ت.results.طول():
        س := ت.results.بگیر(ای)
        سرچاپ "  می دهد " + س.name + " از گونه " + اس کیو ال.گونه سلام(س.kind، وارونه س.nullable)
        ای = ای + ۱
    پایان
    اس کیو ال.آزادسازی تحلیل(ت)

    گام(۵، "مقدارها با امنیت سر جایشان می نشینند")
    ناپایا مقدارها := اس کیو ال.مقدارهای تازه()
    اس کیو ال.افزودن متن(مقدارها، "O'Brien")
    اس کیو ال.افزودن عدد(مقدارها، ۱۳۶۷ برگردان صحیح۶۴)
    ناپایا خطا := اس کیو ال.گزارش {}
    پرشده := اس کیو ال.پرکردن("INSERT INTO کتابها (title, year) VALUES (?, ?)"، مقدارها، اس کیو ال.گویش شماره(اس کیو ال.اس کیو لایت)، خطا)
    سرچاپ "  " + پرشده
    اس کیو ال.آزادسازی گزارش(خطا)
    اس کیو ال.آزادسازی مقدارها(مقدارها)

    گام(۶، "یا بگذارید خودش کد را بنویسد")
    ناپایا ن۲ := اس کیو ال.گزارش {}
    ناپایا پرسمان ها := اس کیو ال.خواندن پرسمان ها("""
-- name: BooksByAuthor :many
SELECT id, title, year FROM "کتابها" WHERE author_id = ?;
"""، ن۲)
    کد := اس کیو ال.تولید کد("store"، پرسمان ها، طرح کلی، ن۲)
    سرچاپ کد
    اس کیو ال.آزادسازی پرسمان ها(پرسمان ها)
    اس کیو ال.آزادسازی گزارش(ن۲)
    برگشت ۰
پایان
خروجی گام 1: طرحی که از پیش دارید 2 جدول خوانده شد، 5 ستون روی کتابها گام 2: پرسمان هایی که از پیش دارید نادرست SELECT id, titles FROM کتابها WHERE author_id = ? SQL311 no column named "titles" in this statement did you mean "title"? نادرست SELECT ک.title, ن.nationality FROM کتابها ک JOIN نویسندگان ن ON ن.id = ک.author_id SQL311 "ن" has no column "nationality" نادرست INSERT INTO کتابها (title) VALUES (?) SQL315 "author_id" is NOT NULL with no default and this INSERT leaves it out add it to the column list and to every row نادرست SELECT id FROM کتابها WHERE year = 'recent' SQL330 "year" is int and this compares it with text a number goes here without quotes نادرست DELETE FROM کتابها SQL320 this DELETE has no WHERE clause and removes every row add a WHERE clause, or use TRUNCATE when that is what you mean گام 3: همان پنج تا، درست شده درست SELECT id, title FROM کتابها WHERE author_id = ? درست SELECT ک.title, ن.country FROM کتابها ک JOIN نویسندگان ن ON ن.id = ک.author_id درست INSERT INTO کتابها (author_id, title) VALUES (?, ?) درست SELECT id FROM کتابها WHERE year = 2024 درست DELETE FROM کتابها WHERE id = ? گام 4: یک پرسمان چه می گیرد و چه می دهد یک select روی کتابها می گیرد year از گونه option.Option<i64> می دهد title از گونه str می دهد price از گونه option.Option<f64> گام 5: مقدارها با امنیت سر جایشان می نشینند INSERT INTO کتابها (title, year) VALUES ('O''Brien', 1367) گام 6: یا بگذارید خودش کد را بنویسد package store import db import db.sql import mem import option struct BooksByAuthorRow: pub id: i64 = 0 as i64 pub title: str = "" pub year: option.Option<i64> = option.None() as option.Option<i64> end func fill_query(c: dyn db.Connection, raw: str, a: sql.Args): str: mut rep := sql.Report {} out := sql.Fill(raw, a, sql.DialectNamed(c.Kind()), rep) sql.FreeReport(rep) ret out end pub func BooksByAuthor(c: dyn db.Connection, author_id: i64): Vector<BooksByAuthorRow>: mut a := sql.NewArgs() sql.AddInt(a, author_id) q := fill_query(c, "SELECT id, title, year FROM \"کتابها\" WHERE author_id = ?", a) sql.FreeArgs(a) mut rows := Vector {} as Vector<BooksByAuthorRow> r := c.Query(q) if r.Ok(): until r.Next(): mut out := BooksByAuthorRow {} out.id = r.Int64(0) out.title = r.Text(1) if r.IsNull(2): out.year = option.None() as option.Option<i64> else: out.year = option.Some(r.Int64(2)) end rows.push(out) end r.Close() end mem.Free(q as void*) ret rows end

گام ۱ تنها آماده‌سازی موجود است. برای این بسته توصیف طرح نمی‌نویسید؛ همان دستورهای CREATE TABLE که دارید را به آن می‌دهید. اعمال را به ترتیب روی پرونده‌های مهاجرت‌تان بگذارید و فهرست همان طرحی می‌شود که برنامه واقعا روی آن اجرا می‌شود.

گام ۲ همان چیزی است که برایش آمده‌اید. پنج پرسمان از آن‌هایی که در هر کدی پیدا می‌شوند، و پنج شکل متفاوت از غلط بودن: ستونی که به اشتباه جمع نوشته شده، ستونی که به جدول دیگرِ پیوند تعلق دارد، INSERT‌ای که ستون NOT NULL بی‌پیش‌فرض را جا انداخته، عددی که با واژه‌ای در گیومه مقایسه شده، و DELETE‌ای بدون WHERE. هر پنج تا بدون پایگاه داده پیدا می‌شوند و هر کدام می‌گویند چه باید کرد. آخری هشدار است نه خطا، چون گاهی پاک کردن کل جدول همان قصد است - نکته این است که شما در بازبینی تصمیم بگیرید، نه ساعت دو بامداد.

گام ۳ همان پنج تا است، درست شده، و می‌ارزد پیش از خواندن بقیه، یک بار پرسمان‌های خودتان را از این دو گام بگذرانید. سریع‌ترین راه همان دستور است: salam sql check src --schema=db هم پرونده‌های .sql را می‌خواند و هم SQL داخل پرونده‌های .salam را.

گام ۴ جایی است که دیگر یک بازبین ساده نیست. وقتی نام‌ها پیدا شدند، گونه‌ها هم می‌آیند: جانگهدار option.Option<i64> است چون year می‌تواند خالی باشد، و title یک str ساده است چون ستونش NOT NULL است. این همان امضایی است که کدتان باید داشته باشد، برگرفته از طرح نه از حافظه.

گام ۵ جلوی قدیمی‌ترین اشکال دنیا را می‌گیرد. پرکردن مقدارها را با نقل‌قولی که موتور می‌خواهد داخل پرسمان می‌نویسد - ببینید با آپاستروف در O'Brien چه می‌کند - و چون پرسمان نخست واکافت شده، ?ای که داخل یک رشته نشسته دست‌نخورده می‌ماند.

گام ۶ بخشی است که می‌توانید دیگر با دست ننویسید. یک پرسمان را با نام و گونه حاشیه‌نویسی کنید و تابع تولیدشده همان پارامترها و همان ساختار ردیفی را دارد که گام ۴ در آورده بود. با salam sql generate queries --schema=db --output=gen/store.salam اجرایش کنید.

دو چیز را با خودتان ببرید. طرح همان دستورهای ساختاری است که از پیش دارید، پس هیچ‌چیز نمی‌تواند از آن جا بماند. و همه‌ی این بررسی‌ها پیش از اجرای برنامه رخ می‌دهند، که تنها زمانی است که اشتباه در یک پرسمان ارزان است.

خواندن یک پرسمان بدون پایگاه داده

بازبینی یک دستور، یا یک متن کامل از دستورهای جدا شده با ;، را تجزیه می‌کند و یک گزارش برمی‌گرداند. ن.ok به محض اینکه خطایی باشد نادرست است؛ متن گزارش همه‌ی فهرست را همان‌طور که یک کامپایلر می‌نویسد نشان می‌دهد، با خط و ستون و پیام و یک خط راهنما. بیشتر قاعده‌های گویش همین‌جا هستند: یک رشته برای SQLite درست است و برای PostgreSQL غلط، و گزارش می‌گوید کدام بخشش را عوض کنید.

db-sql-guide-lint.salam
واردسازی دیتابیس.اس کیو ال

تابع گزارش(عنوان: رشته، پرسمان: رشته، گ: اس کیو ال.گویش):
    ناپایا ن := اس کیو ال.بازبینی(پرسمان، گ)
    اگر ن.ok:
        سرچاپ عنوان، "درست"
    وگرنه:
        سرچاپ عنوان، اس کیو ال.متن گزارش(ن)
    پایان
    اس کیو ال.آزادسازی گزارش(ن)
پایان

تابع ریشه:
    لایت := اس کیو ال.گویش شماره(اس کیو ال.اس کیو لایت)
    مای := اس کیو ال.گویش شماره(اس کیو ال.مای اس کیو ال)
    پست := اس کیو ال.گویش شماره(اس کیو ال.پستگرس)

    گزارش("پرسمان ساده: "، "SELECT id, name FROM users WHERE id = ?"، لایت)
    گزارش("نیمه کاره:   "، "SELECT id FROM users WHERE"، لایت)
    گزارش("نشانگر غلط:  "، "SELECT id FROM users WHERE id = ?"، پست)
    گزارش("ویژه پستگرس:"، "SELECT id FROM users WHERE name ILIKE 'a%'"، مای)
    گزارش("ویژه مای:    "، "CREATE TABLE t (id INT AUTO_INCREMENT)"، لایت)
    گزارش("ویرگول فارسی:"، "SELECT id، name FROM users"، لایت)

    سرچاپ "شمار جانگهدار:"، اس کیو ال.شمار پارامتر("UPDATE users SET name = ?, age = ? WHERE id = ?"، لایت)
    برگشت ۰
پایان
خروجیپرسمان ساده: درست نیمه کاره: error[SQL105] 1:27: expected a value, found the end of the statement help: a column name, a literal, a function call or a placeholder goes here نشانگر غلط: error[SQL201] 1:33: '?' is not a placeholder in postgres help: postgres numbers its placeholders: $1, $2 ویژه پستگرس: error[SQL205] 1:33: ILIKE is postgres only help: use LOWER(x) LIKE LOWER(y), or LIKE on a case-insensitive column ویژه مای: error[SQL211] 1:24: AUTO_INCREMENT is a mysql keyword help: sqlite spells it AUTOINCREMENT ویرگول فارسی: error[SQL005] 1:10: an Arabic comma '،' is not SQL punctuation help: write ',' instead شمار جانگهدار: 3

کامپایلر همین بررسی‌ها را به شکل یک دستور هم دارد، پس می‌توان یک پروژه‌ی کامل را بدون نوشتن برنامه‌ای برایش بررسی کرد: salam sql check src --schema=db پرونده‌های .sql زیر src را می‌خواند، و رشته‌های SQL داخل پرونده‌های .salam آن را، و هر کدام را با جایگاهشان در منبع سلام گزارش می‌کند. بدون --dialect هر پرونده‌ی سلام با همان موتوری خوانده می‌شود که واردسازی کرده، پس درختی که db/sqlite و db/mysql را با هم دارد بدون هیچ گزینه‌ای درست بررسی می‌شود. پرسمانی که تکه‌تکه ساخته شده - با + یا .concat چسبانده شده، یا هر رشته‌ای که تنها ایرادش این است که در میانه تمام می‌شود - تکه است نه دستور، پس شمرده و رد می‌شود و خطای نگارشی گزارش نمی‌شود. شمارش در خط پایانی می‌آید، پس هیچ‌چیز بی‌صدا بررسی‌نشده نمی‌ماند؛ تکه بودن خودش دلیل دیگری است برای بستن مقدارها به شکل جانگهدار به جای چسباندنشان به متن.

هر عیب یک کد دارد. SQL0xx واکافتی است، SQL1xx نگارشی، SQL2xx قاعده‌ی گویش و SQL3xx نام یا شماری که با طرح نمی‌خواند. وقتی می‌خواهید یک چیز خاص را بپذیرید روی کد تطبیق بدهید؛ هرگز روی پیام تطبیق ندهید.

مهاجرت‌های شما همان طرح هستند

اعمال دستورهای ساختار را روی یک فهرست جداول اجرا می‌کند: CREATE TABLE جدولی را با ستون‌ها و گونه‌هایشان و NOT NULL و PRIMARY KEY آن‌ها می‌افزاید، ALTER TABLE می‌افزاید و حذف و تغییر نام می‌کند، DROP برمی‌دارد و CREATE VIEW ستون‌های نما را ثبت می‌کند. همان رشته‌هایی را که به دیتابیس.افزودن مهاجرت می‌دهید به آن بدهید و فهرست همان طرحی می‌شود که برنامه واقعا دارد.

db-sql-guide-catalog.salam
واردسازی دیتابیس.اس کیو ال

ناپایا طرح جدول ها := اس کیو ال.فهرست جداول {}

تابع بررسی(پرسمان: رشته):
    ناپایا ن := اس کیو ال.بررسی(پرسمان، طرح جدول ها)
    اگر ن.ok و ن.warnings == ۰:
        سرچاپ "درست "، پرسمان
    وگرنه:
        سرچاپ "نادرست"، پرسمان
        سرچاپ اس کیو ال.متن گزارش(ن)
    پایان
    اس کیو ال.آزادسازی گزارش(ن)
پایان

تابع ریشه:
    طرح جدول ها = اس کیو ال.فهرست تازه(اس کیو ال.گویش شماره(اس کیو ال.اس کیو لایت))
    دیرکن اس کیو ال.آزادسازی فهرست(طرح جدول ها)

    ناپایا ساخته := اس کیو ال.اعمال(طرح جدول ها، """
        CREATE TABLE users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            email TEXT NOT NULL,
            name TEXT
        );
        CREATE TABLE orders (
            id INTEGER PRIMARY KEY,
            user_id INTEGER NOT NULL,
            total REAL NOT NULL
        );
    """)
    سرچاپ "طرح خوانده شد:"، ساخته.ok، " جدول ها:"، اس کیو ال.شمار جدول(طرح جدول ها)
    اس کیو ال.آزادسازی گزارش(ساخته)

    بررسی("SELECT u.email, o.total FROM users u JOIN orders o ON o.user_id = u.id WHERE u.id = ?")
    بررسی("SELECT id, mail FROM users")
    بررسی("SELECT id FROM user")
    بررسی("INSERT INTO users (name) VALUES (?)")
    بررسی("DELETE FROM orders")
    برگشت ۰
پایان
خروجیطرح خوانده شد: true جدول ها: 2 درست SELECT u.email, o.total FROM users u JOIN orders o ON o.user_id = u.id WHERE u.id = ? نادرست SELECT id, mail FROM users error[SQL311] 1:12: no column named "mail" in this statement help: did you mean "email"? نادرست SELECT id FROM user error[SQL317] 1:16: no table named "user" help: did you mean "users"? نادرست INSERT INTO users (name) VALUES (?) error[SQL315] 1:1: "email" is NOT NULL with no default and this INSERT leaves it out help: add it to the column list and to every row نادرست DELETE FROM orders warning[SQL320] 1:1: this DELETE has no WHERE clause and removes every row help: add a WHERE clause, or use TRUNCATE when that is what you mean

با یک فهرست، بررسی نام‌ها را پیدا می‌کند: ستون یا جدول ناشناخته خطا است و نزدیک‌ترین نام واقعی پیشنهاد می‌شود، ستونی که دو جدول پیوندخورده هر دو دارند تا وقتی مشخصش نکنید خطا است، INSERT برابر فهرست ستون‌ها و برابر ستون‌هایی که NOT NULL بدون مقدار پیش‌فرض هستند بررسی می‌شود، و UPDATE یا DELETE بدون WHERE هشدار است، چون تقریبا هرگز منظور همین نبوده.

گونه‌هایی هم که در دست دارد می‌خواند: مقایسه‌ی ستون عددی با مقداری در گیومه که عدد نیست روی SQLite و MySQL هشدار است، چون آنجا بی‌صدا هیچ‌وقت برابر نمی‌شود یا بی‌صدا صفر می‌شود، و روی PostgreSQL خطا است چون نمی‌پذیردش؛ ستونی در فهرست نتیجه‌ی پرسمان GROUP BY که نه گروه شده و نه تجمیع، روی PostgreSQL خطا و جای دیگر هشدار است، با همان استثنایی که خود آن موتورها می‌گذارند: گروه کردن روی تمام کلید اصلی یک جدول بقیه‌ی ستون‌های همان جدول را تعیین می‌کند، پس آن‌ها بی‌اشکال هستند؛ و USING (col) در هر دو سمت پیوند بررسی می‌شود. زیرپرسمانی که برای مقایسه‌ای که در آن نشسته شمار ستون نادرستی برمی‌گرداند، ORDER BY 3 وقتی دستور دو ستون برمی‌گرداند، LIMIT که عدد نیست، تجمیع در WHERE به جای HAVING، ستونی که در یک SET دو بار مقدار می‌گیرد، و دو ستون نتیجه با یک نام جایگزین هم گزارش می‌شوند.

گذاشتن مقدارها، با امنیت

هر سه راه‌انداز SQL دستور آماده ندارند - تنها db/sqlite است که Prepare و Bind* دارد - پس کدی که باید روی MySQL یا PostgreSQL اجرا شود دست آخر مقدارها را با دست به SQL می‌چسباند، و همین‌جاست که اشتباه در نقل‌قول تبدیل به تزریق می‌شود. پرکردن همین یک کار را درست انجام می‌دهد: پرسمان را واکافت می‌کند، پس می‌داند کدام ? جانگهدار است و کدام نویسه‌ای داخل یک رشته، می‌سنجد که شمار مقدارها بخواند، و هر مقدار را همان‌طور که گویش می‌خواهد می‌نویسد.

db-sql-guide-fill.salam
واردسازی دیتابیس.اس کیو ال

تابع نمایش(پرسمان: رشته، م: اس کیو ال.مقدارها، گ: اس کیو ال.گویش):
    ناپایا ن := اس کیو ال.گزارش {}
    خروجی := اس کیو ال.پرکردن(پرسمان، م، گ، ن)
    اگر ن.ok:
        سرچاپ خروجی
    وگرنه:
        سرچاپ اس کیو ال.متن گزارش(ن)
    پایان
    اس کیو ال.آزادسازی گزارش(ن)
پایان

تابع ریشه:
    لایت := اس کیو ال.گویش شماره(اس کیو ال.اس کیو لایت)
    پست := اس کیو ال.گویش شماره(اس کیو ال.پستگرس)

    ناپایا ردیف := اس کیو ال.مقدارهای تازه()
    اس کیو ال.افزودن متن(ردیف، "O'Brien")
    اس کیو ال.افزودن عدد(ردیف، ۴۱ برگردان صحیح۶۴)
    اس کیو ال.افزودن منطقی(ردیف، درست)
    اس کیو ال.افزودن خالی(ردیف)
    نمایش("INSERT INTO users (name, age, paid, note) VALUES (?, ?, ?, ?)"، ردیف، لایت)
    نمایش("INSERT INTO users (name, age, paid, note) VALUES ($1, $2, $3, $4)"، ردیف، پست)
    اس کیو ال.آزادسازی مقدارها(ردیف)

    ناپایا حمله := اس کیو ال.مقدارهای تازه()
    اس کیو ال.افزودن متن(حمله، "x' OR '1'='1")
    نمایش("SELECT id FROM users WHERE name = ?"، حمله، لایت)
    اس کیو ال.آزادسازی مقدارها(حمله)

    ناپایا یکی := اس کیو ال.مقدارهای تازه()
    اس کیو ال.افزودن عدد(یکی، ۷ برگردان صحیح۶۴)
    نمایش("SELECT id FROM notes WHERE body = '?' AND id = ?"، یکی، لایت)
    نمایش("SELECT id FROM users WHERE id = ? AND org = ?"، یکی، لایت)
    اس کیو ال.آزادسازی مقدارها(یکی)
    برگشت ۰
پایان
خروجیINSERT INTO users (name, age, paid, note) VALUES ('O''Brien', 41, 1, NULL) INSERT INTO users (name, age, paid, note) VALUES ('O''Brien', 41, TRUE, NULL) SELECT id FROM users WHERE name = 'x'' OR ''1''=''1' SELECT id FROM notes WHERE body = '?' AND id = 7 error[SQL400] 1:1: this query takes 2 values but got 1 help: add or remove an argument so the two agree

مقدار متنی در گیومه‌ی تک پیچیده می‌شود و هر گیومه‌ی داخلش دو برابر، و روی MySQL ممیز وارون هم دو برابر می‌شود، چون MySQL ممیز وارون را گریز می‌خواند و آن دو تای دیگر نه. مقدار منطقی روی SQLite و MySQL 1 یا 0 است و روی PostgreSQL TRUE یا FALSE؛ خالی NULL می‌شود؛ عددها ساده نوشته می‌شوند. '?' در پرسمان چهارم همان‌طور که بود می‌ماند، چیزی که جست‌وجو و جایگزینی ساده روی رشته اشتباه می‌گرفت.

این جایگزینی است، نه دستور آماده: پایگاه داده هنوز یک دستور کامل را تجزیه می‌کند و بازاستفاده‌ی نقشه‌ی اجرا نیست. جایی که راه‌انداز می‌تواند آماده و بسته کند، مانند sqlite، همان ابزار بهتری است. جایی که نمی‌تواند، این راه امن گذاشتن مقدارها است، و یک تابع بازبینی‌شده است به جای قاعده‌ی نقل‌قولی که در هر فراخوانی تکرار شود.

گونه‌ی هر جانگهدار

تحلیل کن هر کاری که بررسی می‌کند انجام می‌دهد و علاوه بر آن می‌گوید پرسمان چه می‌گیرد و چه برمی‌گرداند. هر پارامتر می‌گوید با کدام ستون، در کدام جدول، مقایسه شده و آن ستون چه گونه‌ای دارد؛ هر ستون نتیجه می‌گوید ستون با چه نامی برمی‌گردد، گونه‌اش چیست و می‌تواند خالی باشد یا نه. گونه سلام آن را به گونه‌ی سلام تبدیل می‌کند که مقدار را در آن می‌خوانید، پس LEFT JOIN به شما option.Option<i64> می‌دهد آنجا که پیوند درونی i64 می‌دهد.

db-sql-guide-analyze.salam
واردسازی دیتابیس.اس کیو ال

تابع شرح(پرسمان: رشته، طرح: اس کیو ال.فهرست جداول):
    ناپایا ت := اس کیو ال.تحلیل کن(پرسمان، طرح)
    سرچاپ پرسمان
    سرچاپ "  دستور:"، اس کیو ال.نام دستور(ت.kind)، "روی"، ت.table
    ناپایا ای := ۰
    تا ای < ت.params.طول():
        پ := ت.params.بگیر(ای)
        سرچاپ "  جانگهدار"، پ.ordinal، "ستون"، پ.column، "از گونه"، اس کیو ال.گونه سلام(پ.kind، پ.not_null)
        ای = ای + ۱
    پایان
    ناپایا جی := ۰
    تا جی < ت.results.طول():
        س := ت.results.بگیر(جی)
        سرچاپ "  ستون"، س.name، "برمی گردد با گونه"، اس کیو ال.گونه سلام(س.kind، وارونه س.nullable)
        جی = جی + ۱
    پایان
    اس کیو ال.آزادسازی تحلیل(ت)
پایان

تابع ریشه:
    ناپایا طرح := اس کیو ال.فهرست تازه(اس کیو ال.گویش شماره(اس کیو ال.اس کیو لایت))
    دیرکن اس کیو ال.آزادسازی فهرست(طرح)
    ناپایا ساخته := اس کیو ال.اعمال(طرح، """
        CREATE TABLE users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            email TEXT NOT NULL,
            name TEXT,
            age INTEGER
        );
    """)
    اس کیو ال.آزادسازی گزارش(ساخته)

    شرح("SELECT id, name FROM users WHERE email = ? AND age > ?"، طرح)
    شرح("INSERT INTO users (email, name) VALUES (?, ?) RETURNING id"، طرح)
    برگشت ۰
پایان
خروجیSELECT id, name FROM users WHERE email = ? AND age > ? دستور: select روی users جانگهدار 1 ستون email از گونه str جانگهدار 2 ستون age از گونه option.Option<i64> ستون id برمی گردد با گونه i64 ستون name برمی گردد با گونه option.Option<str> INSERT INTO users (email, name) VALUES (?, ?) RETURNING id دستور: insert روی users جانگهدار 1 ستون email از گونه str جانگهدار 2 ستون name از گونه option.Option<str> ستون id برمی گردد با گونه i64

همین اندازه بس است تا کد اتصال یک پرسمان را بسازید، یا در یک آزمون مطمئن شوید پرسمان هنوز همان چیزی را می‌گیرد و برمی‌گرداند که کد دور و برش باور دارد. جانگهدارها به ترتیب ظاهر شدن شماره می‌خورند، همان ترتیبی که راه‌انداز آن‌ها را می‌بندد؛ برای PostgreSQL شماره همان عددی است که در $n نوشته شده و جا افتادن یکی از آن شماره‌ها خودش خطا است.

کارابزار
این SQL برای موتور من درست نوشته شده؟بازبینی
چند مقدار می‌بندد؟شمار پارامتر، جانگهدارها
خواندن طرحفهرست تازه، اعمال
جدول‌ها و ستون‌ها وجود دارند؟بررسی
چه می‌گیرد و چه برمی‌گرداند؟تحلیل کن
کدام گونه‌ی سلام یک ستون را می‌خواند؟گونه سلام
گذاشتن مقدارها در SQL با امنیتمقدارهای تازه، افزودن ...، پرکردن
گشتن در طرحشمار جدول، نام جدول، شمار ستون، ستون شماره، جدول دارد، ستون دارد

تولید توابع پرسمان

وقتی طرح و تحلیل در دست است، گام آخر مکانیکی می‌شود، پس بسته خودش انجامش می‌دهد: یک پرونده‌ی .sql را همان‌طور که sqlc می‌خواهد حاشیه‌نویسی کنید و تولید کد کد سلام آن را می‌نویسد - یک ساختار ردیف برای هر پرسمان، یک تابع گونه‌دار برای هر پرسمان، و هر کدام هنگام تولید برابر طرح بررسی می‌شود.

db-sql-guide-generate.salam
واردسازی دیتابیس.اس کیو ال

تابع ریشه:
    ناپایا طرح := اس کیو ال.فهرست تازه(اس کیو ال.گویش شماره(اس کیو ال.اس کیو لایت))
    دیرکن اس کیو ال.آزادسازی فهرست(طرح)
    ناپایا ساخته := اس کیو ال.اعمال(طرح، """
        CREATE TABLE users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            email TEXT NOT NULL,
            name TEXT
        );
    """)
    اس کیو ال.آزادسازی گزارش(ساخته)

    پرسمان ها := """
-- name: GetUser :one
SELECT id, email, name FROM users WHERE email = ?;

-- name: CreateUser :exec
INSERT INTO users (email, name) VALUES (?, ?);
"""
    ناپایا ن := اس کیو ال.گزارش {}
    ناپایا خوانده := اس کیو ال.خواندن پرسمان ها(پرسمان ها، ن)
    سرچاپ "پرسمان ها:"، خوانده.طول()
    کد := اس کیو ال.تولید کد("store"، خوانده، طرح، ن)
    اگر ن.ok:
        سرچاپ کد
    وگرنه:
        سرچاپ اس کیو ال.متن گزارش(ن)
    پایان
    اس کیو ال.آزادسازی پرسمان ها(خوانده)
    اس کیو ال.آزادسازی گزارش(ن)
    برگشت ۰
پایان
خروجیپرسمان ها: 2 package store import db import db.sql import mem import option struct GetUserRow: pub id: i64 = 0 as i64 pub email: str = "" pub name: option.Option<str> = option.None() as option.Option<str> end func fill_query(c: dyn db.Connection, raw: str, a: sql.Args): str: mut rep := sql.Report {} out := sql.Fill(raw, a, sql.DialectNamed(c.Kind()), rep) sql.FreeReport(rep) ret out end pub func GetUser(c: dyn db.Connection, email: str, ok &: bool): GetUserRow: mut a := sql.NewArgs() sql.AddText(a, email) q := fill_query(c, "SELECT id, email, name FROM users WHERE email = ?", a) sql.FreeArgs(a) mut out := GetUserRow {} ok = false r := c.Query(q) if r.Ok(): if r.Next(): out.id = r.Int64(0) out.email = r.Text(1) if r.IsNull(2): out.name = option.None() as option.Option<str> else: out.name = option.Some(r.Text(2)) end ok = true end r.Close() end mem.Free(q as void*) ret out end pub func CreateUser(c: dyn db.Connection, email: str, name: str): bool: mut a := sql.NewArgs() sql.AddText(a, email) sql.AddText(a, name) q := fill_query(c, "INSERT INTO users (email, name) VALUES (?, ?)", a) sql.FreeArgs(a) done := c.Exec(q) == 0 mem.Free(q as void*) ret done end

گونه‌ها اینها هستند: :one (نخستین ردیف، با پارامتر خروجی ok &: bool)، :many (یک وکتور از ردیف‌ها)، :exec (یک منطقی) و :execrows (شمار ردیف‌های تغییریافته). نام پارامترها از ستونی می‌آید که هر جانگهدار با آن مقایسه شده و گونه‌شان هم از همان؛ ستونی که می‌تواند خالی باشد به شکل option.Option<T> برمی‌گردد و با IsNull خوانده می‌شود. پرسمانی که با طرح نخواند تولید را متوقف می‌کند و نام پرسمان در پیام می‌آید، پس غلط املایی هرگز به پرونده‌ی تولیدشده نمی‌رسد.

دستورش این است: salam sql generate queries --schema=db --output=gen/store.salam --package=store. پرونده‌ی تولیدشده یک dyn db.Connection می‌گیرد، پس یک مجموعه تابع به SQLite و MySQL و PostgreSQL خدمت می‌کند و نقل‌قول هر گویش را هنگام اجرا از c.Kind() برمی‌دارد.

گونه‌ها

پارامتر Param

ساختار پارامتر
یک جانگهدار، و ستونی که به آن بسته شده.
نامانگلیسیگونهتوضیح
markermarkerرشته = ""جانگهدار همان‌طور که نوشته شده: ? یا $2 یا :name.
ordinalordinalصحیح = 0جایش، از ۱؛ برای $n همان عدد است.
tabletableرشته = ""جدول ستونی که با آن مقایسه شده، وقتی چنین ستونی بوده.
columncolumnرشته = ""ستونی که با آن مقایسه شده، وقتی چنین ستونی بوده.
kindkindصحیح = 7گونه‌ی TYPE_* آن ستون، یا نوع ناشناخته.
not_nullnot_nullمنطقی = نادرستدرست وقتی آن ستون نمی‌تواند خالی باشد.
db-sql-Methods.salam
واردسازی دیتابیس.اس کیو ال

تابع ریشه:
    لایت := اس کیو ال.گویش شماره(اس کیو ال.اس کیو لایت)
    سرچاپ لایت.name، اس کیو ال.گویش نام("postgresql").name، اس کیو ال.گویش شماره(اس کیو ال.ماریادی بی).name

    ناپایا بد := اس کیو ال.بازبینی("SELECT id FROM t WHERE"، لایت)
    سرچاپ بد.ok، بد.errors، بد.warnings، بد.statements
    سرچاپ اس کیو ال.متن عیب(بد.items.بگیر(۰))
    اس کیو ال.آزادسازی گزارش(بد)

    سرچاپ اس کیو ال.شمار پارامتر("SELECT a FROM t WHERE b = ? AND c = ?"، لایت)
    ناپایا نشانه ها := اس کیو ال.جانگهدارها("SELECT a FROM t WHERE b = ? AND c = ?"، لایت)
    سرچاپ نشانه ها.طول()، نشانه ها.بگیر(۰)
    نشانه ها.آزادکن()

    ناپایا فهرست := اس کیو ال.فهرست تازه(لایت)
    ناپایا طرح := اس کیو ال.اعمال(فهرست، """
        CREATE TABLE users (id INTEGER PRIMARY KEY, email TEXT NOT NULL, age INTEGER);
    """)
    سرچاپ "طرح:"، طرح.ok، اس کیو ال.شمار جدول(فهرست)، اس کیو ال.نام جدول(فهرست، ۰)
    اس کیو ال.آزادسازی گزارش(طرح)
    سرچاپ اس کیو ال.جدول دارد(فهرست، "users")، اس کیو ال.ستون دارد(فهرست، "users"، "email")
    ستون یک := اس کیو ال.ستون شماره(فهرست، "users"، ۱)
    سرچاپ ستون یک.name، اس کیو ال.نام نوع(ستون یک.kind)، ستون یک.not_null

    ناپایا گم := اس کیو ال.بررسی("SELECT nope FROM users"، فهرست)
    سرچاپ اس کیو ال.متن گزارش(گم)
    اس کیو ال.آزادسازی گزارش(گم)

    ناپایا ت := اس کیو ال.تحلیل کن("SELECT id, age FROM users WHERE email = ?"، فهرست)
    سرچاپ اس کیو ال.نام دستور(ت.kind)، ت.table، ت.params.طول()، ت.results.طول()
    پ := ت.params.بگیر(۰)
    سرچاپ پ.marker، پ.ordinal، پ.table + "." + پ.column، اس کیو ال.گونه سلام(پ.kind، پ.not_null)
    س := ت.results.بگیر(۱)
    سرچاپ س.name، اس کیو ال.نام نوع(س.kind)، س.nullable
    اس کیو ال.آزادسازی تحلیل(ت)

    ناپایا مقدارها := اس کیو ال.مقدارهای تازه()
    اس کیو ال.افزودن عدد(مقدارها، ۳ برگردان صحیح۶۴)
    اس کیو ال.افزودن متن(مقدارها، "a'b")
    اس کیو ال.افزودن منطقی(مقدارها، نادرست)
    اس کیو ال.افزودن اعشار(مقدارها، ۲.۵)
    اس کیو ال.افزودن خالی(مقدارها)
    سرچاپ اس کیو ال.شمار مقدار(مقدارها)
    ناپایا خطا := اس کیو ال.گزارش {}
    پرشده := اس کیو ال.پرکردن("INSERT INTO t (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)"، مقدارها، لایت، خطا)
    سرچاپ پرشده
    اس کیو ال.آزادسازی گزارش(خطا)
    اس کیو ال.آزادسازی مقدارها(مقدارها)

    اس کیو ال.آزادسازی فهرست(فهرست)
    برگشت ۰
پایان
خروجیsqlite postgres mariadb false 1 0 0 error[SQL105] 1:23: expected a value, found the end of the statement help: a column name, a literal, a function call or a placeholder goes here 2 2 ? طرح: true 1 users true true email text true error[SQL311] 1:8: no column named "nope" in this statement select users 1 2 ? 1 users.email str age int true 5 INSERT INTO t (a, b, c, d, e) VALUES (3, 'a''b', 0, 2.5, NULL)

ستون نتیجه ResultCol

ساختار ستون نتیجه
یک ستون از آنچه دستور برمی‌گرداند.
نامانگلیسیگونهتوضیح
namenameرشته = ""نامی که با آن برمی‌گردد: نام جایگزین، یا نام خود ستون.
tabletableرشته = ""جدولی که از آن آمده، وقتی ستون ساده است.
kindkindصحیح = 7گونه‌ی TYPE_* آن.
nullablenullableمنطقی = درستدرست وقتی می‌تواند خالی برگردد، که پیوند بیرونی آن را برای تمام یک سمتش درست می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

تحلیل Analysis

ساختار تحلیل
آنچه تحلیل کن درباره‌ی یک دستور در می‌آورد.
نامانگلیسیگونهتوضیح
okokمنطقی = درستدرست وقتی هیچ‌چیز خطا نیست.
kindkindصحیح = 0کدام دستور STMT_* است.
tabletableرشته = ""جدولی که از آن می‌خواند یا در آن می‌نویسد.
paramsparamsوکتور<پارامتر>جانگهدارهایش، به ترتیب بستن.
resultsresultsوکتور<ستون نتیجه>ستون‌هایی که برمی‌گرداند.
reportreportگزارشعیب‌ها، همان‌طور که بررسی می‌داد.
ownedownedوکتور<رشته>رشته‌هایی که تحلیل مالکشان است. آزادسازی تحلیل آزادشان می‌کند؛ جای دیگری نباید خوانده شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

مقدارها Args

ساختار مقدارها
مقدارهایی که پرسمان می‌بندد، به ترتیب. با مقدارهای تازه و توابع افزودن ... بسازیدش و با آزادسازی مقدارها آزادش کنید.
نامانگلیسیگونهتوضیح
kindskindsوکتور<صحیح>هر مقدار از چه گونه‌ای است؛ یک درایه برای هر مقدار.
intsintsوکتور<صحیح۶۴>مقدارهای صحیح، با همان شماره.
floatsfloatsوکتور<اعشار۶۴>مقدارهای اعشاری، با همان شماره.
textstextsوکتور<رشته>مقدارهای متنی، با همان شماره. افزودن متن رشته را رونوشت می‌کند، پس فراخواننده مال خودش را نگه می‌دارد.
boolsboolsوکتور<منطقی>مقدارهای منطقی، با همان شماره.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

گویش Dialect

ساختار گویش
هر چه میان موتورها تفاوت دارد: نام‌ها و رشته‌ها چطور نقل‌قول می‌شوند، چه جانگهدارهایی هست، چه بندهایی پشتیبانی می‌شوند. با گویش شماره یا گویش نام یکی بسازید.
نامانگلیسیگونهتوضیح
ididصحیح = 0کدام موتور: اس کیو لایت، مای اس کیو ال، ماریادی بی یا پستگرس.
namenameرشته = "sqlite"نام موتور، همان‌طور که در عیب‌ها می‌آید.
double_quoted_stringdouble_quoted_stringمنطقی = نادرستدرست وقتی "x" رشته است نه نام (MySQL).
backtick_identbacktick_identمنطقی = نادرستدرست وقتی `x` نام است (MySQL و SQLite).
bracket_identbracket_identمنطقی = نادرستدرست وقتی [x] نام است (SQLite).
hash_commenthash_commentمنطقی = نادرستدرست وقتی # توضیح را آغاز می‌کند (MySQL).
dollar_stringdollar_stringمنطقی = نادرستدرست وقتی $tag$ ... $tag$ رشته است (PostgreSQL).
backslash_escapebackslash_escapeمنطقی = نادرستدرست وقتی ممیز وارون داخل رشته می‌گریزاند (MySQL).
qmark_paramqmark_paramمنطقی = نادرستدرست وقتی ? جانگهدار است.
numbered_paramnumbered_paramمنطقی = نادرستدرست وقتی $1 جانگهدار است.
named_paramnamed_paramمنطقی = نادرستدرست وقتی :name و @name جانگهدار هستند.
returningreturningمنطقی = نادرستدرست وقتی RETURNING پشتیبانی می‌شود.
on_conflicton_conflictمنطقی = نادرستدرست وقتی ON CONFLICT پشتیبانی می‌شود.
on_duplicateon_duplicateمنطقی = نادرستدرست وقتی ON DUPLICATE KEY UPDATE پشتیبانی می‌شود.
limit_commalimit_commaمنطقی = نادرستدرست وقتی LIMIT start, count پشتیبانی می‌شود.
ilikeilikeمنطقی = نادرستدرست وقتی ILIKE پشتیبانی می‌شود.
colon_castcolon_castمنطقی = نادرستدرست وقتی x::type تبدیل گونه است.
autoincrement_wordautoincrement_wordرشته = ""واژه‌ی خود موتور برای کلید خودافزا.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

عیب Diag

ساختار عیب
یک عیب: چه چیزی غلط است، کجا، و به جایش چه بنویسید.
نامانگلیسیگونهتوضیح
severityseverityصحیح = 0خطا، هشدار یا یادداشت.
codecodeرشته = ""کد، برای نمونه SQL311. روی همین تطبیق بدهید، نه روی پیام.
messagemessageرشته = ""چه چیزی غلط است، در یک خط.
helphelpرشته = ""به جایش چه بنویسید؛ وقتی پیشنهادی نیست خالی است.
linelineصحیح = 1خطی که از آن شروع می‌شود، از ۱.
colcolصحیح = 1ستونی که از آن شروع می‌شود، از ۱.
offsetoffsetصحیح = 0جابجایی بایتی در SQL که از آن شروع می‌شود.
lengthlengthصحیح = 0چند بایت را می‌پوشاند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

گزارش Report

ساختار گزارش
عیب‌های یک اجرا، به ترتیبی که پیدا شدند.
نامانگلیسیگونهتوضیح
okokمنطقی = درستدرست وقتی هیچ‌چیز خطا نیست. هشدارها آن را نادرست نمی‌کنند.
errorserrorsصحیح = 0چند خطا هست.
warningswarningsصحیح = 0چند هشدار هست.
statementsstatementsصحیح = 0چند دستور تجزیه شد، که راه شمردن آنچه بررسی شده است.
itemsitemsوکتور<عیب>خود عیب‌ها.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

ستون Column

ساختار ستون
یک ستون از طرح.
نامانگلیسیگونهتوضیح
namenameرشته = ""نامش، همان‌طور که طرح نوشته.
type_nametype_nameرشته = ""گونه‌اش، همان‌طور که طرح نوشته.
kindkindصحیح = 7آن گونه کدام‌یک از گونه‌های TYPE_* است.
not_nullnot_nullمنطقی = نادرستدرست وقتی نمی‌تواند خالی باشد.
has_defaulthas_defaultمنطقی = نادرستدرست وقتی مقدار پیش‌فرض دارد، که همان چیزی است که به INSERT اجازه می‌دهد آن را نیاورد.
primaryprimaryمنطقی = نادرستدرست وقتی بخشی از کلید اصلی است.
autoautoمنطقی = نادرستدرست وقتی موتور خودش پرش می‌کند.
generatedgeneratedمنطقی = نادرستدرست وقتی محاسبه می‌شود و نمی‌توان در آن نوشت.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

جدول Table

ساختار جدول
یک جدول یا نما از طرح.
نامانگلیسیگونهتوضیح
namenameرشته = ""نامش.
is_viewis_viewمنطقی = نادرستدرست وقتی نما است.
openopenمنطقی = نادرستدرست وقتی ستون‌هایش معلوم نیست، که بررسی ستون را برایش خاموش می‌کند.
columnscolumnsوکتور<ستون>ستون‌هایش، به ترتیب اعلان.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

فهرست جداول Catalog

ساختار فهرست جداول
طرحی که پرسمان برابر آن بررسی می‌شود. با فهرست تازه یکی بسازید و با اعمال پرش کنید.
نامانگلیسیگونهتوضیح
ddگویشگویشی که دستورهای ساختار و پرسمان‌ها با آن خوانده می‌شوند.
tablestablesوکتور<جدول>جدول‌ها و نماهایی که دارد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

پرسمان Query

ساختار پرسمان
یک پرسمان حاشیه‌نویسی‌شده که از یک پرونده‌ی .sql خوانده شده.
نامانگلیسیگونهتوضیح
namenameرشته = ""نامی که در سرآیند -- name: آمده و برای تابع تولیدشده و ساختار ردیفش به کار می‌رود.
kindkindصحیح = 0یکی از گونه‌های Q_*.
texttextرشته = ""خود SQL، بدون ; پایانی.
linelineصحیح = 1خطی که سرآیندش در آن است، تا عیب بتواند به پرونده اشاره کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

پایاها و متغیرها

دستور ناشناخته STMT_UNKNOWN

پایا دستور ناشناخته: صحیح۳۲ = 0
دستوری که این بسته مدلش نمی‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

دستور گزینش STMT_SELECT

پایا دستور گزینش: صحیح۳۲ = 1
یک SELECT یا VALUES یا عمل مجموعه‌ای.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

دستور درج STMT_INSERT

پایا دستور درج: صحیح۳۲ = 2
یک INSERT یا REPLACE.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

دستور بروزرسانی STMT_UPDATE

پایا دستور بروزرسانی: صحیح۳۲ = 3
یک UPDATE.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

دستور حذف STMT_DELETE

پایا دستور حذف: صحیح۳۲ = 4
یک DELETE.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

دستور طرح STMT_DDL

پایا دستور طرح: صحیح۳۲ = 5
دستوری که طرح را عوض می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

اس کیو لایت SQLITE

پایا اس کیو لایت: صحیح۳۲ = 0
گویش SQLite.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

مای اس کیو ال MYSQL

پایا مای اس کیو ال: صحیح۳۲ = 1
گویش MySQL.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

ماریادی بی MARIADB

پایا ماریادی بی: صحیح۳۲ = 2
گویش MariaDB: همان MySQL به‌اضافه‌ی RETURNING.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

پستگرس POSTGRES

پایا پستگرس: صحیح۳۲ = 3
گویش PostgreSQL.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

خطا ERROR

پایا خطا: صحیح۳۲ = 0
شدت عیبی که دستور را غلط می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

هشدار WARNING

پایا هشدار: صحیح۳۲ = 1
شدت عیبی که خواندنش می‌ارزد ولی دستور را غلط نمی‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

یادداشت NOTE

پایا یادداشت: صحیح۳۲ = 2
شدت یک یادآوری.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

نوع خالی TYPE_NULL

پایا نوع خالی: صحیح۳۲ = 0
گونه‌ی NULL در SQL. شماره‌گذاری همان گونه‌های ستون در دیتابیس است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

نوع صحیح TYPE_INT

پایا نوع صحیح: صحیح۳۲ = 1
ستون عدد صحیح.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

نوع اعشاری TYPE_FLOAT

پایا نوع اعشاری: صحیح۳۲ = 2
ستون اعشاری یا دهدهی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

نوع متن TYPE_TEXT

پایا نوع متن: صحیح۳۲ = 3
ستون متنی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

نوع دودویی TYPE_BLOB

پایا نوع دودویی: صحیح۳۲ = 4
ستون دودویی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

نوع منطقی TYPE_BOOL

پایا نوع منطقی: صحیح۳۲ = 5
ستون منطقی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

نوع زمان TYPE_TIME

پایا نوع زمان: صحیح۳۲ = 6
ستون تاریخ یا زمان یا مهر زمانی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

نوع ناشناخته TYPE_UNKNOWN

پایا نوع ناشناخته: صحیح۳۲ = 7
گونه‌ای که بسته نتوانست در بیاورد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

پرسمان یکی Q_ONE

پایا پرسمان یکی: صحیح۳۲ = 0
پرسمان حداکثر یک ردیف برمی‌گرداند؛ تابع تولیدشده یک ok &: bool می‌گیرد و ساختار ردیف را برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

پرسمان چندی Q_MANY

پایا پرسمان چندی: صحیح۳۲ = 1
پرسمان هر تعداد ردیف برمی‌گرداند؛ تابع تولیدشده یک وکتور از آن‌ها برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

پرسمان اجرا Q_EXEC

پایا پرسمان اجرا: صحیح۳۲ = 2
پرسمان داده را تغییر می‌دهد و تابع تولیدشده می‌گوید کار کرد یا نه.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

پرسمان شمار Q_EXECROWS

پایا پرسمان شمار: صحیح۳۲ = 3
مانند Q_EXEC، با این تفاوت که تابع تولیدشده شمار ردیف‌های تغییریافته را برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

تابع‌ها

بررسی Check

تابع بررسی(sql: رشته، c: فهرست جداول): گزارش
تجزیه‌ی SQL و پیدا کردنش در یک فهرست: جدول و ستون ناشناخته، ستون دوپهلو، شمار مقدارهای INSERT و ستون‌های لازمش، و نوشتن‌هایی که WHERE ندارند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

تحلیل کن Analyze

تابع تحلیل کن(sql: رشته، c: فهرست جداول): تحلیل
هر کاری که بررسی می‌کند، به‌اضافه‌ی گونه‌ی هر جانگهدار و هر ستون بازگشتی. با آزادسازی تحلیل آزادش کنید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

آزادسازی تحلیل FreeAnalysis

تابع آزادسازی تحلیل(a &: تحلیل)
آزاد کردن یک تحلیل و رشته‌های داخلش.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

نام دستور StmtKindName

تابع نام دستور(k: صحیح): رشته
نام یک گونه‌ی STMT_*: "select" و "insert" و مانند آن.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

مقدارهای تازه NewArgs

تابع مقدارهای تازه(): مقدارها
یک فهرست مقدار خالی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

افزودن عدد AddInt

تابع افزودن عدد(a &: مقدارها، v: صحیح۶۴)
افزودن یک مقدار صحیح.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

افزودن اعشار AddFloat

تابع افزودن اعشار(a &: مقدارها، v: اعشار۶۴)
افزودن یک مقدار اعشاری.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

افزودن متن AddText

تابع افزودن متن(a &: مقدارها، v: رشته)
افزودن یک مقدار متنی. رشته رونوشت می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

افزودن منطقی AddBool

تابع افزودن منطقی(a &: مقدارها، v: منطقی)
افزودن یک مقدار منطقی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

افزودن خالی AddNull

تابع افزودن خالی(a &: مقدارها)
افزودن یک NULL در SQL.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

شمار مقدار ArgCount

تابع شمار مقدار(a: مقدارها): صحیح
فهرست چند مقدار دارد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

آزادسازی مقدارها FreeArgs

تابع آزادسازی مقدارها(a &: مقدارها)
آزاد کردن یک فهرست مقدار و متنی که رونوشت کرده.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

پرکردن Fill

تابع پرکردن(query: رشته، a: مقدارها، d: گویش، err &: گزارش): رشته
نوشتن مقدارها داخل پرسمان و برگرداندن SQL آماده. نخست پرسمان واکافت می‌شود، پس ? داخل یک رشته دست نخورده می‌ماند، شمار باید بخواند، و هر مقدار همان‌طور که گویش می‌خواهد نوشته می‌شود: گیومه‌ها دو برابر، ممیز وارون روی MySQL دو برابر، TRUE و FALSE روی PostgreSQL. این جایگزینی است نه دستور آماده، و نتیجه مال شماست که آزادش کنید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

گویش شماره DialectOf

تابع گویش شماره(id: صحیح): گویش
گویش یکی از اس کیو لایت، مای اس کیو ال، ماریادی بی یا پستگرس.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

گویش نام DialectNamed

تابع گویش نام(name: رشته): گویش
گویش یک نام مانند "sqlite" یا "mysql" یا "mariadb" یا "postgres"، که همان چیزی است که دیتابیس.اس کیو لایت و ا.نوع() می‌دهند. نام ناشناخته SQLite می‌دهد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

آزادسازی گزارش FreeReport

تابع آزادسازی گزارش(r &: گزارش)
آزاد کردن یک گزارش.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

متن عیب DiagText

تابع متن عیب(d: عیب): رشته
یک عیب به صورت یک خط متن، با خط راهنمایش زیر آن.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

متن گزارش ReportText

تابع متن گزارش(r: گزارش): رشته
یک گزارش کامل به صورت متن، هر عیب در یک بند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

بازبینی Lint

تابع بازبینی(sql: رشته، d: گویش): گزارش
تجزیه‌ی SQL و گزارش آنچه در آن غلط است، بدون طرح. تنها مشکلات واکافتی و نگارشی و گویشی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

شمار پارامتر ParamCount

تابع شمار پارامتر(sql: رشته، d: گویش): صحیح
چند جانگهدار در این SQL بسته می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

جانگهدارها Placeholders

تابع جانگهدارها(sql: رشته، d: گویش): وکتور<رشته>
هر جانگهدار همان‌طور که نوشته شده، به ترتیب. وکتور و رشته‌هایش مال شماست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

فهرست تازه NewCatalog

تابع فهرست تازه(d: گویش): فهرست جداول
یک فهرست خالی که دستورهای ساختار و پرسمان‌ها را با این گویش می‌خواند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

اعمال Apply

تابع اعمال(c &: فهرست جداول، ddl: رشته): گزارش
اجرای دستورهای ساختار روی فهرست و گزارش آنچه در آن‌ها غلط بود. یک بار برای هر مهاجرت، به ترتیب، صدایش بزنید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

آزادسازی فهرست FreeCatalog

تابع آزادسازی فهرست(c &: فهرست جداول)
آزاد کردن یک فهرست و هر نامی که در آن است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

شمار جدول TableCount

تابع شمار جدول(c: فهرست جداول): صحیح
چند جدول و نما در فهرست هست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

نام جدول TableName

تابع نام جدول(c: فهرست جداول، i: صحیح): رشته
نام جدول این جایگاه، یا "".

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

جدول دارد HasTable

تابع جدول دارد(c: فهرست جداول، name: رشته): منطقی
اینکه فهرست جدول یا نمایی با این نام دارد یا نه، بدون توجه به بزرگی و کوچکی حرف.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

شمار ستون ColumnCount

تابع شمار ستون(c: فهرست جداول، table: رشته): صحیح
یک جدول چند ستون دارد، یا ۰ وقتی چنین جدولی نیست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

ستون شماره ColumnAt

تابع ستون شماره(c: فهرست جداول، table: رشته، i: صحیح): ستون
ستون این جایگاه از یک جدول، یا یک ستون خالی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

ستون دارد HasColumn

تابع ستون دارد(c: فهرست جداول، table: رشته، column: رشته): منطقی
اینکه جدول ستونی با این نام دارد یا نه، بدون توجه به بزرگی و کوچکی حرف.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

نام نوع KindName

تابع نام نوع(k: صحیح): رشته
نام یک گونه‌ی TYPE_*: "int" و "text" و مانند آن.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

گونه سلام SalamType

تابع گونه سلام(k: صحیح، not_null: منطقی): رشته
گونه‌ی سلامی که ستونی از این گونه را می‌خواند: i64 یا f64 یا bool یا str، پیچیده در option.Option وقتی مقدار می‌تواند خالی باشد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

خواندن پرسمان ها ParseQueries

تابع خواندن پرسمان ها(src: رشته، err &: گزارش): وکتور<پرسمان>
خواندن سرآیندهای -- name: Thing :one و SQL آن‌ها از یک پرونده‌ی پرسمان. نام بد یا گونه‌ی ناشناخته گزارش می‌شود نه حدس زده.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

آزادسازی پرسمان ها FreeQueries

تابع آزادسازی پرسمان ها(v &: وکتور<پرسمان>)
آزاد کردن پرسمان ها و متنی که مالکش هستند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam

تولید کد Generate

تابع تولید کد(pkg: رشته، queries: وکتور<پرسمان>، c: فهرست جداول، err &: گزارش): رشته
نوشتن کد سلام برای یک پرونده‌ی پرسمان کامل: یک ساختار ردیف و یک تابع برای هر پرسمان، که هر کدام نخست برابر فهرست تحلیل می‌شود. پرسمانی که نخواند با نامش گزارش می‌شود و چیزی برایش تولید نمی‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-sql-Methods.salam