-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsupabase_schema.sql
More file actions
329 lines (284 loc) · 9.12 KB
/
Copy pathsupabase_schema.sql
File metadata and controls
329 lines (284 loc) · 9.12 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
-- Supabase/PostgreSQL Schema for Code Graph Database
-- This schema converts the SQLite schema to PostgreSQL-compatible syntax
-- Enable UUID extension for better ID generation (optional)
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- Repositories table - tracks analyzed codebases
CREATE TABLE IF NOT EXISTS repositories (
id BIGSERIAL PRIMARY KEY,
repository_url TEXT,
repository_path TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
CONSTRAINT unique_repository_path UNIQUE(repository_path)
);
-- Add comment to table
COMMENT ON TABLE repositories IS 'Stores metadata about analyzed code repositories';
COMMENT ON COLUMN repositories.repository_url IS 'GitHub URL or remote repository URL';
COMMENT ON COLUMN repositories.repository_path IS 'Local or unique identifier path';
-- Graphs table - tracks different graph types for each repository
CREATE TABLE IF NOT EXISTS graphs (
id BIGSERIAL PRIMARY KEY,
repository_id BIGINT NOT NULL,
graph_type TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
total_nodes INTEGER DEFAULT 0,
total_edges INTEGER DEFAULT 0,
CONSTRAINT fk_repository
FOREIGN KEY (repository_id)
REFERENCES repositories(id)
ON DELETE CASCADE,
CONSTRAINT unique_repository_graph_type UNIQUE(repository_id, graph_type)
);
-- Add comment to table
COMMENT ON TABLE graphs IS 'Stores different graph representations (combined, call, declaration)';
COMMENT ON COLUMN graphs.graph_type IS 'Type: combined, call, or declaration';
-- Nodes table - stores all code entities
CREATE TABLE IF NOT EXISTS nodes (
id BIGSERIAL PRIMARY KEY,
graph_id BIGINT NOT NULL,
node_id TEXT NOT NULL,
node_type TEXT NOT NULL,
name TEXT NOT NULL,
qualified_name TEXT,
file_path TEXT,
line_number INTEGER,
parent_id TEXT,
metadata JSONB, -- PostgreSQL JSONB for better performance
CONSTRAINT fk_graph_nodes
FOREIGN KEY (graph_id)
REFERENCES graphs(id)
ON DELETE CASCADE,
CONSTRAINT unique_graph_node UNIQUE(graph_id, node_id)
);
-- Add comment to table
COMMENT ON TABLE nodes IS 'Stores code entities (functions, classes, methods, etc.)';
COMMENT ON COLUMN nodes.node_type IS 'Type: FUNCTION, CLASS, METHOD, PROPERTY, IMPORT, FILE';
COMMENT ON COLUMN nodes.metadata IS 'Additional node attributes stored as JSON';
-- Edges table - stores relationships between nodes
CREATE TABLE IF NOT EXISTS edges (
id BIGSERIAL PRIMARY KEY,
graph_id BIGINT NOT NULL,
source_id TEXT NOT NULL,
target_id TEXT NOT NULL,
edge_type TEXT NOT NULL,
metadata JSONB, -- PostgreSQL JSONB for better performance
CONSTRAINT fk_graph_edges
FOREIGN KEY (graph_id)
REFERENCES graphs(id)
ON DELETE CASCADE
);
-- Add comment to table
COMMENT ON TABLE edges IS 'Stores relationships between code entities';
COMMENT ON COLUMN edges.edge_type IS 'Type: calls, contains, inherits, etc.';
-- Indexes for fast queries
-- Index for finding nodes by parent (for subtree queries)
CREATE INDEX IF NOT EXISTS idx_nodes_parent
ON nodes(graph_id, parent_id);
-- Index for finding nodes by type
CREATE INDEX IF NOT EXISTS idx_nodes_type
ON nodes(graph_id, node_type);
-- Index for finding nodes by file
CREATE INDEX IF NOT EXISTS idx_nodes_file
ON nodes(graph_id, file_path);
-- Index for finding nodes by name (for search)
CREATE INDEX IF NOT EXISTS idx_nodes_name
ON nodes(name);
-- GIN index for JSONB metadata search
CREATE INDEX IF NOT EXISTS idx_nodes_metadata
ON nodes USING GIN(metadata);
-- Index for finding edges by source
CREATE INDEX IF NOT EXISTS idx_edges_source
ON edges(graph_id, source_id);
-- Index for finding edges by target
CREATE INDEX IF NOT EXISTS idx_edges_target
ON edges(graph_id, target_id);
-- Composite index for edge lookups
CREATE INDEX IF NOT EXISTS idx_edges_source_target
ON edges(graph_id, source_id, target_id);
-- GIN index for edge metadata search
CREATE INDEX IF NOT EXISTS idx_edges_metadata
ON edges USING GIN(metadata);
-- Index for repository lookups
CREATE INDEX IF NOT EXISTS idx_repositories_path
ON repositories(repository_path);
-- Index for repository URL lookups
CREATE INDEX IF NOT EXISTS idx_repositories_url
ON repositories(repository_url);
-- Trigger to automatically update updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_repositories_updated_at
BEFORE UPDATE ON repositories
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- Row Level Security (RLS) policies for Supabase
-- Enable RLS on all tables
ALTER TABLE repositories ENABLE ROW LEVEL SECURITY;
ALTER TABLE graphs ENABLE ROW LEVEL SECURITY;
ALTER TABLE nodes ENABLE ROW LEVEL SECURITY;
ALTER TABLE edges ENABLE ROW LEVEL SECURITY;
-- Example RLS policies (adjust based on your authentication needs)
-- Allow authenticated users to read all data
CREATE POLICY "Allow authenticated read on repositories"
ON repositories FOR SELECT
TO authenticated
USING (true);
CREATE POLICY "Allow authenticated read on graphs"
ON graphs FOR SELECT
TO authenticated
USING (true);
CREATE POLICY "Allow authenticated read on nodes"
ON nodes FOR SELECT
TO authenticated
USING (true);
CREATE POLICY "Allow authenticated read on edges"
ON edges FOR SELECT
TO authenticated
USING (true);
-- Allow authenticated users to insert their own data
CREATE POLICY "Allow authenticated insert on repositories"
ON repositories FOR INSERT
TO authenticated
WITH CHECK (true);
CREATE POLICY "Allow authenticated insert on graphs"
ON graphs FOR INSERT
TO authenticated
WITH CHECK (true);
CREATE POLICY "Allow authenticated insert on nodes"
ON nodes FOR INSERT
TO authenticated
WITH CHECK (true);
CREATE POLICY "Allow authenticated insert on edges"
ON edges FOR INSERT
TO authenticated
WITH CHECK (true);
-- Allow authenticated users to update their own data
CREATE POLICY "Allow authenticated update on repositories"
ON repositories FOR UPDATE
TO authenticated
USING (true)
WITH CHECK (true);
CREATE POLICY "Allow authenticated update on graphs"
ON graphs FOR UPDATE
TO authenticated
USING (true)
WITH CHECK (true);
-- Allow authenticated users to delete their own data
CREATE POLICY "Allow authenticated delete on repositories"
ON repositories FOR DELETE
TO authenticated
USING (true);
-- Useful views for common queries
-- View to get graph statistics
CREATE OR REPLACE VIEW graph_statistics AS
SELECT
r.id as repository_id,
r.repository_path,
r.repository_url,
g.id as graph_id,
g.graph_type,
g.total_nodes,
g.total_edges,
g.created_at,
r.updated_at
FROM repositories r
JOIN graphs g ON r.id = g.repository_id
ORDER BY r.updated_at DESC;
-- View to get node counts by type per graph
CREATE OR REPLACE VIEW node_type_counts AS
SELECT
g.id as graph_id,
r.repository_path,
g.graph_type,
n.node_type,
COUNT(*) as count
FROM graphs g
JOIN repositories r ON g.repository_id = r.id
JOIN nodes n ON g.id = n.graph_id
GROUP BY g.id, r.repository_path, g.graph_type, n.node_type
ORDER BY g.id, count DESC;
-- View to get top-level nodes (nodes with no parent)
CREATE OR REPLACE VIEW top_level_nodes AS
SELECT
g.id as graph_id,
g.graph_type,
n.*
FROM nodes n
JOIN graphs g ON n.graph_id = g.id
WHERE n.parent_id IS NULL OR n.parent_id = ''
ORDER BY g.id, n.name;
-- Helper function for recursive subtree queries
CREATE OR REPLACE FUNCTION get_subtree(
p_graph_id BIGINT,
p_root_node_id TEXT DEFAULT NULL,
p_max_depth INTEGER DEFAULT NULL
)
RETURNS TABLE (
id BIGINT,
graph_id BIGINT,
node_id TEXT,
node_type TEXT,
name TEXT,
qualified_name TEXT,
file_path TEXT,
line_number INTEGER,
parent_id TEXT,
metadata JSONB,
depth INTEGER
) AS $$
BEGIN
RETURN QUERY
WITH RECURSIVE subtree AS (
-- Base case
SELECT
n.*,
0 as depth
FROM nodes n
WHERE n.graph_id = p_graph_id
AND (
p_root_node_id IS NULL AND (n.parent_id IS NULL OR n.parent_id = '')
OR n.node_id = p_root_node_id
)
UNION ALL
-- Recursive case
SELECT
n.*,
s.depth + 1
FROM nodes n
INNER JOIN subtree s ON n.parent_id = s.node_id AND n.graph_id = s.graph_id
WHERE p_max_depth IS NULL OR s.depth < p_max_depth
)
SELECT * FROM subtree;
END;
$$ LANGUAGE plpgsql;
-- Helper function to get edges for a subtree
CREATE OR REPLACE FUNCTION get_subtree_edges(
p_graph_id BIGINT,
p_node_ids TEXT[]
)
RETURNS TABLE (
id BIGINT,
graph_id BIGINT,
source_id TEXT,
target_id TEXT,
edge_type TEXT,
metadata JSONB
) AS $$
BEGIN
RETURN QUERY
SELECT e.*
FROM edges e
WHERE e.graph_id = p_graph_id
AND e.source_id = ANY(p_node_ids)
AND e.target_id = ANY(p_node_ids);
END;
$$ LANGUAGE plpgsql;
-- Grant necessary permissions (adjust based on your needs)
-- GRANT USAGE ON SCHEMA public TO authenticated;
-- GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO authenticated;
-- GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO authenticated;