Create and populate the `source_lines` table.
(conn: &Connection, repo_path: &Path)
| 12 | |
| 13 | /// Create and populate the `source_lines` table. |
| 14 | pub fn load(conn: &Connection, repo_path: &Path) -> Result<()> { |
| 15 | conn.execute_batch( |
| 16 | "CREATE TABLE IF NOT EXISTS source_lines ( |
| 17 | file_path TEXT, |
| 18 | line_number INTEGER, |
| 19 | content TEXT, |
| 20 | is_blank INTEGER, |
| 21 | PRIMARY KEY (file_path, line_number) |
| 22 | )", |
| 23 | )?; |
| 24 | |
| 25 | let files = walk_source_files(repo_path); |
| 26 | |
| 27 | conn.execute_batch("BEGIN")?; |
| 28 | |
| 29 | let mut stmt = conn.prepare( |
| 30 | "INSERT OR IGNORE INTO source_lines |
| 31 | (file_path, line_number, content, is_blank) |
| 32 | VALUES (?1, ?2, ?3, ?4)", |
| 33 | )?; |
| 34 | |
| 35 | for file_info in &files { |
| 36 | if file_info.size > MAX_FILE_SIZE { |
| 37 | continue; |
| 38 | } |
| 39 | |
| 40 | let abs_path = repo_path.join(&file_info.path); |
| 41 | let Ok(bytes) = std::fs::read(&abs_path) else { |
| 42 | continue; |
| 43 | }; |
| 44 | let content = String::from_utf8_lossy(&bytes); |
| 45 | |
| 46 | for (i, line) in content.lines().enumerate() { |
| 47 | let line_number = (i + 1) as i64; |
| 48 | let is_blank: i64 = if line.trim().is_empty() { 1 } else { 0 }; |
| 49 | stmt.execute(params![file_info.path, line_number, line, is_blank])?; |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | drop(stmt); |
| 54 | conn.execute_batch("COMMIT")?; |
| 55 | |
| 56 | // Create index after bulk insert for better performance. |
| 57 | conn.execute_batch( |
| 58 | "CREATE INDEX IF NOT EXISTS idx_source_lines_content ON source_lines(content)", |
| 59 | )?; |
| 60 | |
| 61 | Ok(()) |
| 62 | } |
nothing calls this directly
no test coverage detected