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

پستگرس db/postgres

کارخواه PostgreSQL نوشته‌شده با خود سلام: رشته‌ی اتصال و نشانی، TLS، پرسمان، تراکنش، استخر اتصال و مهاجرت.

واردسازی دیتابیس.پستگرس

این بسته مستقیم با PostgreSQL حرف می‌زند: پروتکل شبکه‌ی پستگرس را در خود سلام پیاده می‌کند، با ورود به روش گذرواژه‌ی ساده، MD5 و SCRAM-SHA-256 و TLS اختیاری، پس به libpq یا هیچ کتابخانه‌ی بیرونی دیگری نیاز ندارد. همه‌ی ردیف‌های نتیجه یک‌جا از سرور گرفته می‌شوند، پس تعداد ردیف پیش از خواندن هم معلوم است. هر پایگاه داده در رابط مشترک اتصال از بسته‌ی دیتابیس هم می‌نشیند و با آن به تابع‌های مستقل از موتور، استخر اتصال و مهاجرت طرح‌واره دسترسی دارید. این صفحه با یک آموزش شروع می‌شود و مرجع کامل همه‌ی تابع‌ها و گونه‌ها پس از آن می‌آید.

آموزش: کتاب‌فروشی در یازده گام

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

اول یک سرور راه بیندازید. با داکر یک فرمان کافی است؛ این فرمان پایگاه داده‌ی bookshop و کاربر postgres را با گذرواژه‌ی secret می‌سازد:

docker run -d --name bookshop-db -p 5432:5432 -e POSTGRES_PASSWORD=secret -e POSTGRES_DB=bookshop postgres:17-alpine

بدون داکر، PostgreSQL را از بسته‌های سیستم‌عامل نصب کنید، فرمان createdb bookshop را بزنید و همین گذرواژه را به کاربر postgres بدهید. برنامه‌ها به 127.0.0.1 روی درگاه ۵۴۳۲ وصل می‌شوند. برنامه‌ی واقعی به جای postgres با کاربر خودش وارد می‌شود، همان‌طور که گام ۲ نشان می‌دهد.

۱. اتصال

بازکردن یک رشته‌ی اتصال از جفت‌های key=value می‌گیرد، همان قالبی که psql و libpq به کار می‌برند. این تابع همیشه یک پایگاه داده برمی‌گرداند، حتی وقتی ورود شکست خورده باشد، پس پیش از هر کاری معتبر را بپرسید؛ در آن صورت خطا پیام سرور را دارد. پینگ یک پرسمان بسیار کوچک می‌فرستد تا مطمئن شود اتصال هنوز کار می‌کند، و برای وارسی سلامت یک سرویس همیشه‌روشن مناسب است.

db-postgres-connect.salam
واردسازی دیتابیس.پستگرس

تابع ریشه:
    پ := پستگرس.بازکردن("host=127.0.0.1 port=5432 user=postgres password=secret dbname=bookshop")
    دیرکن پستگرس.بستن(پ)
    اگر وارونه پستگرس.معتبر(پ):
        چاپ "اتصال برقرار نشد: " + پستگرس.خطا(پ)
        برگشت ۱
    پایان
    سرچاپ "وصل شد به"، پستگرس.نام پایگاه داده(پ)، "با کاربر"، پستگرس.نام کاربر(پ)
    سرچاپ "سرور"، پستگرس.نام میزبان(پ) + ":" + پستگرس.درگاه(پ)، "نسخه"، پستگرس.نسخه سرور(پ)
    سرچاپ پستگرس.پرسمان متن(پ، "SELECT split_part(version(), ' on ', 1)")
    سرچاپ "زنده است:"، پستگرس.پینگ(پ)

    اشتباه := پستگرس.بازکردن("host=127.0.0.1 user=postgres password=wrong dbname=bookshop")
    دیرکن پستگرس.بستن(اشتباه)
    سرچاپ "با گذرواژه‌ی نادرست:"، پستگرس.معتبر(اشتباه)
    چاپ پستگرس.خطا(اشتباه)

    خاموش := پستگرس.بازکردن("host=127.0.0.1 port=5499 user=postgres password=secret connect_timeout=3")
    دیرکن پستگرس.بستن(خاموش)
    سرچاپ "وقتی سروری روی درگاه نیست:"، پستگرس.معتبر(خاموش)
    چاپ پستگرس.خطا(خاموش)
پایان
خروجیوصل شد به bookshop با کاربر postgres سرور 127.0.0.1:5432 نسخه 170011 PostgreSQL 17.11 زنده است: true با گذرواژه‌ی نادرست: false FATAL: password authentication failed for user "postgres" وقتی سروری روی درگاه نیست: false connection to server at "127.0.0.1", port 5499 failed

پیام‌های خود سرور به همان زبان PostgreSQL می‌مانند و با شدت خطا شروع می‌شوند: FATAL برای ورود ردشده و ERROR برای دستوری که شکست خورده. پیام خطا با یک خط تازه تمام می‌شود و برای همین نمونه‌ها آن را با چاپ می‌نویسند نه سرچاپ. اگر چیزی روی درگاه گوش ندهد، بازکردن بی‌درنگ شکست می‌خورد. connect_timeout بر حسب ثانیه است و تعیین می‌کند ورود برای هر پاسخ سرور چقدر صبر کند؛ اگر ننویسید ۳۰ ثانیه است.

۲. رشته‌ی اتصال، نشانی و TLS

همین تنظیم‌ها را به سه شکل می‌توان نوشت: جفت‌های key=value، نشانی postgresql://user:password@host:port/dbname?key=value، یا پنج آرگومان بازکردن کامل. این گام یک نقش ورود برای فروشگاه هم می‌سازد، با گذرواژه‌ای که فاصله و @ دارد، تا نشان دهد چنین مقداری در هر شکل چطور نوشته می‌شود.

db-postgres-options.salam
واردسازی دیتابیس.پستگرس

تابع ریشه:
    مدیر := پستگرس.بازکردن کامل("127.0.0.1"، ۵۴۳۲، "postgres"، "secret"، "bookshop")
    دیرکن پستگرس.بستن(مدیر)
    سرچاپ "بازکردن کامل:"، پستگرس.معتبر(مدیر)
    _ := پستگرس.اجرا(مدیر، "DROP ROLE IF EXISTS clerk")
    _ := پستگرس.اجرا(مدیر، "CREATE ROLE clerk LOGIN PASSWORD 'p@ss word'")

    الف := پستگرس.بازکردن("host=127.0.0.1 user=clerk password='p@ss word' dbname=bookshop")
    دیرکن پستگرس.بستن(الف)
    سرچاپ "مقدار در نقل قول:"، پستگرس.معتبر(الف)، پستگرس.نام کاربر(الف)

    ب := پستگرس.بازکردن("postgresql://clerk:p%40ss%[email protected]:5432/bookshop?connect_timeout=5")
    دیرکن پستگرس.بستن(ب)
    سرچاپ "نشانی:"، پستگرس.معتبر(ب)، پستگرس.نام کاربر(ب)، پستگرس.نام پایگاه داده(ب)

    ج := پستگرس.بازکردن("host=127.0.0.1 user=clerk password='p@ss word' dbname=bookshop sslmode=disable")
    دیرکن پستگرس.بستن(ج)
    سرچاپ "sslmode=disable:"، پستگرس.معتبر(ج)، پستگرس.پرسمان متن(ج، "SHOW ssl")

    ت := پستگرس.بازکردن("host=127.0.0.1 user=clerk password='p@ss word' dbname=bookshop sslmode=require")
    دیرکن پستگرس.بستن(ت)
    سرچاپ "sslmode=require:"، پستگرس.معتبر(ت)
    چاپ پستگرس.خطا(ت)
پایان
خروجیبازکردن کامل: true مقدار در نقل قول: true clerk نشانی: true clerk bookshop sslmode=disable: true off sslmode=require: false server does not support SSL, but SSL was required

در شکل key=value مقداری که فاصله دارد میان نقل‌قول تکی می‌آید. در نشانی، نویسه‌هایی که معنای خاص دارند درصدی کد می‌شوند: %40 برای @ و %20 برای فاصله. بازکردن کامل آرگومان‌هایش را بی نقل‌قول کنار هم می‌گذارد، پس فقط برای مقدارهای بی‌فاصله مناسب است.

کلیدهایی که این بسته می‌خواند این‌ها هستند: host (یا hostaddr)، port، user، password، dbname، sslmode، sslrootcert و connect_timeout؛ کلیدهای دیگر نادیده گرفته می‌شوند. sslmode مثل libpq رفتار می‌کند: prefer (پیش‌فرض) اگر سرور TLS داشته باشد آن را به کار می‌برد، require بدون TLS ادامه نمی‌دهد، verify-ca و verify-full گواهی سرور را هم وارسی می‌کنند (اگر sslrootcert بدهید، با همان فایل CA)، و disable و allow اصلا TLS نمی‌خواهند. بدون یکی از حالت‌های verify گواهی وارسی نمی‌شود. سرور آزمایشی این‌جا TLS را خاموش دارد، برای همین require شکست می‌خورد. سوکت یونیکس پشتیبانی نمی‌شود؛ حتی روی همان ماشین هم با TCP وصل شوید.

