aboutsummaryrefslogtreecommitdiffstats
path: root/ui/src/state/runbooks/runbook.ts
blob: 8555f4ea1594004567c00af8b07c159af5b4cf52 (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
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
import Database from "@tauri-apps/plugin-sql";
import { uuidv7 } from "uuidv7";

export default class Runbook {
  id: string;
  created: Date;
  updated: Date;

  private _name: string;
  private _content: string;

  set name(value: string) {
    this.updated = new Date();
    this._name = value;
  }

  set content(value: string) {
    this.updated = new Date();
    this._content = value;
  }

  get content() {
    return this._content;
  }

  get name() {
    return this._name;
  }

  constructor(
    id: string,
    name: string,
    content: string,
    created: Date,
    updated: Date,
  ) {
    this.id = id;
    this._name = name;
    this._content = content;
    this.created = created;
    this.updated = updated;
  }

  /// Create a new Runbook, and automatically generate an ID.
  public static async create(): Promise<Runbook> {
    let now = new Date();

    // Initialize with the same value for created/updated, to avoid needing null.
    let runbook = new Runbook(uuidv7(), "", "", now, now);
    await runbook.save();

    return runbook;
  }

  public static async load(id: String): Promise<Runbook | null> {
    const db = await Database.load("sqlite:runbooks.db");

    let res = await db.select<any[]>("select * from runbooks where id = $1", [
      id,
    ]);

    if (res.length == 0) return null;

    let rb = res[0];

    return new Runbook(
      rb.id,
      rb.name,
      rb.content,
      new Date(rb.created / 1000000),
      new Date(rb.updated / 1000000),
    );
  }

  static async all(): Promise<Runbook[]> {
    const db = await Database.load("sqlite:runbooks.db");

    let res = await db.select<any[]>(
      "select * from runbooks order by updated desc",
    );

    return res.map((i) => {
      return new Runbook(
        i.id,
        i.name,
        i.content,
        new Date(i.created / 1000000),
        new Date(i.updated / 1000000),
      );
    });
  }

  public async save() {
    const db = await Database.load("sqlite:runbooks.db");

    await db.execute(
      `insert into runbooks(id, name, content, created, updated)
          values ($1, $2, $3, $4, $5)

          on conflict(id) do update
            set
              name=$2,
              content=$3,
              updated=$5`,

      // getTime returns a timestamp as unix milliseconds
      // we won't need or use the resolution here, but elsewhere Atuin stores timestamps in sqlite as nanoseconds since epoch
      // let's do that across the board to avoid mistakes
      [
        this.id,
        this._name,
        this._content,
        this.created.getTime() * 1000000,
        this.updated.getTime() * 1000000,
      ],
    );
  }

  public static async delete(id: string) {
    const db = await Database.load("sqlite:runbooks.db");

    await db.execute("delete from runbooks where id=$1", [id]);
  }
}