• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rogerpadilla / nukak / #520

29 Dec 2025 12:41PM UTC coverage: 86.536% (-10.7%) from 97.192%
#520

push

web-flow
Merge pull request #70 from rogerpadilla/feat/migrations-issue-38

feat: add support for database migrations

669 of 915 branches covered (73.11%)

Branch coverage included in aggregate %.

135 of 276 new or added lines in 9 files covered. (48.91%)

56 existing lines in 6 files now uncovered.

2294 of 2509 relevant lines covered (91.43%)

146.06 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

12.33
/packages/migrate/src/generator/postgresSchemaGenerator.ts
1
import type { ColumnType, FieldOptions } from 'nukak/type';
2
import { AbstractSchemaGenerator } from '../schemaGenerator.js';
1✔
3

4
/**
5
 * PostgreSQL-specific schema generator
6
 */
7
export class PostgresSchemaGenerator extends AbstractSchemaGenerator {
1✔
8
  protected readonly serialPrimaryKeyType = 'SERIAL PRIMARY KEY';
1✔
9

10
  constructor() {
11
    super('"');
1✔
12
  }
13

14
  protected mapColumnType(columnType: ColumnType, field: FieldOptions): string {
15
    switch (columnType) {
2!
16
      case 'int':
NEW
17
        return 'INTEGER';
×
18
      case 'smallint':
NEW
19
        return 'SMALLINT';
×
20
      case 'bigint':
NEW
21
        return 'BIGINT';
×
22
      case 'float':
23
      case 'double':
24
      case 'real':
NEW
25
        return 'DOUBLE PRECISION';
×
26
      case 'decimal':
27
      case 'numeric':
NEW
28
        if (field.precision !== undefined) {
×
NEW
29
          if (field.scale !== undefined) {
×
NEW
30
            return `NUMERIC(${field.precision}, ${field.scale})`;
×
31
          }
NEW
32
          return `NUMERIC(${field.precision})`;
×
33
        }
NEW
34
        return 'NUMERIC';
×
35
      case 'boolean':
NEW
36
        return 'BOOLEAN';
×
37
      case 'char':
NEW
38
        return `CHAR(${field.length ?? 1})`;
×
39
      case 'varchar':
NEW
40
        return `VARCHAR(${field.length ?? 255})`;
×
41
      case 'text':
42
        return 'TEXT';
1✔
43
      case 'uuid':
NEW
44
        return 'UUID';
×
45
      case 'date':
NEW
46
        return 'DATE';
×
47
      case 'time':
NEW
48
        return 'TIME';
×
49
      case 'timestamp':
NEW
50
        return 'TIMESTAMP';
×
51
      case 'timestamptz':
NEW
52
        return 'TIMESTAMPTZ';
×
53
      case 'json':
NEW
54
        return 'JSON';
×
55
      case 'jsonb':
56
        return 'JSONB';
1✔
57
      case 'blob':
58
      case 'bytea':
NEW
59
        return 'BYTEA';
×
60
      case 'vector':
NEW
61
        if (field.length) {
×
NEW
62
          return `VECTOR(${field.length})`;
×
63
        }
NEW
64
        return 'VECTOR';
×
65
      case 'serial':
NEW
66
        return 'SERIAL';
×
67
      case 'bigserial':
NEW
68
        return 'BIGSERIAL';
×
69
      default:
NEW
70
        return 'TEXT';
×
71
    }
72
  }
73

74
  protected getBooleanType(): string {
NEW
75
    return 'BOOLEAN';
×
76
  }
77

78
  protected generateAlterColumnStatement(tableName: string, columnName: string, newDefinition: string): string {
79
    // PostgreSQL uses ALTER COLUMN ... TYPE for type changes
NEW
80
    return `ALTER TABLE ${this.escapeId(tableName)} ALTER COLUMN ${newDefinition};`;
×
81
  }
82

83
  protected override generateColumnComment(comment: string): string {
84
    // PostgreSQL handles comments separately via COMMENT ON COLUMN
NEW
85
    return '';
×
86
  }
87

88
  /**
89
   * Generate COMMENT ON COLUMN statement for PostgreSQL
90
   */
91
  generateColumnCommentStatement(tableName: string, columnName: string, comment: string): string {
NEW
92
    const escapedComment = comment.replace(/'/g, "''");
×
NEW
93
    return `COMMENT ON COLUMN ${this.escapeId(tableName)}.${this.escapeId(columnName)} IS '${escapedComment}';`;
×
94
  }
95

96
  override generateDropIndex(tableName: string, indexName: string): string {
97
    // PostgreSQL doesn't require table name in DROP INDEX
NEW
98
    return `DROP INDEX IF EXISTS ${this.escapeId(indexName)};`;
×
99
  }
100
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc