basedon/laravel-mssql-case-adapter
Composer 安装命令:
composer require basedon/laravel-mssql-case-adapter
包简介
Transparent snake_case to UPPERCASE identifier mapping for legacy SQL Server databases in Laravel.
README 文档
README
Write clean, snake_case Laravel code against legacy UPPERCASE SQL Server schemas.
Legacy enterprise MSSQL databases often use strict uppercase naming (SITES, SITE_ID, USER_FIRST_NAME). Writing $user->USER_FIRST_NAME ruins the developer experience and fights every Eloquent convention — especially relationships and eager loading. This package translates identifiers transparently at the database driver and grammar layer: your models, relations, and queries stay 100% lowercase, and the package converts both directions automatically.
class Site extends Model // table SITES (SITE_ID, SITE_NAME) { public function user(): HasOne { return $this->hasOne(User::class, 'site_id'); // column SITE_ID on USERS } } Site::with('user')->where('site_name', 'HQ')->get(); // select * from [SITES] where [SITE_NAME] = ? // select * from [USERS] where [USERS].[SITE_ID] in (...) // → models hydrate with lowercase attributes: $site->site_name, $site->user->user_id
Live demo: see hackeru2/legacy-mssql-demo-app — a full Laravel 13 JSON API (relations, pivots, nested eager loading) running against an UPPERCASE SQL Server schema, CI-tested on both default and case-sensitive collations.
Installation
composer require basedon/laravel-mssql-case-adapter
Point your connection at the mssql-adapted driver — everything else is a standard sqlsrv config:
// config/database.php 'connections' => [ 'legacy' => [ 'driver' => 'mssql-adapted', 'host' => env('DB_HOST', 'localhost'), 'database' => env('DB_DATABASE'), 'username' => env('DB_USERNAME'), 'password' => env('DB_PASSWORD'), // 'trust_server_certificate' => true, ], ],
That's it. No traits, no per-model configuration.
How it works
| Layer | Mechanism |
|---|---|
| Queries out | A custom query grammar translates every table, column, and alias through the identifier resolver before wrapping it in [...] — selects, wheres, joins, order by, inserts, updates, and relationship constraints included. |
| Results in | PDO::ATTR_CASE => PDO::CASE_LOWER is merged into the connection options (covers raw DB::select() too), and the query post-processor maps result keys through the resolver as a safety net. |
| Schema | The schema grammar translates identifiers as well, so Schema::hasTable('sites') and migrations work — including under case-sensitive collations. |
Do I even need this? Under SQL Server's default case-insensitive collations, identifier matching already works; the pain is result hydration and Eloquent relationship key matching, which this package fixes. Under case-sensitive (binary) collations, the grammar translation is what makes lowercase queries work at all. CI runs the full suite against both.
Custom naming strategies
The default UppercaseResolver maps site_name ↔ SITE_NAME. For prefixed or irregular legacy schemas (e.g. orders → TBL_ORDERS), implement the contract and register it:
use Basedon\MssqlCaseAdapter\Resolvers\IdentifierResolver; class TblPrefixResolver implements IdentifierResolver { public function toDatabase(string $identifier): string { return 'TBL_'.strtoupper($identifier); } public function toApplication(string $identifier): string { return strtolower(preg_replace('/^TBL_/', '', $identifier)); } }
// Globally, in config/mssql-case-adapter.php (php artisan vendor:publish --tag=mssql-case-adapter-config) 'identifier_resolver' => TblPrefixResolver::class, // …or per connection: 'legacy' => [ 'driver' => 'mssql-adapted', 'identifier_resolver' => TblPrefixResolver::class, // ... ],
The resolver must be bijective for the identifiers you use: toApplication(toDatabase($x)) === $x.
Generating models from a legacy schema
php artisan mssql:inspect --connection=legacy --path=app/Models --namespace="App\Models"
Scans INFORMATION_SCHEMA and generates Eloquent model stubs with the right $connection, $table (only when not derivable), $primaryKey, $casts, and $timestamps — all in lowercase application naming.
Configuration
| Key | Default | Meaning |
|---|---|---|
identifier_resolver |
UppercaseResolver::class |
Naming strategy (global or per connection). |
pdo_case_lower |
true |
Merge PDO::ATTR_CASE => CASE_LOWER into options (per connection: case_lower). An explicit PDO::ATTR_CASE in the connection options always wins. |
normalize_results |
true |
Post-processor maps result keys through the resolver. |
Limitations
- Raw SQL bypasses the grammar.
DB::raw(),selectRaw(),orderByRaw(),DB::statement()are passed through untouched — write database-side (UPPERCASE) identifiers in raw fragments. Result keys of raw selects are still lowercased by the PDO case option. - Mixed-case application identifiers (
siteName) are not round-trippable with the default resolver; stick to snake_case (Laravel convention) or supply a custom resolver.
Testing
composer test # unit + feature (no database needed) composer analyse # larastan, level 5 composer format # pint
Integration tests run in GitHub Actions against a real mcr.microsoft.com/mssql/server:2022 container with uppercase tables, on both a default-collation database and a Latin1_General_BIN (case-sensitive) database.
License
MIT
统计信息
- 总下载量: 5
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-07-12