comparison src/implab/data/ObjectStore.js @ 0:fc2517695ee1

Initial commit, draft import of existing work
author cin
date Thu, 01 Jun 2017 13:20:03 +0300
parents
children f0035923ff3e
comparison
equal deleted inserted replaced
-1:000000000000 0:fc2517695ee1
1 define([ "dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array",
2 "../safe", "dojo/when", "dojo/Deferred", "dojo/store/util/QueryResults" ], function(declare,
3 lang, array, safe, when, Deferred, QueryResults) {
4 /**
5 * @module core/data/RestStore
6 *
7 * Реализует шаблон репозитария dojo/store над уже имеющимся хранилищем. При получении и
8 * отправке данных в нижележащие хранилище используется core/data/MapSchema для преобразования
9 * данных.
10 */
11 return declare(null, {
12
13 model: null,
14
15 mapping: null,
16
17 _dataContext: null,
18
19 _store : null, // backing store
20
21 _cache : null,
22
23 constructor : function(options) {
24 options = options || {};
25
26 if (options.store)
27 this._store = options.store;
28
29 if (options.dataContext) {
30 this._dataContext = options.dataContext;
31 }
32
33 if (options.cache === false) {
34 // no cache at all
35 } else if (options.cache === "string" && options.dataContext) {
36 this._cache = this._dataContext.getCache(options.cache);
37 } else {
38 this._cache = {};
39 }
40 },
41
42 getDataContext : function() {
43 return this._dataContext;
44 },
45
46 // READ
47 get : function(id) {
48 var me = this;
49 var cache = me.getCacheEntry(id);
50 if (cache)
51 return cache;
52 else
53 return when(me._store.get(id), function(data) {
54 return me._mapToObject(id, data);
55 });
56 },
57
58 query : function(query, options) {
59 var me = this;
60 var d = me._store.query(query, options);
61 var result = QueryResults(when(d, function(data) {
62 return array.map(data, function(item) {
63 return me._mapToObject(me._store.getIdentity(item), item);
64 });
65 }));
66 result.total = d.total;
67 return result;
68 },
69
70 getIdentity : function(object) {
71 return object.getId();
72 },
73
74 // UPDATE
75 put : function(object, directives) {
76 return this._store.put(this._mapFromObject(object), directives);
77 },
78
79 // INSERT
80 add : function(object, directives) {
81 var me = this;
82 // добавляем в хранилище данные, сохраняем в кеше объект с
83 // полученным идентификатором
84 return when(
85 me._store.add(this._mapFromObject(object), directives),
86 function(id) {
87 object.attach(id, me);
88 me.storeCacheEntry(id, object);
89 return id;
90 });
91 },
92
93 // DELETE
94 remove : function(id) {
95 var me = this;
96 return when(me._store.remove(id), function() {
97 me.removeCacheEntry(id);
98 });
99 },
100
101 _mapToObject : function(id, data) {
102 var instance = this.createInstance(id);
103 this.populateInstance(instance, data);
104 return instance;
105 },
106
107 _mapFromObject : function(object) {
108 return this.serializeInstance(object);
109 },
110
111 getCacheEntry : function(id) {
112 safe.argumentNotNull(id, "id");
113 id = id.toString();
114
115 return this._cache[id];
116 },
117
118 storeCacheEntry : function(id, object) {
119 safe.argumentNotNull(id, "id");
120 id = id.toString();
121
122 this._cache[id] = object;
123 },
124
125 removeCacheEntry : function(id) {
126 safe.argumentNotNull(id, "id");
127 id = id.toString();
128 delete this._cache[id];
129 },
130
131 /** Создает экземпляр сущности с указанным идентификатором, либо извлекает из кеша, если таковая уже имеется.
132 * @remarks
133 * Технически сюда можно было бы дополнительно передать данные для ининциализации объекта,
134 * но концептуально это не верно, поскольку процесс чтения объекта состоит из двух этапов:
135 * 1. Создание пустого объекта (createInstance)
136 * 2. Заполнение объекта при помощи схемы отображения (populateInstance)
137 * при этом первый этап может быть выполнен за долго до второго, например,
138 * при создании заглушек в процессе установления ссылок между объектами.
139 */
140 createInstance : function(id) {
141 var instance = this.getCacheEntry(id);
142 if (!instance) {
143 instance = this.createInstanceImpl(id);
144 this.storeCacheEntry(id, instance);
145 }
146 return instance;
147 },
148
149 /** Непосредственно создает экземпляр сущнсти, т.е. является фабричным методом.
150 * @param {String} id идентификатор создаваемого экземпляра.
151 */
152 createInstanceImpl : function(id) {
153 var opts = {
154 dataContext : this.getDataContext(),
155 id : id
156 };
157
158 return new this.itemsType(opts);
159 },
160
161 populateInstance : function(instance, data) {
162 this.mapping.readData(instance, data,this.getDataContext());
163 if (instance.onPopulate)
164 instance.onPopulate();
165 },
166
167 serializeInstance : function(instance) {
168 var data = {};
169 this.mapping.writeData(instance, data, this.getDataContext());
170 return data;
171 }
172
173 });
174 });