• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pkgxdev / libpkgx / 11988253053

23 Nov 2024 03:17PM UTC coverage: 82.734% (-0.1%) from 82.843%
11988253053

push

github

mxcl
If sqlite doesn’t load fall back to old mechanism

553 of 735 branches covered (75.24%)

Branch coverage included in aggregate %.

4 of 12 new or added lines in 1 file covered. (33.33%)

2461 of 2908 relevant lines covered (84.63%)

2695.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.66
/src/hooks/useSyncCache.ts
1
import { Database } from "../../vendor/sqlite3@0.10.0/mod.ts";
34✔
2
import * as pkgutils from "../utils/pkg.ts";
34✔
3
import usePantry from "./usePantry.ts";
34✔
4
import useConfig from "./useConfig.ts";
34✔
5

6
export default async function() {
34✔
7
  if (Deno.build.os == 'windows') return
×
8

9
  const path = useConfig().cache.join('pantry.db').rm()  // delete it first so pantry instantiation doesn't use cache
36✔
10
  const { ls, ...pantry } = usePantry()
36✔
11

12
  const sqlite3 = (await install_sqlite())?.string
36✔
13
  if (!sqlite3) return
×
14
  const db = new Database(path.string, { sqlite3 })
108✔
15

16
  // unique or don’t insert what is already there or just dump tables first perhaps
36✔
17

18
  try {
36✔
19
    // speeds up by using memory as much as possible
36✔
20
    db.exec(`
36✔
21
      PRAGMA synchronous = OFF;
22
      PRAGMA journal_mode = MEMORY;
23
      PRAGMA temp_store = MEMORY;
24
      `);
36✔
25

26
    await db.transaction(async () => {
36✔
27
      db.exec(`
38✔
28
        DROP TABLE IF EXISTS provides;
29
        DROP TABLE IF EXISTS dependencies;
30
        DROP TABLE IF EXISTS companions;
31
        DROP TABLE IF EXISTS runtime_env;
32
        CREATE TABLE provides (
33
          project TEXT,
34
          program TEXT
35
        );
36
        CREATE TABLE dependencies (
37
          project TEXT,
38
          pkgspec TEXT
39
        );
40
        CREATE TABLE companions (
41
          project TEXT,
42
          pkgspec TEXT
43
        );
44
        CREATE TABLE runtime_env (
45
          project TEXT,
46
          envline TEXT
47
        );
48
        CREATE INDEX idx_project ON provides(project);
49
        CREATE INDEX idx_program ON provides(program);
50
        CREATE INDEX idx_project_dependencies ON dependencies(project);
51
        CREATE INDEX idx_project_companions ON companions(project);
52
        `);
38✔
53

54
      for await (const pkg of ls()) {
38✔
55
        if (!pkg.path.string.startsWith(pantry.prefix.string)) {
×
56
          // don’t cache PKGX_PANTRY_PATH additions
57
          continue;
×
58
        }
×
59

60
        try {
3,088✔
61
          const project = pantry.project(pkg.project)
3,088✔
62
          const [programs, deps, companions, yaml] = await Promise.all([
3,088✔
63
            project.provides(),
3,088✔
64
            project.runtime.deps(),
3,088✔
65
            project.companions(),
3,088✔
66
            project.yaml()
3,088✔
67
          ])
3,088✔
68

69
          for (const program of programs) {
3,088✔
70
            db.exec(`INSERT INTO provides (project, program) VALUES ('${pkg.project}', '${program}');`);
10,501✔
71
          }
10,501✔
72

73
          for (const dep of deps) {
3,088✔
74
            db.exec(`INSERT INTO dependencies (project, pkgspec) VALUES ('${pkg.project}', '${pkgutils.str(dep)}')`);
7,376✔
75
          }
7,376✔
76

77
          for (const companion of companions) {
3,088✔
78
            db.exec(`INSERT INTO companions (project, pkgspec) VALUES ('${pkg.project}', '${pkgutils.str(companion)}')`);
3,192✔
79
          }
3,192✔
80

81
          for (const [key, value] of Object.entries(yaml.runtime?.env ?? {})) {
3,088✔
82
            db.exec(`INSERT INTO runtime_env (project, envline) VALUES ('${pkg.project}', '${key}=${value}')`);
3,400✔
83
          }
3,400✔
84
        } catch {
×
85
          console.warn("corrupt yaml", pkg.path)
×
86
        }
×
87
      }
3,088✔
88
    })()
36✔
89
  } catch (err) {
×
90
    path.rm()
×
91
    throw err
×
92
  } finally {
×
93
    db.close();
36✔
94
  }
36✔
95
}
36✔
96

