Skip to content

Instantly share code, notes, and snippets.

@magicien
Last active October 7, 2017 23:15
Show Gist options
  • Save magicien/1645bb878d2960fb544c83fef43ccbd9 to your computer and use it in GitHub Desktop.
Save magicien/1645bb878d2960fb544c83fef43ccbd9 to your computer and use it in GitHub Desktop.
async function getResult(request) {
const promise = new Promise((resolve, reject) => {
request.onsuccess = () => {
resolve(request.result)
}
request.onerror = () => {
reject(request.error)
}
})
return promise
}
async function waitTransaction(transaction) {
const promise = new Promise((resolve, reject) => {
transaction.oncomplete = () => {
resolve()
}
transaction.onerror = () => {
reject(transaction.error)
}
transaction.onabort = () => {
// QuotaExceededError とか
reject(transaction.error)
}
})
return promise
}
async function getDB(name) {
const version = 1 // onupgradeneededの処理内容を変えた場合は、バージョンを上げる
const request = window.indexedDB.open(dbName, version)
request.onupgradeneeded = () => {
// DB作成時の処理。Storeの作成とかインデックス設定はここでしかできない。
const db = request.result
const filesStore = db.createObjectStore('files', { keyPath: 'path' })
// keyPath の他にインデックスを作るならこんな感じ。
// filesStore.createIndex('category', 'category', { unique: false })
}
return getResult(request)
}
async function deleteDB(name) {
const request = window.indexedDB.deleteDatabase(name)
return getResult(request)
}
async function getAllRecords(dbName, storeName) {
const db = await getDB(dbName)
const transaction = db.transaction(storeName, 'readonly')
const store = transaction.objectStore(storeName)
return getResult(store.getAll())
}
async function parseZip(zip) {
const fileArray = []
for(const fileName of Object.keys(zip.files)){
const file = zip.file(fileName)
const isDir = (file === null || file.dir)
let content = null
if(!isDir){
content = await file.async('blob')
}
fileArray.push({
path: fileName, // pathがキー値なので、重複するとエラー。というか上書きされる。
dir: isDir,
content // Blobも保存できる
})
}
return fileArray
}
async function putFiles(files) {
const db = await getDB('github')
const transaction = db.transaction('files', 'readwrite')
const filesStore = transaction.objectStore('files')
for(const file of files){
filesStore.put(file)
}
return waitTransaction(transaction)
}
async function getFiles() {
return getAllRecords('github', 'files')
}
const zip = ... // 前回取得したJSZipのZipObject
// zipをIndexedDB(DB名:github、Store名:files)に保存する
const promise = parseZip(zip)
.then((files) => putFiles(files))
.catch((err) => {
console.error(err)
})
// 保存した値を取得する
promise
.then(() => getFiles())
.then((files) => {
for(const file of files){
console.log(`file path: ${file.path}`)
}
})
.catch((err) => {
console.error(err)
}
// ディスク使用量と上限を確認
navigator.storage.estimate().then(console.log)
// => {quota: 1022017842, usage: 195357} 単位はbyte
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment