prax-orm 0.6.5

A next-generation, type-safe ORM for Rust inspired by Prisma
Documentation
<article class="max-w-4xl mx-auto px-6 py-12">
  <header class="mb-12">
    <h1 class="text-4xl font-bold mb-4">Microsoft SQL Server</h1>
    <p class="text-xl text-muted">
      Full MSSQL support with Tiberius driver, including Azure SQL, indexed views, MERGE statements, and SQL Agent jobs.
    </p>
  </header>

  <div class="space-y-12">
    <!-- Introduction -->
    <section>
      <h2 class="text-2xl font-semibold mb-4">Overview</h2>
      <p class="text-muted mb-4">
        Prax provides comprehensive Microsoft SQL Server support through the Tiberius async driver.
        This includes Azure SQL Database, Azure SQL Managed Instance, and on-premises SQL Server instances.
      </p>
      <div class="grid md:grid-cols-3 gap-4">
        <div class="p-4 rounded-xl bg-surface border border-border">
          <div class="text-2xl mb-2">🔒</div>
          <h4 class="font-semibold mb-1">Azure Ready</h4>
          <p class="text-muted text-sm">Full Azure SQL support with TLS and AAD authentication</p>
        </div>
        <div class="p-4 rounded-xl bg-surface border border-border">
          <div class="text-2xl mb-2"></div>
          <h4 class="font-semibold mb-1">MERGE & OUTPUT</h4>
          <p class="text-muted text-sm">Native upsert with MERGE and RETURNING via OUTPUT</p>
        </div>
        <div class="p-4 rounded-xl bg-surface border border-border">
          <div class="text-2xl mb-2">📊</div>
          <h4 class="font-semibold mb-1">SQL Agent</h4>
          <p class="text-muted text-sm">Scheduled jobs via SQL Server Agent integration</p>
        </div>
      </div>
    </section>

    <!-- Connection -->
    <section>
      <h2 class="text-2xl font-semibold mb-4">Connection Configuration</h2>
      <p class="text-muted mb-4">
        Configure your MSSQL connection in <code class="px-2 py-1 bg-surface-elevated rounded">prax.toml</code>.
        Supports both SQL authentication and Windows/Azure AD authentication.
      </p>
      <app-code-block [code]="connectionExample" language="toml" filename="prax.toml" />
    </section>

    <!-- Schema -->
    <section>
      <h2 class="text-2xl font-semibold mb-4">Schema Definition</h2>
      <p class="text-muted mb-4">
        Use MSSQL-specific data types with the <code class="px-2 py-1 bg-surface-elevated rounded">&#64;db.</code> attribute.
      </p>
      <app-code-block [code]="schemaExample" language="prax" filename="prax/schema.prax" />
      <div class="mt-4 overflow-x-auto">
        <table class="w-full text-sm">
          <thead>
            <tr class="border-b border-border">
              <th class="text-left py-3 px-4 font-semibold">Prax Type</th>
              <th class="text-left py-3 px-4 font-semibold">MSSQL Type</th>
              <th class="text-left py-3 px-4 font-semibold">Notes</th>
            </tr>
          </thead>
          <tbody class="text-muted">
            <tr class="border-b border-border">
              <td class="py-3 px-4"><code>String</code></td>
              <td class="py-3 px-4"><code>NVARCHAR(255)</code></td>
              <td class="py-3 px-4">Use &#64;db.NVarChar(Max) for unlimited</td>
            </tr>
            <tr class="border-b border-border">
              <td class="py-3 px-4"><code>Int</code></td>
              <td class="py-3 px-4"><code>INT</code></td>
              <td class="py-3 px-4">&#64;db.BigInt for larger values</td>
            </tr>
            <tr class="border-b border-border">
              <td class="py-3 px-4"><code>DateTime</code></td>
              <td class="py-3 px-4"><code>DATETIME2</code></td>
              <td class="py-3 px-4">Higher precision than DATETIME</td>
            </tr>
            <tr class="border-b border-border">
              <td class="py-3 px-4"><code>Decimal</code></td>
              <td class="py-3 px-4"><code>DECIMAL(18,2)</code></td>
              <td class="py-3 px-4">Configurable precision/scale</td>
            </tr>
            <tr class="border-b border-border">
              <td class="py-3 px-4"><code>Bytes</code></td>
              <td class="py-3 px-4"><code>VARBINARY(MAX)</code></td>
              <td class="py-3 px-4">Binary data storage</td>
            </tr>
          </tbody>
        </table>
      </div>
    </section>

    <!-- Indexed Views -->
    <section>
      <h2 class="text-2xl font-semibold mb-4">Indexed Views (Materialized Views)</h2>
      <p class="text-muted mb-4">
        MSSQL supports indexed views, which are materialized views with a clustered index.
        They're automatically updated when base tables change.
      </p>
      <app-code-block [code]="indexedViewExample" language="prax" filename="prax/schema.prax" />
      <div class="mt-4 p-4 rounded-xl bg-info-500/10 border border-info-500/30">
        <p class="text-info-400 text-sm">
          <strong>Note:</strong> Indexed views require <code>SCHEMABINDING</code> and have restrictions on
          the types of queries they can contain. Prax automatically handles these requirements.
        </p>
      </div>
    </section>

    <!-- MERGE Statement -->
    <section>
      <h2 class="text-2xl font-semibold mb-4">MERGE Statement (Upsert)</h2>
      <p class="text-muted mb-4">
        MSSQL uses the <code class="px-2 py-1 bg-surface-elevated rounded">MERGE</code> statement for upsert operations,
        providing atomic insert-or-update functionality.
      </p>
      <app-code-block [code]="mergeExample" language="rust" filename="src/main.rs" />
    </section>

    <!-- OUTPUT Clause -->
    <section>
      <h2 class="text-2xl font-semibold mb-4">OUTPUT Clause (RETURNING)</h2>
      <p class="text-muted mb-4">
        Get inserted/updated/deleted values back from DML statements using the OUTPUT clause.
      </p>
      <app-code-block [code]="outputClauseExample" language="rust" filename="src/main.rs" />
    </section>

    <!-- CROSS APPLY -->
    <section>
      <h2 class="text-2xl font-semibold mb-4">CROSS APPLY (LATERAL Joins)</h2>
      <p class="text-muted mb-4">
        MSSQL's CROSS APPLY and OUTER APPLY are equivalent to LATERAL joins in PostgreSQL.
      </p>
      <app-code-block [code]="crossApplyExample" language="rust" filename="src/main.rs" />
    </section>

    <!-- Locking -->
    <section>
      <h2 class="text-2xl font-semibold mb-4">Table Hints & Locking</h2>
      <p class="text-muted mb-4">
        Control locking behavior with MSSQL table hints.
      </p>
      <app-code-block [code]="lockingExample" language="rust" filename="src/main.rs" />
    </section>

    <!-- SQL Agent -->
    <section>
      <h2 class="text-2xl font-semibold mb-4">SQL Server Agent Jobs</h2>
      <p class="text-muted mb-4">
        Define and manage scheduled jobs that run on SQL Server Agent.
      </p>
      <app-code-block [code]="sqlAgentExample" language="rust" filename="migrations/jobs.rs" />
    </section>

    <!-- AlwaysOn -->
    <section>
      <h2 class="text-2xl font-semibold mb-4">AlwaysOn Availability Groups</h2>
      <p class="text-muted mb-4">
        Configure read replicas and automatic failover with AlwaysOn.
      </p>
      <app-code-block [code]="alwaysOnExample" language="rust" filename="src/config.rs" />
    </section>

    <!-- Feature Support -->
    <section>
      <h2 class="text-2xl font-semibold mb-4">MSSQL Feature Support</h2>
      <div class="overflow-x-auto">
        <table class="w-full text-sm">
          <thead>
            <tr class="border-b border-border">
              <th class="text-left py-3 px-4 font-semibold">Feature</th>
              <th class="text-left py-3 px-4 font-semibold">Status</th>
              <th class="text-left py-3 px-4 font-semibold">Notes</th>
            </tr>
          </thead>
          <tbody class="text-muted">
            <tr class="border-b border-border">
              <td class="py-3 px-4">Indexed Views</td>
              <td class="py-3 px-4"><span class="text-success-400"></span></td>
              <td class="py-3 px-4">Automatic maintenance</td>
            </tr>
            <tr class="border-b border-border">
              <td class="py-3 px-4">MERGE Statement</td>
              <td class="py-3 px-4"><span class="text-success-400"></span></td>
              <td class="py-3 px-4">Full upsert support</td>
            </tr>
            <tr class="border-b border-border">
              <td class="py-3 px-4">OUTPUT Clause</td>
              <td class="py-3 px-4"><span class="text-success-400"></span></td>
              <td class="py-3 px-4">INSERTED/DELETED access</td>
            </tr>
            <tr class="border-b border-border">
              <td class="py-3 px-4">CROSS/OUTER APPLY</td>
              <td class="py-3 px-4"><span class="text-success-400"></span></td>
              <td class="py-3 px-4">Lateral join equivalent</td>
            </tr>
            <tr class="border-b border-border">
              <td class="py-3 px-4">SQL Agent Jobs</td>
              <td class="py-3 px-4"><span class="text-success-400"></span></td>
              <td class="py-3 px-4">Scheduled tasks</td>
            </tr>
            <tr class="border-b border-border">
              <td class="py-3 px-4">AlwaysOn</td>
              <td class="py-3 px-4"><span class="text-success-400"></span></td>
              <td class="py-3 px-4">HA and read replicas</td>
            </tr>
            <tr class="border-b border-border">
              <td class="py-3 px-4">Row-Level Security</td>
              <td class="py-3 px-4"><span class="text-success-400"></span></td>
              <td class="py-3 px-4">Security predicates</td>
            </tr>
            <tr class="border-b border-border">
              <td class="py-3 px-4">Dynamic Data Masking</td>
              <td class="py-3 px-4"><span class="text-success-400"></span></td>
              <td class="py-3 px-4">Column masking</td>
            </tr>
          </tbody>
        </table>
      </div>
    </section>
  </div>
</article>