97
export async function provides(program: string) {
34✔
98
  const db = await _db()
36✔
99
  if (!db) return
×
100
  try {
36✔
101
   return db.sql`SELECT project FROM provides WHERE program = ${program}`.map(x => x.project);
36✔
102
  } finally {
36✔
103
    db.close()
36✔
104
  }
36✔
105
}
36✔
106

107
export async function dependencies(project: string) {
×
108
  const db = await _db()
×
109
  if (!db) return
×
110
  try {
×
111
    return db.sql`SELECT pkgspec FROM dependencies WHERE project = ${project}`.map(x => pkgutils.parse(x.pkgspec));
×
112
  } finally {
×
113
    db.close()
×
114
  }
×
115
}
×
116

117
export async function completion(prefix: string) {
34✔
118
  const db = await _db()
36✔
119
  try {
36✔
120
    return db?.prepare(`SELECT program FROM provides WHERE program LIKE '${prefix}%'`).value<[string]>()!;
36✔
121
  } finally {
36✔
122
    db?.close()
36✔
123
  }
36✔
124
}
36✔
125

126
/// is the cache available?
2✔
127
export function available() {
34✔
128
  if (Deno.build.os == 'windows') {
×
129
    return false
×
130
  } else {
×
131
    const path = useConfig().cache.join('pantry.db')
242✔
132
    return path.isFile()
242✔
133
  }
242✔
134
}
242✔
135

136
export async function companions(project: string) {
34✔
137
  const db = await _db()
36✔
138
  if (!db) return
×
139
  try {
36✔
140
    return db.sql`SELECT pkgspec FROM companions WHERE project = ${project}`.map(x => pkgutils.parse(x.pkgspec));
36✔
141
  } finally {
36✔
142
    db.close()
36✔
143
  }
36✔
144
}
36✔
145

146
export async function runtime_env(project: string) {
34✔
147
  const db = await _db()
36✔
148
  if (!db) return
×
149
  try {
36✔
150
    const rv: Record<string, string> = {}
36✔
151
    for (const {envline: line} of db.sql`SELECT envline FROM runtime_env WHERE project = ${project}`) {
36✔
152
      const [key, ...rest] = line.split("=")
36✔
153
      rv[key] = rest.join('=')
36✔
154
    }
36✔
155
    return rv
36✔
156
  } finally {
36✔
157
    db.close()
36✔
158
  }
36✔
159
}
36✔
160

161
import useCellar from "./useCellar.ts"
34✔
162

163
async function _db() {
42✔
164
  try {
42✔
NEW
165
    if (Deno.build.os == 'windows') return
×
166
    const path = useConfig().cache.join('pantry.db')
42✔
NEW
167
    if (!path.isFile()) return
×
168
    const sqlite = await useCellar().has({ project: "sqlite.org", constraint: new semver.Range('*') })
168✔
NEW
169
    if (!sqlite) return
×
NEW
170
    const ext = host().platform == 'darwin' ? 'dylib' : 'so'
×
171
    return new Database(path.string, {readonly: true, sqlite3: sqlite.path.join(`lib/libsqlite3.${ext}`).string})
168✔
NEW
172
  } catch {
×
NEW
173
    console.warn("couldn’t load pantry.db")
×
NEW
174
    return
×
NEW
175
  }
×
176
}
42✔
177

178
import install from "../porcelain/install.ts"
34✔
179
import host from "../utils/host.ts";
34✔
180
import Path from "../utils/Path.ts";
181
import { semver } from "../../mod.ts";
34✔
182

183
async function install_sqlite(): Promise<Path | undefined> {
36✔
184
  const foo = await install("sqlite.org")
36✔
185
  for (const bar of foo) {
36✔
186
    if (bar.pkg.project == 'sqlite.org') {
38✔
187
      const ext = host().platform == 'darwin' ? 'dylib' : 'so'
×
188
      return bar.path.join(`lib/libsqlite3.${ext}`)
39✔
189
    }
39✔
190
  }
38!
191
}
36✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc