Repository navigation
Expand file tree
/
Copy pathintrospect.go
More file actions
114 lines (98 loc) · 2.84 KB
/
Copy pathintrospect.go
File metadata and controls
114 lines (98 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package sqlite
import (
"webtyp.com/ddl"
"webtyp.com/storage"
)
type queryer interface {
Query(string, ...any) (storage.Rows, error)
}
func tableColumns(q queryer, table string) ([]string, error) {
// PRAGMA table_info does not support parameter binding.
// Table name comes from ModelName(), which is usually trusted,
// but we quote it just in case.
rows, err := q.Query("PRAGMA table_info(\"" + table + "\")")
if err != nil {
return nil, err
}
defer rows.Close()
var cols []string
for rows.Next() {
var cid int
var name, ctype string
var notnull, pk int
var dflt any
if err := rows.Scan(&cid, &name, &ctype, ¬null, &dflt, &pk); err != nil {
return nil, err
}
cols = append(cols, name)
}
return cols, rows.Err()
}
func (c *sqliteConn) TableColumns(table string) ([]string, error) {
return tableColumns(c, table)
}
func (e *sqliteTxExecutor) TableColumns(table string) ([]string, error) {
return tableColumns(e, table)
}
func tables(q queryer) ([]string, error) {
rows, err := q.Query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name")
if err != nil {
return nil, err
}
defer rows.Close()
var tables []string
for rows.Next() {
var name string
if err := rows.Scan(&name); err != nil {
return nil, err
}
tables = append(tables, name)
}
return tables, rows.Err()
}
func columns(q queryer, table string) ([]ddl.ColumnInfo, error) {
rows, err := q.Query("PRAGMA table_info(\"" + table + "\")")
if err != nil {
return nil, err
}
defer rows.Close()
var cols []ddl.ColumnInfo
for rows.Next() {
var cid int
var name, ctype string
var notnull, pk int
var dflt any
if err := rows.Scan(&cid, &name, &ctype, ¬null, &dflt, &pk); err != nil {
return nil, err
}
cols = append(cols, ddl.ColumnInfo{
Name: name,
Type: ctype,
NotNull: notnull == 1,
PK: pk > 0,
})
}
return cols, rows.Err()
}
// Tables returns all user-defined table names in the database.
func (c *sqliteConn) Tables() ([]string, error) {
return tables(c)
}
// Columns returns full column metadata for the given table using PRAGMA table_info.
func (c *sqliteConn) Columns(table string) ([]ddl.ColumnInfo, error) {
return columns(c, table)
}
// Tables returns all user-defined table names in the database.
func (e *sqliteTxExecutor) Tables() ([]string, error) {
return tables(e)
}
// Columns returns full column metadata for the given table using PRAGMA table_info.
func (e *sqliteTxExecutor) Columns(table string) ([]ddl.ColumnInfo, error) {
return columns(e, table)
}
// Ensure both executors implement TableIntrospector
var _ ddl.TableIntrospector = (*sqliteConn)(nil)
var _ ddl.TableIntrospector = (*sqliteTxExecutor)(nil)
// Ensure both executors implement ddl.SchemaInspector
var _ ddl.SchemaInspector = (*sqliteConn)(nil)
var _ ddl.SchemaInspector = (*sqliteTxExecutor)(nil)