Merged 1.3.x_branch into master
This commit is contained in:
13
README.md
13
README.md
@@ -102,6 +102,19 @@ await api.directory.list('/', async (remote_path, page_count, get_page) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Asynchronous directory list
|
||||
const snap = await api.directory.snapshot('/');
|
||||
try {
|
||||
for (let i = 0; i < snap.page_count; i++) {
|
||||
const items = await snap.get_page(i); // Always 'await'
|
||||
console.log(items);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
} finally {
|
||||
await snap.release();
|
||||
}
|
||||
|
||||
// Create new directory
|
||||
await api.directory.create('/test');
|
||||
|
||||
|
||||
@@ -91,12 +91,12 @@ test('can create and remove a directory using api', async () => {
|
||||
await conn.disconnect();
|
||||
});
|
||||
|
||||
test('can get directory list using api', async () => {
|
||||
test('can get directory list and snapshot using api', async () => {
|
||||
const conn =
|
||||
await repertory.create_pool(2, TEST_HOST, TEST_PORT, TEST_PASSWORD);
|
||||
const api = repertory.create_api(conn);
|
||||
await api.directory.list('/', async (remote_path, page_count, get_page) => {
|
||||
console.log(remote_path, page_count, get_page);
|
||||
|
||||
const test_results = async (remote_path, page_count, get_page) => {
|
||||
expect(remote_path).toEqual('/');
|
||||
expect(page_count).toBeGreaterThanOrEqual(1);
|
||||
expect(get_page).toBeInstanceOf(Function);
|
||||
@@ -110,8 +110,23 @@ test('can get directory list using api', async () => {
|
||||
expect(items[1].directory).toBeTruthy();
|
||||
expect(items[1].path).toEqual('..');
|
||||
}
|
||||
};
|
||||
|
||||
await api.directory.list('/', async (remote_path, page_count, get_page) => {
|
||||
console.log(remote_path, page_count, get_page);
|
||||
await test_results(remote_path, page_count, get_page);
|
||||
});
|
||||
|
||||
const snap = await api.directory.snapshot('/');
|
||||
try {
|
||||
console.log(snap.remote_path, snap.page_count, snap.get_page);
|
||||
await test_results(snap.remote_path, snap.page_count, snap.get_page);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
} finally {
|
||||
await snap.release();
|
||||
}
|
||||
|
||||
await conn.disconnect();
|
||||
});
|
||||
|
||||
|
||||
@@ -12,10 +12,13 @@ export const connect = async (host_or_ip, port, password) => {
|
||||
export const create_api = conn => {
|
||||
return {
|
||||
directory : {
|
||||
list : async (remote_path, page_reader_cb) =>
|
||||
create: async remote_path => ops.create_directory(conn, remote_path),
|
||||
list: async (remote_path, page_reader_cb) =>
|
||||
ops.list_directory(conn, remote_path, page_reader_cb),
|
||||
create : async remote_path => ops.create_directory(conn, remote_path),
|
||||
remove : async remote_path => ops.remove_directory(conn, remote_path),
|
||||
remove: async remote_path => ops.remove_directory(conn, remote_path),
|
||||
snapshot: async remote_path => {
|
||||
return ops.snapshot_directory(conn, remote_path);
|
||||
},
|
||||
},
|
||||
file : {
|
||||
create_or_open : async remote_path => new file(
|
||||
|
||||
132
src/ops/index.js
132
src/ops/index.js
@@ -4,6 +4,69 @@ import {Uint64BE} from 'int64-buffer';
|
||||
import file from '../io/file';
|
||||
import packet from '../networking/packet';
|
||||
|
||||
const _snapshot_directory = async (conn, remote_path) => {
|
||||
try {
|
||||
const request = new packet();
|
||||
request.encode_utf8(remote_path);
|
||||
|
||||
const response =
|
||||
await conn.send('::RemoteJSONCreateDirectorySnapshot', request);
|
||||
response.decode_ui32(); // Service flags
|
||||
|
||||
const result = response.decode_i32();
|
||||
if (result === 0) {
|
||||
const data = JSON.parse(response.decode_utf8());
|
||||
|
||||
let released = false;
|
||||
const release = async () => {
|
||||
if (!released) {
|
||||
released = true;
|
||||
const request = new packet();
|
||||
request.encode_ui64(data.handle);
|
||||
await conn.send('::RemoteJSONReleaseDirectorySnapshot', request);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
const get_page = async page => {
|
||||
try {
|
||||
const request = new packet();
|
||||
request.encode_utf8(remote_path);
|
||||
request.encode_ui64(data.handle);
|
||||
request.encode_ui32(page);
|
||||
|
||||
const response =
|
||||
await conn.send('::RemoteJSONReadDirectorySnapshot', request);
|
||||
response.decode_ui32(); // Service flags
|
||||
|
||||
const result = response.decode_i32();
|
||||
if (result === 0 || result === -120) {
|
||||
const data = JSON.parse(response.decode_utf8());
|
||||
return data.directory_list;
|
||||
}
|
||||
} catch (err) {
|
||||
await release();
|
||||
return Promise.reject(new Error(`'get_page' failed: ${err}`));
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
return {
|
||||
get_page,
|
||||
page_count: data.page_count,
|
||||
release,
|
||||
remote_path,
|
||||
};
|
||||
} catch (err) {
|
||||
await release();
|
||||
return Promise.reject(new Error(`'snapshot_directory' failed: ${err}`));
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
return Promise.reject(new Error(`'snapshot_directory' failed: ${err}`));
|
||||
}
|
||||
};
|
||||
|
||||
export const close_file =
|
||||
async (conn, remote_path, handle, optional_thread_id) => {
|
||||
try {
|
||||
@@ -19,7 +82,7 @@ export const close_file =
|
||||
} catch (err) {
|
||||
return Promise.reject(new Error(`'close_file' failed: ${err}`));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const create_directory = async (conn, remote_path) => {
|
||||
try {
|
||||
@@ -57,7 +120,7 @@ export const create_or_open_file =
|
||||
} catch (err) {
|
||||
return Promise.reject(new Error(`'create_or_open_file' failed: ${err}`));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const delete_file = async (conn, remote_path) => {
|
||||
try {
|
||||
@@ -158,7 +221,7 @@ export const download_file =
|
||||
} catch (err) {
|
||||
return Promise.reject(new Error(`'download_file' failed: ${err}`));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const get_drive_information = async conn => {
|
||||
try {
|
||||
@@ -173,7 +236,7 @@ export const get_drive_information = async conn => {
|
||||
return {
|
||||
free,
|
||||
total,
|
||||
used : (new Uint64BE(total) - new Uint64BE(free)).toString(10),
|
||||
used: (new Uint64BE(total) - new Uint64BE(free)).toString(10),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -206,53 +269,16 @@ export const get_file_attributes =
|
||||
} catch (err) {
|
||||
return Promise.reject(new Error(`'get_file_attributes' failed: ${err}`));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const list_directory = async (conn, remote_path, page_reader_cb) => {
|
||||
const dir_snapshot = await _snapshot_directory(conn, remote_path);
|
||||
try {
|
||||
const request = new packet();
|
||||
request.encode_utf8(remote_path);
|
||||
|
||||
const response =
|
||||
await conn.send('::RemoteJSONCreateDirectorySnapshot', request);
|
||||
response.decode_ui32(); // Service flags
|
||||
|
||||
const result = response.decode_i32();
|
||||
if (result === 0) {
|
||||
const data = JSON.parse(response.decode_utf8());
|
||||
const cleanup = async () => {
|
||||
const request = new packet();
|
||||
request.encode_ui64(data.handle);
|
||||
await conn.send('::RemoteJSONReleaseDirectorySnapshot', request);
|
||||
};
|
||||
try {
|
||||
const get_page = async page => {
|
||||
const request = new packet();
|
||||
request.encode_utf8(remote_path);
|
||||
request.encode_ui64(data.handle);
|
||||
request.encode_ui32(page);
|
||||
|
||||
const response =
|
||||
await conn.send('::RemoteJSONReadDirectorySnapshot', request);
|
||||
response.decode_ui32(); // Service flags
|
||||
|
||||
const result = response.decode_i32();
|
||||
if (result === 0 || result === -120) {
|
||||
const data = JSON.parse(response.decode_utf8());
|
||||
return data.directory_list;
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
await page_reader_cb(remote_path, data.page_count, get_page);
|
||||
await cleanup();
|
||||
await page_reader_cb(dir_snapshot.remote_path, dir_snapshot.page_count, dir_snapshot.get_page);
|
||||
await dir_snapshot.release();
|
||||
} catch (err) {
|
||||
await cleanup();
|
||||
return Promise.reject(new Error(`'list_directory' failed: ${err}`));
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
return Promise.reject(new Error(`'list_directory' failed: ${err}`));
|
||||
await dir_snapshot.release();
|
||||
return Promise.reject(`'list_directory' failed: ${err}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -297,7 +323,7 @@ export const read_file =
|
||||
} catch (err) {
|
||||
return Promise.reject(new Error(`'read_file' failed: ${err}`));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const remove_directory = async (conn, remote_path) => {
|
||||
try {
|
||||
@@ -313,6 +339,8 @@ export const remove_directory = async (conn, remote_path) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const snapshot_directory = _snapshot_directory;
|
||||
|
||||
export const truncate_file =
|
||||
async (conn, handle, remote_path, length, optional_thread_id) => {
|
||||
try {
|
||||
@@ -329,7 +357,7 @@ export const truncate_file =
|
||||
} catch (err) {
|
||||
return Promise.reject(new Error(`'truncate_file' failed: ${err}`));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const upload_file =
|
||||
async (conn, local_path, remote_path, progress_cb, overwrite, resume) => {
|
||||
@@ -387,7 +415,7 @@ export const upload_file =
|
||||
new file(conn, await open_file(conn, remote_path), remote_path);
|
||||
await cleanup(f);
|
||||
return Promise.reject(
|
||||
new Error("'upload_file' failed: file exists"));
|
||||
new Error('\'upload_file\' failed: file exists'));
|
||||
} catch (err) {
|
||||
await create_dest();
|
||||
}
|
||||
@@ -431,7 +459,7 @@ export const upload_file =
|
||||
} catch (err) {
|
||||
return Promise.reject(new Error(`'upload_file' failed: ${err}`));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const write_file =
|
||||
async (conn, handle, remote_path, offset, buffer, optional_thread_id) => {
|
||||
@@ -455,4 +483,4 @@ export const write_file =
|
||||
} catch (err) {
|
||||
return Promise.reject(new Error(`'write_file' failed: ${err}`));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user