۳. ساختن جدول‌ها

اجرا دستوری را اجرا می‌کند که ردیفی برنمی‌گرداند و در صورت موفقیت ۰ و در صورت شکست ۱- می‌دهد. چند دستور جداشده با نقطه‌ویرگول را هم یک‌جا می‌پذیرد که برای تعریف طرح‌واره مناسب است. گونه‌های PostgreSQL را متناسب با داده انتخاب کنید: bigint GENERATED ALWAYS AS IDENTITY برای شناسه، numeric برای پول، text[] برای فهرست برچسب‌ها و jsonb برای جزئیات بی‌قالب.

db-postgres-schema.salam
واردسازی دیتابیس.پستگرس

تابع ریشه:
    پ := پستگرس.بازکردن("host=127.0.0.1 user=postgres password=secret dbname=bookshop")
    دیرکن پستگرس.بستن(پ)

    طرح := `
        DROP TABLE IF EXISTS orders, books;
        CREATE TABLE books (
            id       bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
            title    text NOT NULL UNIQUE,
            author   text NOT NULL,
            year     int CHECK (year > 0),
            price    numeric(6, 2) NOT NULL CHECK (price >= 0),
            stock    int NOT NULL DEFAULT 0 CHECK (stock >= 0),
            isbn     text,
            tags     text[] NOT NULL DEFAULT '{}',
            info     jsonb NOT NULL DEFAULT '{}'
        );
        CREATE TABLE orders (
            id       bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
            customer text NOT NULL,
            book_id  bigint NOT NULL REFERENCES books (id),
            qty      int NOT NULL CHECK (qty > 0),
            total    numeric(8, 2) NOT NULL
        );`
    اگر پستگرس.اجرا(پ، طرح) نابرابر ۰:
        چاپ پستگرس.خطا(پ)
        برگشت ۱
    پایان

    ر := پستگرس.پرسمان(پ، `SELECT table_name, column_name, data_type, is_nullable
        FROM information_schema.columns
        WHERE table_name IN ('books', 'orders') ORDER BY table_name, ordinal_position`)
    دیرکن ر.بستن()
    تا ر.بعدی():
        سرچاپ ر.متن(۰) + "." + ر.متن(۱)، ر.متن(۲)، "خالی‌پذیر:"، ر.متن(۳)
    پایان
پایان
خروجیbooks.id bigint خالی‌پذیر: NO books.title text خالی‌پذیر: NO books.author text خالی‌پذیر: NO books.year integer خالی‌پذیر: YES books.price numeric خالی‌پذیر: NO books.stock integer خالی‌پذیر: NO books.isbn text خالی‌پذیر: YES books.tags ARRAY خالی‌پذیر: NO books.info jsonb خالی‌پذیر: NO orders.id bigint خالی‌پذیر: NO orders.customer text خالی‌پذیر: NO orders.book_id bigint خالی‌پذیر: NO orders.qty integer خالی‌پذیر: NO orders.total numeric خالی‌پذیر: NO

قیدهایی مثل UNIQUE، CHECK (stock >= 0) و REFERENCES باعث می‌شوند پایگاه داده داده‌ی نادرست را رد کند، حتی وقتی اشکالی در برنامه بخواهد آن را بنویسد. گام ۹ نشان می‌دهد این رد شدن چه شکلی دارد.

۴. افزودن ردیف و گرفتن شناسه‌ی تازه

دستور INSERT ... RETURNING id یک پرسمان است که شناسه‌ی ساخته‌شده را برمی‌گرداند، پس آن را با پرسمان اجرا کنید و تنها ردیفش را بخوانید. متنی که از بیرون برنامه می‌آید از نقل قول می‌گذرد که آن را به شکل یک رشته‌ی SQL نقل‌قول‌دار و گریزخورده برمی‌گرداند: نقل‌قول درون متن دوتایی می‌شود و نمی‌تواند رشته را زودتر ببندد. اجرا با شمارش یک دستور را اجرا می‌کند و می‌گوید چند ردیف افزوده، به‌روز یا حذف شد.

db-postgres-insert.salam
واردسازی دیتابیس.پستگرس
واردسازی رشته

تابع افزودن کتاب(پ: پستگرس.پایگاه داده، عنوان: رشته، نویسنده: رشته، سال: صحیح، قیمت: رشته، موجودی: صحیح): صحیح۶۴:
    دستور := "INSERT INTO books (title, author, year, price, stock) VALUES (" + پستگرس.نقل قول(پ، عنوان) + ", " + پستگرس.نقل قول(پ، نویسنده) + ", " + رشته.از عدد(سال) + ", " + قیمت + ", " + رشته.از عدد(موجودی) + ") RETURNING id"
    ر := پستگرس.پرسمان(پ، دستور)
    دیرکن ر.بستن()
    اگر وارونه ر.بعدی():
        چاپ پستگرس.خطا(پ)
        برگشت ۰
    پایان
    برگشت ر.عدد صحیح۶۴(۰)
پایان

تابع ریشه:
    پ := پستگرس.بازکردن("host=127.0.0.1 user=postgres password=secret dbname=bookshop")
    دیرکن پستگرس.بستن(پ)

    سرچاپ پستگرس.نقل قول(پ، "کتاب 'سووشون' از سیمین دانشور")
    سرچاپ "بوف کور شناسه‌ی"، افزودن کتاب(پ، "بوف کور"، "صادق هدایت"، ۱۳۱۵، "12.50"، ۴)، "گرفت"
    سرچاپ "سووشون شناسه‌ی"، افزودن کتاب(پ، "سووشون"، "سیمین دانشور"، ۱۳۴۸، "9.99"، ۲)، "گرفت"

    تعداد := پستگرس.اجرا با شمارش(پ، `INSERT INTO books (title, author, year, price, stock, isbn, tags) VALUES
        ('گلستان', 'سعدی', 656, 7.25, 3, '978-9643510011', '{شعر,کلاسیک}'),
        ('شازده کوچولو', 'آنتوان دو سنت‌اگزوپری', 1322, 6.00, 10, '978-9643620475', '{افسانه,کلاسیک}'),
        ('سمفونی مردگان', 'عباس معروفی', 1368, 11.00, 1, NULL, '{رمان}')`)
    سرچاپ تعداد، "کتاب دیگر افزوده شد، آخرین شناسه"، پ.شناسه آخرین درج()

    ر := پستگرس.پرسمان(پ، "UPDATE books SET tags = '{رمان,کلاسیک}' WHERE title = 'بوف کور' RETURNING id, title, tags")
    تا ر.بعدی():
        سرچاپ "به‌روز شد"، ر.عدد صحیح(۰)، ر.متن(۱)، ر.متن(۲)
    پایان
    ر.بستن()

    سرچاپ "افزایش قیمت روی"، پستگرس.اجرا با شمارش(پ، "UPDATE books SET price = price + 1 WHERE year < 1300")، "کتاب کهن"
پایان
خروجی'کتاب ''سووشون'' از سیمین دانشور' بوف کور شناسه‌ی 1 گرفت سووشون شناسه‌ی 2 گرفت 3 کتاب دیگر افزوده شد، آخرین شناسه 5 به‌روز شد 1 بوف کور {رمان,کلاسیک} افزایش قیمت روی 1 کتاب کهن

شناسه آخرین درج مقدار lastval() را از سرور می‌پرسد، یعنی آخرین مقداری که یک دنباله یا ستون شناسه در این نشست ساخته است. پس از درج سه‌ردیفی، این شناسه‌ی ردیف آخر است؛ اگر همه‌ی شناسه‌ها را بخواهید RETURNING روشن‌تر است. RETURNING روی UPDATE و DELETE هم کار می‌کند، همان‌طور که تغییر برچسب نشان می‌دهد.

پ.تعداد تغییرات() شمار ردیف‌هایی است که آخرین پ.اجرا(...) تغییر داد. این عدد فقط وقتی نگه داشته می‌شود که متد را روی خود مقدار صدا بزنید؛ تابع بسته‌ای پستگرس.اجرا(پ، ...) روی یک رونوشت کار می‌کند و پس از آن پ.تعداد تغییرات() صفر می‌ماند. اجرا با شمارش این پرسش را از میان برمی‌دارد.

۵. خواندن ردیف‌ها درون ساختارهای خودتان

