⭐ Moe-Counter Compatible Website Hit Counter Written in Gleam mayu.due.moe
hit-counter svg moe
at main 85 lines 2.1 kB view raw
1import gleam/dynamic 2import gleam/option 3import sqlight 4import wisp 5 6pub type Counter { 7 Counter(name: String, num: Int, created_at: String, updated_at: String) 8} 9 10pub fn setup(connection) { 11 let _ = 12 sqlight.exec( 13 "pragma foreign_keys = off; 14 15 create table if not exists tb_count ( 16 id integer primary key autoincrement not null unique, 17 name text not null unique, 18 num int not null default (0) 19 ) strict;", 20 connection, 21 ) 22 let add_column = fn(name) { 23 let _ = 24 sqlight.exec( 25 "alter table tb_count add column " <> name <> " text;", 26 connection, 27 ) 28 29 Nil 30 } 31 32 add_column("created_at") 33 add_column("updated_at") 34 35 Nil 36} 37 38pub fn get_counter(connection, name) { 39 case name { 40 "demo" -> Ok(Counter("demo", 1_234_567_890, "", "")) 41 _ -> { 42 case 43 sqlight.query( 44 "INSERT INTO tb_count (name, created_at, updated_at, num) 45 VALUES (?1, datetime('now'), datetime('now'), 1) 46 ON CONFLICT(name) DO UPDATE SET 47 num = tb_count.num + 1, 48 updated_at = datetime('now') 49 RETURNING name, num, created_at, updated_at;", 50 with: [sqlight.text(name)], 51 on: connection, 52 expecting: dynamic.tuple4( 53 dynamic.string, 54 dynamic.int, 55 dynamic.optional(dynamic.string), 56 dynamic.optional(dynamic.string), 57 ), 58 ) 59 { 60 Ok([row]) -> 61 Ok(Counter( 62 row.0, 63 row.1, 64 option.unwrap(row.2, ""), 65 option.unwrap(row.3, ""), 66 )) 67 Ok([]) -> { 68 wisp.log_error("Database query returned no rows unexpectedly.") 69 70 Error("Unreachable entity") 71 } 72 Ok([_, _, ..]) -> { 73 wisp.log_error("Database query returned multiple rows unexpectedly.") 74 75 Error("Unreachable entity") 76 } 77 Error(_) -> { 78 wisp.log_error("Database query failed.") 79 80 Error("Database operation failed") 81 } 82 } 83 } 84 } 85}