Skip to content
Closed
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
274 changes: 143 additions & 131 deletions Libraries/Storage/AsyncStorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
*/
'use strict';

import type { AsyncStorageBackend } from './AsyncStorageTypes';

var NativeModules = require('NativeModules');
var RCTAsyncSQLiteStorage = NativeModules.AsyncSQLiteDBStorage;
var RCTAsyncRocksDBStorage = NativeModules.AsyncRocksDBStorage;
Expand Down Expand Up @@ -144,59 +146,6 @@ var AsyncStorage = {
});
},

/**
* Merges an existing `key` value with an input value, assuming both values
* are stringified JSON. Returns a `Promise` object.
*
* **NOTE:** This is not supported by all native implementations.
*
* @param key Key of the item to modify.
* @param value New value to merge for the `key`.
* @param callback Function that will be called with any error.
* @returns A `Promise` object.
*
* @example <caption>Example</caption>
* let UID123_object = {
* name: 'Chris',
* age: 30,
* traits: {hair: 'brown', eyes: 'brown'},
* };
* // You only need to define what will be added or updated
* let UID123_delta = {
* age: 31,
* traits: {eyes: 'blue', shoe_size: 10}
* };
*
* AsyncStorage.setItem('UID123', JSON.stringify(UID123_object), () => {
* AsyncStorage.mergeItem('UID123', JSON.stringify(UID123_delta), () => {
* AsyncStorage.getItem('UID123', (err, result) => {
* console.log(result);
* });
* });
* });
*
* // Console log result:
* // => {'name':'Chris','age':31,'traits':
* // {'shoe_size':10,'hair':'brown','eyes':'blue'}}
*/
mergeItem: function(
key: string,
value: string,
callback?: ?(error: ?Error) => void
): Promise {
return new Promise((resolve, reject) => {
RCTAsyncStorage.multiMerge([[key,value]], function(errors) {
var errs = convertErrors(errors);
callback && callback(errs && errs[0]);
if (errs) {
reject(errs[0]);
} else {
resolve(null);
}
});
});
},

/**
* Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably
* don't want to call this; use `removeItem` or `multiRemove` to clear only
Expand Down Expand Up @@ -406,86 +355,149 @@ var AsyncStorage = {
});
},

/**
* Batch operation to merge in existing and new values for a given set of
* keys. This assumes that the values are stringified JSON. Returns a
* `Promise` object.
*
* **NOTE**: This is not supported by all native implementations.
*
* @param keyValuePairs Array of key-value array for the items to merge.
* @param callback Function that will be called with an array of any
* key-specific errors found.
* @returns A `Promise` object.
*
* @example <caption>Example</caption>
* // first user, initial values
* let UID234_object = {
* name: 'Chris',
* age: 30,
* traits: {hair: 'brown', eyes: 'brown'},
* };
*
* // first user, delta values
* let UID234_delta = {
* age: 31,
* traits: {eyes: 'blue', shoe_size: 10},
* };
*
* // second user, initial values
* let UID345_object = {
* name: 'Marge',
* age: 25,
* traits: {hair: 'blonde', eyes: 'blue'},
* };
*
* // second user, delta values
* let UID345_delta = {
* age: 26,
* traits: {eyes: 'green', shoe_size: 6},
* };
*
* let multi_set_pairs = [['UID234', JSON.stringify(UID234_object)], ['UID345', JSON.stringify(UID345_object)]]
* let multi_merge_pairs = [['UID234', JSON.stringify(UID234_delta)], ['UID345', JSON.stringify(UID345_delta)]]
*
* AsyncStorage.multiSet(multi_set_pairs, (err) => {
* AsyncStorage.multiMerge(multi_merge_pairs, (err) => {
* AsyncStorage.multiGet(['UID234','UID345'], (err, stores) => {
* stores.map( (result, i, store) => {
* let key = store[i][0];
* let val = store[i][1];
* console.log(key, val);
* });
* });
* });
* });
*
* // Console log results:
* // => UID234 {"name":"Chris","age":31,"traits":{"shoe_size":10,"hair":"brown","eyes":"blue"}}
* // => UID345 {"name":"Marge","age":26,"traits":{"shoe_size":6,"hair":"blonde","eyes":"green"}}
*/
multiMerge: function(
keyValuePairs: Array<Array<string>>,
callback?: ?(errors: ?Array<Error>) => void
): Promise {
return new Promise((resolve, reject) => {
RCTAsyncStorage.multiMerge(keyValuePairs, function(errors) {
var error = convertErrors(errors);
callback && callback(error);
if (error) {
reject(error);
} else {
resolve(null);
}
});
});
},
setBackend: function (
backend: AsyncStorageBackend

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

semi: Missing semicolon.

) {
RCTAsyncStorage = backend;
// Not all native implementations support merge.
if (backend.multiMerge) {
AsyncStorage.mergeItem = mergeItem;
AsyncStorage.multiMerge = multiMerge;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the other methods such as getAllKeys?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mkonicek same as above. I don't want to mix a bunch of different changes in one PR

} else {
delete AsyncStorage.mergeItem;
delete AsyncStorage.multiMerge;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why delete them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mkonicek nothing changed in this respect, this is old code

}
}
};