پرسمان یک ردیف ها برمی‌گرداند. بعدی به ردیف بعد می‌رود و اگر ردیفی نماند نادرست برمی‌گرداند، پس تا ر.بعدی(): از همه‌ی ردیف‌ها می‌گذرد؛ درون حلقه متن، عدد صحیح، عدد صحیح۶۴ و عدد اعشار یک ستون را با شماره‌اش، از ۰، می‌خوانند. حلقه را در تابعی بگذارید که یک وکتور از ساختار خودتان پر کند تا بقیه‌ی برنامه هیچ‌وقت ردیف SQL نبیند.

db-postgres-structs.salam
واردسازی دیتابیس
واردسازی دیتابیس.پستگرس
واردسازی رشته

ساختار کتاب:
    همگانی شناسه: صحیح۶۴ = ۰
    همگانی عنوان: رشته = ""
    همگانی نویسنده: رشته = ""
    همگانی سال: صحیح = ۰
    همگانی سنت: صحیح = ۰
    همگانی موجودی: صحیح = ۰
پایان

تابع پول(سنت: صحیح): رشته:
    خرده := سنت % ۱۰۰
    اگر خرده کوچکتر ۱۰:
        برگشت رشته.از عدد(سنت / ۱۰۰) + ".0" + رشته.از عدد(خرده)
    پایان
    برگشت رشته.از عدد(سنت / ۱۰۰) + "." + رشته.از عدد(خرده)
پایان

تابع خواندن کتاب ها(پ: پستگرس.پایگاه داده، شرط: رشته): وکتور<کتاب>:
    ناپایا خروجی := وکتور {} برگردان وکتور<کتاب>
    ر := پستگرس.پرسمان(پ، "SELECT id, title, author, year, (price * 100)::int AS cents, stock FROM books " + شرط)
    دیرکن ر.بستن()
    تا ر.بعدی():
        خروجی.بیفزا(کتاب { شناسه = ر.عدد صحیح۶۴(۰)، عنوان = ر.متن(۱)، نویسنده = ر.متن(۲)، سال = ر.عدد صحیح(۳)، سنت = ر.عدد صحیح(۴)، موجودی = ر.عدد صحیح(۵) })
    پایان
    برگشت خروجی
پایان

تابع ریشه:
    پ := پستگرس.بازکردن("host=127.0.0.1 user=postgres password=secret dbname=bookshop")
    دیرکن پستگرس.بستن(پ)

    کتاب ها := خواندن کتاب ها(پ، "ORDER BY year")
    سرچاپ کتاب ها.طول()، "کتاب"
    هر ک در کتاب ها:
        سرچاپ ک.شناسه، ک.عنوان، "از"، ک.نویسنده، ک.سال، پول(ک.سنت)، "موجودی"، ک.موجودی
    پایان

    ارزان ها := خواندن کتاب ها(پ، "WHERE price < 10 ORDER BY price")
    سرچاپ "زیر ۱۰:"، ارزان ها.طول()

    ر := پستگرس.پرسمان(پ، "SELECT title, price, stock, isbn FROM books WHERE id = 3")
    دیرکن ر.بستن()
    ر.بعدی()
    تکرار ر.تعداد ستون() در ستون:
        نوع داده := ر.نوع ستون(ستون)
        ناپایا نام := "متن"
        اگر نوع داده برابر دیتابیس.نوع صحیح: نام = "صحیح" پایان
        اگر نوع داده برابر دیتابیس.نوع اعشاری: نام = "اعشاری" پایان
        سرچاپ ر.نام ستون(ستون)، "="، ر.متن(ستون)، "از نوع"، نام
    پایان
پایان
خروجی5 کتاب 3 گلستان از سعدی 656 8.25 موجودی 3 1 بوف کور از صادق هدایت 1315 12.50 موجودی 4 4 شازده کوچولو از آنتوان دو سنت‌اگزوپری 1322 6.00 موجودی 10 2 سووشون از سیمین دانشور 1348 9.99 موجودی 2 5 سمفونی مردگان از عباس معروفی 1368 11.00 موجودی 1 زیر ۱۰: 3 title = گلستان از نوع متن price = 8.25 از نوع اعشاری stock = 3 از نوع صحیح isbn = 978-9643510011 از نوع متن

قیمت‌ها به شکل سنت درست ((price * 100)::int در SQL) خوانده می‌شوند نه با عدد اعشار، چون عدد اعشاری دودویی بیشتر مبلغ‌های ده‌دهی را دقیق نگه نمی‌دارد. متن مقدار دقیق numeric را همان‌طور که سرور نوشته می‌دهد، مثل 8.25، و این هم راه امن دیگری است. نام ستون و نوع ستون ستون‌ها را توصیف می‌کنند: عددهای صحیح و منطقی‌ها دیتابیس.نوع صحیح، real و double precision و numeric دیتابیس.نوع اعشاری، bytea دیتابیس.نوع دودویی و بقیه، از جمله تاریخ، آرایه و jsonb، دیتابیس.نوع متن هستند. کار با هر ردیف ها که تمام شد آن را ببندید؛ ساده‌ترین راه دیرکن ر.بستن() درست پس از پرسمان است.

۶. مقدارهای کاربر، به شکل امن

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

db-postgres-safe.salam
واردسازی دیتابیس.پستگرس
واردسازی تبدیل
واردسازی رشته

تابع الگوی شبیه(متن: رشته): رشته:
    برگشت "%" + رشته.جایگزینی(رشته.جایگزینی(رشته.جایگزینی(متن، "\\"، "\\\\")، "%"، "\\%")، "_"، "\\_") + "%"
پایان

تابع جستجو(پ: پستگرس.پایگاه داده، واژه ها: رشته): صحیح:
    دستور := "SELECT title FROM books WHERE title ILIKE " + پستگرس.نقل قول(پ، الگوی شبیه(واژه ها)) + " ORDER BY title"
    ر := پستگرس.پرسمان(پ، دستور)
    دیرکن ر.بستن()
    سرچاپ "جستجوی"، پستگرس.نقل قول(پ، واژه ها)، "یافت:"، ر.تعداد ردیف()
    تا ر.بعدی():
        سرچاپ "  " + ر.متن(۰)
    پایان
    برگشت ر.تعداد ردیف()
پایان

تابع ریشه:
    پ := پستگرس.بازکردن("host=127.0.0.1 user=postgres password=secret dbname=bookshop")
    دیرکن پستگرس.بستن(پ)

    _ := جستجو(پ، "کو")
    _ := جستجو(پ، "x' OR '1'='1")
    _ := جستجو(پ، "'; DROP TABLE books; --")
    _ := جستجو(پ، "100%")
    سرچاپ "کتاب‌ها هنوز سر جایشان‌اند:"، پستگرس.پرسمان عدد(پ، "SELECT count(*) FROM books")

    نوشته := "3 OR 1=1"
    شناسه := تبدیل.تجزیه عدد(نوشته)
    اگر تبدیل.قالب عدد(شناسه) نابرابر نوشته:
        سرچاپ "شناسه‌ی کتاب نیست:"، نوشته
    پایان
    سرچاپ پستگرس.نقل قول(پ، `C:\books\new`)
