this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

struggling with sqlite bindings

+206 -134
+4 -4
src/core/types.odin
··· 21 21 } 22 22 23 23 Album :: struct { 24 - id: Album_Id, 25 - title: string, 26 - mb_id: Maybe(string), // MUSICBRAINZ_ALBUMID, 27 - mb_rg_id: Maybe(string), // MUSICBRAINZ_RELEASEGROUPID, 24 + id: string `sqlite:"id"`, 25 + title: string `sqlite:"title"`, 26 + mb_id: Maybe(string) `sqlite:"mb_id"`, // MUSICBRAINZ_ALBUMID, 27 + mb_rg_id: Maybe(string) `sqlite:"mb_rg_id"`, // MUSICBRAINZ_RELEASEGROUPID, 28 28 } 29 29 30 30
-123
src/db/album.odin
··· 1 - package db 2 - 3 - import sqlite "../../vendor/sqlite" 4 - import sa "../../vendor/sqlite/addons" 5 - import types "../core" 6 - import "core:fmt" 7 - import "core:mem" 8 - import "core:testing" 9 - 10 - new_album :: proc( 11 - db: ^sqlite.Connection, 12 - album: types.Album, 13 - allocator := context.allocator, 14 - ) -> sqlite.Result_Code { 15 - 16 - id := gen_id("album", allocator) 17 - defer delete(id, allocator) 18 - 19 - 20 - params := make([dynamic]sa.Query_Param, 2, 4, allocator) 21 - defer delete_dynamic_array(params) 22 - 23 - params[0] = sa.Query_Param{1, id} 24 - params[1] = sa.Query_Param{2, album.title} 25 - 26 - 27 - mb_id, mb_rg_id: string 28 - ok: bool 29 - 30 - mb_id, ok = album.mb_id.? 31 - if ok do append(&params, sa.Query_Param{3, mb_id}) 32 - 33 - mb_rg_id, ok = album.mb_rg_id.? 34 - if ok do append(&params, sa.Query_Param{4, mb_rg_id}) 35 - 36 - return sa.execute( 37 - db, 38 - "INSERT INTO album (id, title, mb_id, mb_rg_id) VALUES (?, ?, ?, ?)", 39 - params[:], 40 - ) 41 - } 42 - 43 - new_album_batch :: proc( 44 - db: ^sqlite.Connection, 45 - albums: []types.Album, 46 - allocator := context.allocator, 47 - ) -> sqlite.Result_Code { 48 - 49 - rc: sqlite.Result_Code 50 - 51 - n := len(albums) 52 - 53 - 54 - fmt.printfln("Starting transaction") 55 - rc = sa.execute(db, "BEGIN TRANSACTION;") 56 - assert(rc == .Ok) 57 - 58 - for album in albums { 59 - fmt.printfln("Inserting %v", album) 60 - rc = new_album(db, album, allocator) 61 - assert(rc == .Ok) 62 - } 63 - 64 - fmt.printfln("Commiting transaction") 65 - rc = sa.execute(db, "COMMIT;") 66 - assert(rc == .Ok) 67 - 68 - return rc 69 - } 70 - 71 - 72 - // ================ 73 - // Tests 74 - // ================ 75 - 76 - 77 - // @(test) 78 - // should_create_new_album :: proc(t: ^testing.T) { 79 - // 80 - // 81 - // track: mem.Tracking_Allocator 82 - // mem.tracking_allocator_init(&track, context.allocator) 83 - // context.allocator = mem.tracking_allocator(&track) 84 - // defer { 85 - // if len(track.allocation_map) > 0 { 86 - // fmt.eprintf("=== %v allocations not freed: ===\n", len(track.allocation_map)) 87 - // for _, entry in track.allocation_map { 88 - // fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location) 89 - // } 90 - // } 91 - // if len(track.bad_free_array) > 0 { 92 - // fmt.eprintf("=== %v incorrect frees: ===\n", len(track.bad_free_array)) 93 - // for entry in track.bad_free_array { 94 - // fmt.eprintf("- %p @ %v\n", entry.memory, entry.location) 95 - // } 96 - // } 97 - // mem.tracking_allocator_destroy(&track) 98 - // } 99 - // 100 - // 101 - // db: ^sqlite.Connection 102 - // 103 - // if rc := sqlite.open(db_url, &db); rc != .Ok { 104 - // fmt.panicf("failed to open database. result code {}", rc) 105 - // } 106 - // fmt.printfln("connected to database") 107 - // 108 - // defer { 109 - // sqlite.close(db) 110 - // fmt.printfln("\nconnection closed") 111 - // } 112 - // 113 - // album := types.Album { 114 - // id = "test", 115 - // title = "Test title", 116 - // mb_id = "asdf", 117 - // mb_rg_id = "asdf", 118 - // } 119 - // 120 - // rc := new_album(db, album) 121 - // testing.expect(t, rc == .Ok) 122 - // 123 - // }
+7 -7
src/db/artist.odin src/db/repo/artist.odin
··· 1 - #+vet explicit-allocators 2 - package db 1 + package repo 3 2 4 - import sqlite "../../vendor/sqlite" 5 - import sa "../../vendor/sqlite/addons" 6 - import types "../core" 3 + import db_pkg "../" 4 + import sqlite "../../../vendor/sqlite" 5 + import sa "../../../vendor/sqlite/addons" 6 + import types "../../core" 7 7 import "core:fmt" 8 8 import "core:mem" 9 9 import "core:testing" ··· 14 14 allocator := context.allocator, 15 15 ) -> sqlite.Result_Code { 16 16 17 - id := gen_id("artist", allocator) 17 + id := db_pkg.gen_id("artist", allocator) 18 18 defer delete(id, allocator) 19 19 20 20 ··· 145 145 146 146 db: ^sqlite.Connection 147 147 148 - if rc := sqlite.open(db_url, &db); rc != .Ok { 148 + if rc := sqlite.open(db_pkg.db_url, &db); rc != .Ok { 149 149 fmt.panicf("failed to open database. result code {}", rc) 150 150 } 151 151 fmt.printfln("connected to database")
+91
src/db/repo/album.odin
··· 1 + package repo 2 + 3 + import db_pkg "../" 4 + import sqlite "../../../vendor/sqlite" 5 + import sa "../../../vendor/sqlite/addons" 6 + import types "../../core" 7 + import "core:fmt" 8 + 9 + new_album :: proc( 10 + db: ^sqlite.Connection, 11 + album: types.Album, 12 + allocator := context.allocator, 13 + ) -> sqlite.Result_Code { 14 + 15 + id := db_pkg.gen_id("album", allocator) 16 + defer delete(id, allocator) 17 + 18 + 19 + params := make([dynamic]sa.Query_Param, 2, 4, allocator) 20 + defer delete_dynamic_array(params) 21 + 22 + params[0] = sa.Query_Param{1, id} 23 + params[1] = sa.Query_Param{2, album.title} 24 + 25 + 26 + mb_id, mb_rg_id: string 27 + ok: bool 28 + 29 + mb_id, ok = album.mb_id.? 30 + if ok do append(&params, sa.Query_Param{3, mb_id}) 31 + 32 + mb_rg_id, ok = album.mb_rg_id.? 33 + if ok do append(&params, sa.Query_Param{4, mb_rg_id}) 34 + 35 + return sa.execute( 36 + db, 37 + "INSERT INTO album (id, title, mb_id, mb_rg_id) VALUES (?, ?, ?, ?)", 38 + params[:], 39 + ) 40 + } 41 + 42 + 43 + new_album_batch :: proc( 44 + db: ^sqlite.Connection, 45 + albums: []types.Album, 46 + allocator := context.allocator, 47 + ) -> sqlite.Result_Code { 48 + 49 + rc: sqlite.Result_Code 50 + 51 + n := len(albums) 52 + 53 + 54 + fmt.printfln("Starting transaction") 55 + rc = sa.execute(db, "BEGIN TRANSACTION;") 56 + assert(rc == .Ok) 57 + 58 + for album in albums { 59 + fmt.printfln("Inserting %v", album) 60 + rc = new_album(db, album, allocator) 61 + assert(rc == .Ok) 62 + } 63 + 64 + fmt.printfln("Commiting transaction") 65 + rc = sa.execute(db, "COMMIT;") 66 + assert(rc == .Ok) 67 + 68 + return rc 69 + } 70 + 71 + get_album_by_id :: proc( 72 + db: ^sqlite.Connection, 73 + id: string, 74 + allocator := context.allocator, 75 + ) -> ( 76 + res: types.Album, 77 + ok: bool, 78 + ) { 79 + 80 + params := []sa.Query_Param{{1, id}} 81 + query := "SELECT * FROM album WHERE id = ? LIMIT 1" 82 + 83 + albums := make([dynamic]types.Album, 0, 1) 84 + 85 + rc := sa.query(db, &albums, query, params) 86 + if (rc != .Ok || len(albums) != 1) { 87 + return res, false 88 + } 89 + 90 + return albums[0], true 91 + }
+104
src/db/repo/album.test.odin
··· 1 + 2 + package repo 3 + 4 + import db_pkg "../" 5 + import sqlite "../../../vendor/sqlite" 6 + import types "../../core" 7 + import "core:fmt" 8 + import "core:mem" 9 + import "core:testing" 10 + 11 + 12 + @(test) 13 + should_create_new_album :: proc(t: ^testing.T) { 14 + 15 + 16 + track: mem.Tracking_Allocator 17 + mem.tracking_allocator_init(&track, context.allocator) 18 + context.allocator = mem.tracking_allocator(&track) 19 + defer { 20 + if len(track.allocation_map) > 0 { 21 + fmt.eprintf("=== %v allocations not freed: ===\n", len(track.allocation_map)) 22 + for _, entry in track.allocation_map { 23 + fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location) 24 + } 25 + } 26 + if len(track.bad_free_array) > 0 { 27 + fmt.eprintf("=== %v incorrect frees: ===\n", len(track.bad_free_array)) 28 + for entry in track.bad_free_array { 29 + fmt.eprintf("- %p @ %v\n", entry.memory, entry.location) 30 + } 31 + } 32 + mem.tracking_allocator_destroy(&track) 33 + } 34 + 35 + 36 + db: ^sqlite.Connection 37 + 38 + if rc := sqlite.open(db_pkg.db_url, &db); rc != .Ok { 39 + fmt.panicf("failed to open database. result code {}", rc) 40 + } 41 + fmt.printfln("connected to database") 42 + 43 + defer { 44 + sqlite.close(db) 45 + fmt.printfln("\nconnection closed") 46 + } 47 + 48 + album := types.Album { 49 + id = "test", 50 + title = "Test title", 51 + mb_id = "asdf", 52 + mb_rg_id = "asdf", 53 + } 54 + 55 + rc := new_album(db, album) 56 + testing.expect(t, rc == .Ok) 57 + 58 + } 59 + 60 + 61 + @(test) 62 + should_get_album_by_id :: proc(t: ^testing.T) { 63 + 64 + 65 + track: mem.Tracking_Allocator 66 + mem.tracking_allocator_init(&track, context.allocator) 67 + context.allocator = mem.tracking_allocator(&track) 68 + defer { 69 + if len(track.allocation_map) > 0 { 70 + fmt.eprintf("=== %v allocations not freed: ===\n", len(track.allocation_map)) 71 + for _, entry in track.allocation_map { 72 + fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location) 73 + } 74 + } 75 + if len(track.bad_free_array) > 0 { 76 + fmt.eprintf("=== %v incorrect frees: ===\n", len(track.bad_free_array)) 77 + for entry in track.bad_free_array { 78 + fmt.eprintf("- %p @ %v\n", entry.memory, entry.location) 79 + } 80 + } 81 + mem.tracking_allocator_destroy(&track) 82 + } 83 + 84 + 85 + db: ^sqlite.Connection 86 + 87 + if rc := sqlite.open(db_pkg.db_url, &db); rc != .Ok { 88 + fmt.panicf("failed to open database. result code {}", rc) 89 + } 90 + fmt.printfln("connected to database") 91 + 92 + defer { 93 + sqlite.close(db) 94 + fmt.printfln("\nconnection closed") 95 + } 96 + 97 + 98 + input := "album_019cf0fc-b57a-7f58-a298-ad3166101dd9" 99 + 100 + album, ok := get_album_by_id(db, input) 101 + testing.expect(t, ok) 102 + testing.expect(t, album.title == "Test title") 103 + 104 + }