genorm icon indicating copy to clipboard operation
genorm copied to clipboard

Add PostgreSQL and SQLite placeholder support

Open Copilot opened this issue 5 months ago • 2 comments

MySQL/MariaDB use ? placeholders in prepared statements, while PostgreSQL uses numbered placeholders ($1, $2, $3, ...). This change adds database-specific placeholder formatting with security-focused implementation.

Implementation

  • DBType enum: MySQL, PostgreSQL, SQLite constants
  • Option pattern: WithDBType() configures placeholder format per query
  • Placeholder generation: Placeholders are generated correctly at creation time, not via post-processing
  • queryBuilder: Tracks argument indices and safely converts expression placeholders for PostgreSQL
  • Updated constructors: Insert(), Select(), Update(), Delete(), Pluck() accept options

Security

The implementation generates placeholders at the point of creation rather than using post-processing string replacement:

  • INSERT statements: Generate correct placeholder format (? or $n) directly in buildValueList
  • Query expressions: Use queryBuilder with argument index tracking to safely handle WHERE, IN, and other clauses
  • No blind text replacement: Eliminates potential SQL injection risks from scanning entire query strings

Usage

// PostgreSQL
userValues, err := genorm.
    Select(orm.User(), genorm.WithDBType(genorm.PostgreSQL)).
    Where(genorm.InLit(user.IDExpr, id1, id2, id3)).
    GetAll(db)
// Generates: SELECT ... WHERE id IN ($1, $2, $3)

// MySQL (default, unchanged)
userValues, err := genorm.
    Select(orm.User()).
    Where(genorm.InLit(user.IDExpr, id1, id2, id3)).
    GetAll(db)
// Generates: SELECT ... WHERE id IN (?, ?, ?)

Default behavior unchanged—existing code continues to work without modification.

  • Fixes mazrean/genorm#100
Original prompt

This section details on the original issue you should resolve

<issue_title>PostgreSQL,SQLite対応</issue_title> <issue_description>Prepared StatementのプレースホルダーがMySQL/MariaDBでは?なのが、$1$2$3…になるのに対応する必要がある。</issue_description>

Comments on the Issue (you are @copilot in this section)

@mazrean DBごとにライブラリ側の挙動を変える必要がある。
  • どこかでパラメーターとして設定できるようにする
  • database/sqlを利用して読み取る

があるが、後者は流石に闇が深すぎるので前者が良さそう。</comment_new>

  • Fixes mazrean/genorm#100

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot avatar Nov 06 '25 12:11 Copilot