Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add drive.rename(oldPath, newPath) #376

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,20 @@ console.log(entry) // => { seq, key, value: { executable, linkname, blob, metada

await drive.del('/images/old-logo.png')

await drive.rename('/images/blob.txt', '/images/example.txt')

await drive.symlink('/images/logo.shortcut', '/images/logo.png')

for await (const file of drive.list('/images')) {
console.log('list', file) // => { key, value }
}

const rs = drive.createReadStream('/blob.txt')
const rs = drive.createReadStream('/images/example.txt')
for await (const chunk of rs) {
console.log('rs', chunk) // => <Buffer ..>
}

const ws = drive.createWriteStream('/blob.txt')
const ws = drive.createWriteStream('/images/example.txt')
ws.write('new example')
ws.end()
ws.once('close', () => console.log('file saved'))
Expand Down Expand Up @@ -204,6 +206,10 @@ A `blobs: <length>` option can be passed in if you know the corresponding blobs

Purge both cores (db and blobs) from your storage, completely removing all the drive's data.

#### `await drive.rename(oldPath, newPath, [options])`

Renames a single `oldPath` entry in the drive to be `newPath`. `options` are the same as in `get`.

#### `await drive.symlink(path, linkname)`

Creates an entry in drive at `path` that points to the entry at `linkname`.
Expand Down
10 changes: 10 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,16 @@ module.exports = class Hyperdrive extends ReadyResource {
await Promise.all(proms)
}

async rename (oldPath, newPath, opts) {
const b = this.batch()
const existingEntry = await b.entry(oldPath, opts)
if (existingEntry === null) return b.flush()

await b.db.del(std(oldPath, false), { keyEncoding })
await b.db.put(std(newPath, false), existingEntry.value, { keyEncoding })
return b.flush()
}

async symlink (name, dst, { metadata = null } = {}) {
return this.db.put(std(name, false), { executable: false, linkname: dst, blob: null, metadata }, { keyEncoding })
}
Expand Down
33 changes: 33 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,39 @@ test('drive.del() deletes entry at path', async (t) => {
t.is(entry, null)
})

test('drive.rename(oldPath, newPath) updates the entry at <oldPath> to use <newPath> as a key', async (t) => {
const { drive } = await testenv(t.teardown)
const buf = fs.readFileSync(__filename)
await drive.put(__filename, buf)
await drive.rename(__filename, 'new-file')
const resultOld = await drive.get(__filename)
t.is(resultOld, null)
const resultNew = await drive.get('new-file')
t.is(b4a.compare(buf, resultNew), 0)
})

test('drive.rename(oldPath, newPath) does nothing if renaming a non-existing <oldPath>', async (t) => {
const { drive } = await testenv(t.teardown)
const buf = fs.readFileSync(__filename)
await drive.put(__filename, buf)
await drive.rename('non-existing', 'new-file')
const resultOld = await drive.get(__filename)
t.is(b4a.compare(buf, resultOld), 0)
const resultNew = await drive.get('new-file')
t.is(resultNew, null)
})

test('drive.rename(oldPath, newPath) can rename a symlink', async (t) => {
const { drive } = await testenv(t.teardown)
const buf = fs.readFileSync(__filename)
await drive.put(__filename, buf)
await drive.symlink('pointer', __filename)
await drive.rename('pointer', 'new-pointer')
const entry = await drive.entry('new-pointer')
t.is(entry.value.linkname, __filename)
t.is(b4a.compare(buf, await drive.get(entry.value.linkname)), 0)
})

test('drive.symlink(from, to) updates the entry at <from> to include a reference for <to>', async (t) => {
const { drive } = await testenv(t.teardown)
const buf = fs.readFileSync(__filename)
Expand Down