sproutcore 1.6.0.rc.2-x86-mingw32 → 1.6.0.1-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +12 -0
- data/VERSION.yml +1 -1
- data/bin/sc-docs +6 -1
- data/lib/buildtasks/target.rake +1 -1
- data/lib/frameworks/sproutcore/Buildfile +5 -1
- data/lib/frameworks/sproutcore/CHANGELOG.md +175 -1
- data/lib/frameworks/sproutcore/apps/test_controls/controllers/select.js +12 -0
- data/lib/frameworks/sproutcore/apps/test_controls/resources/select_page.js +19 -5
- data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +28 -31
- data/lib/frameworks/sproutcore/frameworks/ajax/system/response.js +9 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/controller.js +21 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/responder_context.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/template_helpers/checkbox_support.js +6 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/template_helpers/text_field_support.js +26 -8
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/keyboard.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +12 -5
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/template.js +25 -9
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/locale.js +157 -5
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/render_context.js +7 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +9 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/sparse_array.js +8 -8
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/string.js +104 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/theme.js +3 -56
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/utils.js +4 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/object/content_destroyed.js +59 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/string.js +41 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/template_helpers/text_field_support.js +10 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/panes/template.js +16 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/handlebars.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/clippingFrame.js +11 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/didAppendToDocument.js +18 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/insertBefore.js +10 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/keyboard.js +18 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template_collection.js +9 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +9 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +15 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +14 -8
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/theming.js +8 -18
- data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/fixtures.js +12 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/mixins/relationship_support.js +296 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/models/child_record.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +330 -326
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +22 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +614 -614
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/data_sources/data_source.js +14 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record.js +3 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array_complex.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_complex.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/core_methods.js +20 -13
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +61 -46
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChangesFromNestedStore.js +30 -30
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitChangesFromNestedStore.js +24 -24
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/connectDataSource.js +31 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/pushRelationships.js +1177 -0
- data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/localized/system/datetime.js +4 -63
- data/lib/frameworks/sproutcore/frameworks/desktop/mixins/border.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/mixins/scrollable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/alert.js +7 -8
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +18 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/panel.js +9 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drag_data_source.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drop_target.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/button.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/checkbox.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/collection.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/disclosure.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/image_button.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/master_detail.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/menu.js +12 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/panel.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/picker.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/progress.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/radio.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/radio_group.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segment.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segmented.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/slider.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/toolbar.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/well.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/workspace.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/segmented.css +1 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/alert/ui.js +33 -22
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/panel/methods.js +20 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/methods.js +10 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/date_field/methods.js +34 -7
- data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +14 -15
- data/lib/frameworks/sproutcore/frameworks/desktop/views/checkbox.js +40 -14
- data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +699 -700
- data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/master_detail.js +11 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +16 -6
- data/lib/frameworks/sproutcore/frameworks/desktop/views/progress.js +0 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/radio.js +49 -7
- data/lib/frameworks/sproutcore/frameworks/desktop/views/select_button.js +9 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/views/select_field.js +6 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/slider.js +4 -26
- data/lib/frameworks/sproutcore/frameworks/desktop/views/web.js +20 -19
- data/lib/frameworks/sproutcore/frameworks/experimental/Buildfile +2 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/designers/view_designer.js +249 -249
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/mixins/edit_mode.js +13 -5
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/mixins/emptiness.js +53 -37
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/render_delegates/form.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/render_delegates/form_row.js +3 -11
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/mixins/edit_mode.js +53 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/mixins/emptiness.js +114 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form.js +174 -6
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_row.js +86 -6
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/views/form.js +80 -110
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/views/form_row.js +96 -97
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/README.md +2 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/models/record.js +20 -36
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/ext/menu.js +121 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/ext/menu_item.js +90 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/mixins/select_view_menu.js +139 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/render_delegates/select_button.js +14 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/ext/menu_resizing.js +25 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/mixins/select_view_menu/bindings.js +43 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/mixins/select_view_menu/check_selected.js +32 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/popup_button/menu_setup.js +40 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/popup_button/show_menu.js +45 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/select/menu_width.js +49 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/select/selected_item.js +191 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/popup_button.js +264 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/select.js +450 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/mixins/split_child.js +14 -6
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/mixins/split_thumb.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/render_delegates/split.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/render_delegates/split_divider.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/views/split.js +9 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/views/thumb.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +7 -17
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_value_support.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/flowed_layout.js +35 -8
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editor.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editor_delegate.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inner_frame.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/canvas_image.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/helpers/sizing.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/image.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/label.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/render_delegate.js +6 -6
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/images/favicon.ico +0 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/text_field.css +0 -5
- data/lib/frameworks/sproutcore/frameworks/foundation/system/exception_handler.js +4 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/system/math.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +13 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/string_measurement.js +6 -9
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/flowed_layout/tests.js +912 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/methods.js +36 -7
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +58 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/validators/validator.js +1 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/views/field.js +0 -15
- data/lib/frameworks/sproutcore/frameworks/foundation/views/label.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +25 -14
- data/lib/frameworks/sproutcore/frameworks/handlebars/handlebars.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +15 -9
- data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/flatten.js +24 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/ext/array.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/ext/function.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/array.js +19 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/copyable.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/freezable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +14 -14
- data/lib/frameworks/sproutcore/frameworks/runtime/system/error.js +3 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/system/logger.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/system/range_observer.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/runtime/system/set.js +15 -16
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/itemType.js +6 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/enhance.js +30 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/range_observer/create.js +17 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/system/state.js +9 -2
- data/lib/frameworks/sproutcore/frameworks/statechart/system/statechart.js +3 -1
- data/lib/frameworks/sproutcore/frameworks/testing/resources/runner.css +0 -1
- data/lib/frameworks/sproutcore/frameworks/yuireset/resources/base.css +80 -0
- data/lib/frameworks/sproutcore/frameworks/yuireset/resources/core.css +0 -4
- data/lib/frameworks/sproutcore/lib/index.rhtml +2 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list.css +3 -3
- data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list_item.css +2 -2
- data/lib/frameworks/sproutcore/themes/ace/resources/form/form.css +9 -0
- data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu.css +3 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/picker.js +1 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/workspace.js +1 -1
- data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/button.js +1 -1
- data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/panel.js +1 -1
- data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/progress.js +2 -0
- data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/slider.js +1 -1
- data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/well.js +1 -1
- data/lib/sproutcore/builders/base.rb +5 -1
- data/lib/sproutcore/builders/handlebars.rb +12 -1
- data/lib/sproutcore/models/target.rb +1 -9
- data/lib/sproutcore/rack/proxy.rb +238 -92
- data/lib/sproutcore/tools/docs.rb +1 -7
- data/spec/fixtures/builder_tests/apps/handlebars_test/Buildfile +1 -0
- data/spec/fixtures/builder_tests/apps/handlebars_test/{template.handlebars → templates/template.handlebars} +2 -0
- data/spec/lib/builders/handlebars_spec.rb +10 -4
- data/sproutcore.gemspec +3 -1
- metadata +73 -44
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/english.lproj/default_styles.css +0 -5
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/english.lproj/strings.js +0 -15
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_checkbox_field.js +0 -17
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_field.js +0 -17
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_label.js +0 -17
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_radio_field.js +0 -17
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_text_field.js +0 -17
@@ -133,6 +133,27 @@ SC.RecordAttribute = SC.Object.extend(
|
|
133
133
|
@default NO
|
134
134
|
*/
|
135
135
|
aggregate: NO,
|
136
|
+
|
137
|
+
|
138
|
+
/**
|
139
|
+
Can only be used for toOne or toMany relationship attributes. If YES,
|
140
|
+
this flag will lazily create the related record that was pushed in
|
141
|
+
from the data source (via pushRetrieve) if the related record does
|
142
|
+
not exist yet.
|
143
|
+
|
144
|
+
Useful when you have a record used as a join table. Assumptions then
|
145
|
+
can be made that the record exists at all times (even if it doesn't).
|
146
|
+
For instance, if you have a contact that is a member of groups,
|
147
|
+
a group will be created automatically when a contact pushes a new
|
148
|
+
group.
|
149
|
+
|
150
|
+
Note that you will have to take care of destroying the created record
|
151
|
+
once all relationships are removed from it.
|
152
|
+
|
153
|
+
@property {Boolean}
|
154
|
+
@default NO
|
155
|
+
*/
|
156
|
+
lazilyInstantiate: NO,
|
136
157
|
|
137
158
|
// ..........................................................
|
138
159
|
// HELPER PROPERTIES
|
@@ -149,7 +170,7 @@ SC.RecordAttribute = SC.Object.extend(
|
|
149
170
|
*/
|
150
171
|
typeClass: function() {
|
151
172
|
var ret = this.get('type');
|
152
|
-
if (SC.typeOf(ret) === SC.T_STRING) ret = SC.
|
173
|
+
if (SC.typeOf(ret) === SC.T_STRING) ret = SC.requiredObjectForPropertyPath(ret);
|
153
174
|
return ret ;
|
154
175
|
}.property('type').cacheable(),
|
155
176
|
|
@@ -318,7 +318,7 @@ SC.NestedStore = SC.Store.extend(
|
|
318
318
|
if (!editables) editables = this.editables = [];
|
319
319
|
editables[storeKey] = 1 ; // mark as editable
|
320
320
|
|
321
|
-
} else this.dataHashes[storeKey] =
|
321
|
+
} else this.dataHashes[storeKey] = pstore.dataHashes[storeKey];
|
322
322
|
|
323
323
|
// also copy the status + revision
|
324
324
|
this.statuses[storeKey] = this.statuses[storeKey];
|
@@ -11,14 +11,14 @@ sc_require('models/record');
|
|
11
11
|
@class
|
12
12
|
|
13
13
|
|
14
|
-
The Store is where you can find all of your dataHashes. Stores can be
|
15
|
-
chained for editing purposes and committed back one chain level at a time
|
14
|
+
The Store is where you can find all of your dataHashes. Stores can be
|
15
|
+
chained for editing purposes and committed back one chain level at a time
|
16
16
|
all the way back to a persistent data source.
|
17
|
-
|
17
|
+
|
18
18
|
Every application you create should generally have its own store objects.
|
19
19
|
Once you create the store, you will rarely need to work with the store
|
20
|
-
directly except to retrieve records and collections.
|
21
|
-
|
20
|
+
directly except to retrieve records and collections.
|
21
|
+
|
22
22
|
Internally, the store will keep track of changes to your json data hashes
|
23
23
|
and manage syncing those changes with your data source. A data source may
|
24
24
|
be a server, local storage, or any other persistent code.
|
@@ -27,19 +27,19 @@ sc_require('models/record');
|
|
27
27
|
@since SproutCore 1.0
|
28
28
|
*/
|
29
29
|
SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
30
|
-
|
30
|
+
|
31
31
|
/**
|
32
32
|
An (optional) name of the store, which can be useful during debugging,
|
33
33
|
especially if you have multiple nested stores.
|
34
|
-
|
34
|
+
|
35
35
|
@type String
|
36
36
|
*/
|
37
37
|
name: null,
|
38
38
|
|
39
39
|
/**
|
40
|
-
An array of all the chained stores that current rely on the receiver
|
40
|
+
An array of all the chained stores that current rely on the receiver
|
41
41
|
store.
|
42
|
-
|
42
|
+
|
43
43
|
@type Array
|
44
44
|
*/
|
45
45
|
nestedStores: null,
|
@@ -48,39 +48,39 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
48
48
|
The data source is the persistent storage that will provide data to the
|
49
49
|
store and save changes. You normally will set your data source when you
|
50
50
|
first create your store in your application.
|
51
|
-
|
51
|
+
|
52
52
|
@type SC.DataSource
|
53
53
|
*/
|
54
54
|
dataSource: null,
|
55
|
-
|
55
|
+
|
56
56
|
/**
|
57
57
|
This type of store is not nested.
|
58
|
-
|
58
|
+
|
59
59
|
@default NO
|
60
60
|
@type Boolean
|
61
61
|
*/
|
62
62
|
isNested: NO,
|
63
|
-
|
63
|
+
|
64
64
|
/**
|
65
65
|
This type of store is not nested.
|
66
|
-
|
66
|
+
|
67
67
|
@default NO
|
68
68
|
@type Boolean
|
69
69
|
*/
|
70
70
|
commitRecordsAutomatically: NO,
|
71
|
-
|
71
|
+
|
72
72
|
// ..........................................................
|
73
73
|
// DATA SOURCE SUPPORT
|
74
|
-
//
|
75
|
-
|
74
|
+
//
|
75
|
+
|
76
76
|
/**
|
77
77
|
Convenience method. Sets the current data source to the passed property.
|
78
78
|
This will also set the store property on the dataSource to the receiver.
|
79
|
-
|
79
|
+
|
80
80
|
If you are using this from the `core.js` method of your app, you may need to
|
81
81
|
just pass a string naming your data source class. If this is the case,
|
82
82
|
then your data source will be instantiated the first time it is requested.
|
83
|
-
|
83
|
+
|
84
84
|
@param {SC.DataSource|String} dataSource the data source
|
85
85
|
@returns {SC.Store} receiver
|
86
86
|
*/
|
@@ -88,48 +88,48 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
88
88
|
this.set('dataSource', dataSource);
|
89
89
|
return this ;
|
90
90
|
},
|
91
|
-
|
91
|
+
|
92
92
|
// lazily convert data source to real object
|
93
93
|
_getDataSource: function() {
|
94
94
|
var ret = this.get('dataSource');
|
95
95
|
if (typeof ret === SC.T_STRING) {
|
96
|
-
ret = SC.
|
97
|
-
if (ret
|
98
|
-
|
96
|
+
ret = SC.requiredObjectForPropertyPath(ret);
|
97
|
+
if (ret.isClass) ret = ret.create();
|
98
|
+
this.set('dataSource', ret);
|
99
99
|
}
|
100
100
|
return ret;
|
101
101
|
},
|
102
|
-
|
102
|
+
|
103
103
|
/**
|
104
|
-
Convenience method. Creates a `CascadeDataSource` with the passed
|
105
|
-
data source arguments and sets the `CascadeDataSource` as the data source
|
104
|
+
Convenience method. Creates a `CascadeDataSource` with the passed
|
105
|
+
data source arguments and sets the `CascadeDataSource` as the data source
|
106
106
|
for the receiver.
|
107
|
-
|
107
|
+
|
108
108
|
@param {SC.DataSource...} dataSource one or more data source arguments
|
109
|
-
@returns {SC.Store}
|
109
|
+
@returns {SC.Store} receiver
|
110
110
|
*/
|
111
111
|
cascade: function(dataSource) {
|
112
112
|
var dataSources = SC.A(arguments) ;
|
113
113
|
dataSource = SC.CascadeDataSource.create({
|
114
|
-
dataSources: dataSources
|
114
|
+
dataSources: dataSources
|
115
115
|
});
|
116
116
|
return this.from(dataSource);
|
117
117
|
},
|
118
|
-
|
118
|
+
|
119
119
|
// ..........................................................
|
120
120
|
// STORE CHAINING
|
121
|
-
//
|
122
|
-
|
123
|
-
/**
|
121
|
+
//
|
122
|
+
|
123
|
+
/**
|
124
124
|
Returns a new nested store instance that can be used to buffer changes
|
125
|
-
until you are ready to commit them. When you are ready to commit your
|
125
|
+
until you are ready to commit them. When you are ready to commit your
|
126
126
|
changes, call `commitChanges()` or `destroyChanges()` and then `destroy()`
|
127
127
|
when you are finished with the chained store altogether.
|
128
|
-
|
128
|
+
|
129
129
|
store = MyApp.store.chain();
|
130
130
|
.. edit edit edit
|
131
131
|
store.commitChanges().destroy();
|
132
|
-
|
132
|
+
|
133
133
|
@param {Hash} attrs optional attributes to set on new store
|
134
134
|
@param {Class} newStoreClass optional the class of the newly-created nested store (defaults to SC.NestedStore)
|
135
135
|
@returns {SC.NestedStore} new nested store chained to receiver
|
@@ -137,7 +137,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
137
137
|
chain: function(attrs, newStoreClass) {
|
138
138
|
if (!attrs) attrs = {};
|
139
139
|
attrs.parentStore = this;
|
140
|
-
|
140
|
+
|
141
141
|
if (newStoreClass) {
|
142
142
|
// Ensure the passed-in class is a type of nested store.
|
143
143
|
if (SC.typeOf(newStoreClass) !== 'class') throw new Error("%@ is not a valid class".fmt(newStoreClass));
|
@@ -146,24 +146,24 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
146
146
|
else {
|
147
147
|
newStoreClass = SC.NestedStore;
|
148
148
|
}
|
149
|
-
|
149
|
+
|
150
150
|
// Replicate parent records references
|
151
151
|
attrs.childRecords = this.childRecords ? SC.clone(this.childRecords) : {};
|
152
152
|
attrs.parentRecords = this.parentRecords ? SC.clone(this.parentRecords) : {};
|
153
|
-
|
153
|
+
|
154
154
|
var ret = newStoreClass.create(attrs),
|
155
155
|
nested = this.nestedStores;
|
156
|
-
|
156
|
+
|
157
157
|
if (!nested) nested = this.nestedStores = [];
|
158
158
|
nested.push(ret);
|
159
159
|
return ret ;
|
160
160
|
},
|
161
|
-
|
161
|
+
|
162
162
|
/** @private
|
163
|
-
|
163
|
+
|
164
164
|
Called by a nested store just before it is destroyed so that the parent
|
165
165
|
can remove the store from its list of nested stores.
|
166
|
-
|
166
|
+
|
167
167
|
@returns {SC.Store} receiver
|
168
168
|
*/
|
169
169
|
willDestroyNestedStore: function(nestedStore) {
|
@@ -176,7 +176,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
176
176
|
/**
|
177
177
|
Used to determine if a nested store belongs directly or indirectly to the
|
178
178
|
receiver.
|
179
|
-
|
179
|
+
|
180
180
|
@param {SC.Store} store store instance
|
181
181
|
@returns {Boolean} YES if belongs
|
182
182
|
*/
|
@@ -186,110 +186,110 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
186
186
|
},
|
187
187
|
|
188
188
|
// ..........................................................
|
189
|
-
// SHARED DATA STRUCTURES
|
190
|
-
//
|
191
|
-
|
189
|
+
// SHARED DATA STRUCTURES
|
190
|
+
//
|
191
|
+
|
192
192
|
/** @private
|
193
|
-
JSON data hashes indexed by store key.
|
194
|
-
|
193
|
+
JSON data hashes indexed by store key.
|
194
|
+
|
195
195
|
*IMPORTANT: Property is not observable*
|
196
196
|
|
197
197
|
Shared by a store and its child stores until you make edits to it.
|
198
|
-
|
198
|
+
|
199
199
|
@type Hash
|
200
200
|
*/
|
201
201
|
dataHashes: null,
|
202
202
|
|
203
203
|
/** @private
|
204
204
|
The current status of a data hash indexed by store key.
|
205
|
-
|
205
|
+
|
206
206
|
*IMPORTANT: Property is not observable*
|
207
207
|
|
208
208
|
Shared by a store and its child stores until you make edits to it.
|
209
|
-
|
209
|
+
|
210
210
|
@type Hash
|
211
211
|
*/
|
212
212
|
statuses: null,
|
213
|
-
|
213
|
+
|
214
214
|
/** @private
|
215
|
-
This array contains the revisions for the attributes indexed by the
|
216
|
-
storeKey.
|
217
|
-
|
215
|
+
This array contains the revisions for the attributes indexed by the
|
216
|
+
storeKey.
|
217
|
+
|
218
218
|
*IMPORTANT: Property is not observable*
|
219
|
-
|
220
|
-
Revisions are used to keep track of when an attribute hash has been
|
221
|
-
changed. A store shares the revisions data with its parent until it
|
219
|
+
|
220
|
+
Revisions are used to keep track of when an attribute hash has been
|
221
|
+
changed. A store shares the revisions data with its parent until it
|
222
222
|
starts to make changes to it.
|
223
|
-
|
223
|
+
|
224
224
|
@type Hash
|
225
225
|
*/
|
226
226
|
revisions: null,
|
227
227
|
|
228
228
|
/**
|
229
|
-
Array indicates whether a data hash is possibly in use by an external
|
229
|
+
Array indicates whether a data hash is possibly in use by an external
|
230
230
|
record for editing. If a data hash is editable then it may be modified
|
231
|
-
at any time and therefore chained stores may need to clone the
|
231
|
+
at any time and therefore chained stores may need to clone the
|
232
232
|
attributes before keeping a copy of them.
|
233
|
-
|
234
|
-
Note that this is kept as an array because it will be stored as a dense
|
233
|
+
|
234
|
+
Note that this is kept as an array because it will be stored as a dense
|
235
235
|
array on some browsers, making it faster.
|
236
|
-
|
236
|
+
|
237
237
|
@type Array
|
238
238
|
*/
|
239
239
|
editables: null,
|
240
|
-
|
240
|
+
|
241
241
|
/**
|
242
242
|
A set of storeKeys that need to be committed back to the data source. If
|
243
243
|
you call `commitRecords()` without passing any other parameters, the keys
|
244
244
|
in this set will be committed instead.
|
245
|
-
|
245
|
+
|
246
246
|
@type SC.Set
|
247
247
|
*/
|
248
248
|
changelog: null,
|
249
|
-
|
249
|
+
|
250
250
|
/**
|
251
251
|
An array of `SC.Error` objects associated with individual records in the
|
252
252
|
store (indexed by store keys).
|
253
|
-
|
253
|
+
|
254
254
|
Errors passed form the data source in the call to dataSourceDidError() are
|
255
255
|
stored here.
|
256
|
-
|
256
|
+
|
257
257
|
@type Array
|
258
258
|
*/
|
259
259
|
recordErrors: null,
|
260
|
-
|
260
|
+
|
261
261
|
/**
|
262
262
|
A hash of `SC.Error` objects associated with queries (indexed by the GUID
|
263
263
|
of the query).
|
264
|
-
|
264
|
+
|
265
265
|
Errors passed from the data source in the call to
|
266
266
|
`dataSourceDidErrorQuery()` are stored here.
|
267
|
-
|
267
|
+
|
268
268
|
@type Hash
|
269
269
|
*/
|
270
270
|
queryErrors: null,
|
271
|
-
|
271
|
+
|
272
272
|
/**
|
273
273
|
A hash of child Records and there immediate parents
|
274
274
|
*/
|
275
275
|
childRecords: null,
|
276
|
-
|
276
|
+
|
277
277
|
/**
|
278
278
|
A hash of parent records with registered children
|
279
279
|
*/
|
280
280
|
parentRecords: null,
|
281
|
-
|
281
|
+
|
282
282
|
// ..........................................................
|
283
283
|
// CORE ATTRIBUTE API
|
284
|
-
//
|
284
|
+
//
|
285
285
|
// The methods in this layer work on data hashes in the store. They do not
|
286
|
-
// perform any changes that can impact records. Usually you will not need
|
286
|
+
// perform any changes that can impact records. Usually you will not need
|
287
287
|
// to use these methods.
|
288
|
-
|
288
|
+
|
289
289
|
/**
|
290
290
|
Returns the current edit status of a storekey. May be one of
|
291
291
|
`EDITABLE` or `LOCKED`. Used mostly for unit testing.
|
292
|
-
|
292
|
+
|
293
293
|
@param {Number} storeKey the store key
|
294
294
|
@returns {Number} edit status
|
295
295
|
*/
|
@@ -297,27 +297,27 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
297
297
|
var editables = this.editables, locks = this.locks;
|
298
298
|
return (editables && editables[storeKey]) ? SC.Store.EDITABLE : SC.Store.LOCKED ;
|
299
299
|
},
|
300
|
-
|
301
|
-
/**
|
300
|
+
|
301
|
+
/**
|
302
302
|
Returns the data hash for the given `storeKey`. This will also 'lock'
|
303
|
-
the hash so that further edits to the parent store will no
|
303
|
+
the hash so that further edits to the parent store will no
|
304
304
|
longer be reflected in this store until you reset.
|
305
|
-
|
305
|
+
|
306
306
|
@param {Number} storeKey key to retrieve
|
307
307
|
@returns {Hash} data hash or null
|
308
308
|
*/
|
309
309
|
readDataHash: function(storeKey) {
|
310
310
|
return this.dataHashes[storeKey];
|
311
311
|
},
|
312
|
-
|
313
|
-
/**
|
312
|
+
|
313
|
+
/**
|
314
314
|
Returns the data hash for the `storeKey`, cloned so that you can edit
|
315
315
|
the contents of the attributes if you like. This will do the extra work
|
316
|
-
to make sure that you only clone the attributes one time.
|
317
|
-
|
318
|
-
If you use this method to modify data hash, be sure to call
|
316
|
+
to make sure that you only clone the attributes one time.
|
317
|
+
|
318
|
+
If you use this method to modify data hash, be sure to call
|
319
319
|
`dataHashDidChange()` when you make edits to record the change.
|
320
|
-
|
320
|
+
|
321
321
|
@param {Number} storeKey the store key to retrieve
|
322
322
|
@returns {Hash} the attributes hash
|
323
323
|
*/
|
@@ -335,48 +335,48 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
335
335
|
}
|
336
336
|
return ret;
|
337
337
|
},
|
338
|
-
|
338
|
+
|
339
339
|
/**
|
340
|
-
Reads a property from the hash - cloning it if needed so you can modify
|
340
|
+
Reads a property from the hash - cloning it if needed so you can modify
|
341
341
|
it independently of any parent store. This method is really only well
|
342
|
-
tested for use with toMany relationships. Although it is public you
|
342
|
+
tested for use with toMany relationships. Although it is public you
|
343
343
|
generally should not call it directly.
|
344
|
-
|
345
|
-
@param {Number} storeKey storeKey of data hash
|
344
|
+
|
345
|
+
@param {Number} storeKey storeKey of data hash
|
346
346
|
@param {String} propertyName property to read
|
347
347
|
@returns {Object} editable property value
|
348
348
|
*/
|
349
349
|
readEditableProperty: function(storeKey, propertyName) {
|
350
|
-
var hash = this.readEditableDataHash(storeKey),
|
350
|
+
var hash = this.readEditableDataHash(storeKey),
|
351
351
|
editables = this.editables[storeKey], // get editable info...
|
352
352
|
ret = hash[propertyName];
|
353
|
-
|
353
|
+
|
354
354
|
// editables must be made into a hash so that we can keep track of which
|
355
355
|
// properties have already been made editable
|
356
356
|
if (editables === 1) editables = this.editables[storeKey] = {};
|
357
|
-
|
357
|
+
|
358
358
|
// clone if needed
|
359
359
|
if (!editables[propertyName]) {
|
360
360
|
ret = hash[propertyName];
|
361
361
|
if (ret && ret.isCopyable) ret = hash[propertyName] = ret.copy(YES);
|
362
362
|
editables[propertyName] = YES ;
|
363
363
|
}
|
364
|
-
|
364
|
+
|
365
365
|
return ret ;
|
366
366
|
},
|
367
|
-
|
367
|
+
|
368
368
|
/**
|
369
369
|
Replaces the data hash for the `storeKey`. This will lock the data hash
|
370
370
|
and mark them as cloned. This will also call `dataHashDidChange()` for
|
371
371
|
you.
|
372
|
-
|
373
|
-
Note that the hash you set here must be a different object from the
|
372
|
+
|
373
|
+
Note that the hash you set here must be a different object from the
|
374
374
|
original data hash. Once you make a change here, you must also call
|
375
375
|
`dataHashDidChange()` to register the changes.
|
376
376
|
|
377
377
|
If the data hash does not yet exist in the store, this method will add it.
|
378
378
|
Pass the optional status to edit the status as well.
|
379
|
-
|
379
|
+
|
380
380
|
@param {Number} storeKey the store key to write
|
381
381
|
@param {Hash} hash the new hash
|
382
382
|
@param {String} status the new hash status
|
@@ -387,53 +387,53 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
387
387
|
// update dataHashes and optionally status.
|
388
388
|
if (hash) this.dataHashes[storeKey] = hash;
|
389
389
|
if (status) this.statuses[storeKey] = status ;
|
390
|
-
|
390
|
+
|
391
391
|
// also note that this hash is now editable
|
392
392
|
var editables = this.editables;
|
393
393
|
if (!editables) editables = this.editables = [];
|
394
394
|
editables[storeKey] = 1 ; // use number for dense array support
|
395
|
-
|
395
|
+
|
396
396
|
var that = this;
|
397
397
|
this._propagateToChildren(storeKey, function(storeKey){
|
398
398
|
that.writeDataHash(storeKey, null, status);
|
399
399
|
});
|
400
|
-
|
400
|
+
|
401
401
|
return this ;
|
402
402
|
},
|
403
403
|
|
404
404
|
/**
|
405
405
|
Removes the data hash from the store. This does not imply a deletion of
|
406
|
-
the record. You could be simply unloading the record. Either way,
|
407
|
-
removing the dataHash will be synced back to the parent store but not to
|
406
|
+
the record. You could be simply unloading the record. Either way,
|
407
|
+
removing the dataHash will be synced back to the parent store but not to
|
408
408
|
the server.
|
409
|
-
|
409
|
+
|
410
410
|
Note that you can optionally pass a new status to go along with this. If
|
411
411
|
you do not pass a status, it will change the status to `SC.RECORD_EMPTY`
|
412
412
|
(assuming you just unloaded the record). If you are deleting the record
|
413
413
|
you may set it to `SC.Record.DESTROYED_CLEAN`.
|
414
|
-
|
414
|
+
|
415
415
|
Be sure to also call `dataHashDidChange()` to register this change.
|
416
|
-
|
416
|
+
|
417
417
|
@param {Number} storeKey
|
418
418
|
@param {String} status optional new status
|
419
|
-
@returns {SC.Store}
|
419
|
+
@returns {SC.Store} receiver
|
420
420
|
*/
|
421
421
|
removeDataHash: function(storeKey, status) {
|
422
422
|
// don't use delete -- that will allow parent dataHash to come through
|
423
|
-
this.dataHashes[storeKey] = null;
|
423
|
+
this.dataHashes[storeKey] = null;
|
424
424
|
this.statuses[storeKey] = status || SC.Record.EMPTY;
|
425
|
-
|
425
|
+
|
426
426
|
// hash is gone and therefore no longer editable
|
427
427
|
var editables = this.editables;
|
428
428
|
if (editables) editables[storeKey] = 0 ;
|
429
|
-
|
430
|
-
return this ;
|
429
|
+
|
430
|
+
return this ;
|
431
431
|
},
|
432
|
-
|
432
|
+
|
433
433
|
/**
|
434
|
-
Reads the current status for a storeKey. This will also lock the data
|
434
|
+
Reads the current status for a storeKey. This will also lock the data
|
435
435
|
hash. If no status is found, returns `SC.RECORD_EMPTY`.
|
436
|
-
|
436
|
+
|
437
437
|
@param {Number} storeKey the store key
|
438
438
|
@returns {Number} status
|
439
439
|
*/
|
@@ -443,41 +443,41 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
443
443
|
this.readDataHash(storeKey);
|
444
444
|
return this.statuses[storeKey] || SC.Record.EMPTY;
|
445
445
|
},
|
446
|
-
|
446
|
+
|
447
447
|
/**
|
448
|
-
Reads the current status for the storeKey without actually locking the
|
448
|
+
Reads the current status for the storeKey without actually locking the
|
449
449
|
record. Usually you won't need to use this method. It is mostly used
|
450
450
|
internally.
|
451
|
-
|
451
|
+
|
452
452
|
@param {Number} storeKey the store key
|
453
453
|
@returns {Number} status
|
454
454
|
*/
|
455
455
|
peekStatus: function(storeKey) {
|
456
|
-
return this.statuses[storeKey] || SC.Record.EMPTY;
|
456
|
+
return this.statuses[storeKey] || SC.Record.EMPTY;
|
457
457
|
},
|
458
|
-
|
458
|
+
|
459
459
|
/**
|
460
|
-
Writes the current status for a storeKey. If the new status is
|
461
|
-
`SC.Record.ERROR`, you may also pass an optional error object. Otherwise
|
460
|
+
Writes the current status for a storeKey. If the new status is
|
461
|
+
`SC.Record.ERROR`, you may also pass an optional error object. Otherwise
|
462
462
|
this param is ignored.
|
463
|
-
|
463
|
+
|
464
464
|
@param {Number} storeKey the store key
|
465
465
|
@param {String} newStatus the new status
|
466
466
|
@param {SC.Error} error optional error object
|
467
467
|
@returns {SC.Store} receiver
|
468
468
|
*/
|
469
469
|
writeStatus: function(storeKey, newStatus) {
|
470
|
-
// use writeDataHash for now to handle optimistic lock. maximize code
|
470
|
+
// use writeDataHash for now to handle optimistic lock. maximize code
|
471
471
|
// reuse.
|
472
472
|
return this.writeDataHash(storeKey, null, newStatus);
|
473
473
|
},
|
474
|
-
|
474
|
+
|
475
475
|
/**
|
476
476
|
Call this method whenever you modify some editable data hash to register
|
477
477
|
with the Store that the attribute values have actually changed. This will
|
478
|
-
do the book-keeping necessary to track the change across stores including
|
478
|
+
do the book-keeping necessary to track the change across stores including
|
479
479
|
managing locks.
|
480
|
-
|
480
|
+
|
481
481
|
@param {Number|Array} storeKeys one or more store keys that changed
|
482
482
|
@param {Number} rev optional new revision number. normally leave null
|
483
483
|
@param {Boolean} statusOnly (optional) YES if only status changed
|
@@ -485,13 +485,13 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
485
485
|
@returns {SC.Store} receiver
|
486
486
|
*/
|
487
487
|
dataHashDidChange: function(storeKeys, rev, statusOnly, key) {
|
488
|
-
|
488
|
+
|
489
489
|
// update the revision for storeKey. Use generateStoreKey() because that
|
490
|
-
// gaurantees a universally (to this store hierarchy anyway) unique
|
490
|
+
// gaurantees a universally (to this store hierarchy anyway) unique
|
491
491
|
// key value.
|
492
492
|
if (!rev) rev = SC.Store.generateStoreKey();
|
493
493
|
var isArray, len, idx, storeKey;
|
494
|
-
|
494
|
+
|
495
495
|
isArray = SC.typeOf(storeKeys) === SC.T_ARRAY;
|
496
496
|
if (isArray) {
|
497
497
|
len = storeKeys.length;
|
@@ -499,39 +499,39 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
499
499
|
len = 1;
|
500
500
|
storeKey = storeKeys;
|
501
501
|
}
|
502
|
-
|
502
|
+
|
503
503
|
var that = this;
|
504
504
|
for(idx=0;idx<len;idx++) {
|
505
505
|
if (isArray) storeKey = storeKeys[idx];
|
506
506
|
this.revisions[storeKey] = rev;
|
507
507
|
this._notifyRecordPropertyChange(storeKey, statusOnly, key);
|
508
|
-
|
508
|
+
|
509
509
|
this._propagateToChildren(storeKey, function(storeKey){
|
510
510
|
that.dataHashDidChange(storeKey, null, statusOnly, key);
|
511
511
|
});
|
512
512
|
}
|
513
|
-
|
513
|
+
|
514
514
|
return this ;
|
515
515
|
},
|
516
516
|
|
517
|
-
/** @private
|
517
|
+
/** @private
|
518
518
|
Will push all changes to a the recordPropertyChanges property
|
519
519
|
and execute `flush()` once at the end of the runloop.
|
520
520
|
*/
|
521
521
|
_notifyRecordPropertyChange: function(storeKey, statusOnly, key) {
|
522
|
-
|
523
|
-
var records = this.records,
|
522
|
+
|
523
|
+
var records = this.records,
|
524
524
|
nestedStores = this.get('nestedStores'),
|
525
525
|
K = SC.Store,
|
526
526
|
rec, editState, len, idx, store, status, keys;
|
527
|
-
|
527
|
+
|
528
528
|
// pass along to nested stores
|
529
529
|
len = nestedStores ? nestedStores.length : 0 ;
|
530
530
|
for(idx=0;idx<len;idx++) {
|
531
531
|
store = nestedStores[idx];
|
532
532
|
status = store.peekStatus(storeKey); // important: peek avoids read-lock
|
533
533
|
editState = store.storeKeyEditState(storeKey);
|
534
|
-
|
534
|
+
|
535
535
|
// when store needs to propagate out changes in the parent store
|
536
536
|
// to nested stores
|
537
537
|
if (editState === K.INHERITED) {
|
@@ -543,29 +543,29 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
543
543
|
store.reset();
|
544
544
|
}
|
545
545
|
}
|
546
|
-
|
546
|
+
|
547
547
|
// store info in changes hash and schedule notification if needed.
|
548
548
|
var changes = this.recordPropertyChanges;
|
549
549
|
if (!changes) {
|
550
|
-
changes = this.recordPropertyChanges =
|
550
|
+
changes = this.recordPropertyChanges =
|
551
551
|
{ storeKeys: SC.CoreSet.create(),
|
552
552
|
records: SC.CoreSet.create(),
|
553
553
|
hasDataChanges: SC.CoreSet.create(),
|
554
554
|
propertyForStoreKeys: {} };
|
555
555
|
}
|
556
|
-
|
556
|
+
|
557
557
|
changes.storeKeys.add(storeKey);
|
558
558
|
|
559
559
|
if (records && (rec=records[storeKey])) {
|
560
560
|
changes.records.push(storeKey);
|
561
|
-
|
561
|
+
|
562
562
|
// If there are changes other than just the status we need to record
|
563
563
|
// that information so we do the right thing during the next flush.
|
564
564
|
// Note that if we're called multiple times before flush and one call
|
565
565
|
// has `statusOnly=true` and another has `statusOnly=false`, the flush
|
566
566
|
// will (correctly) operate in `statusOnly=false` mode.
|
567
567
|
if (!statusOnly) changes.hasDataChanges.push(storeKey);
|
568
|
-
|
568
|
+
|
569
569
|
// If this is a key specific change, make sure that only those
|
570
570
|
// properties/keys are notified. However, if a previous invocation of
|
571
571
|
// `_notifyRecordPropertyChange` specified that all keys have changed, we
|
@@ -574,7 +574,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
574
574
|
if (!(keys = changes.propertyForStoreKeys[storeKey])) {
|
575
575
|
keys = changes.propertyForStoreKeys[storeKey] = SC.CoreSet.create();
|
576
576
|
}
|
577
|
-
|
577
|
+
|
578
578
|
// If it's '*' instead of a set, then that means there was a previous
|
579
579
|
// invocation that said all keys have changed.
|
580
580
|
if (keys !== '*') {
|
@@ -586,22 +586,22 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
586
586
|
changes.propertyForStoreKeys[storeKey] = '*';
|
587
587
|
}
|
588
588
|
}
|
589
|
-
|
589
|
+
|
590
590
|
this.invokeOnce(this.flush);
|
591
591
|
return this;
|
592
592
|
},
|
593
593
|
|
594
594
|
/**
|
595
|
-
Delivers any pending changes to materialized records. Normally this
|
595
|
+
Delivers any pending changes to materialized records. Normally this
|
596
596
|
happens once, automatically, at the end of the RunLoop. If you have
|
597
|
-
updated some records and need to update records immediately, however,
|
597
|
+
updated some records and need to update records immediately, however,
|
598
598
|
you may call this manually.
|
599
599
|
|
600
600
|
@returns {SC.Store} receiver
|
601
601
|
*/
|
602
602
|
flush: function() {
|
603
603
|
if (!this.recordPropertyChanges) return this;
|
604
|
-
|
604
|
+
|
605
605
|
var changes = this.recordPropertyChanges,
|
606
606
|
storeKeys = changes.storeKeys,
|
607
607
|
hasDataChanges = changes.hasDataChanges,
|
@@ -609,26 +609,26 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
609
609
|
propertyForStoreKeys = changes.propertyForStoreKeys,
|
610
610
|
recordTypes = SC.CoreSet.create(),
|
611
611
|
rec, recordType, statusOnly, idx, len, storeKey, keys;
|
612
|
-
|
612
|
+
|
613
613
|
storeKeys.forEach(function(storeKey) {
|
614
614
|
if (records.contains(storeKey)) {
|
615
615
|
statusOnly = hasDataChanges.contains(storeKey) ? NO : YES;
|
616
616
|
rec = this.records[storeKey];
|
617
617
|
keys = propertyForStoreKeys ? propertyForStoreKeys[storeKey] : null;
|
618
|
-
|
618
|
+
|
619
619
|
// Are we invalidating all keys? If so, don't pass any to
|
620
620
|
// storeDidChangeProperties.
|
621
621
|
if (keys === '*') keys = null;
|
622
|
-
|
622
|
+
|
623
623
|
// remove it so we don't trigger this twice
|
624
624
|
records.remove(storeKey);
|
625
|
-
|
625
|
+
|
626
626
|
if (rec) rec.storeDidChangeProperties(statusOnly, keys);
|
627
627
|
}
|
628
|
-
|
628
|
+
|
629
629
|
recordType = SC.Store.recordTypeFor(storeKey);
|
630
630
|
recordTypes.add(recordType);
|
631
|
-
|
631
|
+
|
632
632
|
}, this);
|
633
633
|
|
634
634
|
if (storeKeys.get('length') > 0) this._notifyRecordArrays(storeKeys, recordTypes);
|
@@ -638,19 +638,19 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
638
638
|
records.clear();
|
639
639
|
// Provide full reference to overwrite
|
640
640
|
this.recordPropertyChanges.propertyForStoreKeys = {};
|
641
|
-
|
641
|
+
|
642
642
|
return this;
|
643
643
|
},
|
644
|
-
|
644
|
+
|
645
645
|
/**
|
646
646
|
Resets the store content. This will clear all internal data for all
|
647
647
|
records, resetting them to an EMPTY state. You generally do not want
|
648
648
|
to call this method yourself, though you may override it.
|
649
|
-
|
649
|
+
|
650
650
|
@returns {SC.Store} receiver
|
651
651
|
*/
|
652
652
|
reset: function() {
|
653
|
-
|
653
|
+
|
654
654
|
// create a new empty data store
|
655
655
|
this.dataHashes = {} ;
|
656
656
|
this.revisions = {} ;
|
@@ -662,6 +662,9 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
662
662
|
this.recordErrors = null;
|
663
663
|
this.queryErrors = null;
|
664
664
|
|
665
|
+
var dataSource = this.get('dataSource');
|
666
|
+
if (dataSource && dataSource.reset) { dataSource.reset(); }
|
667
|
+
|
665
668
|
var records = this.records, storeKey;
|
666
669
|
if (records) {
|
667
670
|
for(storeKey in records) {
|
@@ -669,21 +672,21 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
669
672
|
this._notifyRecordPropertyChange(parseInt(storeKey, 10), NO);
|
670
673
|
}
|
671
674
|
}
|
672
|
-
|
675
|
+
|
673
676
|
this.set('hasChanges', NO);
|
674
677
|
},
|
675
|
-
|
678
|
+
|
676
679
|
/** @private
|
677
680
|
Called by a nested store on a parent store to commit any changes from the
|
678
|
-
store. This will copy any changed dataHashes as well as any persistant
|
681
|
+
store. This will copy any changed dataHashes as well as any persistant
|
679
682
|
change logs.
|
680
|
-
|
683
|
+
|
681
684
|
If the parentStore detects a conflict with the optimistic locking, it will
|
682
|
-
raise an exception before it makes any changes. If you pass the
|
685
|
+
raise an exception before it makes any changes. If you pass the
|
683
686
|
force flag then this detection phase will be skipped and the changes will
|
684
687
|
be applied even if another resource has modified the store in the mean
|
685
688
|
time.
|
686
|
-
|
689
|
+
|
687
690
|
@param {SC.Store} nestedStore the child store
|
688
691
|
@param {SC.Set} changes the set of changed store keys
|
689
692
|
@param {Boolean} force
|
@@ -692,20 +695,20 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
692
695
|
commitChangesFromNestedStore: function(nestedStore, changes, force) {
|
693
696
|
// first, check for optimistic locking problems
|
694
697
|
if (!force) this._verifyLockRevisions(changes, nestedStore.locks);
|
695
|
-
|
696
|
-
// OK, no locking issues. So let's just copy them changes.
|
698
|
+
|
699
|
+
// OK, no locking issues. So let's just copy them changes.
|
697
700
|
// get local reference to values.
|
698
|
-
var len = changes.length, i, storeKey, myDataHashes, myStatuses,
|
699
|
-
myEditables, myRevisions, myParentRecords, myChildRecords,
|
701
|
+
var len = changes.length, i, storeKey, myDataHashes, myStatuses,
|
702
|
+
myEditables, myRevisions, myParentRecords, myChildRecords,
|
700
703
|
chDataHashes, chStatuses, chRevisions, chParentRecords, chChildRecords;
|
701
|
-
|
704
|
+
|
702
705
|
myRevisions = this.revisions ;
|
703
706
|
myDataHashes = this.dataHashes;
|
704
707
|
myStatuses = this.statuses;
|
705
708
|
myEditables = this.editables ;
|
706
709
|
myParentRecords = this.parentRecords ? this.parentRecords : this.parentRecords ={} ;
|
707
710
|
myChildRecords = this.childRecords ? this.childRecords : this.childRecords = {} ;
|
708
|
-
|
711
|
+
|
709
712
|
// setup some arrays if needed
|
710
713
|
if (!myEditables) myEditables = this.editables = [] ;
|
711
714
|
chDataHashes = nestedStore.dataHashes;
|
@@ -713,7 +716,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
713
716
|
chStatuses = nestedStore.statuses;
|
714
717
|
chParentRecords = nestedStore.parentRecords || {};
|
715
718
|
chChildRecords = nestedStore.childRecords || {};
|
716
|
-
|
719
|
+
|
717
720
|
for(i=0;i<len;i++) {
|
718
721
|
storeKey = changes[i];
|
719
722
|
|
@@ -723,32 +726,32 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
723
726
|
myRevisions[storeKey] = chRevisions[storeKey];
|
724
727
|
myParentRecords[storeKey] = chParentRecords[storeKey];
|
725
728
|
myChildRecords[storeKey] = chChildRecords[storeKey];
|
726
|
-
|
729
|
+
|
727
730
|
myEditables[storeKey] = 0 ; // always make dataHash no longer editable
|
728
|
-
|
731
|
+
|
729
732
|
this._notifyRecordPropertyChange(storeKey, NO);
|
730
733
|
}
|
731
|
-
|
734
|
+
|
732
735
|
// add any records to the changelog for commit handling
|
733
736
|
var myChangelog = this.changelog, chChangelog = nestedStore.changelog;
|
734
737
|
if (chChangelog) {
|
735
738
|
if (!myChangelog) myChangelog = this.changelog = SC.CoreSet.create();
|
736
739
|
myChangelog.addEach(chChangelog);
|
737
|
-
}
|
740
|
+
}
|
738
741
|
this.changelog = myChangelog;
|
739
|
-
|
742
|
+
|
740
743
|
// immediately flush changes to notify records - nested stores will flush
|
741
744
|
// later on.
|
742
745
|
if (!this.get('parentStore')) this.flush();
|
743
|
-
|
746
|
+
|
744
747
|
return this ;
|
745
748
|
},
|
746
749
|
|
747
750
|
/** @private
|
748
|
-
Verifies that the passed lock revisions match the current revisions
|
749
|
-
in the receiver store. If the lock revisions do not match, then the
|
751
|
+
Verifies that the passed lock revisions match the current revisions
|
752
|
+
in the receiver store. If the lock revisions do not match, then the
|
750
753
|
store is in a conflict and an exception will be raised.
|
751
|
-
|
754
|
+
|
752
755
|
@param {Array} changes set of changes we are trying to apply
|
753
756
|
@param {SC.Set} locks the locks to verify
|
754
757
|
@returns {SC.Store} receiver
|
@@ -763,85 +766,85 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
763
766
|
|
764
767
|
// if the save revision for the item does not match the current rev
|
765
768
|
// the someone has changed the data hash in this store and we have
|
766
|
-
// a conflict.
|
769
|
+
// a conflict.
|
767
770
|
if (lock < rev) throw SC.Store.CHAIN_CONFLICT_ERROR;
|
768
|
-
}
|
771
|
+
}
|
769
772
|
}
|
770
773
|
return this ;
|
771
774
|
},
|
772
|
-
|
775
|
+
|
773
776
|
// ..........................................................
|
774
777
|
// HIGH-LEVEL RECORD API
|
775
|
-
//
|
776
|
-
|
778
|
+
//
|
779
|
+
|
777
780
|
/**
|
778
781
|
Finds a single record instance with the specified `recordType` and id or
|
779
782
|
an array of records matching some query conditions.
|
780
|
-
|
783
|
+
|
781
784
|
Finding a Single Record
|
782
785
|
---
|
783
|
-
|
786
|
+
|
784
787
|
If you pass a single `recordType` and id, this method will return an
|
785
788
|
actual record instance. If the record has not been loaded into the store
|
786
789
|
yet, this method will ask the data source to retrieve it. If no data
|
787
790
|
source indicates that it can retrieve the record, then this method will
|
788
791
|
return `null`.
|
789
|
-
|
792
|
+
|
790
793
|
Note that if the record needs to be retrieved from the server, then the
|
791
|
-
record instance returned from this method will not have any data yet.
|
794
|
+
record instance returned from this method will not have any data yet.
|
792
795
|
Instead it will have a status of `SC.Record.READY_LOADING`. You can
|
793
796
|
monitor the status property to be notified when the record data is
|
794
797
|
available for you to use it.
|
795
|
-
|
798
|
+
|
796
799
|
Find a Collection of Records
|
797
800
|
---
|
798
|
-
|
799
|
-
If you pass only a record type or a query object, you can instead find
|
801
|
+
|
802
|
+
If you pass only a record type or a query object, you can instead find
|
800
803
|
all records matching a specified set of conditions. When you call
|
801
804
|
`find()` in this way, it will create a query if needed and pass it to the
|
802
805
|
data source to fetch the results.
|
803
|
-
|
806
|
+
|
804
807
|
If this is the first time you have fetched the query, then the store will
|
805
|
-
automatically ask the data source to fetch any records related to it as
|
808
|
+
automatically ask the data source to fetch any records related to it as
|
806
809
|
well. Otherwise you can refresh the query results at anytime by calling
|
807
810
|
`refresh()` on the returned `RecordArray`.
|
808
811
|
|
809
|
-
You can detect whether a RecordArray is fetching from the server by
|
812
|
+
You can detect whether a RecordArray is fetching from the server by
|
810
813
|
checking its status.
|
811
|
-
|
814
|
+
|
812
815
|
Examples
|
813
816
|
---
|
814
|
-
|
817
|
+
|
815
818
|
Finding a single record:
|
816
|
-
|
819
|
+
|
817
820
|
MyApp.store.find(MyApp.Contact, "23"); // returns MyApp.Contact
|
818
|
-
|
821
|
+
|
819
822
|
Finding all records of a particular type:
|
820
|
-
|
823
|
+
|
821
824
|
MyApp.store.find(MyApp.Contact); // returns SC.RecordArray of contacts
|
822
|
-
|
823
|
-
|
825
|
+
|
826
|
+
|
824
827
|
Finding all contacts with first name John:
|
825
|
-
|
828
|
+
|
826
829
|
var query = SC.Query.local(MyApp.Contact, "firstName = %@", "John");
|
827
830
|
MyApp.store.find(query); // returns SC.RecordArray of contacts
|
828
|
-
|
831
|
+
|
829
832
|
Finding all contacts using a remote query:
|
830
|
-
|
833
|
+
|
831
834
|
var query = SC.Query.remote(MyApp.Contact);
|
832
835
|
MyApp.store.find(query); // returns SC.RecordArray filled by server
|
833
|
-
|
836
|
+
|
834
837
|
@param {SC.Record|String} recordType the expected record type
|
835
838
|
@param {String} id the id to load
|
836
839
|
@returns {SC.Record} record instance or null
|
837
840
|
*/
|
838
841
|
find: function(recordType, id) {
|
839
|
-
|
842
|
+
|
840
843
|
// if recordType is passed as string, find object
|
841
844
|
if (SC.typeOf(recordType)===SC.T_STRING) {
|
842
845
|
recordType = SC.objectForPropertyPath(recordType);
|
843
846
|
}
|
844
|
-
|
847
|
+
|
845
848
|
// handle passing a query...
|
846
849
|
if ((arguments.length === 1) && !(recordType && recordType.get && recordType.get('isRecord'))) {
|
847
850
|
if (!recordType) throw new Error("SC.Store#find() must pass recordType or query");
|
@@ -849,7 +852,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
849
852
|
recordType = SC.Query.local(recordType);
|
850
853
|
}
|
851
854
|
return this._findQuery(recordType, YES, YES);
|
852
|
-
|
855
|
+
|
853
856
|
// handle finding a single record
|
854
857
|
} else {
|
855
858
|
return this._findRecord(recordType, id);
|
@@ -858,36 +861,35 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
858
861
|
|
859
862
|
/** @private
|
860
863
|
DEPRECATED used find() instead.
|
861
|
-
|
864
|
+
|
862
865
|
This method will accept a record type or query and return a record array
|
863
|
-
matching the results. This method was commonly used prior to SproutCore
|
866
|
+
matching the results. This method was commonly used prior to SproutCore
|
864
867
|
1.0. It has been deprecated in favor of a single `find()` method instead.
|
865
|
-
|
868
|
+
|
866
869
|
For compatibility, this method will continue to work in SproutCore 1.0 but
|
867
|
-
it will raise a warning. It will be removed in a future version of
|
870
|
+
it will raise a warning. It will be removed in a future version of
|
868
871
|
SproutCore.
|
869
872
|
*/
|
870
873
|
findAll: function(recordType, conditions, params) {
|
871
874
|
SC.Logger.warn("SC.Store#findAll() will be removed in a future version of SproutCore. Use SC.Store#find() instead");
|
872
|
-
|
873
875
|
|
874
876
|
if (!recordType || !recordType.isQuery) {
|
875
877
|
recordType = SC.Query.local(recordType, conditions, params);
|
876
878
|
}
|
877
|
-
|
879
|
+
|
878
880
|
return this._findQuery(recordType, YES, YES);
|
879
881
|
},
|
880
|
-
|
881
|
-
|
882
|
+
|
883
|
+
|
882
884
|
_findQuery: function(query, createIfNeeded, refreshIfNew) {
|
883
885
|
|
884
886
|
// lookup the local RecordArray for this query.
|
885
|
-
var cache = this._scst_recordArraysByQuery,
|
887
|
+
var cache = this._scst_recordArraysByQuery,
|
886
888
|
key = SC.guidFor(query),
|
887
889
|
ret, ra ;
|
888
890
|
if (!cache) cache = this._scst_recordArraysByQuery = {};
|
889
891
|
ret = cache[key];
|
890
|
-
|
892
|
+
|
891
893
|
// if a RecordArray was not found, then create one and also add it to the
|
892
894
|
// list of record arrays to update.
|
893
895
|
if (!ret && createIfNeeded) {
|
@@ -899,51 +901,51 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
899
901
|
|
900
902
|
if (refreshIfNew) this.refreshQuery(query);
|
901
903
|
}
|
902
|
-
|
904
|
+
|
903
905
|
this.flush();
|
904
906
|
return ret ;
|
905
907
|
},
|
906
|
-
|
908
|
+
|
907
909
|
_findRecord: function(recordType, id) {
|
908
910
|
|
909
|
-
var storeKey ;
|
910
|
-
|
911
|
-
// if a record instance is passed, simply use the storeKey. This allows
|
911
|
+
var storeKey ;
|
912
|
+
|
913
|
+
// if a record instance is passed, simply use the storeKey. This allows
|
912
914
|
// you to pass a record from a chained store to get the same record in the
|
913
915
|
// current store.
|
914
916
|
if (recordType && recordType.get && recordType.get('isRecord')) {
|
915
917
|
storeKey = recordType.get('storeKey');
|
916
|
-
|
917
|
-
// otherwise, lookup the storeKey for the passed id. look in subclasses
|
918
|
+
|
919
|
+
// otherwise, lookup the storeKey for the passed id. look in subclasses
|
918
920
|
// as well.
|
919
921
|
} else storeKey = id ? recordType.storeKeyFor(id) : null;
|
920
|
-
|
922
|
+
|
921
923
|
if (storeKey && (this.readStatus(storeKey) === SC.Record.EMPTY)) {
|
922
924
|
storeKey = this.retrieveRecord(recordType, id);
|
923
925
|
}
|
924
|
-
|
926
|
+
|
925
927
|
// now we have the storeKey, materialize the record and return it.
|
926
928
|
return storeKey ? this.materializeRecord(storeKey) : null ;
|
927
929
|
},
|
928
930
|
|
929
931
|
// ..........................................................
|
930
932
|
// RECORD ARRAY OPERATIONS
|
931
|
-
//
|
933
|
+
//
|
932
934
|
|
933
935
|
/**
|
934
|
-
Called by the record array just before it is destroyed. This will
|
936
|
+
Called by the record array just before it is destroyed. This will
|
935
937
|
de-register it from receiving future notifications.
|
936
938
|
|
937
939
|
You should never call this method yourself. Instead call `destroy()` on
|
938
940
|
the `RecordArray` directly.
|
939
|
-
|
941
|
+
|
940
942
|
@param {SC.RecordArray} recordArray the record array
|
941
943
|
@returns {SC.Store} receiver
|
942
944
|
*/
|
943
945
|
recordArrayWillDestroy: function(recordArray) {
|
944
946
|
var cache = this._scst_recordArraysByQuery,
|
945
947
|
set = this.get('recordArrays');
|
946
|
-
|
948
|
+
|
947
949
|
if (cache) delete cache[SC.guidFor(recordArray.get('query'))];
|
948
950
|
if (set) set.remove(recordArray);
|
949
951
|
return this ;
|
@@ -956,7 +958,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
956
958
|
|
957
959
|
You should never call this method yourself. Instead call `refresh()` on
|
958
960
|
the `RecordArray` directly.
|
959
|
-
|
961
|
+
|
960
962
|
@param {SC.Query} query the record array query to refresh
|
961
963
|
@returns {SC.Store} receiver
|
962
964
|
*/
|
@@ -964,21 +966,21 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
964
966
|
if (!query) throw new Error("refreshQuery() requires a query");
|
965
967
|
|
966
968
|
var cache = this._scst_recordArraysByQuery,
|
967
|
-
recArray = cache ? cache[SC.guidFor(query)] : null,
|
969
|
+
recArray = cache ? cache[SC.guidFor(query)] : null,
|
968
970
|
source = this._getDataSource();
|
969
|
-
|
971
|
+
|
970
972
|
if (source && source.fetch) {
|
971
973
|
if (recArray) recArray.storeWillFetchQuery(query);
|
972
974
|
source.fetch.call(source, this, query);
|
973
975
|
}
|
974
|
-
|
975
|
-
return this ;
|
976
|
+
|
977
|
+
return this ;
|
976
978
|
},
|
977
|
-
|
978
|
-
/** @private
|
979
|
+
|
980
|
+
/** @private
|
979
981
|
Will ask all record arrays that have been returned from `findAll`
|
980
982
|
with an `SC.Query` to check their arrays with the new `storeKey`s
|
981
|
-
|
983
|
+
|
982
984
|
@param {SC.IndexSet} storeKeys set of storeKeys that changed
|
983
985
|
@param {SC.Set} recordTypes
|
984
986
|
@returns {SC.Store} receiver
|
@@ -990,29 +992,29 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
990
992
|
recordArrays.forEach(function(recArray) {
|
991
993
|
if (recArray) recArray.storeDidChangeStoreKeys(storeKeys, recordTypes);
|
992
994
|
}, this);
|
993
|
-
|
995
|
+
|
994
996
|
return this ;
|
995
997
|
},
|
996
|
-
|
997
|
-
|
998
|
+
|
999
|
+
|
998
1000
|
// ..........................................................
|
999
1001
|
// LOW-LEVEL HELPERS
|
1000
|
-
//
|
1001
|
-
|
1002
|
+
//
|
1003
|
+
|
1002
1004
|
/**
|
1003
1005
|
Array of all records currently in the store with the specified
|
1004
1006
|
type. This method only reflects the actual records loaded into memory and
|
1005
1007
|
therefore is not usually needed at runtime. However you will often use
|
1006
1008
|
this method for testing.
|
1007
|
-
|
1009
|
+
|
1008
1010
|
@param {SC.Record} recordType the record type
|
1009
1011
|
@returns {SC.Array} array instance - usually SC.RecordArray
|
1010
1012
|
*/
|
1011
1013
|
recordsFor: function(recordType) {
|
1012
|
-
var storeKeys = [],
|
1014
|
+
var storeKeys = [],
|
1013
1015
|
storeKeysById = recordType.storeKeysById(),
|
1014
1016
|
id, storeKey, ret;
|
1015
|
-
|
1017
|
+
|
1016
1018
|
// collect all non-empty store keys
|
1017
1019
|
for(id in storeKeysById) {
|
1018
1020
|
storeKey = storeKeysById[id]; // get the storeKey
|
@@ -1020,23 +1022,23 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1020
1022
|
storeKeys.push(storeKey);
|
1021
1023
|
}
|
1022
1024
|
}
|
1023
|
-
|
1025
|
+
|
1024
1026
|
if (storeKeys.length>0) {
|
1025
1027
|
ret = SC.RecordArray.create({ store: this, storeKeys: storeKeys });
|
1026
1028
|
} else ret = storeKeys; // empty array
|
1027
1029
|
return ret ;
|
1028
1030
|
},
|
1029
|
-
|
1031
|
+
|
1030
1032
|
_TMP_REC_ATTRS: {},
|
1031
|
-
|
1032
|
-
/**
|
1033
|
+
|
1034
|
+
/**
|
1033
1035
|
Given a `storeKey`, return a materialized record. You will not usually
|
1034
1036
|
call this method yourself. Instead it will used by other methods when
|
1035
1037
|
you find records by id or perform other searches.
|
1036
1038
|
|
1037
1039
|
If a `recordType` has been mapped to the storeKey, then a record instance
|
1038
1040
|
will be returned even if the data hash has not been requested yet.
|
1039
|
-
|
1041
|
+
|
1040
1042
|
Each Store instance returns unique record instances for each storeKey.
|
1041
1043
|
|
1042
1044
|
@param {Number} storeKey The storeKey for the dataHash.
|
@@ -1044,33 +1046,33 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1044
1046
|
*/
|
1045
1047
|
materializeRecord: function(storeKey) {
|
1046
1048
|
var records = this.records, ret, recordType, attrs;
|
1047
|
-
|
1049
|
+
|
1048
1050
|
// look up in cached records
|
1049
1051
|
if (!records) records = this.records = {}; // load cached records
|
1050
1052
|
ret = records[storeKey];
|
1051
1053
|
if (ret) return ret;
|
1052
|
-
|
1054
|
+
|
1053
1055
|
// not found -- OK, create one then.
|
1054
1056
|
recordType = SC.Store.recordTypeFor(storeKey);
|
1055
1057
|
if (!recordType) return null; // not recordType registered, nothing to do
|
1056
|
-
|
1058
|
+
|
1057
1059
|
attrs = this._TMP_REC_ATTRS ;
|
1058
1060
|
attrs.storeKey = storeKey ;
|
1059
1061
|
attrs.store = this ;
|
1060
1062
|
ret = records[storeKey] = recordType.create(attrs);
|
1061
|
-
|
1063
|
+
|
1062
1064
|
return ret ;
|
1063
1065
|
},
|
1064
1066
|
|
1065
1067
|
// ..........................................................
|
1066
1068
|
// CORE RECORDS API
|
1067
|
-
//
|
1068
|
-
// The methods in this section can be used to manipulate records without
|
1069
|
+
//
|
1070
|
+
// The methods in this section can be used to manipulate records without
|
1069
1071
|
// actually creating record instances.
|
1070
|
-
|
1072
|
+
|
1071
1073
|
/**
|
1072
1074
|
Creates a new record instance with the passed `recordType` and `dataHash`.
|
1073
|
-
You can also optionally specify an id or else it will be pulled from the
|
1075
|
+
You can also optionally specify an id or else it will be pulled from the
|
1074
1076
|
data hash.
|
1075
1077
|
|
1076
1078
|
Note that the record will not yet be saved back to the server. To save
|
@@ -1085,8 +1087,8 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1085
1087
|
createRecord: function(recordType, dataHash, id) {
|
1086
1088
|
var primaryKey, storeKey, status, K = SC.Record, changelog, defaultVal,
|
1087
1089
|
ret;
|
1088
|
-
|
1089
|
-
// First, try to get an id. If no id is passed, look it up in the
|
1090
|
+
|
1091
|
+
// First, try to get an id. If no id is passed, look it up in the
|
1090
1092
|
// dataHash.
|
1091
1093
|
if (!id && (primaryKey = recordType.prototype.primaryKey)) {
|
1092
1094
|
id = dataHash[primaryKey];
|
@@ -1097,57 +1099,57 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1097
1099
|
id = dataHash[primaryKey] = defaultVal();
|
1098
1100
|
}
|
1099
1101
|
}
|
1100
|
-
|
1102
|
+
|
1101
1103
|
// Next get the storeKey - base on id if available
|
1102
1104
|
storeKey = id ? recordType.storeKeyFor(id) : SC.Store.generateStoreKey();
|
1103
|
-
|
1105
|
+
|
1104
1106
|
// now, check the state and do the right thing.
|
1105
1107
|
status = this.readStatus(storeKey);
|
1106
|
-
|
1108
|
+
|
1107
1109
|
// check state
|
1108
1110
|
// any busy or ready state or destroyed dirty state is not allowed
|
1109
|
-
if ((status & K.BUSY) ||
|
1110
|
-
(status & K.READY) ||
|
1111
|
-
(status === K.DESTROYED_DIRTY)) {
|
1111
|
+
if ((status & K.BUSY) ||
|
1112
|
+
(status & K.READY) ||
|
1113
|
+
(status === K.DESTROYED_DIRTY)) {
|
1112
1114
|
throw id ? K.RECORD_EXISTS_ERROR : K.BAD_STATE_ERROR;
|
1113
|
-
|
1115
|
+
|
1114
1116
|
// allow error or destroyed state only with id
|
1115
1117
|
} else if (!id && (status===SC.DESTROYED_CLEAN || status===SC.ERROR)) {
|
1116
1118
|
throw K.BAD_STATE_ERROR;
|
1117
1119
|
}
|
1118
|
-
|
1120
|
+
|
1119
1121
|
// add dataHash and setup initial status -- also save recordType
|
1120
1122
|
this.writeDataHash(storeKey, (dataHash ? dataHash : {}), K.READY_NEW);
|
1121
|
-
|
1123
|
+
|
1122
1124
|
SC.Store.replaceRecordTypeFor(storeKey, recordType);
|
1123
1125
|
this.dataHashDidChange(storeKey);
|
1124
|
-
|
1126
|
+
|
1125
1127
|
// Record is now in a committable state -- add storeKey to changelog
|
1126
1128
|
changelog = this.changelog;
|
1127
1129
|
if (!changelog) changelog = SC.Set.create();
|
1128
1130
|
changelog.add(storeKey);
|
1129
1131
|
this.changelog = changelog;
|
1130
|
-
|
1132
|
+
|
1131
1133
|
// if commit records is enabled
|
1132
1134
|
if(this.get('commitRecordsAutomatically')){
|
1133
1135
|
this.invokeLast(this.commitRecords);
|
1134
1136
|
}
|
1135
|
-
|
1137
|
+
|
1136
1138
|
// Finally return materialized record, after we propagate the status to
|
1137
1139
|
// any aggregrate records.
|
1138
1140
|
ret = this.materializeRecord(storeKey);
|
1139
1141
|
if (ret) ret.propagateToAggregates();
|
1140
1142
|
return ret;
|
1141
|
-
},
|
1142
|
-
|
1143
|
+
},
|
1144
|
+
|
1143
1145
|
/**
|
1144
|
-
Creates an array of new records. You must pass an array of `dataHash`es
|
1146
|
+
Creates an array of new records. You must pass an array of `dataHash`es
|
1145
1147
|
plus a `recordType` and, optionally, an array of ids. This will create an
|
1146
1148
|
array of record instances with the same record type.
|
1147
|
-
|
1149
|
+
|
1148
1150
|
If you need to instead create a bunch of records with different data types
|
1149
1151
|
you can instead pass an array of `recordType`s, one for each data hash.
|
1150
|
-
|
1152
|
+
|
1151
1153
|
@param {SC.Record|Array} recordTypes class or array of classes
|
1152
1154
|
@param {Array} dataHashes array of data hashes
|
1153
1155
|
@param {Array} ids (optional) ids to assign to records
|
@@ -1164,14 +1166,14 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1164
1166
|
}
|
1165
1167
|
return ret ;
|
1166
1168
|
},
|
1167
|
-
|
1168
|
-
|
1169
|
+
|
1170
|
+
|
1169
1171
|
/**
|
1170
|
-
Unloads a record, removing the data hash from the store. If you try to
|
1171
|
-
unload a record that is already destroyed then this method will have no effect.
|
1172
|
-
If you unload a record that does not exist or an error then an exception
|
1172
|
+
Unloads a record, removing the data hash from the store. If you try to
|
1173
|
+
unload a record that is already destroyed then this method will have no effect.
|
1174
|
+
If you unload a record that does not exist or an error then an exception
|
1173
1175
|
will be raised.
|
1174
|
-
|
1176
|
+
|
1175
1177
|
@param {SC.Record} recordType the recordType
|
1176
1178
|
@param {String} id the record id
|
1177
1179
|
@param {Number} storeKey (optional) if passed, ignores recordType and id
|
@@ -1184,35 +1186,35 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1184
1186
|
// handle status - ignore if destroying or destroyed
|
1185
1187
|
if ((status === K.BUSY_DESTROYING) || (status & K.DESTROYED)) {
|
1186
1188
|
return this; // nothing to do
|
1187
|
-
|
1189
|
+
|
1188
1190
|
// error out if empty
|
1189
1191
|
} else if (status & K.BUSY) {
|
1190
1192
|
throw K.BUSY_ERROR ;
|
1191
|
-
|
1193
|
+
|
1192
1194
|
// otherwise, destroy in dirty state
|
1193
1195
|
} else status = newStatus ;
|
1194
|
-
|
1196
|
+
|
1195
1197
|
// remove the data hash, set new status
|
1196
1198
|
this.removeDataHash(storeKey, status);
|
1197
1199
|
this.dataHashDidChange(storeKey);
|
1198
|
-
|
1200
|
+
|
1199
1201
|
// Handle all the child Records
|
1200
1202
|
var that = this;
|
1201
1203
|
this._propagateToChildren(storeKey, function(storeKey){
|
1202
1204
|
that.unloadRecord(null, null, storeKey, newStatus);
|
1203
1205
|
});
|
1204
|
-
|
1206
|
+
|
1205
1207
|
return this ;
|
1206
1208
|
},
|
1207
|
-
|
1209
|
+
|
1208
1210
|
/**
|
1209
1211
|
Unloads a group of records. If you have a set of record ids, unloading
|
1210
|
-
them this way can be faster than retrieving each record and unloading
|
1212
|
+
them this way can be faster than retrieving each record and unloading
|
1211
1213
|
it individually.
|
1212
1214
|
|
1213
1215
|
You can pass either a single `recordType` or an array of `recordType`s. If
|
1214
1216
|
you pass a single `recordType`, then the record type will be used for each
|
1215
|
-
record. If you pass an array, then each id must have a matching record
|
1217
|
+
record. If you pass an array, then each id must have a matching record
|
1216
1218
|
type in the array.
|
1217
1219
|
|
1218
1220
|
You can optionally pass an array of `storeKey`s instead of the `recordType`
|
@@ -1259,10 +1261,10 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1259
1261
|
|
1260
1262
|
/**
|
1261
1263
|
Destroys a record, removing the data hash from the store and adding the
|
1262
|
-
record to the destroyed changelog. If you try to destroy a record that is
|
1263
|
-
already destroyed then this method will have no effect. If you destroy a
|
1264
|
+
record to the destroyed changelog. If you try to destroy a record that is
|
1265
|
+
already destroyed then this method will have no effect. If you destroy a
|
1264
1266
|
record that does not exist or an error then an exception will be raised.
|
1265
|
-
|
1267
|
+
|
1266
1268
|
@param {SC.Record} recordType the recordType
|
1267
1269
|
@param {String} id the record id
|
1268
1270
|
@param {Number} storeKey (optional) if passed, ignores recordType and id
|
@@ -1275,22 +1277,22 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1275
1277
|
// handle status - ignore if destroying or destroyed
|
1276
1278
|
if ((status === K.BUSY_DESTROYING) || (status & K.DESTROYED)) {
|
1277
1279
|
return this; // nothing to do
|
1278
|
-
|
1280
|
+
|
1279
1281
|
// error out if empty
|
1280
1282
|
} else if (status === K.EMPTY) {
|
1281
1283
|
throw K.NOT_FOUND_ERROR ;
|
1282
|
-
|
1284
|
+
|
1283
1285
|
// error out if busy
|
1284
1286
|
} else if (status & K.BUSY) {
|
1285
1287
|
throw K.BUSY_ERROR ;
|
1286
|
-
|
1288
|
+
|
1287
1289
|
// if new status, destroy but leave in clean state
|
1288
1290
|
} else if (status === K.READY_NEW) {
|
1289
1291
|
status = K.DESTROYED_CLEAN ;
|
1290
|
-
|
1292
|
+
|
1291
1293
|
// otherwise, destroy in dirty state
|
1292
1294
|
} else status = K.DESTROYED_DIRTY ;
|
1293
|
-
|
1295
|
+
|
1294
1296
|
// remove the data hash, set new status
|
1295
1297
|
this.writeStatus(storeKey, status);
|
1296
1298
|
this.dataHashDidChange(storeKey);
|
@@ -1306,30 +1308,30 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1306
1308
|
if(this.get('commitRecordsAutomatically')){
|
1307
1309
|
this.invokeLast(this.commitRecords);
|
1308
1310
|
}
|
1309
|
-
|
1311
|
+
|
1310
1312
|
var that = this;
|
1311
1313
|
this._propagateToChildren(storeKey, function(storeKey){
|
1312
1314
|
that.destroyRecord(null, null, storeKey);
|
1313
1315
|
});
|
1314
|
-
|
1316
|
+
|
1315
1317
|
return this ;
|
1316
1318
|
},
|
1317
|
-
|
1319
|
+
|
1318
1320
|
/**
|
1319
1321
|
Destroys a group of records. If you have a set of record ids, destroying
|
1320
|
-
them this way can be faster than retrieving each record and destroying
|
1322
|
+
them this way can be faster than retrieving each record and destroying
|
1321
1323
|
it individually.
|
1322
|
-
|
1324
|
+
|
1323
1325
|
You can pass either a single `recordType` or an array of `recordType`s. If
|
1324
1326
|
you pass a single `recordType`, then the record type will be used for each
|
1325
|
-
record. If you pass an array, then each id must have a matching record
|
1327
|
+
record. If you pass an array, then each id must have a matching record
|
1326
1328
|
type in the array.
|
1327
1329
|
|
1328
1330
|
You can optionally pass an array of `storeKey`s instead of the `recordType`
|
1329
1331
|
and ids. In this case the first two parameters will be ignored. This
|
1330
1332
|
is usually only used by low-level internal methods. You will not usually
|
1331
1333
|
destroy records this way.
|
1332
|
-
|
1334
|
+
|
1333
1335
|
@param {SC.Record|Array} recordTypes class or array of classes
|
1334
1336
|
@param {Array} ids ids to destroy
|
1335
1337
|
@param {Array} storeKeys (optional) store keys to destroy
|
@@ -1355,7 +1357,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1355
1357
|
}
|
1356
1358
|
return this ;
|
1357
1359
|
},
|
1358
|
-
|
1360
|
+
|
1359
1361
|
/**
|
1360
1362
|
register a Child Record to the parent
|
1361
1363
|
*/
|
@@ -1380,7 +1382,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1380
1382
|
this.childRecords = crs;
|
1381
1383
|
this.parentRecords = prs;
|
1382
1384
|
},
|
1383
|
-
|
1385
|
+
|
1384
1386
|
/**
|
1385
1387
|
materialize the parent when passing in a store key for the child
|
1386
1388
|
*/
|
@@ -1390,10 +1392,10 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1390
1392
|
crs = this.childRecords;
|
1391
1393
|
pk = crs ? this.childRecords[childStoreKey] : null ;
|
1392
1394
|
if (SC.none(pk)) return null;
|
1393
|
-
|
1395
|
+
|
1394
1396
|
return this.materializeRecord(pk);
|
1395
1397
|
},
|
1396
|
-
|
1398
|
+
|
1397
1399
|
/**
|
1398
1400
|
function for retrieving a parent record key
|
1399
1401
|
|
@@ -1404,7 +1406,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1404
1406
|
var crs = this.childRecords || {};
|
1405
1407
|
return crs[storeKey];
|
1406
1408
|
},
|
1407
|
-
|
1409
|
+
|
1408
1410
|
/**
|
1409
1411
|
function that propagates a function call to all children
|
1410
1412
|
*/
|
@@ -1417,12 +1419,12 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1417
1419
|
if (children.hasOwnProperty(key)) func(key);
|
1418
1420
|
}
|
1419
1421
|
},
|
1420
|
-
|
1422
|
+
|
1421
1423
|
/**
|
1422
1424
|
Notes that the data for the given record id has changed. The record will
|
1423
1425
|
be committed to the server the next time you commit the root store. Only
|
1424
1426
|
call this method on a record in a READY state of some type.
|
1425
|
-
|
1427
|
+
|
1426
1428
|
@param {SC.Record} recordType the recordType
|
1427
1429
|
@param {String} id the record id
|
1428
1430
|
@param {Number} storeKey (optional) if passed, ignores recordType and id
|
@@ -1433,55 +1435,55 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1433
1435
|
recordDidChange: function(recordType, id, storeKey, key, statusOnly) {
|
1434
1436
|
if (storeKey === undefined) storeKey = recordType.storeKeyFor(id);
|
1435
1437
|
var status = this.readStatus(storeKey), changelog, K = SC.Record;
|
1436
|
-
|
1438
|
+
|
1437
1439
|
// BUSY_LOADING, BUSY_CREATING, BUSY_COMMITTING, BUSY_REFRESH_CLEAN
|
1438
1440
|
// BUSY_REFRESH_DIRTY, BUSY_DESTROYING
|
1439
1441
|
if (status & K.BUSY) {
|
1440
1442
|
throw K.BUSY_ERROR ;
|
1441
|
-
|
1443
|
+
|
1442
1444
|
// if record is not in ready state, then it is not found.
|
1443
1445
|
// ERROR, EMPTY, DESTROYED_CLEAN, DESTROYED_DIRTY
|
1444
1446
|
} else if (!(status & K.READY)) {
|
1445
1447
|
throw K.NOT_FOUND_ERROR ;
|
1446
|
-
|
1448
|
+
|
1447
1449
|
// otherwise, make new status READY_DIRTY unless new.
|
1448
1450
|
// K.READY_CLEAN, K.READY_DIRTY, ignore K.READY_NEW
|
1449
1451
|
} else {
|
1450
1452
|
if (status != K.READY_NEW) this.writeStatus(storeKey, K.READY_DIRTY);
|
1451
1453
|
}
|
1452
|
-
|
1454
|
+
|
1453
1455
|
// record data hash change
|
1454
1456
|
this.dataHashDidChange(storeKey, null, statusOnly, key);
|
1455
|
-
|
1457
|
+
|
1456
1458
|
// record in changelog
|
1457
1459
|
changelog = this.changelog ;
|
1458
1460
|
if (!changelog) changelog = this.changelog = SC.Set.create() ;
|
1459
1461
|
changelog.add(storeKey);
|
1460
1462
|
this.changelog = changelog;
|
1461
|
-
|
1463
|
+
|
1462
1464
|
// if commit records is enabled
|
1463
1465
|
if(this.get('commitRecordsAutomatically')){
|
1464
1466
|
this.invokeLast(this.commitRecords);
|
1465
1467
|
}
|
1466
|
-
|
1468
|
+
|
1467
1469
|
return this ;
|
1468
1470
|
},
|
1469
1471
|
|
1470
1472
|
/**
|
1471
1473
|
Mark a group of records as dirty. The records will be committed to the
|
1472
|
-
server the next time you commit changes on the root store. If you have a
|
1473
|
-
set of record ids, marking them dirty this way can be faster than
|
1474
|
+
server the next time you commit changes on the root store. If you have a
|
1475
|
+
set of record ids, marking them dirty this way can be faster than
|
1474
1476
|
retrieving each record and destroying it individually.
|
1475
|
-
|
1477
|
+
|
1476
1478
|
You can pass either a single `recordType` or an array of `recordType`s. If
|
1477
1479
|
you pass a single `recordType`, then the record type will be used for each
|
1478
|
-
record. If you pass an array, then each id must have a matching record
|
1480
|
+
record. If you pass an array, then each id must have a matching record
|
1479
1481
|
type in the array.
|
1480
1482
|
|
1481
1483
|
You can optionally pass an array of `storeKey`s instead of the `recordType`
|
1482
1484
|
and ids. In this case the first two parameters will be ignored. This
|
1483
|
-
is usually only used by low-level internal methods.
|
1484
|
-
|
1485
|
+
is usually only used by low-level internal methods.
|
1486
|
+
|
1485
1487
|
@param {SC.Record|Array} recordTypes class or array of classes
|
1486
1488
|
@param {Array} ids ids to destroy
|
1487
1489
|
@param {Array} storeKeys (optional) store keys to destroy
|
@@ -1506,20 +1508,20 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1506
1508
|
this.recordDidChange(undefined, undefined, storeKey);
|
1507
1509
|
}
|
1508
1510
|
}
|
1509
|
-
return this ;
|
1511
|
+
return this ;
|
1510
1512
|
},
|
1511
1513
|
|
1512
1514
|
/**
|
1513
|
-
Retrieves a set of records from the server. If the records has
|
1514
|
-
already been loaded in the store, then this method will simply return.
|
1515
|
-
Otherwise if your store has a `dataSource`, this will call the
|
1516
|
-
`dataSource` to retrieve the record. Generally you will not need to
|
1515
|
+
Retrieves a set of records from the server. If the records has
|
1516
|
+
already been loaded in the store, then this method will simply return.
|
1517
|
+
Otherwise if your store has a `dataSource`, this will call the
|
1518
|
+
`dataSource` to retrieve the record. Generally you will not need to
|
1517
1519
|
call this method yourself. Instead you can just use `find()`.
|
1518
|
-
|
1519
|
-
This will not actually create a record instance but it will initiate a
|
1520
|
-
load of the record from the server. You can subsequently get a record
|
1520
|
+
|
1521
|
+
This will not actually create a record instance but it will initiate a
|
1522
|
+
load of the record from the server. You can subsequently get a record
|
1521
1523
|
instance itself using `materializeRecord()`.
|
1522
|
-
|
1524
|
+
|
1523
1525
|
@param {SC.Record|Array} recordTypes class or array of classes
|
1524
1526
|
@param {Array} ids ids to retrieve
|
1525
1527
|
@param {Array} storeKeys (optional) store keys to retrieve
|
@@ -1528,7 +1530,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1528
1530
|
@returns {Array} storeKeys to be retrieved
|
1529
1531
|
*/
|
1530
1532
|
retrieveRecords: function(recordTypes, ids, storeKeys, isRefresh, callbacks) {
|
1531
|
-
|
1533
|
+
|
1532
1534
|
var source = this._getDataSource(),
|
1533
1535
|
isArray = SC.typeOf(recordTypes) === SC.T_ARRAY,
|
1534
1536
|
hasCallbackArray = SC.typeOf(callbacks) === SC.T_ARRAY,
|
@@ -1537,12 +1539,12 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1537
1539
|
rev = SC.Store.generateStoreKey(),
|
1538
1540
|
K = SC.Record,
|
1539
1541
|
recordType, idx, storeKey, status, ok, callback;
|
1540
|
-
|
1542
|
+
|
1541
1543
|
if (!isArray) recordType = recordTypes;
|
1542
|
-
|
1544
|
+
|
1543
1545
|
// if no storeKeys were passed, map recordTypes + ids
|
1544
1546
|
for(idx=0;idx<len;idx++) {
|
1545
|
-
|
1547
|
+
|
1546
1548
|
// collect store key
|
1547
1549
|
if (storeKeys) {
|
1548
1550
|
storeKey = storeKeys[idx];
|
@@ -1552,10 +1554,10 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1552
1554
|
}
|
1553
1555
|
//collect the callback
|
1554
1556
|
callback = hasCallbackArray ? callbacks[idx] : callbacks;
|
1555
|
-
|
1557
|
+
|
1556
1558
|
// collect status and process
|
1557
1559
|
status = this.readStatus(storeKey);
|
1558
|
-
|
1560
|
+
|
1559
1561
|
// K.EMPTY, K.ERROR, K.DESTROYED_CLEAN - initial retrieval
|
1560
1562
|
if ((status == K.EMPTY) || (status == K.ERROR) || (status == K.DESTROYED_CLEAN)) {
|
1561
1563
|
this.writeStatus(storeKey, K.BUSY_LOADING);
|
@@ -1577,19 +1579,19 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1577
1579
|
// K.DESTROY_DIRTY, bad state...
|
1578
1580
|
} else if (status == K.DESTROYED_DIRTY) {
|
1579
1581
|
throw K.BAD_STATE_ERROR ;
|
1580
|
-
|
1582
|
+
|
1581
1583
|
// ignore K.BUSY_LOADING, K.BUSY_REFRESH_CLEAN, K.BUSY_REFRESH_DIRTY
|
1582
1584
|
}
|
1583
1585
|
}
|
1584
1586
|
}
|
1585
|
-
|
1587
|
+
|
1586
1588
|
// now retrieve storekeys from dataSource. if there is no dataSource,
|
1587
1589
|
// then act as if we couldn't retrieve.
|
1588
1590
|
ok = NO;
|
1589
1591
|
if (source) ok = source.retrieveRecords.call(source, this, ret, ids);
|
1590
1592
|
|
1591
1593
|
// if the data source could not retrieve or if there is no source, then
|
1592
|
-
// simulate the data source calling dataSourceDidError on those we are
|
1594
|
+
// simulate the data source calling dataSourceDidError on those we are
|
1593
1595
|
// loading for the first time or dataSourceDidComplete on refreshes.
|
1594
1596
|
if (!ok) {
|
1595
1597
|
len = ret.length;
|
@@ -1600,7 +1602,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1600
1602
|
if (status === K.BUSY_LOADING) {
|
1601
1603
|
this.writeStatus(storeKey, K.ERROR);
|
1602
1604
|
this.dataHashDidChange(storeKey, rev, YES);
|
1603
|
-
|
1605
|
+
|
1604
1606
|
} else if (status & K.BUSY_REFRESH) {
|
1605
1607
|
this.writeStatus(storeKey, K.READY | (status & 0x03));
|
1606
1608
|
this.dataHashDidChange(storeKey, rev, YES);
|
@@ -1610,11 +1612,11 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1610
1612
|
}
|
1611
1613
|
return ret ;
|
1612
1614
|
},
|
1613
|
-
|
1615
|
+
|
1614
1616
|
_TMP_RETRIEVE_ARRAY: [],
|
1615
|
-
|
1617
|
+
|
1616
1618
|
_callback_queue: {},
|
1617
|
-
|
1619
|
+
|
1618
1620
|
/**
|
1619
1621
|
@private
|
1620
1622
|
stores the callbacks for the storeKeys that are inflight
|
@@ -1651,14 +1653,14 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1651
1653
|
delete queue[key];
|
1652
1654
|
});
|
1653
1655
|
}
|
1654
|
-
|
1656
|
+
|
1655
1657
|
}
|
1656
1658
|
}
|
1657
1659
|
},
|
1658
|
-
|
1660
|
+
|
1659
1661
|
/*
|
1660
1662
|
@private
|
1661
|
-
|
1663
|
+
|
1662
1664
|
*/
|
1663
1665
|
_cancelCallback: function(storeKey){
|
1664
1666
|
var queue = this._callback_queue;
|
@@ -1666,17 +1668,17 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1666
1668
|
delete queue[storeKey];
|
1667
1669
|
}
|
1668
1670
|
},
|
1669
|
-
|
1670
|
-
|
1671
|
+
|
1672
|
+
|
1671
1673
|
/**
|
1672
1674
|
Retrieves a record from the server. If the record has already been loaded
|
1673
|
-
in the store, then this method will simply return. Otherwise if your
|
1674
|
-
store has a `dataSource`, this will call the `dataSource` to retrieve the
|
1675
|
-
record. Generally you will not need to call this method yourself.
|
1675
|
+
in the store, then this method will simply return. Otherwise if your
|
1676
|
+
store has a `dataSource`, this will call the `dataSource` to retrieve the
|
1677
|
+
record. Generally you will not need to call this method yourself.
|
1676
1678
|
Instead you can just use `find()`.
|
1677
|
-
|
1678
|
-
This will not actually create a record instance but it will initiate a
|
1679
|
-
load of the record from the server. You can subsequently get a record
|
1679
|
+
|
1680
|
+
This will not actually create a record instance but it will initiate a
|
1681
|
+
load of the record from the server. You can subsequently get a record
|
1680
1682
|
instance itself using `materializeRecord()`.
|
1681
1683
|
|
1682
1684
|
@param {SC.Record} recordType class
|
@@ -1684,12 +1686,12 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1684
1686
|
@param {Number} storeKey (optional) store key
|
1685
1687
|
@param {Boolean} isRefresh
|
1686
1688
|
@param {Function} callback (optional)
|
1687
|
-
@returns {Number} storeKey that was retrieved
|
1689
|
+
@returns {Number} storeKey that was retrieved
|
1688
1690
|
*/
|
1689
1691
|
retrieveRecord: function(recordType, id, storeKey, isRefresh, callback) {
|
1690
1692
|
var array = this._TMP_RETRIEVE_ARRAY,
|
1691
1693
|
ret;
|
1692
|
-
|
1694
|
+
|
1693
1695
|
if (storeKey) {
|
1694
1696
|
array[0] = storeKey;
|
1695
1697
|
storeKey = array;
|
@@ -1698,7 +1700,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1698
1700
|
array[0] = id;
|
1699
1701
|
id = array;
|
1700
1702
|
}
|
1701
|
-
|
1703
|
+
|
1702
1704
|
ret = this.retrieveRecords(recordType, id, storeKey, isRefresh, callback);
|
1703
1705
|
array.length = 0 ;
|
1704
1706
|
return ret[0];
|
@@ -1708,7 +1710,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1708
1710
|
Refreshes a record from the server. If the record has already been loaded
|
1709
1711
|
in the store, then this method will request a refresh from the
|
1710
1712
|
`dataSource`. Otherwise it will attempt to retrieve the record.
|
1711
|
-
|
1713
|
+
|
1712
1714
|
@param {String} id to id of the record to load
|
1713
1715
|
@param {SC.Record} recordType the expected record type
|
1714
1716
|
@param {Number} storeKey (optional) optional store key
|
@@ -1723,7 +1725,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1723
1725
|
Refreshes a set of records from the server. If the records has already been loaded
|
1724
1726
|
in the store, then this method will request a refresh from the
|
1725
1727
|
`dataSource`. Otherwise it will attempt to retrieve them.
|
1726
|
-
|
1728
|
+
|
1727
1729
|
@param {SC.Record|Array} recordTypes class or array of classes
|
1728
1730
|
@param {Array} ids ids to destroy
|
1729
1731
|
@param {Array} storeKeys (optional) store keys to destroy
|
@@ -1734,29 +1736,29 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1734
1736
|
var ret = this.retrieveRecords(recordTypes, ids, storeKeys, YES, callback);
|
1735
1737
|
return ret && ret.length>0;
|
1736
1738
|
},
|
1737
|
-
|
1739
|
+
|
1738
1740
|
/**
|
1739
1741
|
Commits the passed store keys or ids. If no `storeKey`s are given,
|
1740
|
-
it will commit any records in the changelog.
|
1741
|
-
|
1742
|
-
Based on the current state of the record, this will ask the data
|
1742
|
+
it will commit any records in the changelog.
|
1743
|
+
|
1744
|
+
Based on the current state of the record, this will ask the data
|
1743
1745
|
source to perform the appropriate actions
|
1744
1746
|
on the store keys.
|
1745
|
-
|
1747
|
+
|
1746
1748
|
@param {Array} recordTypes the expected record types (SC.Record)
|
1747
1749
|
@param {Array} ids to commit
|
1748
1750
|
@param {SC.Set} storeKeys to commit
|
1749
1751
|
@param {Hash} params optional additional parameters to pass along to the
|
1750
1752
|
data source
|
1751
1753
|
@param {Function|Array} callback function or array of callbacks
|
1752
|
-
|
1754
|
+
|
1753
1755
|
@returns {Boolean} if the action was succesful.
|
1754
1756
|
*/
|
1755
1757
|
commitRecords: function(recordTypes, ids, storeKeys, params, callbacks) {
|
1756
1758
|
var source = this._getDataSource(),
|
1757
1759
|
isArray = SC.typeOf(recordTypes) === SC.T_ARRAY,
|
1758
|
-
hasCallbackArray = SC.typeOf(callbacks) === SC.T_ARRAY,
|
1759
|
-
retCreate= [], retUpdate= [], retDestroy = [],
|
1760
|
+
hasCallbackArray = SC.typeOf(callbacks) === SC.T_ARRAY,
|
1761
|
+
retCreate= [], retUpdate= [], retDestroy = [],
|
1760
1762
|
rev = SC.Store.generateStoreKey(),
|
1761
1763
|
K = SC.Record,
|
1762
1764
|
recordType, idx, storeKey, status, key, ret, len, callback;
|
@@ -1769,9 +1771,9 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1769
1771
|
}
|
1770
1772
|
|
1771
1773
|
len = storeKeys ? storeKeys.get('length') : (ids ? ids.get('length') : 0);
|
1772
|
-
|
1774
|
+
|
1773
1775
|
for(idx=0;idx<len;idx++) {
|
1774
|
-
|
1776
|
+
|
1775
1777
|
// collect store key
|
1776
1778
|
if (storeKeys) {
|
1777
1779
|
storeKey = storeKeys[idx];
|
@@ -1780,16 +1782,16 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1780
1782
|
else recordType = recordTypes;
|
1781
1783
|
storeKey = recordType.storeKeyFor(ids[idx]);
|
1782
1784
|
}
|
1783
|
-
|
1785
|
+
|
1784
1786
|
//collect the callback
|
1785
1787
|
callback = hasCallbackArray ? callbacks[idx] : callbacks;
|
1786
|
-
|
1788
|
+
|
1787
1789
|
// collect status and process
|
1788
1790
|
status = this.readStatus(storeKey);
|
1789
|
-
|
1791
|
+
|
1790
1792
|
if ((status == K.EMPTY) || (status == K.ERROR)) {
|
1791
1793
|
throw K.NOT_FOUND_ERROR ;
|
1792
|
-
}
|
1794
|
+
}
|
1793
1795
|
else {
|
1794
1796
|
if(status==K.READY_NEW) {
|
1795
1797
|
this.writeStatus(storeKey, K.BUSY_CREATING);
|
@@ -1809,16 +1811,16 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1809
1811
|
} else if (status==K.DESTROYED_CLEAN) {
|
1810
1812
|
this.dataHashDidChange(storeKey, rev, YES);
|
1811
1813
|
}
|
1812
|
-
// ignore K.READY_CLEAN, K.BUSY_LOADING, K.BUSY_CREATING, K.BUSY_COMMITTING,
|
1814
|
+
// ignore K.READY_CLEAN, K.BUSY_LOADING, K.BUSY_CREATING, K.BUSY_COMMITTING,
|
1813
1815
|
// K.BUSY_REFRESH_CLEAN, K_BUSY_REFRESH_DIRTY, KBUSY_DESTROYING
|
1814
1816
|
}
|
1815
1817
|
}
|
1816
|
-
|
1818
|
+
|
1817
1819
|
// now commit storekeys to dataSource
|
1818
1820
|
if (source && (len>0 || params)) {
|
1819
1821
|
ret = source.commitRecords.call(source, this, retCreate, retUpdate, retDestroy, params);
|
1820
1822
|
}
|
1821
|
-
|
1823
|
+
|
1822
1824
|
//remove all commited changes from changelog
|
1823
1825
|
if (ret && !recordTypes && !ids) {
|
1824
1826
|
if (storeKeys === this.changelog) {
|
@@ -1832,13 +1834,13 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1832
1834
|
},
|
1833
1835
|
|
1834
1836
|
/**
|
1835
|
-
Commits the passed store key or id. Based on the current state of the
|
1837
|
+
Commits the passed store key or id. Based on the current state of the
|
1836
1838
|
record, this will ask the data source to perform the appropriate action
|
1837
1839
|
on the store key.
|
1838
|
-
|
1839
|
-
You have to pass either the id or the storeKey otherwise it will return
|
1840
|
+
|
1841
|
+
You have to pass either the id or the storeKey otherwise it will return
|
1840
1842
|
NO.
|
1841
|
-
|
1843
|
+
|
1842
1844
|
@param {SC.Record} recordType the expected record type
|
1843
1845
|
@param {String} id the id of the record to commit
|
1844
1846
|
@param {Number} storeKey the storeKey of the record to commit
|
@@ -1859,17 +1861,17 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1859
1861
|
array[0] = id;
|
1860
1862
|
id = array;
|
1861
1863
|
}
|
1862
|
-
|
1864
|
+
|
1863
1865
|
ret = this.commitRecords(recordType, id, storeKey, params, callback);
|
1864
1866
|
array.length = 0 ;
|
1865
1867
|
return ret;
|
1866
1868
|
},
|
1867
|
-
|
1869
|
+
|
1868
1870
|
/**
|
1869
|
-
Cancels an inflight request for the passed records. Depending on the
|
1870
|
-
server implementation, this could cancel an entire request, causing
|
1871
|
+
Cancels an inflight request for the passed records. Depending on the
|
1872
|
+
server implementation, this could cancel an entire request, causing
|
1871
1873
|
other records to also transition their current state.
|
1872
|
-
|
1874
|
+
|
1873
1875
|
@param {SC.Record|Array} recordTypes class or array of classes
|
1874
1876
|
@param {Array} ids ids to destroy
|
1875
1877
|
@param {Array} storeKeys (optional) store keys to destroy
|
@@ -1881,22 +1883,22 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1881
1883
|
K = SC.Record,
|
1882
1884
|
ret = [],
|
1883
1885
|
status, len, idx, id, recordType, storeKey;
|
1884
|
-
|
1886
|
+
|
1885
1887
|
len = (storeKeys === undefined) ? ids.length : storeKeys.length;
|
1886
1888
|
for(idx=0;idx<len;idx++) {
|
1887
1889
|
if (isArray) recordType = recordTypes[idx] || SC.Record;
|
1888
1890
|
else recordType = recordTypes || SC.Record;
|
1889
|
-
|
1891
|
+
|
1890
1892
|
id = ids ? ids[idx] : undefined ;
|
1891
|
-
|
1893
|
+
|
1892
1894
|
if(storeKeys===undefined){
|
1893
1895
|
storeKey = recordType.storeKeyFor(id);
|
1894
1896
|
}else{
|
1895
|
-
storeKey = storeKeys ? storeKeys[idx] : undefined ;
|
1897
|
+
storeKey = storeKeys ? storeKeys[idx] : undefined ;
|
1896
1898
|
}
|
1897
1899
|
if(storeKey) {
|
1898
1900
|
status = this.readStatus(storeKey);
|
1899
|
-
|
1901
|
+
|
1900
1902
|
if ((status == K.EMPTY) || (status == K.ERROR)) {
|
1901
1903
|
throw K.NOT_FOUND_ERROR ;
|
1902
1904
|
}
|
@@ -1904,17 +1906,17 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1904
1906
|
this._cancelCallback(storeKey);
|
1905
1907
|
}
|
1906
1908
|
}
|
1907
|
-
|
1909
|
+
|
1908
1910
|
if (source) source.cancel.call(source, this, ret);
|
1909
|
-
|
1911
|
+
|
1910
1912
|
return this ;
|
1911
1913
|
},
|
1912
1914
|
|
1913
1915
|
/**
|
1914
|
-
Cancels an inflight request for the passed record. Depending on the
|
1915
|
-
server implementation, this could cancel an entire request, causing
|
1916
|
+
Cancels an inflight request for the passed record. Depending on the
|
1917
|
+
server implementation, this could cancel an entire request, causing
|
1916
1918
|
other records to also transition their current state.
|
1917
|
-
|
1919
|
+
|
1918
1920
|
@param {SC.Record|Array} recordTypes class or array of classes
|
1919
1921
|
@param {Array} ids ids to destroy
|
1920
1922
|
@param {Array} storeKeys (optional) store keys to destroy
|
@@ -1923,7 +1925,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1923
1925
|
cancelRecord: function(recordType, id, storeKey) {
|
1924
1926
|
var array = this._TMP_RETRIEVE_ARRAY,
|
1925
1927
|
ret ;
|
1926
|
-
|
1928
|
+
|
1927
1929
|
if (storeKey !== undefined) {
|
1928
1930
|
array[0] = storeKey;
|
1929
1931
|
storeKey = array;
|
@@ -1932,32 +1934,32 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1932
1934
|
array[0] = id;
|
1933
1935
|
id = array;
|
1934
1936
|
}
|
1935
|
-
|
1937
|
+
|
1936
1938
|
ret = this.cancelRecords(recordType, id, storeKey);
|
1937
1939
|
array.length = 0 ;
|
1938
1940
|
return this;
|
1939
1941
|
},
|
1940
1942
|
|
1941
|
-
/**
|
1942
|
-
Convenience method can be called by the store or other parts of your
|
1943
|
+
/**
|
1944
|
+
Convenience method can be called by the store or other parts of your
|
1943
1945
|
application to load a record into the store. This method will take a
|
1944
|
-
recordType and a data hashes and either add or update the
|
1945
|
-
record in the store.
|
1946
|
-
|
1946
|
+
recordType and a data hashes and either add or update the
|
1947
|
+
record in the store.
|
1948
|
+
|
1947
1949
|
The loaded records will be in an `SC.Record.READY_CLEAN` state, indicating
|
1948
|
-
they were loaded from the data source and do not need to be committed
|
1950
|
+
they were loaded from the data source and do not need to be committed
|
1949
1951
|
back before changing.
|
1950
|
-
|
1951
|
-
This method will check the state of the storeKey and call either
|
1952
|
-
`pushRetrieve()` or `dataSourceDidComplete()`. The standard state constraints
|
1952
|
+
|
1953
|
+
This method will check the state of the storeKey and call either
|
1954
|
+
`pushRetrieve()` or `dataSourceDidComplete()`. The standard state constraints
|
1953
1955
|
for these methods apply here.
|
1954
|
-
|
1956
|
+
|
1955
1957
|
The return value will be the `storeKey` used for the push. This is often
|
1956
1958
|
convenient to pass into `loadQuery()`, if you are fetching a remote query.
|
1957
|
-
|
1958
|
-
If you are upgrading from a pre SproutCore 1.0 application, this method
|
1959
|
+
|
1960
|
+
If you are upgrading from a pre SproutCore 1.0 application, this method
|
1959
1961
|
is the closest to the old `updateRecord()`.
|
1960
|
-
|
1962
|
+
|
1961
1963
|
@param {SC.Record} recordType the record type
|
1962
1964
|
@param {Array} dataHash to update
|
1963
1965
|
@param {Array} id optional. if not passed lookup on the hash
|
@@ -1966,44 +1968,44 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1966
1968
|
loadRecord: function(recordType, dataHash, id) {
|
1967
1969
|
var K = SC.Record,
|
1968
1970
|
ret, primaryKey, storeKey;
|
1969
|
-
|
1971
|
+
|
1970
1972
|
// save lookup info
|
1971
1973
|
recordType = recordType || SC.Record;
|
1972
1974
|
primaryKey = recordType.prototype.primaryKey;
|
1973
|
-
|
1974
|
-
|
1975
|
+
|
1976
|
+
|
1975
1977
|
// push each record
|
1976
1978
|
id = id || dataHash[primaryKey];
|
1977
1979
|
ret = storeKey = recordType.storeKeyFor(id); // needed to cache
|
1978
|
-
|
1980
|
+
|
1979
1981
|
if (this.readStatus(storeKey) & K.BUSY) {
|
1980
1982
|
this.dataSourceDidComplete(storeKey, dataHash, id);
|
1981
1983
|
} else this.pushRetrieve(recordType, id, dataHash, storeKey);
|
1982
|
-
|
1984
|
+
|
1983
1985
|
// return storeKey
|
1984
1986
|
return ret ;
|
1985
1987
|
},
|
1986
|
-
|
1987
|
-
/**
|
1988
|
-
Convenience method can be called by the store or other parts of your
|
1988
|
+
|
1989
|
+
/**
|
1990
|
+
Convenience method can be called by the store or other parts of your
|
1989
1991
|
application to load records into the store. This method will take a
|
1990
|
-
recordType and an array of data hashes and either add or update the
|
1991
|
-
record in the store.
|
1992
|
-
|
1992
|
+
recordType and an array of data hashes and either add or update the
|
1993
|
+
record in the store.
|
1994
|
+
|
1993
1995
|
The loaded records will be in an `SC.Record.READY_CLEAN` state, indicating
|
1994
|
-
they were loaded from the data source and do not need to be committed
|
1996
|
+
they were loaded from the data source and do not need to be committed
|
1995
1997
|
back before changing.
|
1996
|
-
|
1997
|
-
This method will check the state of each storeKey and call either
|
1998
|
-
`pushRetrieve()` or `dataSourceDidComplete()`. The standard state
|
1998
|
+
|
1999
|
+
This method will check the state of each storeKey and call either
|
2000
|
+
`pushRetrieve()` or `dataSourceDidComplete()`. The standard state
|
1999
2001
|
constraints for these methods apply here.
|
2000
|
-
|
2002
|
+
|
2001
2003
|
The return value will be the storeKeys used for each push. This is often
|
2002
2004
|
convenient to pass into `loadQuery()`, if you are fetching a remote query.
|
2003
|
-
|
2004
|
-
If you are upgrading from a pre SproutCore 1.0 application, this method
|
2005
|
+
|
2006
|
+
If you are upgrading from a pre SproutCore 1.0 application, this method
|
2005
2007
|
is the closest to the old `updateRecords()`.
|
2006
|
-
|
2008
|
+
|
2007
2009
|
@param {SC.Record} recordTypes the record type or array of record types
|
2008
2010
|
@param {Array} dataHashes array of data hashes to update
|
2009
2011
|
@param {Array} ids optional array of ids. if not passed lookup on hashes
|
@@ -2015,13 +2017,13 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2015
2017
|
ret = [],
|
2016
2018
|
K = SC.Record,
|
2017
2019
|
recordType, id, primaryKey, idx, dataHash, storeKey;
|
2018
|
-
|
2020
|
+
|
2019
2021
|
// save lookup info
|
2020
2022
|
if (!isArray) {
|
2021
2023
|
recordType = recordTypes || SC.Record;
|
2022
2024
|
primaryKey = recordType.prototype.primaryKey ;
|
2023
2025
|
}
|
2024
|
-
|
2026
|
+
|
2025
2027
|
// push each record
|
2026
2028
|
for(idx=0;idx<len;idx++) {
|
2027
2029
|
dataHash = dataHashes.objectAt(idx);
|
@@ -2031,9 +2033,9 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2031
2033
|
}
|
2032
2034
|
id = (ids) ? ids.objectAt(idx) : dataHash[primaryKey];
|
2033
2035
|
ret[idx] = this.loadRecord(recordType, dataHash, id);
|
2034
|
-
|
2036
|
+
|
2035
2037
|
}
|
2036
|
-
|
2038
|
+
|
2037
2039
|
// return storeKeys
|
2038
2040
|
return ret ;
|
2039
2041
|
},
|
@@ -2042,7 +2044,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2042
2044
|
Returns the `SC.Error` object associated with a specific record.
|
2043
2045
|
|
2044
2046
|
@param {Number} storeKey The store key of the record.
|
2045
|
-
|
2047
|
+
|
2046
2048
|
@returns {SC.Error} SC.Error or undefined if no error associated with the record.
|
2047
2049
|
*/
|
2048
2050
|
readError: function(storeKey) {
|
@@ -2054,91 +2056,91 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2054
2056
|
Returns the `SC.Error` object associated with a specific query.
|
2055
2057
|
|
2056
2058
|
@param {SC.Query} query The SC.Query with which the error is associated.
|
2057
|
-
|
2059
|
+
|
2058
2060
|
@returns {SC.Error} SC.Error or undefined if no error associated with the query.
|
2059
2061
|
*/
|
2060
2062
|
readQueryError: function(query) {
|
2061
2063
|
var errors = this.queryErrors ;
|
2062
2064
|
return errors ? errors[SC.guidFor(query)] : undefined ;
|
2063
2065
|
},
|
2064
|
-
|
2066
|
+
|
2065
2067
|
// ..........................................................
|
2066
2068
|
// DATA SOURCE CALLBACKS
|
2067
|
-
//
|
2069
|
+
//
|
2068
2070
|
// Mathods called by the data source on the store
|
2069
2071
|
|
2070
2072
|
/**
|
2071
|
-
Called by a `dataSource` when it cancels an inflight operation on a
|
2073
|
+
Called by a `dataSource` when it cancels an inflight operation on a
|
2072
2074
|
record. This will transition the record back to it non-inflight state.
|
2073
|
-
|
2075
|
+
|
2074
2076
|
@param {Number} storeKey record store key to cancel
|
2075
|
-
@returns {SC.Store}
|
2077
|
+
@returns {SC.Store} receiver
|
2076
2078
|
*/
|
2077
2079
|
dataSourceDidCancel: function(storeKey) {
|
2078
|
-
var status = this.readStatus(storeKey),
|
2080
|
+
var status = this.readStatus(storeKey),
|
2079
2081
|
K = SC.Record;
|
2080
|
-
|
2082
|
+
|
2081
2083
|
// EMPTY, ERROR, READY_CLEAN, READY_NEW, READY_DIRTY, DESTROYED_CLEAN,
|
2082
2084
|
// DESTROYED_DIRTY
|
2083
2085
|
if (!(status & K.BUSY)) {
|
2084
2086
|
throw K.BAD_STATE_ERROR; // should never be called in this state
|
2085
2087
|
}
|
2086
|
-
|
2088
|
+
|
2087
2089
|
// otherwise, determine proper state transition
|
2088
2090
|
switch(status) {
|
2089
2091
|
case K.BUSY_LOADING:
|
2090
2092
|
status = K.EMPTY;
|
2091
2093
|
break ;
|
2092
|
-
|
2094
|
+
|
2093
2095
|
case K.BUSY_CREATING:
|
2094
2096
|
status = K.READY_NEW;
|
2095
2097
|
break;
|
2096
|
-
|
2098
|
+
|
2097
2099
|
case K.BUSY_COMMITTING:
|
2098
2100
|
status = K.READY_DIRTY ;
|
2099
2101
|
break;
|
2100
|
-
|
2102
|
+
|
2101
2103
|
case K.BUSY_REFRESH_CLEAN:
|
2102
2104
|
status = K.READY_CLEAN;
|
2103
2105
|
break;
|
2104
|
-
|
2106
|
+
|
2105
2107
|
case K.BUSY_REFRESH_DIRTY:
|
2106
2108
|
status = K.READY_DIRTY ;
|
2107
2109
|
break ;
|
2108
|
-
|
2110
|
+
|
2109
2111
|
case K.BUSY_DESTROYING:
|
2110
2112
|
status = K.DESTROYED_DIRTY ;
|
2111
2113
|
break;
|
2112
|
-
|
2114
|
+
|
2113
2115
|
default:
|
2114
2116
|
throw K.BAD_STATE_ERROR ;
|
2115
|
-
}
|
2117
|
+
}
|
2116
2118
|
this.writeStatus(storeKey, status) ;
|
2117
2119
|
this.dataHashDidChange(storeKey, null, YES);
|
2118
2120
|
this._cancelCallback(storeKey);
|
2119
|
-
|
2121
|
+
|
2120
2122
|
return this ;
|
2121
2123
|
},
|
2122
|
-
|
2124
|
+
|
2123
2125
|
/**
|
2124
2126
|
Called by a data source when it creates or commits a record. Passing an
|
2125
|
-
optional id will remap the `storeKey` to the new record id. This is
|
2127
|
+
optional id will remap the `storeKey` to the new record id. This is
|
2126
2128
|
required when you commit a record that does not have an id yet.
|
2127
|
-
|
2129
|
+
|
2128
2130
|
@param {Number} storeKey record store key to change to READY_CLEAN state
|
2129
2131
|
@param {Hash} dataHash optional data hash to replace current hash
|
2130
2132
|
@param {Object} newId optional new id to replace the old one
|
2131
|
-
@returns {SC.Store}
|
2133
|
+
@returns {SC.Store} receiver
|
2132
2134
|
*/
|
2133
2135
|
dataSourceDidComplete: function(storeKey, dataHash, newId) {
|
2134
2136
|
var status = this.readStatus(storeKey), K = SC.Record, statusOnly;
|
2135
|
-
|
2137
|
+
|
2136
2138
|
// EMPTY, ERROR, READY_CLEAN, READY_NEW, READY_DIRTY, DESTROYED_CLEAN,
|
2137
2139
|
// DESTROYED_DIRTY
|
2138
2140
|
if (!(status & K.BUSY)) {
|
2139
2141
|
throw K.BAD_STATE_ERROR; // should never be called in this state
|
2140
2142
|
}
|
2141
|
-
|
2143
|
+
|
2142
2144
|
// otherwise, determine proper state transition
|
2143
2145
|
if(status===K.BUSY_DESTROYING) {
|
2144
2146
|
throw K.BAD_STATE_ERROR ;
|
@@ -2147,7 +2149,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2147
2149
|
this.writeStatus(storeKey, status) ;
|
2148
2150
|
if (dataHash) this.writeDataHash(storeKey, dataHash, status) ;
|
2149
2151
|
if (newId) SC.Store.replaceIdFor(storeKey, newId);
|
2150
|
-
|
2152
|
+
|
2151
2153
|
statusOnly = dataHash || newId ? NO : YES;
|
2152
2154
|
this.dataHashDidChange(storeKey, null, statusOnly);
|
2153
2155
|
|
@@ -2158,16 +2160,16 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2158
2160
|
}
|
2159
2161
|
//update callbacks
|
2160
2162
|
this._retreiveCallbackForStoreKey(storeKey);
|
2161
|
-
|
2163
|
+
|
2162
2164
|
return this ;
|
2163
2165
|
},
|
2164
|
-
|
2166
|
+
|
2165
2167
|
/**
|
2166
2168
|
Called by a data source when it has destroyed a record. This will
|
2167
2169
|
transition the record to the proper state.
|
2168
|
-
|
2170
|
+
|
2169
2171
|
@param {Number} storeKey record store key to cancel
|
2170
|
-
@returns {SC.Store}
|
2172
|
+
@returns {SC.Store} receiver
|
2171
2173
|
*/
|
2172
2174
|
dataSourceDidDestroy: function(storeKey) {
|
2173
2175
|
var status = this.readStatus(storeKey), K = SC.Record;
|
@@ -2180,7 +2182,7 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2180
2182
|
// otherwise, determine proper state transition
|
2181
2183
|
else{
|
2182
2184
|
status = K.DESTROYED_CLEAN ;
|
2183
|
-
}
|
2185
|
+
}
|
2184
2186
|
this.removeDataHash(storeKey, status) ;
|
2185
2187
|
this.dataHashDidChange(storeKey);
|
2186
2188
|
|
@@ -2197,10 +2199,10 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2197
2199
|
|
2198
2200
|
/**
|
2199
2201
|
Converts the passed record into an error object.
|
2200
|
-
|
2202
|
+
|
2201
2203
|
@param {Number} storeKey record store key to error
|
2202
2204
|
@param {SC.Error} error [optional] an SC.Error instance to associate with storeKey
|
2203
|
-
@returns {SC.Store}
|
2205
|
+
@returns {SC.Store} receiver
|
2204
2206
|
*/
|
2205
2207
|
dataSourceDidError: function(storeKey, error) {
|
2206
2208
|
var status = this.readStatus(storeKey), errors = this.recordErrors, K = SC.Record;
|
@@ -2233,44 +2235,44 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2233
2235
|
|
2234
2236
|
// ..........................................................
|
2235
2237
|
// PUSH CHANGES FROM DATA SOURCE
|
2236
|
-
//
|
2237
|
-
|
2238
|
+
//
|
2239
|
+
|
2238
2240
|
/**
|
2239
|
-
Call by the data source whenever you want to push new data out of band
|
2241
|
+
Call by the data source whenever you want to push new data out of band
|
2240
2242
|
into the store.
|
2241
|
-
|
2243
|
+
|
2242
2244
|
@param {Class} recordType the SC.Record subclass
|
2243
2245
|
@param {Object} id the record id or null
|
2244
2246
|
@param {Hash} dataHash data hash to load
|
2245
|
-
@param {Number} storeKey optional store key.
|
2247
|
+
@param {Number} storeKey optional store key.
|
2246
2248
|
@returns {Number|Boolean} storeKey if push was allowed, NO if not
|
2247
2249
|
*/
|
2248
2250
|
pushRetrieve: function(recordType, id, dataHash, storeKey) {
|
2249
2251
|
var K = SC.Record, status;
|
2250
|
-
|
2252
|
+
|
2251
2253
|
if(storeKey===undefined) storeKey = recordType.storeKeyFor(id);
|
2252
2254
|
status = this.readStatus(storeKey);
|
2253
2255
|
if(status==K.EMPTY || status==K.ERROR || status==K.READY_CLEAN || status==K.DESTROYED_CLEAN) {
|
2254
|
-
|
2256
|
+
|
2255
2257
|
status = K.READY_CLEAN;
|
2256
2258
|
if(dataHash===undefined) this.writeStatus(storeKey, status) ;
|
2257
2259
|
else this.writeDataHash(storeKey, dataHash, status) ;
|
2258
2260
|
|
2259
2261
|
this.dataHashDidChange(storeKey);
|
2260
|
-
|
2262
|
+
|
2261
2263
|
return storeKey;
|
2262
2264
|
}
|
2263
2265
|
//conflicted (ready)
|
2264
2266
|
return NO;
|
2265
2267
|
},
|
2266
|
-
|
2268
|
+
|
2267
2269
|
/**
|
2268
|
-
Call by the data source whenever you want to push a deletion into the
|
2270
|
+
Call by the data source whenever you want to push a deletion into the
|
2269
2271
|
store.
|
2270
|
-
|
2272
|
+
|
2271
2273
|
@param {Class} recordType the SC.Record subclass
|
2272
2274
|
@param {Object} id the record id or null
|
2273
|
-
@param {Number} storeKey optional store key.
|
2275
|
+
@param {Number} storeKey optional store key.
|
2274
2276
|
@returns {Number|Boolean} storeKey if push was allowed, NO if not
|
2275
2277
|
*/
|
2276
2278
|
pushDestroy: function(recordType, id, storeKey) {
|
@@ -2291,9 +2293,9 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2291
2293
|
},
|
2292
2294
|
|
2293
2295
|
/**
|
2294
|
-
Call by the data source whenever you want to push an error into the
|
2296
|
+
Call by the data source whenever you want to push an error into the
|
2295
2297
|
store.
|
2296
|
-
|
2298
|
+
|
2297
2299
|
@param {Class} recordType the SC.Record subclass
|
2298
2300
|
@param {Object} id the record id or null
|
2299
2301
|
@param {SC.Error} error [optional] an SC.Error instance to associate with id or storeKey
|
@@ -2308,13 +2310,13 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2308
2310
|
|
2309
2311
|
if(status==K.EMPTY || status==K.ERROR || status==K.READY_CLEAN || status==K.DESTROYED_CLEAN){
|
2310
2312
|
status = K.ERROR;
|
2311
|
-
|
2313
|
+
|
2312
2314
|
// Add the error to the array of record errors (for lookup later on if necessary).
|
2313
2315
|
if (error && error.isError) {
|
2314
2316
|
if (!errors) errors = this.recordErrors = [];
|
2315
2317
|
errors[storeKey] = error;
|
2316
2318
|
}
|
2317
|
-
|
2319
|
+
|
2318
2320
|
this.writeStatus(storeKey, status) ;
|
2319
2321
|
this.dataHashDidChange(storeKey, null, YES);
|
2320
2322
|
return storeKey;
|
@@ -2322,29 +2324,29 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2322
2324
|
//conflicted (error)
|
2323
2325
|
return NO;
|
2324
2326
|
},
|
2325
|
-
|
2327
|
+
|
2326
2328
|
// ..........................................................
|
2327
2329
|
// FETCH CALLBACKS
|
2328
|
-
//
|
2329
|
-
|
2330
|
+
//
|
2331
|
+
|
2330
2332
|
// **NOTE**: although these method works on RecordArray instances right now.
|
2331
2333
|
// They could be optimized to actually share query results between nested
|
2332
|
-
// stores. This is why these methods are implemented here instead of
|
2334
|
+
// stores. This is why these methods are implemented here instead of
|
2333
2335
|
// directly on `Query` or `RecordArray` objects.
|
2334
|
-
|
2336
|
+
|
2335
2337
|
/**
|
2336
2338
|
Sets the passed array of storeKeys as the new data for the query. You
|
2337
2339
|
can call this at any time for a remote query to update its content. If
|
2338
2340
|
you want to use incremental loading, then pass a `SparseArray` object.
|
2339
|
-
|
2341
|
+
|
2340
2342
|
If the query you pass is not a REMOTE query, then this method will raise
|
2341
|
-
an exception. This will also implicitly transition the query state to
|
2343
|
+
an exception. This will also implicitly transition the query state to
|
2342
2344
|
`SC.Record.READY`.
|
2343
|
-
|
2345
|
+
|
2344
2346
|
If you called `loadRecords()` before to load the actual content, you can
|
2345
2347
|
call this method with the return value of that method to actually set the
|
2346
2348
|
storeKeys on the result.
|
2347
|
-
|
2349
|
+
|
2348
2350
|
@param {SC.Query} query the query you are loading. must be remote.
|
2349
2351
|
@param {SC.Array} storeKeys array of store keys
|
2350
2352
|
@returns {SC.Store} receiver
|
@@ -2357,75 +2359,75 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2357
2359
|
var recArray = this._findQuery(query, YES, NO);
|
2358
2360
|
if (recArray) recArray.set('storeKeys', storeKeys);
|
2359
2361
|
this.dataSourceDidFetchQuery(query);
|
2360
|
-
|
2362
|
+
|
2361
2363
|
return this ;
|
2362
2364
|
},
|
2363
|
-
|
2365
|
+
|
2364
2366
|
/**
|
2365
|
-
Called by your data source whenever you finish fetching the results of a
|
2367
|
+
Called by your data source whenever you finish fetching the results of a
|
2366
2368
|
query. This will put the query into a READY state if it was loading.
|
2367
|
-
|
2368
|
-
Note that if the query is a REMOTE query, then you must separately load
|
2369
|
-
the results into the query using `loadQueryResults()`. If the query is
|
2370
|
-
LOCAL, then the query will update automatically with any new records you
|
2369
|
+
|
2370
|
+
Note that if the query is a REMOTE query, then you must separately load
|
2371
|
+
the results into the query using `loadQueryResults()`. If the query is
|
2372
|
+
LOCAL, then the query will update automatically with any new records you
|
2371
2373
|
added to the store.
|
2372
|
-
|
2374
|
+
|
2373
2375
|
@param {SC.Query} query the query you fetched
|
2374
2376
|
@returns {SC.Store} receiver
|
2375
2377
|
*/
|
2376
2378
|
dataSourceDidFetchQuery: function(query) {
|
2377
2379
|
return this._scstore_dataSourceDidFetchQuery(query, YES);
|
2378
2380
|
},
|
2379
|
-
|
2381
|
+
|
2380
2382
|
_scstore_dataSourceDidFetchQuery: function(query, createIfNeeded) {
|
2381
2383
|
var recArray = this._findQuery(query, createIfNeeded, NO),
|
2382
2384
|
nestedStores = this.get('nestedStores'),
|
2383
2385
|
loc = nestedStores ? nestedStores.get('length') : 0;
|
2384
|
-
|
2386
|
+
|
2385
2387
|
// fix query if needed
|
2386
2388
|
if (recArray) recArray.storeDidFetchQuery(query);
|
2387
|
-
|
2389
|
+
|
2388
2390
|
// notify nested stores
|
2389
2391
|
while(--loc >= 0) {
|
2390
2392
|
nestedStores[loc]._scstore_dataSourceDidFetchQuery(query, NO);
|
2391
2393
|
}
|
2392
|
-
|
2394
|
+
|
2393
2395
|
return this ;
|
2394
2396
|
},
|
2395
|
-
|
2397
|
+
|
2396
2398
|
/**
|
2397
2399
|
Called by your data source if it cancels fetching the results of a query.
|
2398
2400
|
This will put any RecordArray's back into its original state (READY or
|
2399
2401
|
EMPTY).
|
2400
|
-
|
2402
|
+
|
2401
2403
|
@param {SC.Query} query the query you cancelled
|
2402
2404
|
@returns {SC.Store} receiver
|
2403
2405
|
*/
|
2404
2406
|
dataSourceDidCancelQuery: function(query) {
|
2405
2407
|
return this._scstore_dataSourceDidCancelQuery(query, YES);
|
2406
2408
|
},
|
2407
|
-
|
2409
|
+
|
2408
2410
|
_scstore_dataSourceDidCancelQuery: function(query, createIfNeeded) {
|
2409
2411
|
var recArray = this._findQuery(query, createIfNeeded, NO),
|
2410
2412
|
nestedStores = this.get('nestedStores'),
|
2411
2413
|
loc = nestedStores ? nestedStores.get('length') : 0;
|
2412
|
-
|
2414
|
+
|
2413
2415
|
// fix query if needed
|
2414
2416
|
if (recArray) recArray.storeDidCancelQuery(query);
|
2415
|
-
|
2417
|
+
|
2416
2418
|
// notify nested stores
|
2417
2419
|
while(--loc >= 0) {
|
2418
2420
|
nestedStores[loc]._scstore_dataSourceDidCancelQuery(query, NO);
|
2419
2421
|
}
|
2420
|
-
|
2422
|
+
|
2421
2423
|
return this ;
|
2422
2424
|
},
|
2423
|
-
|
2425
|
+
|
2424
2426
|
/**
|
2425
2427
|
Called by your data source if it encountered an error loading the query.
|
2426
2428
|
This will put the query into an error state until you try to refresh it
|
2427
2429
|
again.
|
2428
|
-
|
2430
|
+
|
2429
2431
|
@param {SC.Query} query the query with the error
|
2430
2432
|
@param {SC.Error} error [optional] an SC.Error instance to associate with query
|
2431
2433
|
@returns {SC.Store} receiver
|
@@ -2457,18 +2459,18 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2457
2459
|
|
2458
2460
|
return this ;
|
2459
2461
|
},
|
2460
|
-
|
2462
|
+
|
2461
2463
|
// ..........................................................
|
2462
2464
|
// INTERNAL SUPPORT
|
2463
|
-
//
|
2464
|
-
|
2465
|
+
//
|
2466
|
+
|
2465
2467
|
/** @private */
|
2466
2468
|
init: function() {
|
2467
2469
|
sc_super();
|
2468
2470
|
this.reset();
|
2469
2471
|
},
|
2470
|
-
|
2471
|
-
|
2472
|
+
|
2473
|
+
|
2472
2474
|
toString: function() {
|
2473
2475
|
// Include the name if the client has specified one.
|
2474
2476
|
var name = this.get('name');
|
@@ -2484,32 +2486,32 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2484
2486
|
|
2485
2487
|
// ..........................................................
|
2486
2488
|
// PRIMARY KEY CONVENIENCE METHODS
|
2487
|
-
//
|
2489
|
+
//
|
2488
2490
|
|
2489
|
-
/**
|
2491
|
+
/**
|
2490
2492
|
Given a `storeKey`, return the `primaryKey`.
|
2491
|
-
|
2493
|
+
|
2492
2494
|
@param {Number} storeKey the store key
|
2493
2495
|
@returns {String} primaryKey value
|
2494
2496
|
*/
|
2495
2497
|
idFor: function(storeKey) {
|
2496
2498
|
return SC.Store.idFor(storeKey);
|
2497
2499
|
},
|
2498
|
-
|
2500
|
+
|
2499
2501
|
/**
|
2500
2502
|
Given a storeKey, return the recordType.
|
2501
|
-
|
2503
|
+
|
2502
2504
|
@param {Number} storeKey the store key
|
2503
2505
|
@returns {SC.Record} record instance
|
2504
2506
|
*/
|
2505
2507
|
recordTypeFor: function(storeKey) {
|
2506
2508
|
return SC.Store.recordTypeFor(storeKey) ;
|
2507
2509
|
},
|
2508
|
-
|
2510
|
+
|
2509
2511
|
/**
|
2510
2512
|
Given a `recordType` and `primaryKey`, find the `storeKey`. If the
|
2511
2513
|
`primaryKey` has not been assigned a `storeKey` yet, it will be added.
|
2512
|
-
|
2514
|
+
|
2513
2515
|
@param {SC.Record} recordType the record type
|
2514
2516
|
@param {String} primaryKey the primary key
|
2515
2517
|
@returns {Number} storeKey
|
@@ -2517,12 +2519,12 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2517
2519
|
storeKeyFor: function(recordType, primaryKey) {
|
2518
2520
|
return recordType.storeKeyFor(primaryKey);
|
2519
2521
|
},
|
2520
|
-
|
2522
|
+
|
2521
2523
|
/**
|
2522
2524
|
Given a `primaryKey` value for the record, returns the associated
|
2523
2525
|
`storeKey`. As opposed to `storeKeyFor()` however, this method
|
2524
2526
|
will **NOT** generate a new `storeKey` but returned `undefined`.
|
2525
|
-
|
2527
|
+
|
2526
2528
|
@param {SC.Record} recordType the record type
|
2527
2529
|
@param {String} primaryKey the primary key
|
2528
2530
|
@returns {Number} a storeKey.
|
@@ -2530,56 +2532,56 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2530
2532
|
storeKeyExists: function(recordType, primaryKey) {
|
2531
2533
|
return recordType.storeKeyExists(primaryKey);
|
2532
2534
|
},
|
2533
|
-
|
2535
|
+
|
2534
2536
|
/**
|
2535
2537
|
Finds all `storeKey`s of a certain record type in this store
|
2536
2538
|
and returns an array.
|
2537
|
-
|
2539
|
+
|
2538
2540
|
@param {SC.Record} recordType
|
2539
2541
|
@returns {Array} set of storeKeys
|
2540
2542
|
*/
|
2541
2543
|
storeKeysFor: function(recordType) {
|
2542
|
-
var ret = [],
|
2544
|
+
var ret = [],
|
2543
2545
|
isEnum = recordType && recordType.isEnumerable,
|
2544
2546
|
recType, storeKey, isMatch ;
|
2545
|
-
|
2547
|
+
|
2546
2548
|
if (!this.statuses) return ret;
|
2547
2549
|
for(storeKey in SC.Store.recordTypesByStoreKey) {
|
2548
2550
|
recType = SC.Store.recordTypesByStoreKey[storeKey];
|
2549
|
-
|
2551
|
+
|
2550
2552
|
// if same record type and this store has it
|
2551
2553
|
if (isEnum) isMatch = recordType.contains(recType);
|
2552
2554
|
else isMatch = recType === recordType;
|
2553
|
-
|
2555
|
+
|
2554
2556
|
if(isMatch && this.statuses[storeKey]) ret.push(parseInt(storeKey, 10));
|
2555
2557
|
}
|
2556
|
-
|
2558
|
+
|
2557
2559
|
return ret;
|
2558
2560
|
},
|
2559
|
-
|
2561
|
+
|
2560
2562
|
/**
|
2561
2563
|
Finds all `storeKey`s in this store
|
2562
2564
|
and returns an array.
|
2563
|
-
|
2565
|
+
|
2564
2566
|
@returns {Array} set of storeKeys
|
2565
2567
|
*/
|
2566
2568
|
storeKeys: function() {
|
2567
2569
|
var ret = [], storeKey;
|
2568
2570
|
if(!this.statuses) return ret;
|
2569
|
-
|
2571
|
+
|
2570
2572
|
for(storeKey in this.statuses) {
|
2571
2573
|
// if status is not empty
|
2572
2574
|
if(this.statuses[storeKey] != SC.Record.EMPTY) {
|
2573
2575
|
ret.push(parseInt(storeKey, 10));
|
2574
2576
|
}
|
2575
2577
|
}
|
2576
|
-
|
2578
|
+
|
2577
2579
|
return ret;
|
2578
2580
|
},
|
2579
|
-
|
2581
|
+
|
2580
2582
|
/**
|
2581
2583
|
Returns string representation of a `storeKey`, with status.
|
2582
|
-
|
2584
|
+
|
2583
2585
|
@param {Number} storeKey
|
2584
2586
|
@returns {String}
|
2585
2587
|
*/
|
@@ -2587,54 +2589,54 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
2587
2589
|
var rec = this.materializeRecord(storeKey);
|
2588
2590
|
return rec.statusString();
|
2589
2591
|
}
|
2590
|
-
|
2592
|
+
|
2591
2593
|
}) ;
|
2592
2594
|
|
2593
2595
|
SC.Store.mixin(/** @scope SC.Store.prototype */{
|
2594
|
-
|
2596
|
+
|
2595
2597
|
/**
|
2596
2598
|
Standard error raised if you try to commit changes from a nested store
|
2597
2599
|
and there is a conflict.
|
2598
|
-
|
2600
|
+
|
2599
2601
|
@type Error
|
2600
2602
|
*/
|
2601
2603
|
CHAIN_CONFLICT_ERROR: new Error("Nested Store Conflict"),
|
2602
|
-
|
2604
|
+
|
2603
2605
|
/**
|
2604
|
-
Standard error if you try to perform an operation on a nested store
|
2606
|
+
Standard error if you try to perform an operation on a nested store
|
2605
2607
|
without a parent.
|
2606
|
-
|
2608
|
+
|
2607
2609
|
@type Error
|
2608
2610
|
*/
|
2609
2611
|
NO_PARENT_STORE_ERROR: new Error("Parent Store Required"),
|
2610
|
-
|
2612
|
+
|
2611
2613
|
/**
|
2612
2614
|
Standard error if you try to perform an operation on a nested store that
|
2613
2615
|
is only supported in root stores.
|
2614
|
-
|
2616
|
+
|
2615
2617
|
@type Error
|
2616
2618
|
*/
|
2617
2619
|
NESTED_STORE_UNSUPPORTED_ERROR: new Error("Unsupported In Nested Store"),
|
2618
|
-
|
2620
|
+
|
2619
2621
|
/**
|
2620
2622
|
Standard error if you try to retrieve a record in a nested store that is
|
2621
2623
|
dirty. (This is allowed on the main store, but not in nested stores.)
|
2622
|
-
|
2624
|
+
|
2623
2625
|
@type Error
|
2624
2626
|
*/
|
2625
2627
|
NESTED_STORE_RETRIEVE_DIRTY_ERROR: new Error("Cannot Retrieve Dirty Record in Nested Store"),
|
2626
2628
|
|
2627
2629
|
/**
|
2628
2630
|
Data hash state indicates the data hash is currently editable
|
2629
|
-
|
2631
|
+
|
2630
2632
|
@type String
|
2631
2633
|
*/
|
2632
2634
|
EDITABLE: 'editable',
|
2633
|
-
|
2635
|
+
|
2634
2636
|
/**
|
2635
|
-
Data hash state indicates the hash no longer tracks changes from a
|
2637
|
+
Data hash state indicates the hash no longer tracks changes from a
|
2636
2638
|
parent store, but it is not editable.
|
2637
|
-
|
2639
|
+
|
2638
2640
|
@type String
|
2639
2641
|
*/
|
2640
2642
|
LOCKED: 'locked',
|
@@ -2642,88 +2644,88 @@ SC.Store.mixin(/** @scope SC.Store.prototype */{
|
|
2642
2644
|
/**
|
2643
2645
|
Data hash state indicates the hash is tracking changes from the parent
|
2644
2646
|
store and is not editable.
|
2645
|
-
|
2647
|
+
|
2646
2648
|
@type String
|
2647
2649
|
*/
|
2648
2650
|
INHERITED: 'inherited',
|
2649
|
-
|
2651
|
+
|
2650
2652
|
/** @private
|
2651
2653
|
This array maps all storeKeys to primary keys. You will not normally
|
2652
|
-
access this method directly. Instead use the `idFor()` and
|
2654
|
+
access this method directly. Instead use the `idFor()` and
|
2653
2655
|
`storeKeyFor()` methods on `SC.Record`.
|
2654
2656
|
*/
|
2655
2657
|
idsByStoreKey: [],
|
2656
|
-
|
2658
|
+
|
2657
2659
|
/** @private
|
2658
2660
|
Maps all `storeKey`s to a `recordType`. Once a `storeKey` is associated
|
2659
2661
|
with a `primaryKey` and `recordType` that remains constant throughout the
|
2660
2662
|
lifetime of the application.
|
2661
2663
|
*/
|
2662
2664
|
recordTypesByStoreKey: {},
|
2663
|
-
|
2665
|
+
|
2664
2666
|
/** @private
|
2665
2667
|
Maps some `storeKeys` to query instance. Once a `storeKey` is associated
|
2666
|
-
with a query instance, that remains constant through the lifetime of the
|
2667
|
-
application. If a `Query` is destroyed, it will remove itself from this
|
2668
|
+
with a query instance, that remains constant through the lifetime of the
|
2669
|
+
application. If a `Query` is destroyed, it will remove itself from this
|
2668
2670
|
list.
|
2669
|
-
|
2671
|
+
|
2670
2672
|
Don't access this directly. Use queryFor().
|
2671
2673
|
*/
|
2672
2674
|
queriesByStoreKey: [],
|
2673
|
-
|
2675
|
+
|
2674
2676
|
/** @private
|
2675
2677
|
The next store key to allocate. A storeKey must always be greater than 0
|
2676
2678
|
*/
|
2677
2679
|
nextStoreKey: 1,
|
2678
|
-
|
2680
|
+
|
2679
2681
|
/**
|
2680
2682
|
Generates a new store key for use.
|
2681
|
-
|
2683
|
+
|
2682
2684
|
@type Number
|
2683
2685
|
*/
|
2684
2686
|
generateStoreKey: function() { return this.nextStoreKey++; },
|
2685
|
-
|
2686
|
-
/**
|
2687
|
+
|
2688
|
+
/**
|
2687
2689
|
Given a `storeKey` returns the `primaryKey` associated with the key.
|
2688
2690
|
If no `primaryKey` is associated with the `storeKey`, returns `null`.
|
2689
|
-
|
2691
|
+
|
2690
2692
|
@param {Number} storeKey the store key
|
2691
2693
|
@returns {String} the primary key or null
|
2692
2694
|
*/
|
2693
2695
|
idFor: function(storeKey) {
|
2694
2696
|
return this.idsByStoreKey[storeKey] ;
|
2695
2697
|
},
|
2696
|
-
|
2698
|
+
|
2697
2699
|
/**
|
2698
2700
|
Given a `storeKey`, returns the query object associated with the key. If
|
2699
2701
|
no query is associated with the `storeKey`, returns `null`.
|
2700
|
-
|
2702
|
+
|
2701
2703
|
@param {Number} storeKey the store key
|
2702
2704
|
@returns {SC.Query} query query object
|
2703
2705
|
*/
|
2704
2706
|
queryFor: function(storeKey) {
|
2705
|
-
return this.queriesByStoreKey[storeKey];
|
2707
|
+
return this.queriesByStoreKey[storeKey];
|
2706
2708
|
},
|
2707
|
-
|
2709
|
+
|
2708
2710
|
/**
|
2709
2711
|
Given a `storeKey` returns the `SC.Record` class associated with the key.
|
2710
2712
|
If no record type is associated with the store key, returns `null`.
|
2711
|
-
|
2713
|
+
|
2712
2714
|
The SC.Record class will only be found if you have already called
|
2713
2715
|
storeKeyFor() on the record.
|
2714
|
-
|
2716
|
+
|
2715
2717
|
@param {Number} storeKey the store key
|
2716
2718
|
@returns {SC.Record} the record type
|
2717
2719
|
*/
|
2718
2720
|
recordTypeFor: function(storeKey) {
|
2719
2721
|
return this.recordTypesByStoreKey[storeKey];
|
2720
2722
|
},
|
2721
|
-
|
2723
|
+
|
2722
2724
|
/**
|
2723
|
-
Swaps the `primaryKey` mapped to the given storeKey with the new
|
2725
|
+
Swaps the `primaryKey` mapped to the given storeKey with the new
|
2724
2726
|
`primaryKey`. If the `storeKey` is not currently associated with a record
|
2725
2727
|
this will raise an exception.
|
2726
|
-
|
2728
|
+
|
2727
2729
|
@param {Number} storeKey the existing store key
|
2728
2730
|
@param {String} newPrimaryKey the new primary key
|
2729
2731
|
@returns {SC.Store} receiver
|
@@ -2731,7 +2733,7 @@ SC.Store.mixin(/** @scope SC.Store.prototype */{
|
|
2731
2733
|
replaceIdFor: function(storeKey, newId) {
|
2732
2734
|
var oldId = this.idsByStoreKey[storeKey],
|
2733
2735
|
recordType, storeKeys;
|
2734
|
-
|
2736
|
+
|
2735
2737
|
if (oldId !== newId) { // skip if id isn't changing
|
2736
2738
|
|
2737
2739
|
recordType = this.recordTypeFor(storeKey);
|
@@ -2740,32 +2742,32 @@ SC.Store.mixin(/** @scope SC.Store.prototype */{
|
|
2740
2742
|
}
|
2741
2743
|
|
2742
2744
|
// map one direction...
|
2743
|
-
this.idsByStoreKey[storeKey] = newId;
|
2745
|
+
this.idsByStoreKey[storeKey] = newId;
|
2744
2746
|
|
2745
2747
|
// then the other...
|
2746
2748
|
storeKeys = recordType.storeKeysById() ;
|
2747
2749
|
delete storeKeys[oldId];
|
2748
|
-
storeKeys[newId] = storeKey;
|
2750
|
+
storeKeys[newId] = storeKey;
|
2749
2751
|
}
|
2750
|
-
|
2752
|
+
|
2751
2753
|
return this ;
|
2752
2754
|
},
|
2753
|
-
|
2755
|
+
|
2754
2756
|
/**
|
2755
2757
|
Swaps the `recordType` recorded for a given `storeKey`. Normally you
|
2756
2758
|
should not call this method directly as it can damage the store behavior.
|
2757
|
-
This method is used by other store methods to set the `recordType` for a
|
2759
|
+
This method is used by other store methods to set the `recordType` for a
|
2758
2760
|
`storeKey`.
|
2759
|
-
|
2761
|
+
|
2760
2762
|
@param {Integer} storeKey the store key
|
2761
2763
|
@param {SC.Record} recordType a record class
|
2762
|
-
@returns {SC.Store}
|
2764
|
+
@returns {SC.Store} receiver
|
2763
2765
|
*/
|
2764
2766
|
replaceRecordTypeFor: function(storeKey, recordType) {
|
2765
2767
|
this.recordTypesByStoreKey[storeKey] = recordType;
|
2766
2768
|
return this ;
|
2767
2769
|
}
|
2768
|
-
|
2770
|
+
|
2769
2771
|
});
|
2770
2772
|
|
2771
2773
|
|
@@ -2774,7 +2776,7 @@ SC.Store.prototype.nextStoreIndex = 1;
|
|
2774
2776
|
|
2775
2777
|
// ..........................................................
|
2776
2778
|
// COMPATIBILITY
|
2777
|
-
//
|
2779
|
+
//
|
2778
2780
|
|
2779
2781
|
/** @private
|
2780
2782
|
global store is used only for deprecated compatibility methods. Don't use
|
@@ -2789,14 +2791,14 @@ SC.Store._getDefaultStore = function() {
|
|
2789
2791
|
/** @private
|
2790
2792
|
|
2791
2793
|
DEPRECATED
|
2792
|
-
|
2793
|
-
Included for compatibility, loads data hashes with the named `recordType`.
|
2794
|
-
If no `recordType` is passed, expects to find a `recordType` property in the
|
2794
|
+
|
2795
|
+
Included for compatibility, loads data hashes with the named `recordType`.
|
2796
|
+
If no `recordType` is passed, expects to find a `recordType` property in the
|
2795
2797
|
data hashes. `dataSource` and `isLoaded` params are ignored.
|
2796
|
-
|
2797
|
-
Calls `SC.Store#loadRecords()` on the default store. Do not use this method in
|
2798
|
-
new code.
|
2799
|
-
|
2798
|
+
|
2799
|
+
Calls `SC.Store#loadRecords()` on the default store. Do not use this method in
|
2800
|
+
new code.
|
2801
|
+
|
2800
2802
|
@param {Array} dataHashes data hashes to import
|
2801
2803
|
@param {Object} dataSource ignored
|
2802
2804
|
@param {SC.Record} recordType default record type
|
@@ -2804,37 +2806,35 @@ SC.Store._getDefaultStore = function() {
|
|
2804
2806
|
@returns {Array} SC.Record instances for loaded data hashes
|
2805
2807
|
*/
|
2806
2808
|
SC.Store.updateRecords = function(dataHashes, dataSource, recordType, isLoaded) {
|
2807
|
-
|
2808
2809
|
SC.Logger.warn("SC.Store.updateRecords() is deprecated. Use loadRecords() instead");
|
2809
|
-
|
2810
2810
|
var store = this._getDefaultStore(),
|
2811
2811
|
len = dataHashes.length,
|
2812
2812
|
idx, ret;
|
2813
|
-
|
2813
|
+
|
2814
2814
|
// if no recordType was passed, build an array of recordTypes from hashes
|
2815
2815
|
if (!recordType) {
|
2816
2816
|
recordType = [];
|
2817
2817
|
for(idx=0;idx<len;idx++) recordType[idx] = dataHashes[idx].recordType;
|
2818
2818
|
}
|
2819
|
-
|
2819
|
+
|
2820
2820
|
// call new API. Returns storeKeys
|
2821
2821
|
ret = store.loadRecords(recordType, dataHashes);
|
2822
|
-
|
2822
|
+
|
2823
2823
|
// map to SC.Record instances
|
2824
2824
|
len = ret.length;
|
2825
2825
|
for(idx=0;idx<len;idx++) ret[idx] = store.materializeRecord(ret[idx]);
|
2826
|
-
|
2826
|
+
|
2827
2827
|
return ret ;
|
2828
2828
|
};
|
2829
2829
|
|
2830
2830
|
/** @private
|
2831
2831
|
|
2832
|
-
DEPRECATED
|
2832
|
+
DEPRECATED
|
2833
2833
|
|
2834
2834
|
Finds a record with the passed guid on the default store. This is included
|
2835
2835
|
only for compatibility. You should use the newer `find()` method defined on
|
2836
2836
|
`SC.Store` instead.
|
2837
|
-
|
2837
|
+
|
2838
2838
|
@param {String} guid the guid
|
2839
2839
|
@param {SC.Record} recordType expected record type
|
2840
2840
|
@returns {SC.Record} found record
|
@@ -2845,12 +2845,12 @@ SC.Store.find = function(guid, recordType) {
|
|
2845
2845
|
|
2846
2846
|
/** @private
|
2847
2847
|
|
2848
|
-
DEPRECATED
|
2848
|
+
DEPRECATED
|
2849
2849
|
|
2850
|
-
Passes through to `findAll` on default store. This is included only for
|
2850
|
+
Passes through to `findAll` on default store. This is included only for
|
2851
2851
|
compatibility. You should use the newer `findAll()` defined on `SC.Store`
|
2852
2852
|
instead.
|
2853
|
-
|
2853
|
+
|
2854
2854
|
@param {Hash} filter search parameters
|
2855
2855
|
@param {SC.Record} recordType type of record to find
|
2856
2856
|
@returns {SC.RecordArray} result set
|