// Not all native implementations support merge.
if (!RCTAsyncStorage.multiMerge) {
delete AsyncStorage.mergeItem;
delete AsyncStorage.multiMerge;
AsyncStorage.setBackend(RCTAsyncStorage);

/**
* Batch operation to merge in existing and new values for a given set of
* keys. This assumes that the values are stringified JSON. Returns a
* `Promise` object.
*
* **NOTE**: This is not supported by all native implementations.
*
* @param keyValuePairs Array of key-value array for the items to merge.
* @param callback Function that will be called with an array of any
* key-specific errors found.
* @returns A `Promise` object.
*
* @example <caption>Example</caption>
* // first user, initial values
* let UID234_object = {
* name: 'Chris',
* age: 30,
* traits: {hair: 'brown', eyes: 'brown'},
* };
*
* // first user, delta values
* let UID234_delta = {
* age: 31,
* traits: {eyes: 'blue', shoe_size: 10},
* };
*
* // second user, initial values
* let UID345_object = {
* name: 'Marge',
* age: 25,
* traits: {hair: 'blonde', eyes: 'blue'},
* };
*
* // second user, delta values
* let UID345_delta = {
* age: 26,
* traits: {eyes: 'green', shoe_size: 6},
* };
*
* let multi_set_pairs = [['UID234', JSON.stringify(UID234_object)], ['UID345', JSON.stringify(UID345_object)]]
* let multi_merge_pairs = [['UID234', JSON.stringify(UID234_delta)], ['UID345', JSON.stringify(UID345_delta)]]
*
* AsyncStorage.multiSet(multi_set_pairs, (err) => {
* AsyncStorage.multiMerge(multi_merge_pairs, (err) => {
* AsyncStorage.multiGet(['UID234','UID345'], (err, stores) => {
* stores.map( (result, i, store) => {
* let key = store[i][0];
* let val = store[i][1];
* console.log(key, val);
* });
* });
* });
* });
*
* // Console log results:
* // => UID234 {"name":"Chris","age":31,"traits":{"shoe_size":10,"hair":"brown","eyes":"blue"}}
* // => UID345 {"name":"Marge","age":26,"traits":{"shoe_size":6,"hair":"blonde","eyes":"green"}}
*/
function multiMerge (
keyValuePairs: Array<Array<string>>,
callback?: ?(errors: ?Array<Error>) => void
): Promise {
return new Promise((resolve, reject) => {
RCTAsyncStorage.multiMerge(keyValuePairs, function(errors) {
var error = convertErrors(errors);
callback && callback(error);
if (error) {
reject(error);
} else {
resolve(null);
}
});
});
}

/**
* Merges an existing `key` value with an input value, assuming both values
* are stringified JSON. Returns a `Promise` object.
*
* **NOTE:** This is not supported by all native implementations.
*
* @param key Key of the item to modify.
* @param value New value to merge for the `key`.
* @param callback Function that will be called with any error.
* @returns A `Promise` object.
*
* @example <caption>Example</caption>
* let UID123_object = {
* name: 'Chris',
* age: 30,
* traits: {hair: 'brown', eyes: 'brown'},
* };
* // You only need to define what will be added or updated
* let UID123_delta = {
* age: 31,
* traits: {eyes: 'blue', shoe_size: 10}
* };
*
* AsyncStorage.setItem('UID123', JSON.stringify(UID123_object), () => {
* AsyncStorage.mergeItem('UID123', JSON.stringify(UID123_delta), () => {
* AsyncStorage.getItem('UID123', (err, result) => {
* console.log(result);
* });
* });
* });
*
* // Console log result:
* // => {'name':'Chris','age':31,'traits':
* // {'shoe_size':10,'hair':'brown','eyes':'blue'}}
*/
function mergeItem(
key: string,
value: string,
callback?: ?(error: ?Error) => void
): Promise {
return new Promise((resolve, reject) => {
RCTAsyncStorage.multiMerge([[key,value]], function(errors) {
var errs = convertErrors(errors);
callback && callback(errs && errs[0]);
if (errs) {
reject(errs[0]);
} else {
resolve(null);
}
});
});
}

function convertErrors(errs) {
Expand Down
13 changes: 13 additions & 0 deletions Libraries/Storage/AsyncStorageTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @flow
*/
'use strict';

export type AsyncStorageBackend = {
clear: Function,
getAllKeys: Function,
multiGet: Function,
multiSet: Function,
multiRemove: Function,
multiMerge?: Function
};