پایان
خروجیجستجوی 'کو' یافت: 2 بوف کور شازده کوچولو جستجوی 'x'' OR ''1''=''1' یافت: 0 جستجوی '''; DROP TABLE books; --' یافت: 0 جستجوی '100%' یافت: 0 کتاب‌ها هنوز سر جایشان‌اند: 5 شناسه‌ی کتاب نیست: 3 OR 1=1 E'C:\\books\\new'

هر دو حمله فقط دنبال عنوان‌های عجیب گشتند و جدول سر جایش است. درون الگوی LIKE یا ILIKE نویسه‌های % و _ نویسه‌ی عام‌اند، برای همین جستجو اول آن‌ها را با بک‌اسلش گریز می‌دهد؛ وگرنه جستجوی 100% هر عنوانی را که با 100 شروع شود پیدا می‌کرد. اگر متن بک‌اسلش داشته باشد، نقل قول آن را به شکل E'...' پستگرس با یک فاصله در آغاز می‌نویسد که باز هم یک رشته‌ی واحد است.

ورودی خام را هرگز به نام جدول یا ستون نچسبانید. اگر کاربر ستون مرتب‌سازی را انتخاب می‌کند، انتخابش را با فهرست ثابتی از نام‌ها در برنامه مقایسه کنید و نسخه‌ی خودتان از آن نام را به کار ببرید.

۷. مقدار NULL

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

db-postgres-null.salam
واردسازی دیتابیس.پستگرس

تابع مقدار اس کیو ال(پ: پستگرس.پایگاه داده، متن: رشته): رشته:
    اگر متن برابر "":
        برگشت "NULL"
    پایان
    برگشت پستگرس.نقل قول(پ، متن)
پایان

تابع ریشه:
    پ := پستگرس.بازکردن("host=127.0.0.1 user=postgres password=secret dbname=bookshop")
    دیرکن پستگرس.بستن(پ)

    _ := پستگرس.اجرا(پ، "UPDATE books SET isbn = " + مقدار اس کیو ال(پ، "978-9645595597") + " WHERE title = 'بوف کور'")
    _ := پستگرس.اجرا(پ، "UPDATE books SET isbn = " + مقدار اس کیو ال(پ، "") + " WHERE title LIKE 'سووش%'")

    ر := پستگرس.پرسمان(پ، "SELECT title, isbn FROM books ORDER BY id")
    دیرکن ر.بستن()
    تا ر.بعدی():
        اگر ر.خالی است(۱):
            سرچاپ ر.متن(۰)، "شابک ندارد، متن می‌دهد"، "[" + ر.متن(۱) + "]"
        وگرنه:
            سرچاپ ر.متن(۰)، ر.متن(۱)
        پایان
    پایان

    سرچاپ "بی شابک:"، پستگرس.پرسمان عدد(پ، "SELECT count(*) FROM books WHERE isbn IS NULL")
    سرچاپ "= NULL می‌یابد"، پستگرس.پرسمان عدد(پ، "SELECT count(*) FROM books WHERE isbn = NULL")
    تازه ترین := پستگرس.پرسمان(پ، "SELECT max(year) FROM books WHERE year > 2100")
    دیرکن تازه ترین.بستن()
    تازه ترین.بعدی()
    سرچاپ "بیشینه روی هیچ ردیف:"، تازه ترین.عدد صحیح(۰)، تازه ترین.خالی است(۰)
    سرچاپ پستگرس.پرسمان متن(پ، "SELECT string_agg(coalesce(isbn, 'ندارد'), '، ' ORDER BY id) FROM books")
پایان
خروجیبوف کور 978-9645595597 سووشون شابک ندارد، متن می‌دهد [] گلستان 978-9643510011 شازده کوچولو 978-9643620475 سمفونی مردگان شابک ندارد، متن می‌دهد [] بی شابک: 2 = NULL می‌یابد 0 بیشینه روی هیچ ردیف: 0 true 978-9645595597، ندارد، 978-9643510011، 978-9643620475، ندارد

با IS NULL مقایسه کنید، نه با = NULL که هیچ‌وقت درست نیست. تابع‌های تجمعی مثل max و sum روی هیچ ردیفی NULL برمی‌گردانند نه صفر؛ coalesce(x, جایگزین) همان‌جا در SQL به جای NULL مقدار دیگری می‌گذارد.

۸. تراکنش

یک سفارش دو جدول را تغییر می‌دهد: موجودی کتاب کم می‌شود و ردیفی به orders افزوده می‌شود. یا هر دو باید انجام شوند یا هیچ‌کدام. شروع تراکنش تراکنشی آغاز می‌کند و یک تراکنش برمی‌گرداند که اجرا و پرسمان آن درون تراکنش اجرا می‌شوند؛ ثبت تراکنش تغییرها را نگه می‌دارد و بازگردانی دورشان می‌ریزد.

db-postgres-tx.salam
واردسازی دیتابیس.پستگرس
واردسازی رشته

تابع ثبت سفارش(پ: پستگرس.پایگاه داده، مشتری: رشته، کتاب: صحیح، تعداد: صحیح): منطقی:
    ت := پ.شروع تراکنش()
    اگر وارونه ت.معتبر():
        برگشت نادرست
    پایان
    ر := ت.پرسمان("UPDATE books SET stock = stock - " + رشته.از عدد(تعداد) + " WHERE id = " + رشته.از عدد(کتاب) + " AND stock >= " + رشته.از عدد(تعداد) + " RETURNING price * " + رشته.از عدد(تعداد))
    دیرکن ر.بستن()
    اگر وارونه ر.بعدی():
        ت.بازگردانی()
        سرچاپ مشتری، تعداد، "نسخه از کتاب " + رشته.از عدد(کتاب) + " می‌خواهد: موجودی کافی نیست، بازگردانده شد"
        برگشت نادرست
    پایان
    جمع := ر.متن(۰)
    اگر ت.اجرا("INSERT INTO orders (customer, book_id, qty, total) VALUES (" + پستگرس.نقل قول(پ، مشتری) + ", " + رشته.از عدد(کتاب) + ", " + رشته.از عدد(تعداد) + ", " + جمع + ")") نابرابر ۰:
        ت.بازگردانی()
        برگشت نادرست
    پایان
    اگر ت.ثبت تراکنش() نابرابر ۰:
        برگشت نادرست
    پایان
    سرچاپ مشتری، تعداد، "نسخه از کتاب"، کتاب، "خرید به مبلغ"، جمع
    برگشت درست
پایان

تابع ریشه:
    پ := پستگرس.بازکردن("host=127.0.0.1 user=postgres password=secret dbname=bookshop")
    دیرکن پستگرس.بستن(پ)

    _ := ثبت سفارش(پ، "سارا"، ۱، ۲)
    _ := ثبت سفارش(پ، "امید"، ۵، ۱)
    _ := ثبت سفارش(پ، "لیلا"، ۵، ۱)
    _ := ثبت سفارش(پ، "سارا"، ۴، ۳)

    سرچاپ "سفارش‌ها:"، پستگرس.پرسمان عدد(پ، "SELECT count(*) FROM orders")، "فروش:"، پستگرس.پرسمان متن(پ، "SELECT sum(total) FROM orders")
    سرچاپ "مانده‌ی بوف کور:"، پستگرس.پرسمان عدد(پ، "SELECT stock FROM books WHERE id = 1")، "مانده‌ی سمفونی مردگان:"، پستگرس.پرسمان عدد(پ، "SELECT stock FROM books WHERE id = 5")
پایان
خروجیسارا 2 نسخه از کتاب 1 خرید به مبلغ 25.00 امید 1 نسخه از کتاب 5 خرید به مبلغ 11.00 لیلا 1 نسخه از کتاب 5 می‌خواهد: موجودی کافی نیست، بازگردانده شد سارا 3 نسخه از کتاب 4 خرید به مبلغ 18.00 سفارش‌ها: 3 فروش: 54.00 مانده‌ی بوف کور: 2 مانده‌ی سمفونی مردگان: 0

دستور UPDATE ... WHERE stock >= qty RETURNING ... وارسی موجودی و برداشتن آن را در یک دستور انجام می‌دهد، پس دو مشتری که هم‌زمان آخرین نسخه را سفارش می‌دهند نمی‌توانند هر دو آن را بگیرند: دومی منتظر پایان تراکنش اولی می‌ماند و بعد می‌بیند موجودی صفر است.

همه‌ی دستورهای درون تراکنش را وارسی کنید. پس از یک دستور ناموفق، PostgreSQL بقیه‌ی تراکنش را نادیده می‌گیرد و ثبت تراکنش بعدی به جای ثبت، همه‌چیز را بازمی‌گرداند. در این حالت ثبت تراکنش مقدار ۱- برمی‌گرداند، پس ۰ از آن یعنی تغییرها واقعا ذخیره شده‌اند.

۹. خطاها

همه‌ی فراخوانی‌ها شکست را یک‌جور گزارش می‌دهند. اجرا و اجرا با شمارش ۱- برمی‌گردانند و پرسمان یک ردیف ها می‌دهد که معتبر آن نادرست است و بعدی آن بی‌درنگ نادرست برمی‌گرداند. آن‌گاه خطا پیام سرور را دارد، همراه خط DETAIL اگر باشد؛ این پیام با شروع دستور بعدی پاک می‌شود.

db-postgres-errors.salam
واردسازی دیتابیس.پستگرس
واردسازی رشته

تابع آزمودن(پ: پستگرس.پایگاه داده، دستور: رشته):
    اگر پستگرس.اجرا(پ، دستور) نابرابر ۰:
        چاپ پستگرس.خطا(پ)
    پایان
پایان

تابع ریشه:
    پ := پستگرس.بازکردن("host=127.0.0.1 user=postgres password=secret dbname=bookshop")
    دیرکن پستگرس.بستن(پ)

    آزمودن(پ، "INSERT INTO books (title, author, price) VALUES ('بوف کور', 'کسی دیگر', 5)")
    آزمودن(پ، "UPDATE books SET stock = stock - 50 WHERE id = 1")
    آزمودن(پ، "INSERT INTO orders (customer, book_id, qty, total) VALUES ('امید', 99, 1, 1)")
    آزمودن(پ، "SELEC title FROM books")

    ر := پستگرس.پرسمان(پ، "SELECT nope FROM books")
    سرچاپ "پرسمان معتبر:"، ر.معتبر()، "ردیف:"، ر.تعداد ردیف()، "بعدی:"، ر.بعدی()
    سرچاپ "اجرا با شمارش هنگام خطا:"، پستگرس.اجرا با شمارش(پ، "DELETE FROM nowhere")
    چاپ پستگرس.خطا(پ)

    ت := پ.شروع تراکنش()
    _ := ت.اجرا("UPDATE books SET price = 0 WHERE id = 1")
    _ := ت.اجرا("INSERT INTO books (title) VALUES ('بی‌نام')")
    چاپ پستگرس.خطا(پ)
    _ := ت.اجرا("UPDATE books SET price = 1 WHERE id = 2")
    چاپ پستگرس.خطا(پ)
    ت.بازگردانی()
    سرچاپ "قیمت بوف کور هنوز"، پستگرس.پرسمان متن(پ، "SELECT price FROM books WHERE id = 1")

    قطع کننده := پستگرس.بازکردن("host=127.0.0.1 user=postgres password=secret dbname=bookshop")
    دیرکن پستگرس.بستن(قطع کننده)
    فرایند := پستگرس.پرسمان عدد(پ، "SELECT pg_backend_pid()")
    _ := پستگرس.اجرا(قطع کننده، "SELECT pg_terminate_backend(" + رشته.از عدد(فرایند) + ")")
    سرچاپ "پس از قطع شدن از سوی سرور، پینگ:"، پستگرس.پینگ(پ)
    پستگرس.بازنشانی(پ)
    سرچاپ "پس از بازنشانی، پینگ:"، پستگرس.پینگ(پ)، پستگرس.پرسمان عدد(پ، "SELECT count(*) FROM books")
پایان
خروجیERROR: duplicate key value violates unique constraint "books_title_key" DETAIL: Key (title)=(بوف کور) already exists. ERROR: new row for relation "books" violates check constraint "books_stock_check" DETAIL: Failing row contains (1, بوف کور, صادق هدایت, 1315, 12.50, -48, 978-9645595597, {رمان,کلاسیک}, {}). ERROR: insert or update on table "orders" violates foreign key constraint "orders_book_id_fkey" DETAIL: Key (book_id)=(99) is not present in table "books". ERROR: syntax error at or near "SELEC" پرسمان معتبر: false ردیف: 0 بعدی: false اجرا با شمارش هنگام خطا: -1 ERROR: relation "nowhere" does not exist ERROR: null value in column "author" of relation "books" violates not-null constraint DETAIL: Failing row contains (7, بی‌نام, null, null, null, 0, null, {}, {}). ERROR: current transaction is aborted, commands ignored until end of transaction block قیمت بوف کور هنوز 12.50 پس از قطع شدن از سوی سرور، پینگ: false پس از بازنشانی، پینگ: true 5

بخش دوم قاعده‌ی تراکنش گام ۸ را در عمل نشان می‌دهد: پس از درج ناموفق، دستور بعدی با پیام current transaction is aborted رد می‌شود تا بازگردانی صدا زده شود. بخش آخر یک اتصال قطع‌شده را نشان می‌دهد که این‌جا سرور با pg_terminate_backend قطعش کرده، همان چیزی که با راه‌اندازی دوباره‌ی سرور هم پیش می‌آید. پینگ آن را می‌فهمد و بازنشانی با همان تنظیم‌ها دوباره وصل می‌شود.

پرسمان باید ردیف برگرداند. یک UPDATE یا DELETE بدون RETURNING که با پرسمان اجرا شود کارش را می‌کند، ولی ردیف های برگشتی معتبر نیست؛ برای این‌ها اجرا یا اجرا با شمارش را به کار ببرید.

۱۰. استخر اتصال، و یک اتصال برای هر نخ

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

db-postgres-pool.salam
واردسازی دیتابیس
واردسازی دیتابیس.پستگرس
واردسازی حافظه
واردسازی نخ

پایا نشانی‌پایگاه := "host=127.0.0.1 user=postgres password=secret dbname=bookshop"

ساختار کار:
    همگانی نویسنده: رشته = ""
    همگانی فروش: صحیح = ۰
پایان

تابع شمارش فروش(ک: کار*):
    پ := پستگرس.بازکردن(نشانی‌پایگاه)
    دیرکن پستگرس.بستن(پ)
    ک[۰].فروش = پستگرس.پرسمان عدد(پ، "SELECT coalesce(sum(o.qty), 0) FROM orders o JOIN books b ON b.id = o.book_id WHERE b.author = " + پستگرس.نقل قول(پ، ک[۰].نویسنده))
پایان

تابع ریشه:
    ناپایا استخر := دیتابیس.استخر جدید(۳)
    دیرکن دیتابیس.آزادکردن(استخر)
    تکرار ۳:
        _ := دیتابیس.افزودن(استخر، پستگرس.اتصال(پستگرس.بازکردن(نشانی‌پایگاه)))
    پایان
    سرچاپ "استخر:"، دیتابیس.اندازه(استخر)، "اتصال،"، دیتابیس.بیکار(استخر)، "بیکار"

    الف := دیتابیس.گرفتن(استخر)
    ب := دیتابیس.گرفتن(استخر)
    سرچاپ "دو درخواست در جریان:"، دیتابیس.در استفاده(استخر)، "در استفاده"
    سرچاپ "کتاب‌ها:"، دیتابیس.پرسمان عدد(دیتابیس.اتصال اجاره‌ای(استخر، الف)، "SELECT count(*) FROM books")، "سفارش‌ها:"، دیتابیس.پرسمان عدد(دیتابیس.اتصال اجاره‌ای(استخر، ب)، "SELECT count(*) FROM orders")
    دیتابیس.رهاکردن(استخر، الف)
    دیتابیس.رهاکردن(استخر، ب)

    ناپایا کارها := وکتور {} برگردان وکتور<کار*>
    دیرکن کارها.آزادکن()
    ناپایا گروه := وکتور {} برگردان وکتور<نخ.نخ>
    دیرکن گروه.آزادکن()
    هر نام در ["صادق هدایت"، "عباس معروفی"، "آنتوان دو سنت‌اگزوپری"، "سعدی"]:
        ک := حافظه.تخصیص(اندازه‌گونه(کار)) برگردان کار*
        ک[۰] = کار { نویسنده = نام }
        کارها.بیفزا(ک)
        گروه = نخ.جمع آوری(گروه، نخ‌ساز(شمارش فروش، ک))
    پایان
    نخ.پیوستن به همه(گروه)
    هر ک در کارها:
        سرچاپ ک[۰].نویسنده، "فروش"، ک[۰].فروش
        حافظه.آزادسازی(ک برگردان تهی*)
    پایان
پایان
خروجیاستخر: 3 اتصال، 3 بیکار دو درخواست در جریان: 2 در استفاده کتاب‌ها: 5 سفارش‌ها: 3 صادق هدایت فروش 2 عباس معروفی فروش 1 آنتوان دو سنت‌اگزوپری فروش 3 سعدی فروش 0

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

۱۱. امکانات PostgreSQL

هر کاری که PostgreSQL می‌تواند، فقط یک رشته‌ی SQL فاصله دارد. این گام چند امکان را به کار می‌برد که کد زیادی را از برنامه حذف می‌کنند: ON CONFLICT ... DO UPDATE ردیفی را می‌افزاید یا اگر از قبل باشد به‌روزش می‌کند، عملگرهای jsonb درون سند JSON را می‌خوانند و می‌گردند، unnest ستون آرایه‌ای را به ردیف تبدیل می‌کند، جستجوی متنی واژه‌ها را پیدا می‌کند و یک تابع پنجره‌ای نویسنده‌ها را بر پایه‌ی فروش رتبه می‌دهد.

db-postgres-features.salam
واردسازی دیتابیس.پستگرس

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

تابع ریشه:
    پ := پستگرس.بازکردن("host=127.0.0.1 user=postgres password=secret dbname=bookshop")
    دیرکن پستگرس.بستن(پ)

    _ := پستگرس.اجرا(پ، `INSERT INTO books (title, author, year, price, stock) VALUES
        ('بوف کور', 'صادق هدایت', 1315, 12.50, 5),
        ('شاهنامه', 'فردوسی', 384, 8.75, 4)
        ON CONFLICT (title) DO UPDATE SET stock = books.stock + EXCLUDED.stock`)
    نمایش(پ، "انبار، افزودن یا اضافه کردن:"، "SELECT title, stock FROM books WHERE title IN ('بوف کور', 'شاهنامه') ORDER BY title")

    _ := پستگرس.اجرا(پ، `UPDATE books SET info = '{"pages": 128, "publisher": "امیرکبیر", "translations": ["فرانسوی", "انگلیسی"]}' WHERE title = 'بوف کور';
        UPDATE books SET info = '{"pages": 1200, "publisher": "قطره"}', tags = '{شعر,کلاسیک}' WHERE title = 'شاهنامه'`)
    نمایش(پ، "فیلدهای jsonb:"، "SELECT title, info->>'publisher', (info->>'pages')::int FROM books WHERE info ? 'publisher' ORDER BY title")
    نمایش(پ، "ترجمه به فرانسوی:"، `SELECT title FROM books WHERE info->'translations' @> '["فرانسوی"]'`)

    نمایش(پ، "آرایه‌ها:"، "SELECT tag, count(*) FROM books, unnest(tags) AS tag GROUP BY tag ORDER BY count(*) DESC, tag")
    نمایش(پ، "جستجوی متنی:"، "SELECT title FROM books WHERE to_tsvector('simple', title) @@ plainto_tsquery('simple', 'مردگان')")
    نمایش(پ، "پرفروش‌ها:"، `SELECT b.author, sum(o.total), rank() OVER (ORDER BY sum(o.total) DESC)
        FROM orders o JOIN books b ON b.id = o.book_id GROUP BY b.author`)
پایان
خروجیانبار، افزودن یا اضافه کردن: بوف کور 7 شاهنامه 4 فیلدهای jsonb: بوف کور امیرکبیر 128 شاهنامه قطره 1200 ترجمه به فرانسوی: بوف کور آرایه‌ها: کلاسیک 4 رمان 2 شعر 2 افسانه 1 جستجوی متنی: سمفونی مردگان پرفروش‌ها: صادق هدایت 25.00 1 آنتوان دو سنت‌اگزوپری 18.00 2 عباس معروفی 11.00 3

پیکربندی simple جستجوی متنی واژه‌ها را همان‌طور که نوشته شده‌اند مقایسه می‌کند و برای متن فارسی مناسب است؛ پیکربندی english ریشه‌ی واژه‌های انگلیسی را هم می‌شناسد. هر مقدار به شکل متن و در قالب خود PostgreSQL می‌رسد: آرایه به شکل {رمان,کلاسیک}، jsonb به شکل متن JSON و منطقی به شکل t یا f (که عدد صحیح آن‌ها را ۱ و ۰ می‌خواند). وقتی نتیجه ساختار دارد، بگذارید SQL آن را به JSON بسازد و در سلام بازش کنید، همان‌طور که راهنمای JSON پایین نشان می‌دهد.

بیشتر

  • ورود انبوه: COPY FROM STDIN پشتیبانی نمی‌شود. ردیف‌های زیاد را با یک INSERT چندردیفی برای هر چند صد ردیف و درون یک تراکنش بیفزایید.
  • پرسمان عدد و پرسمان متن نخستین ستون نخستین ردیف را با یک فراخوانی می‌خوانند، برای شمارش، جمع و تنظیم‌ها.
  • کدی که روی دیتابیس.اتصال نوشته شود بدون تغییر روی اس کیو لایت و مای اس کیو ال هم اجرا می‌شود؛ دیتابیس.پرسمان عدد، دیتابیس.اجرای همه و دیتابیس.در تراکنش روی همه‌ی آن‌ها کار می‌کنند.
  • نسخه سرور نسخه‌ی اصلی ضرب در ۱۰۰۰۰ به‌علاوه‌ی نسخه‌ی فرعی را برمی‌گرداند، پس 170011 یعنی 17.11؛ برای امکانات سرورهای تازه‌تر آن را با یک عدد مقایسه کنید.
  • نتیجه‌ها کامل در حافظه نگه داشته می‌شوند. جدول خیلی بزرگ را صفحه‌به‌صفحه با ORDER BY id LIMIT 1000 و WHERE id > آخرین بخوانید.

راهنما: مهاجرت طرح‌واره

طرح‌واره‌ی یک برنامه‌ی واقعی با گذشت زمان تغییر می‌کند و همه‌ی نسخه‌های پایگاه داده باید همراهش بروند. مهاجرت گر از بسته‌ی دیتابیس گام‌های شماره‌دار نگه می‌دارد که هر کدام SQL اعمال و SQL برگرداندن دارند، و گام‌های اعمال‌شده را در جدول schema_migrations ثبت می‌کند. هر گام در تراکنش خودش اجرا می‌شود و در PostgreSQL این شامل CREATE TABLE و CREATE INDEX هم می‌شود، پس گام ناموفق هیچ تغییر نیمه‌کاره‌ای به جا نمی‌گذارد.

db-postgres-guide-migrate.salam
واردسازی دیتابیس
واردسازی دیتابیس.پستگرس

تابع ریشه:
    پ := پستگرس.بازکردن("host=127.0.0.1 user=postgres password=secret dbname=bookshop")
    دیرکن پستگرس.بستن(پ)
    ا := پستگرس.اتصال(پ)

    ناپایا م := دیتابیس.مهاجرت گر جدید()
    دیرکن دیتابیس.آزادکردن مهاجرت گر(م)
    دیتابیس.افزودن مهاجرت(م، ۱، "نقدها"، `CREATE TABLE reviews (
            id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
            book_id bigint NOT NULL REFERENCES books (id),
            stars int NOT NULL CHECK (stars BETWEEN 1 AND 5),
            body text)`، "DROP TABLE reviews")
    دیتابیس.افزودن مهاجرت(م، ۲، "نمایه‌ی مشتری سفارش‌ها"، "CREATE INDEX orders_customer ON orders (customer)"، "DROP INDEX orders_customer")

    سرچاپ "نسخه‌ی طرح‌واره"، دیتابیس.نسخه طرح‌واره(م، ا)، "در انتظار"، دیتابیس.تعداد در انتظار(م، ا)
    سرچاپ "اعمال شد:"، دیتابیس.مهاجرت به بالا(م، ا)
    سرچاپ "نسخه‌ی طرح‌واره"، دیتابیس.نسخه طرح‌واره(م، ا)، "در انتظار"، دیتابیس.تعداد در انتظار(م، ا)
    سرچاپ "اعمال شد:"، دیتابیس.مهاجرت به بالا(م، ا)، "در اجرای دوم"

    سرچاپ "بازگردانی:"، دیتابیس.بازگردانی(م، ا)، "اکنون در"، دیتابیس.نسخه طرح‌واره(م، ا)
    سرچاپ "نمایه هست:"، پستگرس.پرسمان عدد(پ، "SELECT count(*) FROM pg_indexes WHERE indexname = 'orders_customer'")
    سرچاپ "مهاجرت تا ۲:"، دیتابیس.مهاجرت به(م، ا، ۲)
    سرچاپ پستگرس.پرسمان متن(پ، "SELECT string_agg(version || ' ' || name, '، ' ORDER BY version) FROM schema_migrations")
پایان
خروجینسخه‌ی طرح‌واره 0 در انتظار 2 اعمال شد: 2 نسخه‌ی طرح‌واره 2 در انتظار 0 اعمال شد: 0 در اجرای دوم بازگردانی: true اکنون در 1 نمایه هست: 0 مهاجرت تا ۲: 1 1 نقدها، 2 نمایه‌ی مشتری سفارش‌ها

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

راهنما: تنظیم‌ها از متغیرهای محیطی

جای گذرواژه در کد نیست. بازکردن مثل libpq از متغیرهای محیطی PGHOST، PGPORT، PGUSER، PGPASSWORD، PGDATABASE، PGSSLMODE و PGSSLROOTCERT شروع می‌کند و بعد هر چه رشته‌ی اتصال تعیین کند روی آن‌ها می‌گذارد. پس بازکردن("") فقط با محیط وصل می‌شود و برنامه‌ی زیر هم با یک DATABASE_URL تنها کار می‌کند و هم با متغیرهای PG....

db-postgres-guide-env.salam
واردسازی دیتابیس.پستگرس
واردسازی سیستم عامل

تابع ریشه:
    پ := پستگرس.بازکردن(سیستم عامل.متغیر محیطی("DATABASE_URL"))
    دیرکن پستگرس.بستن(پ)
    اگر وارونه پستگرس.معتبر(پ):
        چاپ "پایگاه داده: " + پستگرس.خطا(پ)
        برگشت ۱
    پایان
    سرچاپ "پایگاه داده‌ی"، پستگرس.نام پایگاه داده(پ)، "روی"، پستگرس.نام میزبان(پ)، "با کاربر"، پستگرس.نام کاربر(پ)
    سرچاپ پستگرس.پرسمان عدد(پ، "SELECT count(*) FROM books")، "کتاب"
پایان
خروجیپایگاه داده‌ی bookshop روی 127.0.0.1 با کاربر postgres 6 کتاب

خروجی بالا از اجرای برنامه با متغیرهای PG... به دست آمد:

PGHOST=127.0.0.1 PGUSER=postgres PGPASSWORD=secret PGDATABASE=bookshop salam run app.salam
DATABASE_URL=postgresql://postgres:[email protected]:5432/bookshop salam run app.salam

اگر هیچ‌جا کاربری تعیین نشود، متغیر محیطی USER به کار می‌رود، و اگر پایگاه داده‌ای تعیین نشود، پایگاه داده‌ای هم‌نام کاربر.

راهنما: نتیجه‌ی تودرتو به شکل JSON

فهرست کتاب‌ها، هر کدام با سفارش‌هایش، یا برای هر کتاب یک پرسمان می‌خواهد یا یک پیوند (join) که ردیف‌هایش را باید با دست دوباره گروه کنید. PostgreSQL می‌تواند کل سند تودرتو را با json_agg و json_build_object در یک پرسمان بسازد و جیسون آن را مستقیم درون ساختارهای سلامی می‌خواند که نام فیلدهایشان با کلیدهای JSON یکی است. نام فیلدهای فارسی هم کار می‌کنند، به شرط آن‌که نیم‌فاصله نداشته باشند.

db-postgres-guide-json.salam
واردسازی دیتابیس.پستگرس
واردسازی کدگذاری.جیسون
واردسازی کدگذاری.خطای کدگذاری

ساختار سفارش:
    همگانی مشتری: رشته = ""
    همگانی تعداد: صحیح = ۰
پایان

ساختار کتاب:
    همگانی عنوان: رشته = ""
    همگانی قیمت: اعشار۶۴ = ۰.۰
    همگانی خریدها: وکتور<سفارش> = وکتور {}
پایان

ساختار قفسه:
    همگانی فهرست: وکتور<کتاب> = وکتور {}
پایان

تابع ریشه:
    پ := پستگرس.بازکردن("host=127.0.0.1 user=postgres password=secret dbname=bookshop")
    دیرکن پستگرس.بستن(پ)

    متن := پستگرس.پرسمان متن(پ، `SELECT json_build_object('فهرست', coalesce(json_agg(b ORDER BY b."عنوان"), '[]'))
        FROM (SELECT bk.title AS "عنوان", bk.price AS "قیمت",
                     coalesce((SELECT json_agg(json_build_object('مشتری', o.customer, 'تعداد', o.qty) ORDER BY o.id)
                               FROM orders o WHERE o.book_id = bk.id), '[]') AS "خریدها"
              FROM books bk WHERE bk.id IN (SELECT book_id FROM orders)) b`)

    ناپایا قفسه کتاب := قفسه {}
    ناپایا اشکال := خطای کدگذاری.بدون خطا()
    اگر وارونه جیسون.واسریال سازی آسان گیر(متن، قفسه کتاب، اشکال):
        سرچاپ "جیسون نادرست:"، اشکال.پیام
        برگشت ۱
    پایان
    هر ک در قفسه کتاب.فهرست:
        سرچاپ ک.عنوان، ک.قیمت، "سفارش:"، ک.خریدها.طول()
        هر س در ک.خریدها:
            سرچاپ "  " + س.مشتری، "×"، س.تعداد
        پایان
    پایان
پایان
خروجیبوف کور 12.5 سفارش: 1 سارا × 2 سمفونی مردگان 11 سفارش: 1 امید × 1 شازده کوچولو 6 سفارش: 1 سارا × 3

coalesce(..., '[]') «بدون سفارش» را به فهرست خالی تبدیل می‌کند نه NULL. همین الگو در جهت عکس هم کار می‌کند: یک سند JSON را به شکل یک رشته‌ی نقل‌قول‌شده بفرستید و روی سرور با jsonb_to_recordset بازش کنید.

راهنما: کدام تابع برای کدام کار

می‌خواهیدبه کار ببرید
وصل شویدبازکردن با جفت‌های key=value یا نشانی postgresql://، سپس معتبر
DDL یا نوشتنی را اجرا کنید که شمارش آن را لازم نداریداجرا (۰ یعنی موفق)
بدانید یک نوشتن چند ردیف را تغییر داداجرا با شمارش
شناسه‌های ساخته‌شده یا ردیف‌های تغییرکرده را پس بگیریدپرسمان با INSERT/UPDATE/DELETE ... RETURNING
ردیف‌های زیادی بخوانیدپرسمان، سپس تا ر.بعدی(): و ر.بستن()
یک عدد یا یک رشته بخوانیدپرسمان عدد، پرسمان متن
متن کاربر را در SQL بگذاریدهمیشه نقل قول
NULL را از خالی تشخیص دهیدر.خالی است(ستون)
چند تغییر را با هم یا هیچ‌کدام انجام دهیدپ.شروع تراکنش()، سپس ثبت تراکنش یا بازگردانی
پس از قطع اتصال از سوی سرور ادامه دهیدپینگ، سپس بازنشانی
کدی بنویسید که روی چند موتور کار کنداتصال و تابع‌های کمکی دیتابیس

گونه‌ها

پایگاه داده Database

ساختار پایگاه داده
یک اتصال PostgreSQL.
نامانگلیسیگونهتوضیح
دستهhandleتهی*دستگیره‌ی اتصال؛ اگر اتصالی نباشد تهی است.
تاثیرپذیرفتهaffectedصحیح۶۴ = 0شمار ردیف‌های تغییرکرده در آخرین دستور.
db-postgres-Client.salam
واردسازی دیتابیس
واردسازی دیتابیس.پستگرس

تابع ریشه:
    اگر وارونه پستگرس.در دسترس():
        سرچاپ "کلاینت پستگرس در دسترس نیست"
        برگشت
    پایان
    سرچاپ پستگرس.نسخه کلاینت()
    پ := پستگرس.بازکردن("host=127.0.0.1 port=5432 dbname=shop user=app password=s3cret")
    اگر وارونه پستگرس.معتبر(پ):
        سرچاپ پستگرس.خطا(پ)
        برگشت
    پایان
    سرچاپ پستگرس.نسخه سرور(پ)، پستگرس.نام پایگاه داده(پ)، پستگرس.نام کاربر(پ)، پستگرس.نام میزبان(پ)، پستگرس.درگاه(پ)
    سرچاپ پستگرس.پینگ(پ)
    _ := پستگرس.اجرا(پ، "CREATE TABLE IF NOT EXISTS items (id SERIAL PRIMARY KEY, name TEXT, price NUMERIC)")
    _ := پستگرس.اجرا(پ، "INSERT INTO items (name, price) VALUES (" + پستگرس.نقل قول(پ، "چای") + ", 12.5)")
    سرچاپ پستگرس.اجرا با شمارش(پ، "UPDATE items SET price = price * 1.1")

    ر := پستگرس.پرسمان(پ، "SELECT id, name, price FROM items ORDER BY id")
    سرچاپ ر.معتبر()، ر.تعداد ستون()، ر.تعداد ردیف()، ر.نام ستون(۱)
    تا ر.بعدی():
        سرچاپ ر.عدد صحیح(۰)، ر.متن(۱)، ر.عدد اعشار(۲)، ر.عدد صحیح۶۴(۰)، ر.خالی است(۲)، ر.نوع ستون(۱)
    پایان
    _ := ر.بستن()
    سرچاپ پستگرس.پرسمان عدد(پ، "SELECT COUNT(*) FROM items")، پستگرس.پرسمان متن(پ، "SELECT version()")

    ا := پستگرس.اتصال(پ)
    ت := ا.شروع تراکنش()
    _ := ت.اجرا("DELETE FROM items")
    _ := ت.بازگردانی()
    سرچاپ دیتابیس.پرسمان عدد(ا، "SELECT COUNT(*) FROM items")، پ.نوع()
    پستگرس.بازنشانی(پ)
    _ := پستگرس.بستن(پ)
    _ := پستگرس.بازکردن کامل("db.example.com"، ۵۴۳۲، "app"، "s3cret"، "shop")
پایان

نوع Kind

تابع نوع(): رشته
نام موتور پایگاه داده.

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

معتبر Ok

تابع معتبر(): منطقی
اتصال برقرار است.

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

پینگ Ping

تابع پینگ(): منطقی
اتصال زنده است.

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

اجرا Exec

تابع اجرا(sql: رشته): صحیح
SQLی را اجرا می‌کند که ردیف برنمی‌گرداند، یک یا چند دستور جداشده با نقطه‌ویرگول؛ ۰ یعنی موفق و ۱- یعنی شکست. شکل متدی، شمار ردیف‌های تغییرکرده را برای تعداد تغییرات نگه می‌دارد.

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

پرسمان Query

تابع پرسمان(sql: رشته): dyn db.ردیف ها
پرسمانی را اجرا می‌کند و ردیف‌ها را برمی‌گرداند؛ اگر شکست بخورد یا ردیفی برنگرداند، معتبر نتیجه نادرست است.

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

شروع تراکنش Begin

تابع شروع تراکنش(): dyn db.Tx
با BEGIN تراکنشی آغاز می‌کند؛ اگر این کار شکست بخورد، تراکنش معتبر نیست.

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

شناسه آخرین درج LastInsertId

تابع شناسه آخرین درج(): صحیح۶۴
آخرین مقداری که یک دنباله یا ستون شناسه در این نشست ساخته (SELECT lastval())؛ اگر نباشد ۰.

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

تعداد تغییرات Changes

تابع تعداد تغییرات(): صحیح۶۴
شمار ردیف‌هایی که آخرین اجرای صدازده روی همین مقدار تغییر داد.

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

خطا Error

تابع خطا(): رشته
آخرین پیام خطای سرور یا اتصال که با خط تازه تمام می‌شود؛ پس از دستور موفق خالی است.

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

نقل قول Quote

تابع نقل قول(s: رشته): رشته
رشته را به شکل رشته‌ی SQL نقل‌قول‌دار و گریزخورده برمی‌گرداند که چسباندنش به دستور امن است؛ اگر بک‌اسلش داشته باشد، به شکل E'...'.

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

بستن Close

تابع بستن(): صحیح
می‌بندد و آزاد می‌کند.

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

ردیف ها Rows

ساختار ردیف ها
نتیجه‌ی یک پرسمان.
نامانگلیسیگونهتوضیح
دستهhandleتهی*دستگیره‌ی نتیجه؛ اگر پرسمان شکست خورده باشد تهی است.
ردیفrowصحیح = -1شماره‌ی ردیف جاری؛ پیش از نخستین بعدی برابر ۱-.
تعدادcountصحیح = 0شمار ردیف‌ها.

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

معتبر Ok

تابع معتبر(): منطقی
پرسمان موفق بود و ردیف برگرداند.

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

بعدی Next

تابع بعدی(): منطقی
به ردیف بعدی می‌رود؛ اگر ردیفی نماند، نادرست.

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

تعداد ستون ColumnCount

تابع تعداد ستون(): صحیح
شمار ستون‌ها.

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

تعداد ردیف RowCount

تابع تعداد ردیف(): صحیح
شمار ردیف‌های نتیجه.

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

نام ستون ColumnName

تابع نام ستون(col: صحیح): رشته
نام ستون.

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

نوع ستون ColumnType

تابع نوع ستون(col: صحیح): صحیح
گونه‌ی مقدار ستون در ردیف جاری، یکی از ثابت‌های نوع ... در دیتابیس: عدد صحیح و منطقی نوع صحیح، real و double precision و numeric نوع اعشاری، bytea نوع دودویی، NULL نوع خالی و بقیه نوع متن.

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

خالی است IsNull

تابع خالی است(col: صحیح): منطقی
مقدار ستون تهی است.

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

متن Text

تابع متن(col: صحیح): رشته
مقدار ستون به شکل متن، در قالب خود PostgreSQL؛ برای NULL خالی.

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

عدد صحیح Int

تابع عدد صحیح(col: صحیح): صحیح
مقدار ستون به شکل عدد صحیح؛ t و f به شکل ۱ و ۰ و NULL به شکل ۰ خوانده می‌شوند.

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

عدد صحیح۶۴ Int64

تابع عدد صحیح۶۴(col: صحیح): صحیح۶۴
مقدار ستون به شکل عدد ۶۴ بیتی؛ t و f به شکل ۱ و ۰ و NULL به شکل ۰ خوانده می‌شوند.

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

عدد اعشار Float

تابع عدد اعشار(col: صحیح): اعشار۶۴
مقدار ستون به شکل اعشاری؛ برای NULL صفر.

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

بستن Close

تابع بستن(): صحیح
می‌بندد و آزاد می‌کند.

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

تراکنش Txn

ساختار تراکنش
یک تراکنش.
نامانگلیسیگونهتوضیح
دستهhandleتهی*اشاره‌گر اتصال.

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

معتبر Ok

تابع معتبر(): منطقی
BEGIN موفق بود.

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

اجرا Exec

تابع اجرا(sql: رشته): صحیح
دستوری را اجرا می‌کند؛ صفر یعنی موفق.

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

پرسمان Query

تابع پرسمان(sql: رشته): dyn db.ردیف ها
پرسمانی را اجرا می‌کند و ردیف‌ها را برمی‌گرداند.

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

ثبت تراکنش Commit

تابع ثبت تراکنش(): صحیح
تراکنش را ثبت می‌کند و وقتی تغییرها ذخیره شوند ۰ برمی‌گرداند. اگر ثبت شکست بخورد، یا PostgreSQL به سبب دستوری ناموفق درون تراکنش به جای ثبت همه‌چیز را بازگرداند، ۱- برمی‌گرداند.

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

بازگردانی Rollback

تابع بازگردانی(): صحیح
تراکنش را بازمی‌گرداند.

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

تابع‌ها

در دسترس Available

تابع در دسترس(): منطقی
کلاینت پستگرس در دسترس است؛ چون درون خود سلام است همیشه درست برمی‌گرداند.

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

نسخه کلاینت ClientVersion

تابع نسخه کلاینت(): صحیح
نسخه‌ی پروتکلی که این کارخواه با آن سازگار است، به شکل عدد: همیشه ۱۸۰۰۰۰.

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

نسخه سرور ServerVersion

تابع نسخه سرور(d: پایگاه داده): صحیح
نسخه‌ی سرور به شکل نسخه‌ی اصلی ضرب در ۱۰۰۰۰ به‌علاوه‌ی نسخه‌ی فرعی، مثل 170011 برای 17.11؛ بدون اتصال ۰.

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

بازکردن Open

تابع بازکردن(conninfo: رشته): پایگاه داده
با رشته‌ی اتصال، مثل host=... port=... user=... password=... dbname=...، یا نشانی postgresql:// وصل می‌شود. مقدارهای تعیین‌نشده از PGHOST، PGPORT، PGUSER، PGPASSWORD، PGDATABASE و PGSSLMODE می‌آیند. همیشه یک پایگاه داده برمی‌گرداند؛ معتبر را بپرسید.

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

بازکردن کامل OpenFull

تابع بازکردن کامل(host: رشته، port: صحیح، user: رشته، pass: رشته، dbname: رشته): پایگاه داده
با میزبان، درگاه، کاربر، گذرواژه و نام پایگاه داده وصل می‌شود. مقدارها نقل‌قول نمی‌شوند، پس برای مقدار فاصله‌دار بازکردن را به کار ببرید.

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

معتبر Ok

تابع معتبر(d: پایگاه داده): منطقی
اتصال برقرار است.

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

پینگ Ping

تابع پینگ(d: پایگاه داده): منطقی
اتصال زنده است.

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

بازنشانی Reset

تابع بازنشانی(d: پایگاه داده)
اتصال را می‌بندد و با همان تنظیم‌ها دوباره باز می‌کند، مثلا پس از آن‌که سرور قطعش کرده.

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

بستن Close

تابع بستن(d: پایگاه داده): صحیح
می‌بندد.

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

خطا Error

تابع خطا(d: پایگاه داده): رشته
آخرین پیام خطا.

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

اجرا Exec

تابع اجرا(d: پایگاه داده، sql: رشته): صحیح
SQLی را اجرا می‌کند که ردیف برنمی‌گرداند؛ ۰ یعنی موفق و ۱- یعنی شکست.

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

اجرا با شمارش ExecCount

تابع اجرا با شمارش(d: پایگاه داده، sql: رشته): صحیح۶۴
یک دستور را اجرا می‌کند و شمار ردیف‌هایی را که افزود، به‌روز یا حذف کرد برمی‌گرداند؛ در شکست ۱-.

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

پرسمان Query

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

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

نقل قول Quote

تابع نقل قول(d: پایگاه داده، s: رشته): رشته
رشته را به شکل رشته‌ی SQL نقل‌قول‌دار و گریزخورده برمی‌گرداند که چسباندنش به دستور امن است.

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

نام پایگاه داده DatabaseName

تابع نام پایگاه داده(d: پایگاه داده): رشته
نام پایگاه داده.

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

نام کاربر UserName

تابع نام کاربر(d: پایگاه داده): رشته
نام کاربر.

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

نام میزبان HostName

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

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

درگاه Port

تابع درگاه(d: پایگاه داده): رشته
درگاه، به شکل متن.

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

پرسمان عدد QueryInt

تابع پرسمان عدد(d: پایگاه داده، sql: رشته): صحیح
نخستین ستون نخستین ردیف به شکل عدد صحیح؛ اگر پرسمان شکست بخورد یا چیزی برنگرداند ۰.

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

پرسمان متن QueryText

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

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

اتصال Conn

تابع اتصال(d: پایگاه داده): dyn db.Connection
اتصال را به شکل اتصال مشترک برمی‌گرداند.

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