[{"data":1,"prerenderedAt":2876},["ShallowReactive",2],{"navigation_docs_en":3,"-en-dbx-pg":441,"-en-dbx-pg-surround":2871},[4,45,60,81,112,129,146,173,197,213,242,279,356,372,384,403,429],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":44},"Getting Started","i-lucide-rocket","\u002Fen\u002Fgetting-started","en\u002F1.getting-started",[10,15,20,24,29,34,39],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fen\u002Fgetting-started\u002Fintroduction","en\u002F1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Coming from Laravel","\u002Fen\u002Fgetting-started\u002Fcoming-from-laravel","en\u002F1.getting-started\u002F2.coming-from-laravel","i-lucide-arrow-right-left",{"title":21,"path":22,"stem":23,"icon":19},"Coming from Symfony","\u002Fen\u002Fgetting-started\u002Fcoming-from-symfony","en\u002F1.getting-started\u002F3.coming-from-symfony",{"title":25,"path":26,"stem":27,"icon":28},"Installation","\u002Fen\u002Fgetting-started\u002Finstallation","en\u002F1.getting-started\u002F4.installation","i-lucide-download",{"title":30,"path":31,"stem":32,"icon":33},"Your first module","\u002Fen\u002Fgetting-started\u002Ffirst-module","en\u002F1.getting-started\u002F5.first-module","i-lucide-package-plus",{"title":35,"path":36,"stem":37,"icon":38},"Project structure","\u002Fen\u002Fgetting-started\u002Fproject-structure","en\u002F1.getting-started\u002F6.project-structure","i-lucide-folder-tree",{"title":40,"path":41,"stem":42,"icon":43},"The shop sample application","\u002Fen\u002Fgetting-started\u002Fsample-app","en\u002F1.getting-started\u002F7.sample-app","i-lucide-shopping-cart",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"queue","i-lucide-layers","\u002Fen\u002Fqueue","en\u002F10.queue",[51,56],{"title":52,"path":53,"stem":54,"icon":55},"Overview","\u002Fen\u002Fqueue\u002Foverview","en\u002F10.queue\u002F1.overview","i-lucide-list-ordered",{"title":57,"path":58,"stem":59,"icon":47},"Tasks","\u002Fen\u002Fqueue\u002Ftasks","en\u002F10.queue\u002F2.tasks",{"title":61,"icon":62,"path":63,"stem":64,"children":65,"page":44},"events","i-lucide-workflow","\u002Fen\u002Fevents","en\u002F11.events",[66,71,76],{"title":67,"path":68,"stem":69,"icon":70},"Events","\u002Fen\u002Fevents\u002Foverview","en\u002F11.events\u002F1.overview","i-lucide-radio",{"title":72,"path":73,"stem":74,"icon":75},"Outbox","\u002Fen\u002Fevents\u002Foutbox","en\u002F11.events\u002F2.outbox","i-lucide-inbox",{"title":77,"path":78,"stem":79,"icon":80},"Scheduling","\u002Fen\u002Fevents\u002Fscheduler","en\u002F11.events\u002F3.scheduler","i-lucide-calendar-clock",{"title":82,"icon":83,"path":84,"stem":85,"children":86,"page":44},"auth","i-lucide-shield-check","\u002Fen\u002Fauth","en\u002F12.auth",[87,92,97,102,107],{"title":88,"path":89,"stem":90,"icon":91},"Authentication","\u002Fen\u002Fauth\u002Foverview","en\u002F12.auth\u002F1.overview","i-lucide-key-round",{"title":93,"path":94,"stem":95,"icon":96},"RBAC","\u002Fen\u002Fauth\u002Frbac","en\u002F12.auth\u002F2.rbac","i-lucide-users",{"title":98,"path":99,"stem":100,"icon":101},"Policies","\u002Fen\u002Fauth\u002Fpolicy","en\u002F12.auth\u002F3.policy","i-lucide-gavel",{"title":103,"path":104,"stem":105,"icon":106},"Using auth standalone","\u002Fen\u002Fauth\u002Fstandalone","en\u002F12.auth\u002F4.standalone","i-lucide-plug",{"title":108,"path":109,"stem":110,"icon":111},"Social login with goth, standalone","\u002Fen\u002Fauth\u002Fsocial-standalone","en\u002F12.auth\u002F5.social-standalone","i-lucide-log-in",{"title":113,"icon":114,"path":115,"stem":116,"children":117,"page":44},"mail","i-lucide-mail","\u002Fen\u002Fmail","en\u002F13.mail",[118,121,125],{"title":52,"path":119,"stem":120,"icon":114},"\u002Fen\u002Fmail\u002Foverview","en\u002F13.mail\u002F1.overview",{"title":122,"path":123,"stem":124,"icon":114},"SMTP","\u002Fen\u002Fmail\u002Fsmtp","en\u002F13.mail\u002F2.smtp",{"title":126,"path":127,"stem":128,"icon":114},"MJML","\u002Fen\u002Fmail\u002Fmjml","en\u002F13.mail\u002F3.mjml",{"title":130,"icon":131,"path":132,"stem":133,"children":134,"page":44},"notify","i-lucide-bell","\u002Fen\u002Fnotify","en\u002F14.notify",[135,138,142],{"title":52,"path":136,"stem":137,"icon":131},"\u002Fen\u002Fnotify\u002Foverview","en\u002F14.notify\u002F1.overview",{"title":139,"path":140,"stem":141,"icon":131},"Database channel","\u002Fen\u002Fnotify\u002Fdatabase","en\u002F14.notify\u002F2.database",{"title":143,"path":144,"stem":145,"icon":131},"Broadcast channel","\u002Fen\u002Fnotify\u002Fbroadcast","en\u002F14.notify\u002F3.broadcast",{"title":147,"icon":148,"path":149,"stem":150,"children":151,"page":44},"storage","i-lucide-hard-drive","\u002Fen\u002Fstorage","en\u002F15.storage",[152,155,159,163,168],{"title":52,"path":153,"stem":154,"icon":148},"\u002Fen\u002Fstorage\u002Foverview","en\u002F15.storage\u002F1.overview",{"title":156,"path":157,"stem":158},"Disk API","\u002Fen\u002Fstorage\u002Fdisk-api","en\u002F15.storage\u002F2.disk-api",{"title":160,"path":161,"stem":162,"icon":148},"Memory and local disk","\u002Fen\u002Fstorage\u002Flocal","en\u002F15.storage\u002F3.local",{"title":164,"path":165,"stem":166,"icon":167},"S3","\u002Fen\u002Fstorage\u002Fs3","en\u002F15.storage\u002F4.s3","i-lucide-cloud",{"title":169,"path":170,"stem":171,"icon":172},"Testing","\u002Fen\u002Fstorage\u002Ftesting","en\u002F15.storage\u002F5.testing","i-lucide-flask-conical",{"title":174,"icon":175,"path":176,"stem":177,"children":178,"page":44},"telemetry","i-lucide-activity","\u002Fen\u002Ftelemetry","en\u002F16.telemetry",[179,182,187,192],{"title":52,"path":180,"stem":181,"icon":175},"\u002Fen\u002Ftelemetry\u002Foverview","en\u002F16.telemetry\u002F1.overview",{"title":183,"path":184,"stem":185,"icon":186},"Logging","\u002Fen\u002Ftelemetry\u002Flogging","en\u002F16.telemetry\u002F2.logging","i-lucide-scroll-text",{"title":188,"path":189,"stem":190,"icon":191},"OpenTelemetry","\u002Fen\u002Ftelemetry\u002Fopentelemetry","en\u002F16.telemetry\u002F3.opentelemetry","i-lucide-radar",{"title":193,"path":194,"stem":195,"icon":196},"Sentry","\u002Fen\u002Ftelemetry\u002Fsentry","en\u002F16.telemetry\u002F4.sentry","i-lucide-bug",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":44},"Reference","i-lucide-book-open","\u002Fen\u002Freference","en\u002F17.reference",[203,208],{"title":204,"path":205,"stem":206,"icon":207},"Configuration","\u002Fen\u002Freference\u002Fconfiguration","en\u002F17.reference\u002F1.configuration","i-lucide-settings",{"title":209,"path":210,"stem":211,"icon":212},"External dependencies","\u002Fen\u002Freference\u002Fdependencies","en\u002F17.reference\u002F2.dependencies","i-lucide-package",{"title":214,"icon":215,"path":216,"stem":217,"children":218,"page":44},"Concepts","i-lucide-lightbulb","\u002Fen\u002Fconcepts","en\u002F2.concepts",[219,223,228,232,237],{"title":220,"path":221,"stem":222,"icon":47},"Architecture","\u002Fen\u002Fconcepts\u002Farchitecture","en\u002F2.concepts\u002F1.architecture",{"title":224,"path":225,"stem":226,"icon":227},"Error model","\u002Fen\u002Fconcepts\u002Ferror-model","en\u002F2.concepts\u002F2.error-model","i-lucide-shield-alert",{"title":204,"path":229,"stem":230,"icon":231},"\u002Fen\u002Fconcepts\u002Fconfiguration","en\u002F2.concepts\u002F3.configuration","i-lucide-settings-2",{"title":233,"path":234,"stem":235,"icon":236},"Codegen pipeline","\u002Fen\u002Fconcepts\u002Fcodegen-pipeline","en\u002F2.concepts\u002F4.codegen-pipeline","i-lucide-file-json",{"title":238,"path":239,"stem":240,"icon":241},"Design patterns","\u002Fen\u002Fconcepts\u002Fdesign-patterns","en\u002F2.concepts\u002F5.design-patterns","i-lucide-puzzle",{"title":243,"icon":244,"path":245,"stem":246,"children":247,"page":44},"Kit","i-lucide-box","\u002Fen\u002Fkit","en\u002F3.kit",[248,251,256,261,266,270,275],{"title":52,"path":249,"stem":250,"icon":244},"\u002Fen\u002Fkit\u002Foverview","en\u002F3.kit\u002F1.overview",{"title":252,"path":253,"stem":254,"icon":255},"Application lifecycle","\u002Fen\u002Fkit\u002Fapp","en\u002F3.kit\u002F2.app","i-lucide-power",{"title":257,"path":258,"stem":259,"icon":260},"Server","\u002Fen\u002Fkit\u002Fserver","en\u002F3.kit\u002F3.server","i-lucide-server",{"title":262,"path":263,"stem":264,"icon":265},"Worker","\u002Fen\u002Fkit\u002Fworker","en\u002F3.kit\u002F4.worker","i-lucide-cog",{"title":267,"path":268,"stem":269,"icon":70},"Realtime","\u002Fen\u002Fkit\u002Frealtime","en\u002F3.kit\u002F5.realtime",{"title":271,"path":272,"stem":273,"icon":274},"Migrations","\u002Fen\u002Fkit\u002Fmigrations","en\u002F3.kit\u002F6.migrations","i-lucide-file-stack",{"title":276,"path":277,"stem":278,"icon":111},"Social login","\u002Fen\u002Fkit\u002Fsocial-login","en\u002F3.kit\u002F7.social-login",{"title":280,"icon":281,"path":282,"stem":283,"children":284,"page":44},"CLI Reference","i-lucide-terminal","\u002Fen\u002Fcli","en\u002F4.cli",[285,288,293,298,303,308,313,318,323,328,333,337,342,347,351],{"title":52,"path":286,"stem":287,"icon":281},"\u002Fen\u002Fcli\u002Foverview","en\u002F4.cli\u002F1.overview",{"title":289,"path":290,"stem":291,"icon":292},"add db","\u002Fen\u002Fcli\u002Fadd-db","en\u002F4.cli\u002F10.add-db","i-lucide-database-zap",{"title":294,"path":295,"stem":296,"icon":297},"add compose \u002F add docker","\u002Fen\u002Fcli\u002Fadd-compose","en\u002F4.cli\u002F11.add-compose","i-lucide-container",{"title":299,"path":300,"stem":301,"icon":302},"add mail","\u002Fen\u002Fcli\u002Fadd-mail","en\u002F4.cli\u002F12.add-mail","i-lucide-mail-plus",{"title":304,"path":305,"stem":306,"icon":307},"add notification","\u002Fen\u002Fcli\u002Fadd-notification","en\u002F4.cli\u002F13.add-notification","i-lucide-bell-plus",{"title":309,"path":310,"stem":311,"icon":312},"add realtime","\u002Fen\u002Fcli\u002Fadd-realtime","en\u002F4.cli\u002F14.add-realtime","i-lucide-radio-tower",{"title":314,"path":315,"stem":316,"icon":317},"add seeder","\u002Fen\u002Fcli\u002Fadd-seeder","en\u002F4.cli\u002F15.add-seeder","i-lucide-sprout",{"title":319,"path":320,"stem":321,"icon":322},"new project","\u002Fen\u002Fcli\u002Fnew-project","en\u002F4.cli\u002F2.new-project","i-lucide-folder-plus",{"title":324,"path":325,"stem":326,"icon":327},"new module","\u002Fen\u002Fcli\u002Fnew-module","en\u002F4.cli\u002F3.new-module","i-lucide-blocks",{"title":329,"path":330,"stem":331,"icon":332},"add surface","\u002Fen\u002Fcli\u002Fadd-surface","en\u002F4.cli\u002F4.add-surface","i-lucide-layers-2",{"title":334,"path":335,"stem":336,"icon":244},"add core","\u002Fen\u002Fcli\u002Fadd-core","en\u002F4.cli\u002F5.add-core",{"title":338,"path":339,"stem":340,"icon":341},"add handler","\u002Fen\u002Fcli\u002Fadd-handler","en\u002F4.cli\u002F6.add-handler","i-lucide-webhook",{"title":343,"path":344,"stem":345,"icon":346},"new migration","\u002Fen\u002Fcli\u002Fnew-migration","en\u002F4.cli\u002F7.new-migration","i-lucide-file-plus",{"title":348,"path":349,"stem":350,"icon":265},"worker generators","\u002Fen\u002Fcli\u002Fworker-generators","en\u002F4.cli\u002F8.worker-generators",{"title":352,"path":353,"stem":354,"icon":355},"upgrade templates","\u002Fen\u002Fcli\u002Fupgrade-templates","en\u002F4.cli\u002F9.upgrade-templates","i-lucide-refresh-cw",{"title":357,"icon":227,"path":358,"stem":359,"children":360,"page":44},"errs","\u002Fen\u002Ferrs","en\u002F5.errs",[361,364,368],{"title":52,"path":362,"stem":363,"icon":227},"\u002Fen\u002Ferrs\u002Foverview","en\u002F5.errs\u002F1.overview",{"title":365,"path":366,"stem":367},"API","\u002Fen\u002Ferrs\u002Fapi","en\u002F5.errs\u002F2.api",{"title":369,"path":370,"stem":371,"icon":227},"Integration","\u002Fen\u002Ferrs\u002Fintegration","en\u002F5.errs\u002F3.integration",{"title":373,"icon":231,"path":374,"stem":375,"children":376,"page":44},"envconf","\u002Fen\u002Fenvconf","en\u002F6.envconf",[377,380],{"title":52,"path":378,"stem":379,"icon":231},"\u002Fen\u002Fenvconf\u002Foverview","en\u002F6.envconf\u002F1.overview",{"title":381,"path":382,"stem":383},"Recipes","\u002Fen\u002Fenvconf\u002Frecipes","en\u002F6.envconf\u002F2.recipes",{"title":385,"icon":386,"path":387,"stem":388,"children":389,"page":44},"httperr","i-lucide-globe","\u002Fen\u002Fhttperr","en\u002F7.httperr",[390,393,398],{"title":52,"path":391,"stem":392,"icon":386},"\u002Fen\u002Fhttperr\u002Foverview","en\u002F7.httperr\u002F1.overview",{"title":394,"path":395,"stem":396,"icon":397},"Error responses","\u002Fen\u002Fhttperr\u002Ferror-responses","en\u002F7.httperr\u002F2.error-responses","i-lucide-octagon-alert",{"title":399,"path":400,"stem":401,"icon":402},"Validation","\u002Fen\u002Fhttperr\u002Fvalidation","en\u002F7.httperr\u002F3.validation","i-lucide-badge-check",{"title":404,"icon":405,"path":406,"stem":407,"children":408,"page":44},"dbx","i-lucide-database","\u002Fen\u002Fdbx","en\u002F8.dbx",[409,412,416,420,425],{"title":52,"path":410,"stem":411,"icon":405},"\u002Fen\u002Fdbx\u002Foverview","en\u002F8.dbx\u002F1.overview",{"title":413,"path":414,"stem":415,"icon":106},"pgx","\u002Fen\u002Fdbx\u002Fpg","en\u002F8.dbx\u002F2.pg",{"title":417,"path":418,"stem":419,"icon":47},"bun","\u002Fen\u002Fdbx\u002Fbunx","en\u002F8.dbx\u002F3.bunx",{"title":421,"path":422,"stem":423,"icon":424},"Transactions","\u002Fen\u002Fdbx\u002Ftransactions","en\u002F8.dbx\u002F4.transactions","i-lucide-git-merge",{"title":426,"path":427,"stem":428,"icon":317},"Seeders","\u002Fen\u002Fdbx\u002Fseed","en\u002F8.dbx\u002F5.seed",{"title":430,"icon":55,"path":431,"stem":432,"children":433,"page":44},"paginate","\u002Fen\u002Fpaginate","en\u002F9.paginate",[434,437],{"title":52,"path":435,"stem":436,"icon":55},"\u002Fen\u002Fpaginate\u002Foverview","en\u002F9.paginate\u002F1.overview",{"title":438,"path":439,"stem":440,"icon":19},"Cursor pagination","\u002Fen\u002Fpaginate\u002Fcursor","en\u002F9.paginate\u002F2.cursor",{"id":442,"title":413,"body":443,"description":2864,"extension":2865,"links":2866,"meta":2867,"navigation":2868,"path":414,"seo":2869,"stem":415,"__hash__":2870},"docs_en\u002Fen\u002F8.dbx\u002F2.pg.md",{"type":444,"value":445,"toc":2854},"minimark",[446,485,536,554,559,641,674,681,791,807,811,973,994,1017,1021,1049,1068,1074,1078,1102,1213,1224,1845,1852,2098,2144,2148,2311,2335,2339,2342,2402,2421,2428,2432,2440,2818,2822,2850],[447,448,449,453,454,459,460,465,466,472,473,476,477,480,481,484],"p",{},[450,451,452],"code",{},"dbx\u002Fpg"," is ",[455,456,457],"a",{"href":410},[450,458,404],{},"'s default, pgx-native implementation, built on ",[455,461,413],{"href":462,"rel":463},"https:\u002F\u002Fgithub.com\u002Fjackc\u002Fpgx",[464],"nofollow",", the most widely used PostgreSQL driver in Go. It provides three things: pool construction from a ",[455,467,469],{"href":468},"\u002Fen\u002Fdbx\u002Foverview#config",[450,470,471],{},"dbx.Config",", a transaction-aware query executor (",[450,474,475],{},"DB","), and a ",[450,478,479],{},"dbx.Transactor"," implementation that carries a ",[450,482,483],{},"pgx.Tx"," in the context. It's a standalone package: nothing here requires the gpsystem kit.",[486,487,492],"pre",{"className":488,"code":489,"language":490,"meta":491,"style":491},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import (\n    \"github.com\u002Fgp-system\u002Fdbx\"\n    \"github.com\u002Fgp-system\u002Fdbx\u002Fpg\"\n)\n","go","",[450,493,494,507,520,530],{"__ignoreMap":491},[495,496,499,503],"span",{"class":497,"line":498},"line",1,[495,500,502],{"class":501},"s7zQu","import",[495,504,506],{"class":505},"sMK4o"," (\n",[495,508,510,513,517],{"class":497,"line":509},2,[495,511,512],{"class":505},"    \"",[495,514,516],{"class":515},"sBMFI","github.com\u002Fgp-system\u002Fdbx",[495,518,519],{"class":505},"\"\n",[495,521,523,525,528],{"class":497,"line":522},3,[495,524,512],{"class":505},[495,526,527],{"class":515},"github.com\u002Fgp-system\u002Fdbx\u002Fpg",[495,529,519],{"class":505},[495,531,533],{"class":497,"line":532},4,[495,534,535],{"class":505},")\n",[447,537,538,539,542,543,546,547,550,551,553],{},"There is no wrapper API: the package hands back ",[450,540,541],{},"pgxpool.Pool",", ",[450,544,545],{},"pgx.Rows"," and ",[450,548,549],{},"pgconn.CommandTag",". Whatever the pgx documentation says holds here too. ",[450,552,452],{}," only centralizes pool construction, instrumentation and the transaction plumbing.",[555,556,558],"h2",{"id":557},"pool","Pool",[486,560,562],{"className":488,"code":561,"language":490,"meta":491,"style":491},"pool, err := pg.NewPool(ctx, cfg.DB)  \u002F\u002F DSN from config, connect, ping\npool := pg.MustNewPool(ctx, cfg.DB)   \u002F\u002F same, panics on error, for main()\n",[450,563,564,610],{"__ignoreMap":491},[495,565,566,569,572,575,578,581,584,588,591,594,596,599,601,603,606],{"class":497,"line":498},[495,567,557],{"class":568},"sTEyZ",[495,570,571],{"class":505},",",[495,573,574],{"class":568}," err ",[495,576,577],{"class":505},":=",[495,579,580],{"class":568}," pg",[495,582,583],{"class":505},".",[495,585,587],{"class":586},"s2Zo4","NewPool",[495,589,590],{"class":505},"(",[495,592,593],{"class":568},"ctx",[495,595,571],{"class":505},[495,597,598],{"class":568}," cfg",[495,600,583],{"class":505},[495,602,475],{"class":568},[495,604,605],{"class":505},")",[495,607,609],{"class":608},"sHwdD","  \u002F\u002F DSN from config, connect, ping\n",[495,611,612,615,617,619,621,624,626,628,630,632,634,636,638],{"class":497,"line":509},[495,613,614],{"class":568},"pool ",[495,616,577],{"class":505},[495,618,580],{"class":568},[495,620,583],{"class":505},[495,622,623],{"class":586},"MustNewPool",[495,625,590],{"class":505},[495,627,593],{"class":568},[495,629,571],{"class":505},[495,631,598],{"class":568},[495,633,583],{"class":505},[495,635,475],{"class":568},[495,637,605],{"class":505},[495,639,640],{"class":608},"   \u002F\u002F same, panics on error, for main()\n",[447,642,643,645,646,649,650,653,654,657,658,662,663,665,666,669,670,673],{},[450,644,587],{}," parses the pool config from ",[450,647,648],{},"cfg.DB.DSN()",", sets ",[450,651,652],{},"MaxConns"," (",[450,655,656],{},"DB_MAX_CONNS",", default 10), connects, and ",[659,660,661],"strong",{},"verifies the connection with a ping",", so a wrong password or an unreachable database fails at startup, not on the first request. ",[450,664,623],{}," is the same with a ",[450,667,668],{},"panic","; the generated ",[450,671,672],{},"main.go"," files call it.",[447,675,676,677,680],{},"In a project built on the kit, the generated entry point ties the pool's shutdown into the ",[455,678,679],{"href":258},"server lifecycle",":",[486,682,684],{"className":488,"code":683,"language":490,"meta":491,"style":491},"err := server.Run(ctx, cfg.Server, register,\n    server.WithCloser(\"pgxpool\", func(context.Context) error {\n        pool.Close()\n        return nil\n    }))\n",[450,685,686,721,764,777,785],{"__ignoreMap":491},[495,687,688,691,693,696,698,701,703,705,707,709,711,713,715,718],{"class":497,"line":498},[495,689,690],{"class":568},"err ",[495,692,577],{"class":505},[495,694,695],{"class":568}," server",[495,697,583],{"class":505},[495,699,700],{"class":586},"Run",[495,702,590],{"class":505},[495,704,593],{"class":568},[495,706,571],{"class":505},[495,708,598],{"class":568},[495,710,583],{"class":505},[495,712,257],{"class":568},[495,714,571],{"class":505},[495,716,717],{"class":568}," register",[495,719,720],{"class":505},",\n",[495,722,723,726,728,731,733,736,740,742,744,747,750,752,755,757,761],{"class":497,"line":509},[495,724,725],{"class":568},"    server",[495,727,583],{"class":505},[495,729,730],{"class":586},"WithCloser",[495,732,590],{"class":505},[495,734,735],{"class":505},"\"",[495,737,739],{"class":738},"sfazB","pgxpool",[495,741,735],{"class":505},[495,743,571],{"class":505},[495,745,746],{"class":505}," func(",[495,748,749],{"class":515},"context",[495,751,583],{"class":505},[495,753,754],{"class":515},"Context",[495,756,605],{"class":505},[495,758,760],{"class":759},"spNyl"," error",[495,762,763],{"class":505}," {\n",[495,765,766,769,771,774],{"class":497,"line":522},[495,767,768],{"class":568},"        pool",[495,770,583],{"class":505},[495,772,773],{"class":586},"Close",[495,775,776],{"class":505},"()\n",[495,778,779,782],{"class":497,"line":532},[495,780,781],{"class":501},"        return",[495,783,784],{"class":505}," nil\n",[495,786,788],{"class":497,"line":787},5,[495,789,790],{"class":505},"    }))\n",[447,792,793,794,799,800,803,804,806],{},"The pool is instrumented with ",[455,795,798],{"href":796,"rel":797},"https:\u002F\u002Fgithub.com\u002Fexaring\u002Fotelpgx",[464],"otelpgx",": every query emits an OTel span carrying the statement and its timing, nested under the active request\u002Ftask span. With a no-op tracer provider (dev mode, telemetry off) this is effectively free; with telemetry on the queries show up in the ",[455,801,802],{"href":189},"trace waterfall"," and on ",[455,805,193],{"href":194}," error events.",[555,808,810],{"id":809},"dbtx-the-query-surface-repositories-depend-on","DBTX: the query surface repositories depend on",[486,812,814],{"className":488,"code":813,"language":490,"meta":491,"style":491},"type DBTX interface {\n    Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error)\n    Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error)\n    QueryRow(ctx context.Context, sql string, args ...any) pgx.Row\n}\n",[450,815,816,829,883,929,968],{"__ignoreMap":491},[495,817,818,821,824,827],{"class":497,"line":498},[495,819,820],{"class":505},"type",[495,822,823],{"class":515}," DBTX",[495,825,826],{"class":505}," interface",[495,828,763],{"class":505},[495,830,831,834,836,839,842,844,846,848,851,854,856,859,862,865,867,869,872,874,877,879,881],{"class":497,"line":509},[495,832,833],{"class":586},"    Exec",[495,835,590],{"class":505},[495,837,593],{"class":838},"sHdIc",[495,840,841],{"class":515}," context",[495,843,583],{"class":505},[495,845,754],{"class":515},[495,847,571],{"class":505},[495,849,850],{"class":838}," sql",[495,852,853],{"class":759}," string",[495,855,571],{"class":505},[495,857,858],{"class":838}," args",[495,860,861],{"class":505}," ...",[495,863,864],{"class":515},"any",[495,866,605],{"class":505},[495,868,653],{"class":505},[495,870,871],{"class":515},"pgconn",[495,873,583],{"class":505},[495,875,876],{"class":515},"CommandTag",[495,878,571],{"class":505},[495,880,760],{"class":759},[495,882,535],{"class":505},[495,884,885,888,890,892,894,896,898,900,902,904,906,908,910,912,914,916,918,920,923,925,927],{"class":497,"line":522},[495,886,887],{"class":586},"    Query",[495,889,590],{"class":505},[495,891,593],{"class":838},[495,893,841],{"class":515},[495,895,583],{"class":505},[495,897,754],{"class":515},[495,899,571],{"class":505},[495,901,850],{"class":838},[495,903,853],{"class":759},[495,905,571],{"class":505},[495,907,858],{"class":838},[495,909,861],{"class":505},[495,911,864],{"class":515},[495,913,605],{"class":505},[495,915,653],{"class":505},[495,917,413],{"class":515},[495,919,583],{"class":505},[495,921,922],{"class":515},"Rows",[495,924,571],{"class":505},[495,926,760],{"class":759},[495,928,535],{"class":505},[495,930,931,934,936,938,940,942,944,946,948,950,952,954,956,958,960,963,965],{"class":497,"line":532},[495,932,933],{"class":586},"    QueryRow",[495,935,590],{"class":505},[495,937,593],{"class":838},[495,939,841],{"class":515},[495,941,583],{"class":505},[495,943,754],{"class":515},[495,945,571],{"class":505},[495,947,850],{"class":838},[495,949,853],{"class":759},[495,951,571],{"class":505},[495,953,858],{"class":838},[495,955,861],{"class":505},[495,957,864],{"class":515},[495,959,605],{"class":505},[495,961,962],{"class":515}," pgx",[495,964,583],{"class":505},[495,966,967],{"class":515},"Row\n",[495,969,970],{"class":497,"line":787},[495,971,972],{"class":505},"}\n",[447,974,975,976,653,979,542,981,542,983,986,987,542,990,993],{},"Every repository depends on these three methods. The return types are ",[659,977,978],{},"deliberately raw pgx types",[450,980,549],{},[450,982,545],{},[450,984,985],{},"pgx.Row","), not kit wrappers: scanning, ",[450,988,989],{},"CollectRows",[450,991,992],{},"RowsAffected()"," work exactly as the pgx documentation describes.",[447,995,996,999,1000,1003,1004,1006,1007,1012,1013,1016],{},[450,997,998],{},"DBTX"," is also ",[659,1001,1002],{},"method-for-method identical"," to the ",[450,1005,998],{}," interface ",[455,1008,1011],{"href":1009,"rel":1010},"https:\u002F\u002Fsqlc.dev",[464],"sqlc"," generates. The kit's generators scaffold hand-written repositories, but if a project generated its query code with sqlc, those structs accept ",[450,1014,1015],{},"pg.NewDB(pool)"," unchanged, and participate in the same context-carried transactions.",[555,1018,1020],{"id":1019},"db-the-executor-that-watches-the-context","DB: the executor that watches the context",[486,1022,1024],{"className":488,"code":1023,"language":490,"meta":491,"style":491},"db := pg.NewDB(pool) \u002F\u002F implements DBTX\n",[450,1025,1026],{"__ignoreMap":491},[495,1027,1028,1031,1033,1035,1037,1040,1042,1044,1046],{"class":497,"line":498},[495,1029,1030],{"class":568},"db ",[495,1032,577],{"class":505},[495,1034,580],{"class":568},[495,1036,583],{"class":505},[495,1038,1039],{"class":586},"NewDB",[495,1041,590],{"class":505},[495,1043,557],{"class":568},[495,1045,605],{"class":505},[495,1047,1048],{"class":608}," \u002F\u002F implements DBTX\n",[447,1050,1051,1054,1055,1057,1058,1061,1062,1067],{},[450,1052,1053],{},"pg.DB"," is the kit's single implementation of ",[450,1056,998],{},", and it has exactly one trick: ",[659,1059,1060],{},"every call first looks for a transaction in the context",". If ",[455,1063,1064],{"href":422},[450,1065,1066],{},"WithinTransaction"," opened one, the call runs on it; if not, on the pool. The repository never knows, and never needs to know, which case it is.",[447,1069,1070,1071,1073],{},"This is where the kit's transaction model comes together: the service calls ",[450,1072,1066],{},", and the repositories join automatically, with unchanged signatures.",[555,1075,1077],{"id":1076},"a-shop-repository","A shop repository",[447,1079,1080,1081,1084,1085,1088,1089,1092,1093,1095,1096,1098,1099,680],{},"The ",[455,1082,1083],{"href":41},"shop sample app","'s module-level product repository (",[450,1086,1087],{},"internal\u002Fmodules\u002Fshop\u002Frepository\u002F",", shared by every surface). The repository holds a single ",[450,1090,1091],{},"pg.DBTX"," field. ",[450,1094,672],{}," injects ",[450,1097,1015],{}," through ",[450,1100,1101],{},"Dependencies",[486,1103,1105],{"className":488,"code":1104,"language":490,"meta":491,"style":491},"package repository\n\ntype ProductRepository struct {\n    db pg.DBTX\n}\n\nfunc NewProductRepository(db pg.DBTX) *ProductRepository {\n    return &ProductRepository{db: db}\n}\n",[450,1106,1107,1115,1121,1133,1146,1150,1155,1185,1208],{"__ignoreMap":491},[495,1108,1109,1112],{"class":497,"line":498},[495,1110,1111],{"class":505},"package",[495,1113,1114],{"class":515}," repository\n",[495,1116,1117],{"class":497,"line":509},[495,1118,1120],{"emptyLinePlaceholder":1119},true,"\n",[495,1122,1123,1125,1128,1131],{"class":497,"line":522},[495,1124,820],{"class":505},[495,1126,1127],{"class":515}," ProductRepository",[495,1129,1130],{"class":505}," struct",[495,1132,763],{"class":505},[495,1134,1135,1138,1141,1143],{"class":497,"line":532},[495,1136,1137],{"class":568},"    db ",[495,1139,1140],{"class":515},"pg",[495,1142,583],{"class":505},[495,1144,1145],{"class":515},"DBTX\n",[495,1147,1148],{"class":497,"line":787},[495,1149,972],{"class":505},[495,1151,1153],{"class":497,"line":1152},6,[495,1154,1120],{"emptyLinePlaceholder":1119},[495,1156,1158,1161,1164,1166,1169,1171,1173,1175,1177,1180,1183],{"class":497,"line":1157},7,[495,1159,1160],{"class":505},"func",[495,1162,1163],{"class":586}," NewProductRepository",[495,1165,590],{"class":505},[495,1167,1168],{"class":838},"db",[495,1170,580],{"class":515},[495,1172,583],{"class":505},[495,1174,998],{"class":515},[495,1176,605],{"class":505},[495,1178,1179],{"class":505}," *",[495,1181,1182],{"class":515},"ProductRepository",[495,1184,763],{"class":505},[495,1186,1188,1191,1194,1196,1199,1201,1203,1206],{"class":497,"line":1187},8,[495,1189,1190],{"class":501},"    return",[495,1192,1193],{"class":505}," &",[495,1195,1182],{"class":515},[495,1197,1198],{"class":505},"{",[495,1200,1168],{"class":568},[495,1202,680],{"class":505},[495,1204,1205],{"class":568}," db",[495,1207,972],{"class":505},[495,1209,1211],{"class":497,"line":1210},9,[495,1212,972],{"class":505},[447,1214,1215,1216,1219,1220,1223],{},"Listing products with ",[455,1217,1218],{"href":439},"cursor pagination"," (a keyset seek, not ",[450,1221,1222],{},"OFFSET","):",[486,1225,1227],{"className":488,"code":1226,"language":490,"meta":491,"style":491},"const productSort = \"created_at DESC, id DESC\" \u002F\u002F matches the ORDER BY below\n\nfunc (r *ProductRepository) ListProducts(\n    ctx context.Context, p paginate.CursorParams,\n) (paginate.CursorPage[Product], error) {\n    args := []any{p.FetchLimit()}\n    query := `SELECT id, name, price_cents, stock, created_at FROM products`\n    if p.HasCursor() {\n        var createdAt time.Time\n        var id int64\n        if err := p.DecodeKey(&createdAt, &id); err != nil {\n            return paginate.CursorPage[Product]{}, err\n        }\n        query += ` WHERE (created_at, id) \u003C ($2, $3)`\n        args = append(args, createdAt, id)\n    }\n    query += ` ORDER BY ` + productSort + ` LIMIT $1`\n\n    rows, err := r.db.Query(ctx, query, args...)\n    if err != nil {\n        return paginate.CursorPage[Product]{}, errs.Wrap(err, \"products: list\")\n    }\n    products, err := pgx.CollectRows(rows, pgx.RowToStructByName[Product])\n    if err != nil {\n        return paginate.CursorPage[Product]{}, errs.Wrap(err, \"products: scan\")\n    }\n    return paginate.NewCursorPage(products, p, func(last Product) []any {\n        return []any{last.CreatedAt, last.ID}\n    })\n}\n",[450,1228,1229,1251,1255,1277,1303,1331,1355,1371,1388,1404,1415,1458,1480,1486,1502,1530,1536,1566,1571,1611,1624,1665,1670,1709,1722,1760,1765,1804,1834,1840],{"__ignoreMap":491},[495,1230,1231,1234,1237,1240,1243,1246,1248],{"class":497,"line":498},[495,1232,1233],{"class":505},"const",[495,1235,1236],{"class":568}," productSort ",[495,1238,1239],{"class":505},"=",[495,1241,1242],{"class":505}," \"",[495,1244,1245],{"class":738},"created_at DESC, id DESC",[495,1247,735],{"class":505},[495,1249,1250],{"class":608}," \u002F\u002F matches the ORDER BY below\n",[495,1252,1253],{"class":497,"line":509},[495,1254,1120],{"emptyLinePlaceholder":1119},[495,1256,1257,1259,1261,1264,1267,1269,1271,1274],{"class":497,"line":522},[495,1258,1160],{"class":505},[495,1260,653],{"class":505},[495,1262,1263],{"class":838},"r ",[495,1265,1266],{"class":505},"*",[495,1268,1182],{"class":515},[495,1270,605],{"class":505},[495,1272,1273],{"class":586}," ListProducts",[495,1275,1276],{"class":505},"(\n",[495,1278,1279,1282,1284,1286,1288,1290,1293,1296,1298,1301],{"class":497,"line":532},[495,1280,1281],{"class":838},"    ctx",[495,1283,841],{"class":515},[495,1285,583],{"class":505},[495,1287,754],{"class":515},[495,1289,571],{"class":505},[495,1291,1292],{"class":838}," p",[495,1294,1295],{"class":515}," paginate",[495,1297,583],{"class":505},[495,1299,1300],{"class":515},"CursorParams",[495,1302,720],{"class":505},[495,1304,1305,1307,1309,1311,1313,1316,1319,1322,1325,1327,1329],{"class":497,"line":787},[495,1306,605],{"class":505},[495,1308,653],{"class":505},[495,1310,430],{"class":515},[495,1312,583],{"class":505},[495,1314,1315],{"class":515},"CursorPage",[495,1317,1318],{"class":505},"[",[495,1320,1321],{"class":515},"Product",[495,1323,1324],{"class":505},"],",[495,1326,760],{"class":759},[495,1328,605],{"class":505},[495,1330,763],{"class":505},[495,1332,1333,1336,1338,1341,1343,1345,1347,1349,1352],{"class":497,"line":1152},[495,1334,1335],{"class":568},"    args ",[495,1337,577],{"class":505},[495,1339,1340],{"class":505}," []",[495,1342,864],{"class":515},[495,1344,1198],{"class":505},[495,1346,447],{"class":568},[495,1348,583],{"class":505},[495,1350,1351],{"class":586},"FetchLimit",[495,1353,1354],{"class":505},"()}\n",[495,1356,1357,1360,1362,1365,1368],{"class":497,"line":1157},[495,1358,1359],{"class":568},"    query ",[495,1361,577],{"class":505},[495,1363,1364],{"class":505}," `",[495,1366,1367],{"class":738},"SELECT id, name, price_cents, stock, created_at FROM products",[495,1369,1370],{"class":505},"`\n",[495,1372,1373,1376,1378,1380,1383,1386],{"class":497,"line":1187},[495,1374,1375],{"class":501},"    if",[495,1377,1292],{"class":568},[495,1379,583],{"class":505},[495,1381,1382],{"class":586},"HasCursor",[495,1384,1385],{"class":505},"()",[495,1387,763],{"class":505},[495,1389,1390,1393,1396,1399,1401],{"class":497,"line":1210},[495,1391,1392],{"class":505},"        var",[495,1394,1395],{"class":568}," createdAt ",[495,1397,1398],{"class":515},"time",[495,1400,583],{"class":505},[495,1402,1403],{"class":515},"Time\n",[495,1405,1407,1409,1412],{"class":497,"line":1406},10,[495,1408,1392],{"class":505},[495,1410,1411],{"class":568}," id ",[495,1413,1414],{"class":759},"int64\n",[495,1416,1418,1421,1423,1425,1427,1429,1432,1435,1438,1440,1442,1445,1448,1450,1453,1456],{"class":497,"line":1417},11,[495,1419,1420],{"class":501},"        if",[495,1422,574],{"class":568},[495,1424,577],{"class":505},[495,1426,1292],{"class":568},[495,1428,583],{"class":505},[495,1430,1431],{"class":586},"DecodeKey",[495,1433,1434],{"class":505},"(&",[495,1436,1437],{"class":568},"createdAt",[495,1439,571],{"class":505},[495,1441,1193],{"class":505},[495,1443,1444],{"class":568},"id",[495,1446,1447],{"class":505},");",[495,1449,574],{"class":568},[495,1451,1452],{"class":505},"!=",[495,1454,1455],{"class":505}," nil",[495,1457,763],{"class":505},[495,1459,1461,1464,1466,1468,1470,1472,1474,1477],{"class":497,"line":1460},12,[495,1462,1463],{"class":501},"            return",[495,1465,1295],{"class":515},[495,1467,583],{"class":505},[495,1469,1315],{"class":515},[495,1471,1318],{"class":505},[495,1473,1321],{"class":515},[495,1475,1476],{"class":505},"]{},",[495,1478,1479],{"class":568}," err\n",[495,1481,1483],{"class":497,"line":1482},13,[495,1484,1485],{"class":505},"        }\n",[495,1487,1489,1492,1495,1497,1500],{"class":497,"line":1488},14,[495,1490,1491],{"class":568},"        query ",[495,1493,1494],{"class":505},"+=",[495,1496,1364],{"class":505},[495,1498,1499],{"class":738}," WHERE (created_at, id) \u003C ($2, $3)",[495,1501,1370],{"class":505},[495,1503,1505,1508,1510,1513,1515,1518,1520,1523,1525,1528],{"class":497,"line":1504},15,[495,1506,1507],{"class":568},"        args ",[495,1509,1239],{"class":505},[495,1511,1512],{"class":586}," append",[495,1514,590],{"class":505},[495,1516,1517],{"class":568},"args",[495,1519,571],{"class":505},[495,1521,1522],{"class":568}," createdAt",[495,1524,571],{"class":505},[495,1526,1527],{"class":568}," id",[495,1529,535],{"class":505},[495,1531,1533],{"class":497,"line":1532},16,[495,1534,1535],{"class":505},"    }\n",[495,1537,1539,1541,1543,1545,1548,1551,1554,1556,1559,1561,1564],{"class":497,"line":1538},17,[495,1540,1359],{"class":568},[495,1542,1494],{"class":505},[495,1544,1364],{"class":505},[495,1546,1547],{"class":738}," ORDER BY ",[495,1549,1550],{"class":505},"`",[495,1552,1553],{"class":505}," +",[495,1555,1236],{"class":568},[495,1557,1558],{"class":505},"+",[495,1560,1364],{"class":505},[495,1562,1563],{"class":738}," LIMIT $1",[495,1565,1370],{"class":505},[495,1567,1569],{"class":497,"line":1568},18,[495,1570,1120],{"emptyLinePlaceholder":1119},[495,1572,1574,1577,1579,1581,1583,1586,1588,1590,1592,1595,1597,1599,1601,1604,1606,1608],{"class":497,"line":1573},19,[495,1575,1576],{"class":568},"    rows",[495,1578,571],{"class":505},[495,1580,574],{"class":568},[495,1582,577],{"class":505},[495,1584,1585],{"class":568}," r",[495,1587,583],{"class":505},[495,1589,1168],{"class":568},[495,1591,583],{"class":505},[495,1593,1594],{"class":586},"Query",[495,1596,590],{"class":505},[495,1598,593],{"class":568},[495,1600,571],{"class":505},[495,1602,1603],{"class":568}," query",[495,1605,571],{"class":505},[495,1607,858],{"class":568},[495,1609,1610],{"class":505},"...)\n",[495,1612,1614,1616,1618,1620,1622],{"class":497,"line":1613},20,[495,1615,1375],{"class":501},[495,1617,574],{"class":568},[495,1619,1452],{"class":505},[495,1621,1455],{"class":505},[495,1623,763],{"class":505},[495,1625,1627,1629,1631,1633,1635,1637,1639,1641,1644,1646,1649,1651,1654,1656,1658,1661,1663],{"class":497,"line":1626},21,[495,1628,781],{"class":501},[495,1630,1295],{"class":515},[495,1632,583],{"class":505},[495,1634,1315],{"class":515},[495,1636,1318],{"class":505},[495,1638,1321],{"class":515},[495,1640,1476],{"class":505},[495,1642,1643],{"class":568}," errs",[495,1645,583],{"class":505},[495,1647,1648],{"class":586},"Wrap",[495,1650,590],{"class":505},[495,1652,1653],{"class":568},"err",[495,1655,571],{"class":505},[495,1657,1242],{"class":505},[495,1659,1660],{"class":738},"products: list",[495,1662,735],{"class":505},[495,1664,535],{"class":505},[495,1666,1668],{"class":497,"line":1667},22,[495,1669,1535],{"class":505},[495,1671,1673,1676,1678,1680,1682,1684,1686,1688,1690,1693,1695,1697,1699,1702,1704,1706],{"class":497,"line":1672},23,[495,1674,1675],{"class":568},"    products",[495,1677,571],{"class":505},[495,1679,574],{"class":568},[495,1681,577],{"class":505},[495,1683,962],{"class":568},[495,1685,583],{"class":505},[495,1687,989],{"class":586},[495,1689,590],{"class":505},[495,1691,1692],{"class":568},"rows",[495,1694,571],{"class":505},[495,1696,962],{"class":568},[495,1698,583],{"class":505},[495,1700,1701],{"class":568},"RowToStructByName",[495,1703,1318],{"class":505},[495,1705,1321],{"class":568},[495,1707,1708],{"class":505},"])\n",[495,1710,1712,1714,1716,1718,1720],{"class":497,"line":1711},24,[495,1713,1375],{"class":501},[495,1715,574],{"class":568},[495,1717,1452],{"class":505},[495,1719,1455],{"class":505},[495,1721,763],{"class":505},[495,1723,1725,1727,1729,1731,1733,1735,1737,1739,1741,1743,1745,1747,1749,1751,1753,1756,1758],{"class":497,"line":1724},25,[495,1726,781],{"class":501},[495,1728,1295],{"class":515},[495,1730,583],{"class":505},[495,1732,1315],{"class":515},[495,1734,1318],{"class":505},[495,1736,1321],{"class":515},[495,1738,1476],{"class":505},[495,1740,1643],{"class":568},[495,1742,583],{"class":505},[495,1744,1648],{"class":586},[495,1746,590],{"class":505},[495,1748,1653],{"class":568},[495,1750,571],{"class":505},[495,1752,1242],{"class":505},[495,1754,1755],{"class":738},"products: scan",[495,1757,735],{"class":505},[495,1759,535],{"class":505},[495,1761,1763],{"class":497,"line":1762},26,[495,1764,1535],{"class":505},[495,1766,1768,1770,1772,1774,1777,1779,1782,1784,1786,1788,1790,1793,1796,1798,1800,1802],{"class":497,"line":1767},27,[495,1769,1190],{"class":501},[495,1771,1295],{"class":568},[495,1773,583],{"class":505},[495,1775,1776],{"class":586},"NewCursorPage",[495,1778,590],{"class":505},[495,1780,1781],{"class":568},"products",[495,1783,571],{"class":505},[495,1785,1292],{"class":568},[495,1787,571],{"class":505},[495,1789,746],{"class":505},[495,1791,1792],{"class":838},"last",[495,1794,1795],{"class":515}," Product",[495,1797,605],{"class":505},[495,1799,1340],{"class":505},[495,1801,864],{"class":515},[495,1803,763],{"class":505},[495,1805,1807,1809,1811,1813,1815,1817,1819,1822,1824,1827,1829,1832],{"class":497,"line":1806},28,[495,1808,781],{"class":501},[495,1810,1340],{"class":505},[495,1812,864],{"class":515},[495,1814,1198],{"class":505},[495,1816,1792],{"class":568},[495,1818,583],{"class":505},[495,1820,1821],{"class":568},"CreatedAt",[495,1823,571],{"class":505},[495,1825,1826],{"class":568}," last",[495,1828,583],{"class":505},[495,1830,1831],{"class":568},"ID",[495,1833,972],{"class":505},[495,1835,1837],{"class":497,"line":1836},29,[495,1838,1839],{"class":505},"    })\n",[495,1841,1843],{"class":497,"line":1842},30,[495,1844,972],{"class":505},[447,1846,1847,1848,1851],{},"And the stock decrement the service calls from the ",[450,1849,1850],{},"PlaceOrder"," transaction:",[486,1853,1855],{"className":488,"code":1854,"language":490,"meta":491,"style":491},"func (r *ProductRepository) DecrementStock(ctx context.Context, productID int64, qty int) error {\n    tag, err := r.db.Exec(ctx,\n        `UPDATE products SET stock = stock - $2 WHERE id = $1 AND stock >= $2`,\n        productID, qty)\n    if err != nil {\n        return errs.Wrap(err, \"products: decrement stock\")\n    }\n    if tag.RowsAffected() == 0 {\n        return errs.New(\"insufficient stock\",\n            errs.Code(\"insufficient_stock\"), errs.Public(\"The product is out of stock.\"))\n    }\n    return nil\n}\n",[450,1856,1857,1906,1934,1946,1957,1969,1994,1998,2021,2043,2084,2088,2094],{"__ignoreMap":491},[495,1858,1859,1861,1863,1865,1867,1869,1871,1874,1876,1878,1880,1882,1884,1886,1889,1892,1894,1897,1900,1902,1904],{"class":497,"line":498},[495,1860,1160],{"class":505},[495,1862,653],{"class":505},[495,1864,1263],{"class":838},[495,1866,1266],{"class":505},[495,1868,1182],{"class":515},[495,1870,605],{"class":505},[495,1872,1873],{"class":586}," DecrementStock",[495,1875,590],{"class":505},[495,1877,593],{"class":838},[495,1879,841],{"class":515},[495,1881,583],{"class":505},[495,1883,754],{"class":515},[495,1885,571],{"class":505},[495,1887,1888],{"class":838}," productID",[495,1890,1891],{"class":759}," int64",[495,1893,571],{"class":505},[495,1895,1896],{"class":838}," qty",[495,1898,1899],{"class":759}," int",[495,1901,605],{"class":505},[495,1903,760],{"class":759},[495,1905,763],{"class":505},[495,1907,1908,1911,1913,1915,1917,1919,1921,1923,1925,1928,1930,1932],{"class":497,"line":509},[495,1909,1910],{"class":568},"    tag",[495,1912,571],{"class":505},[495,1914,574],{"class":568},[495,1916,577],{"class":505},[495,1918,1585],{"class":568},[495,1920,583],{"class":505},[495,1922,1168],{"class":568},[495,1924,583],{"class":505},[495,1926,1927],{"class":586},"Exec",[495,1929,590],{"class":505},[495,1931,593],{"class":568},[495,1933,720],{"class":505},[495,1935,1936,1939,1942,1944],{"class":497,"line":522},[495,1937,1938],{"class":505},"        `",[495,1940,1941],{"class":738},"UPDATE products SET stock = stock - $2 WHERE id = $1 AND stock >= $2",[495,1943,1550],{"class":505},[495,1945,720],{"class":505},[495,1947,1948,1951,1953,1955],{"class":497,"line":532},[495,1949,1950],{"class":568},"        productID",[495,1952,571],{"class":505},[495,1954,1896],{"class":568},[495,1956,535],{"class":505},[495,1958,1959,1961,1963,1965,1967],{"class":497,"line":787},[495,1960,1375],{"class":501},[495,1962,574],{"class":568},[495,1964,1452],{"class":505},[495,1966,1455],{"class":505},[495,1968,763],{"class":505},[495,1970,1971,1973,1975,1977,1979,1981,1983,1985,1987,1990,1992],{"class":497,"line":1152},[495,1972,781],{"class":501},[495,1974,1643],{"class":568},[495,1976,583],{"class":505},[495,1978,1648],{"class":586},[495,1980,590],{"class":505},[495,1982,1653],{"class":568},[495,1984,571],{"class":505},[495,1986,1242],{"class":505},[495,1988,1989],{"class":738},"products: decrement stock",[495,1991,735],{"class":505},[495,1993,535],{"class":505},[495,1995,1996],{"class":497,"line":1157},[495,1997,1535],{"class":505},[495,1999,2000,2002,2005,2007,2010,2012,2015,2019],{"class":497,"line":1187},[495,2001,1375],{"class":501},[495,2003,2004],{"class":568}," tag",[495,2006,583],{"class":505},[495,2008,2009],{"class":586},"RowsAffected",[495,2011,1385],{"class":505},[495,2013,2014],{"class":505}," ==",[495,2016,2018],{"class":2017},"sbssI"," 0",[495,2020,763],{"class":505},[495,2022,2023,2025,2027,2029,2032,2034,2036,2039,2041],{"class":497,"line":1210},[495,2024,781],{"class":501},[495,2026,1643],{"class":568},[495,2028,583],{"class":505},[495,2030,2031],{"class":586},"New",[495,2033,590],{"class":505},[495,2035,735],{"class":505},[495,2037,2038],{"class":738},"insufficient stock",[495,2040,735],{"class":505},[495,2042,720],{"class":505},[495,2044,2045,2048,2050,2053,2055,2057,2060,2062,2065,2067,2069,2072,2074,2076,2079,2081],{"class":497,"line":1406},[495,2046,2047],{"class":568},"            errs",[495,2049,583],{"class":505},[495,2051,2052],{"class":586},"Code",[495,2054,590],{"class":505},[495,2056,735],{"class":505},[495,2058,2059],{"class":738},"insufficient_stock",[495,2061,735],{"class":505},[495,2063,2064],{"class":505},"),",[495,2066,1643],{"class":568},[495,2068,583],{"class":505},[495,2070,2071],{"class":586},"Public",[495,2073,590],{"class":505},[495,2075,735],{"class":505},[495,2077,2078],{"class":738},"The product is out of stock.",[495,2080,735],{"class":505},[495,2082,2083],{"class":505},"))\n",[495,2085,2086],{"class":497,"line":1417},[495,2087,1535],{"class":505},[495,2089,2090,2092],{"class":497,"line":1460},[495,2091,1190],{"class":501},[495,2093,784],{"class":505},[495,2095,2096],{"class":497,"line":1482},[495,2097,972],{"class":505},[447,2099,2100,2101,2104,2105,2108,2109,2112,2113,2119,2120,2122,2123,2126,2127,2129,2130,2126,2133,2135,2136,2139,2140,2143],{},"Notice what is ",[659,2102,2103],{},"not"," in the code: a transaction parameter. ",[450,2106,2107],{},"ListProducts"," runs on the pool when called from the public listing endpoint; ",[450,2110,2111],{},"DecrementStock",", called ",[455,2114,2115,2116,2118],{"href":422},"inside the ",[450,2117,1850],{}," transaction",", joins the same ",[450,2121,483],{},", both with the same signature. ",[450,2124,2125],{},"pgx.CollectRows"," + ",[450,2128,1701],{}," is pgx's built-in scanning; the ",[450,2131,2132],{},"WHERE ... AND stock >= $2",[450,2134,992],{}," pair is the atomic stock check, with no ",[450,2137,2138],{},"SELECT","-then-",[450,2141,2142],{},"UPDATE"," race.",[555,2145,2147],{"id":2146},"transactor","Transactor",[486,2149,2151],{"className":488,"code":2150,"language":490,"meta":491,"style":491},"tx := pg.NewTransactor(pool) \u002F\u002F dbx.Transactor\n\nerr := tx.WithinTransaction(ctx, func(ctx context.Context) error {\n    if err := s.orders.Insert(ctx, o); err != nil {\n        return err\n    }\n    return s.products.DecrementStock(ctx, o.ProductID, o.Qty) \u002F\u002F same tx\n})\n",[450,2152,2153,2176,2180,2215,2255,2261,2265,2306],{"__ignoreMap":491},[495,2154,2155,2158,2160,2162,2164,2167,2169,2171,2173],{"class":497,"line":498},[495,2156,2157],{"class":568},"tx ",[495,2159,577],{"class":505},[495,2161,580],{"class":568},[495,2163,583],{"class":505},[495,2165,2166],{"class":586},"NewTransactor",[495,2168,590],{"class":505},[495,2170,557],{"class":568},[495,2172,605],{"class":505},[495,2174,2175],{"class":608}," \u002F\u002F dbx.Transactor\n",[495,2177,2178],{"class":497,"line":509},[495,2179,1120],{"emptyLinePlaceholder":1119},[495,2181,2182,2184,2186,2189,2191,2193,2195,2197,2199,2201,2203,2205,2207,2209,2211,2213],{"class":497,"line":522},[495,2183,690],{"class":568},[495,2185,577],{"class":505},[495,2187,2188],{"class":568}," tx",[495,2190,583],{"class":505},[495,2192,1066],{"class":586},[495,2194,590],{"class":505},[495,2196,593],{"class":568},[495,2198,571],{"class":505},[495,2200,746],{"class":505},[495,2202,593],{"class":838},[495,2204,841],{"class":515},[495,2206,583],{"class":505},[495,2208,754],{"class":515},[495,2210,605],{"class":505},[495,2212,760],{"class":759},[495,2214,763],{"class":505},[495,2216,2217,2219,2221,2223,2226,2228,2231,2233,2236,2238,2240,2242,2245,2247,2249,2251,2253],{"class":497,"line":532},[495,2218,1375],{"class":501},[495,2220,574],{"class":568},[495,2222,577],{"class":505},[495,2224,2225],{"class":568}," s",[495,2227,583],{"class":505},[495,2229,2230],{"class":568},"orders",[495,2232,583],{"class":505},[495,2234,2235],{"class":586},"Insert",[495,2237,590],{"class":505},[495,2239,593],{"class":568},[495,2241,571],{"class":505},[495,2243,2244],{"class":568}," o",[495,2246,1447],{"class":505},[495,2248,574],{"class":568},[495,2250,1452],{"class":505},[495,2252,1455],{"class":505},[495,2254,763],{"class":505},[495,2256,2257,2259],{"class":497,"line":787},[495,2258,781],{"class":501},[495,2260,1479],{"class":568},[495,2262,2263],{"class":497,"line":1152},[495,2264,1535],{"class":505},[495,2266,2267,2269,2271,2273,2275,2277,2279,2281,2283,2285,2287,2289,2292,2294,2296,2298,2301,2303],{"class":497,"line":1157},[495,2268,1190],{"class":501},[495,2270,2225],{"class":568},[495,2272,583],{"class":505},[495,2274,1781],{"class":568},[495,2276,583],{"class":505},[495,2278,2111],{"class":586},[495,2280,590],{"class":505},[495,2282,593],{"class":568},[495,2284,571],{"class":505},[495,2286,2244],{"class":568},[495,2288,583],{"class":505},[495,2290,2291],{"class":568},"ProductID",[495,2293,571],{"class":505},[495,2295,2244],{"class":568},[495,2297,583],{"class":505},[495,2299,2300],{"class":568},"Qty",[495,2302,605],{"class":505},[495,2304,2305],{"class":608}," \u002F\u002F same tx\n",[495,2307,2308],{"class":497,"line":1187},[495,2309,2310],{"class":505},"})\n",[447,2312,2313,2315,2316,2318,2319,2322,2323,2325,2326,2329,2330,2332,2333,583],{},[450,2314,1066],{}," opens a transaction on the pool, injects the ",[450,2317,483],{}," into the context, and commits after ",[450,2320,2321],{},"fn"," returns. Any error, or panic, which is re-raised after rollback, rolls everything back. When the context already carries a transaction, ",[450,2324,2321],{}," ",[659,2327,2328],{},"joins it"," instead of opening a new one: nesting is flat, there are no savepoints, and the outermost call always owns commit\u002Frollback. The full treatment of the pattern, with the shop's ",[450,2331,1850],{}," example, is on ",[455,2334,421],{"href":422},[555,2336,2338],{"id":2337},"escape-hatch-the-context-plumbing","Escape hatch: the context plumbing",[447,2340,2341],{},"For a custom executor (say, a batch writer or a hand-instrumented query path), the transaction carrying is exported:",[486,2343,2345],{"className":488,"code":2344,"language":490,"meta":491,"style":491},"ctx = pg.ContextWithTx(ctx, tx)   \u002F\u002F put a transaction into the context\ntx, ok := pg.TxFromContext(ctx)   \u002F\u002F take the transaction out of the context\n",[450,2346,2347,2374],{"__ignoreMap":491},[495,2348,2349,2352,2354,2356,2358,2361,2363,2365,2367,2369,2371],{"class":497,"line":498},[495,2350,2351],{"class":568},"ctx ",[495,2353,1239],{"class":505},[495,2355,580],{"class":568},[495,2357,583],{"class":505},[495,2359,2360],{"class":586},"ContextWithTx",[495,2362,590],{"class":505},[495,2364,593],{"class":568},[495,2366,571],{"class":505},[495,2368,2188],{"class":568},[495,2370,605],{"class":505},[495,2372,2373],{"class":608},"   \u002F\u002F put a transaction into the context\n",[495,2375,2376,2379,2381,2384,2386,2388,2390,2393,2395,2397,2399],{"class":497,"line":509},[495,2377,2378],{"class":568},"tx",[495,2380,571],{"class":505},[495,2382,2383],{"class":568}," ok ",[495,2385,577],{"class":505},[495,2387,580],{"class":568},[495,2389,583],{"class":505},[495,2391,2392],{"class":586},"TxFromContext",[495,2394,590],{"class":505},[495,2396,593],{"class":568},[495,2398,605],{"class":505},[495,2400,2401],{"class":608},"   \u002F\u002F take the transaction out of the context\n",[447,2403,2404,2405,2407,2408,2410,2411,2413,2414,542,2417,2420],{},"Application code normally never calls these: ",[450,2406,1053],{}," and the ",[450,2409,2147],{}," cover it together. They matter when you need a richer pgx surface than ",[450,2412,998],{}," (e.g. ",[450,2415,2416],{},"CopyFrom",[450,2418,2419],{},"SendBatch",") inside a transaction.",[2422,2423,2424,2425,583],"tip",{},"The transaction semantics (commit\u002Frollback\u002Fnesting\u002Fpanic) are pinned down by dbx's own integration tests against a real PostgreSQL: ",[450,2426,2427],{},"go test -tags=integration .\u002Fdbx\u002Fpg\u002F",[555,2429,2431],{"id":2430},"standalone-example","Standalone example",[447,2433,2434,2436,2437,2439],{},[450,2435,452],{}," needs nothing from the kit: a pool, a ",[450,2438,998],{},"-backed repository and a transactor are enough on their own.",[486,2441,2443],{"className":488,"code":2442,"filename":672,"language":490,"meta":491,"style":491},"package main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com\u002Fgp-system\u002Fdbx\"\n    \"github.com\u002Fgp-system\u002Fdbx\u002Fpg\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    pool := pg.MustNewPool(ctx, dbx.Config{\n        Host: \"localhost\", Port: 5432,\n        User: \"shop\", Password: \"secret\", Database: \"shop\",\n    })\n    defer pool.Close()\n\n    db := pg.NewDB(pool)\n    tx := pg.NewTransactor(pool)\n\n    err := tx.WithinTransaction(ctx, func(ctx context.Context) error {\n        _, err := db.Exec(ctx, `UPDATE products SET stock = stock - 1 WHERE id = $1`, \"prod_42\")\n        return err\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n",[450,2444,2445,2452,2456,2462,2470,2479,2483,2491,2499,2503,2507,2518,2534,2564,2590,2633,2637,2651,2655,2673,2692,2696,2731,2772,2778,2782,2794,2810,2814],{"__ignoreMap":491},[495,2446,2447,2449],{"class":497,"line":498},[495,2448,1111],{"class":505},[495,2450,2451],{"class":515}," main\n",[495,2453,2454],{"class":497,"line":509},[495,2455,1120],{"emptyLinePlaceholder":1119},[495,2457,2458,2460],{"class":497,"line":522},[495,2459,502],{"class":501},[495,2461,506],{"class":505},[495,2463,2464,2466,2468],{"class":497,"line":532},[495,2465,512],{"class":505},[495,2467,749],{"class":515},[495,2469,519],{"class":505},[495,2471,2472,2474,2477],{"class":497,"line":787},[495,2473,512],{"class":505},[495,2475,2476],{"class":515},"log",[495,2478,519],{"class":505},[495,2480,2481],{"class":497,"line":1152},[495,2482,1120],{"emptyLinePlaceholder":1119},[495,2484,2485,2487,2489],{"class":497,"line":1157},[495,2486,512],{"class":505},[495,2488,516],{"class":515},[495,2490,519],{"class":505},[495,2492,2493,2495,2497],{"class":497,"line":1187},[495,2494,512],{"class":505},[495,2496,527],{"class":515},[495,2498,519],{"class":505},[495,2500,2501],{"class":497,"line":1210},[495,2502,535],{"class":505},[495,2504,2505],{"class":497,"line":1406},[495,2506,1120],{"emptyLinePlaceholder":1119},[495,2508,2509,2511,2514,2516],{"class":497,"line":1417},[495,2510,1160],{"class":505},[495,2512,2513],{"class":586}," main",[495,2515,1385],{"class":505},[495,2517,763],{"class":505},[495,2519,2520,2523,2525,2527,2529,2532],{"class":497,"line":1460},[495,2521,2522],{"class":568},"    ctx ",[495,2524,577],{"class":505},[495,2526,841],{"class":568},[495,2528,583],{"class":505},[495,2530,2531],{"class":586},"Background",[495,2533,776],{"class":505},[495,2535,2536,2539,2541,2543,2545,2547,2549,2551,2553,2556,2558,2561],{"class":497,"line":1482},[495,2537,2538],{"class":568},"    pool ",[495,2540,577],{"class":505},[495,2542,580],{"class":568},[495,2544,583],{"class":505},[495,2546,623],{"class":586},[495,2548,590],{"class":505},[495,2550,593],{"class":568},[495,2552,571],{"class":505},[495,2554,2555],{"class":515}," dbx",[495,2557,583],{"class":505},[495,2559,2560],{"class":515},"Config",[495,2562,2563],{"class":505},"{\n",[495,2565,2566,2569,2571,2573,2576,2578,2580,2583,2585,2588],{"class":497,"line":1488},[495,2567,2568],{"class":568},"        Host",[495,2570,680],{"class":505},[495,2572,1242],{"class":505},[495,2574,2575],{"class":738},"localhost",[495,2577,735],{"class":505},[495,2579,571],{"class":505},[495,2581,2582],{"class":568}," Port",[495,2584,680],{"class":505},[495,2586,2587],{"class":2017}," 5432",[495,2589,720],{"class":505},[495,2591,2592,2595,2597,2599,2602,2604,2606,2609,2611,2613,2616,2618,2620,2623,2625,2627,2629,2631],{"class":497,"line":1504},[495,2593,2594],{"class":568},"        User",[495,2596,680],{"class":505},[495,2598,1242],{"class":505},[495,2600,2601],{"class":738},"shop",[495,2603,735],{"class":505},[495,2605,571],{"class":505},[495,2607,2608],{"class":568}," Password",[495,2610,680],{"class":505},[495,2612,1242],{"class":505},[495,2614,2615],{"class":738},"secret",[495,2617,735],{"class":505},[495,2619,571],{"class":505},[495,2621,2622],{"class":568}," Database",[495,2624,680],{"class":505},[495,2626,1242],{"class":505},[495,2628,2601],{"class":738},[495,2630,735],{"class":505},[495,2632,720],{"class":505},[495,2634,2635],{"class":497,"line":1532},[495,2636,1839],{"class":505},[495,2638,2639,2642,2645,2647,2649],{"class":497,"line":1538},[495,2640,2641],{"class":501},"    defer",[495,2643,2644],{"class":568}," pool",[495,2646,583],{"class":505},[495,2648,773],{"class":586},[495,2650,776],{"class":505},[495,2652,2653],{"class":497,"line":1568},[495,2654,1120],{"emptyLinePlaceholder":1119},[495,2656,2657,2659,2661,2663,2665,2667,2669,2671],{"class":497,"line":1573},[495,2658,1137],{"class":568},[495,2660,577],{"class":505},[495,2662,580],{"class":568},[495,2664,583],{"class":505},[495,2666,1039],{"class":586},[495,2668,590],{"class":505},[495,2670,557],{"class":568},[495,2672,535],{"class":505},[495,2674,2675,2678,2680,2682,2684,2686,2688,2690],{"class":497,"line":1613},[495,2676,2677],{"class":568},"    tx ",[495,2679,577],{"class":505},[495,2681,580],{"class":568},[495,2683,583],{"class":505},[495,2685,2166],{"class":586},[495,2687,590],{"class":505},[495,2689,557],{"class":568},[495,2691,535],{"class":505},[495,2693,2694],{"class":497,"line":1626},[495,2695,1120],{"emptyLinePlaceholder":1119},[495,2697,2698,2701,2703,2705,2707,2709,2711,2713,2715,2717,2719,2721,2723,2725,2727,2729],{"class":497,"line":1667},[495,2699,2700],{"class":568},"    err ",[495,2702,577],{"class":505},[495,2704,2188],{"class":568},[495,2706,583],{"class":505},[495,2708,1066],{"class":586},[495,2710,590],{"class":505},[495,2712,593],{"class":568},[495,2714,571],{"class":505},[495,2716,746],{"class":505},[495,2718,593],{"class":838},[495,2720,841],{"class":515},[495,2722,583],{"class":505},[495,2724,754],{"class":515},[495,2726,605],{"class":505},[495,2728,760],{"class":759},[495,2730,763],{"class":505},[495,2732,2733,2736,2738,2740,2742,2744,2746,2748,2750,2752,2754,2756,2759,2761,2763,2765,2768,2770],{"class":497,"line":1672},[495,2734,2735],{"class":568},"        _",[495,2737,571],{"class":505},[495,2739,574],{"class":568},[495,2741,577],{"class":505},[495,2743,1205],{"class":568},[495,2745,583],{"class":505},[495,2747,1927],{"class":586},[495,2749,590],{"class":505},[495,2751,593],{"class":568},[495,2753,571],{"class":505},[495,2755,1364],{"class":505},[495,2757,2758],{"class":738},"UPDATE products SET stock = stock - 1 WHERE id = $1",[495,2760,1550],{"class":505},[495,2762,571],{"class":505},[495,2764,1242],{"class":505},[495,2766,2767],{"class":738},"prod_42",[495,2769,735],{"class":505},[495,2771,535],{"class":505},[495,2773,2774,2776],{"class":497,"line":1711},[495,2775,781],{"class":501},[495,2777,1479],{"class":568},[495,2779,2780],{"class":497,"line":1724},[495,2781,1839],{"class":505},[495,2783,2784,2786,2788,2790,2792],{"class":497,"line":1762},[495,2785,1375],{"class":501},[495,2787,574],{"class":568},[495,2789,1452],{"class":505},[495,2791,1455],{"class":505},[495,2793,763],{"class":505},[495,2795,2796,2799,2801,2804,2806,2808],{"class":497,"line":1767},[495,2797,2798],{"class":568},"        log",[495,2800,583],{"class":505},[495,2802,2803],{"class":586},"Fatal",[495,2805,590],{"class":505},[495,2807,1653],{"class":568},[495,2809,535],{"class":505},[495,2811,2812],{"class":497,"line":1806},[495,2813,1535],{"class":505},[495,2815,2816],{"class":497,"line":1836},[495,2817,972],{"class":505},[555,2819,2821],{"id":2820},"patterns-used","Patterns used",[2823,2824,2825,2837],"ul",{},[2826,2827,2828,653,2831,2833,2834,583],"li",{},[659,2829,2830],{},"Narrow, sqlc-compatible repository interface",[450,2832,998],{},"): ",[455,2835,238],{"href":2836},"\u002Fen\u002Fconcepts\u002Fdesign-patterns#narrow-repository-interface-sqlc-compatible",[2826,2838,2839,653,2842,542,2844,2833,2847,583],{},[659,2840,2841],{},"Unit of Work \u002F transaction in context",[450,2843,1066],{},[450,2845,2846],{},"txKey{}",[455,2848,238],{"href":2849},"\u002Fen\u002Fconcepts\u002Fdesign-patterns#unit-of-work--transaction-in-context",[2851,2852,2853],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":491,"searchDepth":509,"depth":509,"links":2855},[2856,2857,2858,2859,2860,2861,2862,2863],{"id":557,"depth":509,"text":558},{"id":809,"depth":509,"text":810},{"id":1019,"depth":509,"text":1020},{"id":1076,"depth":509,"text":1077},{"id":2146,"depth":509,"text":2147},{"id":2337,"depth":509,"text":2338},{"id":2430,"depth":509,"text":2431},{"id":2820,"depth":509,"text":2821},"The pgx-native database stack: the pool, the DBTX query surface and the context-aware DB executor.","md",null,{},{"icon":106},{"title":413,"description":2864},"388qvLUdj8GJlIZJ-TH1dTzRpPOq6Tpi-S5i29FuiP0",[2872,2874],{"title":52,"path":410,"stem":411,"description":2873,"icon":405,"children":-1},"The dbx module, the database-agnostic contract your code depends on, and the two implementations you choose by import.",{"title":417,"path":418,"stem":419,"description":2875,"icon":47,"children":-1},"The optional bun adapter: query builder and struct models, with the Transactor contract unchanged.",1785445895174]