@@ -28,11 +28,16 @@ export class SQLiteDatabaseClient {
28
28
text ( rows . map ( row => row . detail ) . join ( "\n" ) )
29
29
] ) ;
30
30
}
31
- async describe ( object ) {
32
- const rows = await ( object === undefined
33
- ? this . query ( `SELECT name FROM sqlite_master WHERE type = 'table'` )
34
- : this . query ( `SELECT * FROM pragma_table_info(?)` , [ object ] ) ) ;
35
- if ( ! rows . length ) throw new Error ( "Not found" ) ;
31
+ async describeTables ( ) {
32
+ return this . query ( `SELECT name FROM sqlite_master WHERE type = 'table'` ) ;
33
+ }
34
+ async describeColumns ( { table} = { } ) {
35
+ const rows = await this . query ( `SELECT name, type, notnull FROM pragma_table_info(?) ORDER BY cid` , [ table ] ) ;
36
+ if ( ! rows . length ) throw new Error ( `table not found: ${ table } ` ) ;
37
+ return rows . map ( ( { name, type, notnull} ) => ( { name, type : sqliteType ( type ) , databaseType : type , nullable : ! notnull } ) ) ;
38
+ }
39
+ async describe ( table ) {
40
+ const rows = await ( table === undefined ? this . describeTables ( ) : this . describeColumns ( { table} ) ) ;
36
41
const { columns} = rows ;
37
42
return element ( "table" , { value : rows } , [
38
43
element ( "thead" , [ element ( "tr" , columns . map ( c => element ( "th" , [ text ( c ) ] ) ) ) ] ) ,
@@ -46,10 +51,47 @@ export class SQLiteDatabaseClient {
46
51
return [ strings . join ( "?" ) , params ] ;
47
52
}
48
53
}
54
+
49
55
Object . defineProperty ( SQLiteDatabaseClient . prototype , "dialect" , {
50
56
value : "sqlite"
51
57
} ) ;
52
58
59
+ // https://www.sqlite.org/datatype3.html
60
+ function sqliteType ( type ) {
61
+ switch ( type ) {
62
+ case "NULL" :
63
+ return "null" ;
64
+ case "INT" :
65
+ case "INTEGER" :
66
+ case "TINYINT" :
67
+ case "SMALLINT" :
68
+ case "MEDIUMINT" :
69
+ case "BIGINT" :
70
+ case "UNSIGNED BIG INT" :
71
+ case "INT2" :
72
+ case "INT8" :
73
+ return "integer" ;
74
+ case "TEXT" :
75
+ case "CLOB" :
76
+ return "string" ;
77
+ case "REAL" :
78
+ case "DOUBLE" :
79
+ case "DOUBLE PRECISION" :
80
+ case "FLOAT" :
81
+ case "NUMERIC" :
82
+ return "number" ;
83
+ case "BLOB" :
84
+ return "buffer" ;
85
+ case "DATE" :
86
+ case "DATETIME" :
87
+ return "string" ; // TODO convert strings to Date instances in sql.js
88
+ default :
89
+ return / ^ (?: (?: (?: V A R Y I N G | N A T I V E ) ) ? C H A R A C T E R | (?: N | V A R | N V A R ) C H A R ) \( / . test ( type ) ? "string"
90
+ : / ^ (?: D E C I M A L | N U M E R I C ) \( / . test ( type ) ? "number"
91
+ : "other" ;
92
+ }
93
+ }
94
+
53
95
function load ( source ) {
54
96
return typeof source === "string" ? fetch ( source ) . then ( load )
55
97
: source instanceof Response || source instanceof Blob ? source . arrayBuffer ( ) . then ( load )
0 commit comments