aboutsummaryrefslogtreecommitdiff
path: root/src/database.gleam
blob: 7a1f86bbcd50736e214f8b5c5f1baf6db3994ac2 (plain) (blame)
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
import gleam/dynamic
import gleam/list
import gleam/option
import sqlight
import wisp

pub type Counter {
  Counter(name: String, num: Int, created_at: String, updated_at: String)
}

pub fn setup(connection) {
  let assert Ok(_) =
    sqlight.exec(
      "create table if not exists tb_count (
        id integer primary key autoincrement not null unique,
        name text not null unique,
        num int not null default (0)
      ) strict;",
      connection,
    )
  let existing_column_names = existing_columns(connection)
  let ensure_column = fn(name) {
    case list.contains(existing_column_names, name) {
      True -> Nil
      False -> {
        let assert Ok(_) =
          sqlight.exec(
            "alter table tb_count add column " <> name <> " text;",
            connection,
          )

        Nil
      }
    }
  }

  ensure_column("created_at")
  ensure_column("updated_at")

  Nil
}

fn existing_columns(connection) -> List(String) {
  let assert Ok(columns) =
    sqlight.query(
      "pragma table_info('tb_count');",
      with: [],
      on: connection,
      expecting: dynamic.element(1, dynamic.string),
    )

  columns
}

pub fn get_counter(connection, name) {
  case name {
    "demo" -> Ok(Counter("demo", 1_234_567_890, "", ""))
    _ -> {
      case
        sqlight.query(
          "INSERT INTO tb_count (name, created_at, updated_at, num)
           VALUES (?1, datetime('now'), datetime('now'), 1)
           ON CONFLICT(name) DO UPDATE SET
             num = tb_count.num + 1,
             updated_at = datetime('now')
           RETURNING name, num, created_at, updated_at;",
          with: [sqlight.text(name)],
          on: connection,
          expecting: dynamic.tuple4(
            dynamic.string,
            dynamic.int,
            dynamic.optional(dynamic.string),
            dynamic.optional(dynamic.string),
          ),
        )
      {
        Ok([row]) ->
          Ok(Counter(
            row.0,
            row.1,
            option.unwrap(row.2, ""),
            option.unwrap(row.3, ""),
          ))
        _ -> {
          wisp.log_error("Database query failed or returned unexpected rows.")

          Error("Database operation failed")
        }
      }
    }
  }
}