transport: pass correct channel
[abstract.git] / storage / base / aaSession.cpp
blob7e1533d002555e3dc817aa3a4a9ca0be890c8f26
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent tw=79 ft=cpp: */
3 /*
4 * Copyright (C) 2007,2008 Sergey Yanovich <ynvich@gmail.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #include "xpcom-config.h"
24 #include "nsCOMPtr.h"
25 #include "nsComponentManagerUtils.h"
26 #include "nsServiceManagerUtils.h"
27 #include "nsIIOService.h"
28 #include "nsIFile.h"
29 #include "nsNetCID.h"
30 #include "nsStringAPI.h"
31 #include "nsIArray.h"
32 #include "nsDebugUtils.h"
34 /* Unfrozen API */
35 #include "nsAppDirectoryServiceDefs.h"
36 #include "mozStorageCID.h"
37 #include "mozIStorageService.h"
38 #include "mozIStorageConnection.h"
40 /* Project includes */
41 #include "aaIManager.h"
42 #include "aaISqlRequest.h"
43 #include "aaISqlTransaction.h"
44 #include "aaSessionUtils.h"
45 #include "aaBaseLoaders.h"
46 #include "aaSqlChannel.h"
47 #include "aaSession.h"
49 /******** Transaction Guard ********/
50 class aaGuard
52 public:
53 aaGuard(mozIStorageConnection *aConnection)
54 :mConnection(aConnection) {;}
55 ~aaGuard() { if (mConnection) mConnection->RollbackTransaction(); }
56 nsresult Dismiss();
57 private:
58 mozIStorageConnection *mConnection;
61 inline nsresult
62 aaGuard::Dismiss()
64 mozIStorageConnection *tmp = mConnection;
65 mConnection = nsnull;
66 return tmp->CommitTransaction();
69 /******** aaSession ********/
70 aaSession::aaSession()
74 aaSession::~aaSession()
78 NS_IMPL_ISUPPORTS2(aaSession,
79 aaISaveQuery,
80 aaISession)
82 /* aaISession */
83 NS_IMETHODIMP
84 aaSession::GetConnectionURI(nsIURI * * _retval)
86 NS_ENSURE_ARG_POINTER(_retval);
87 nsresult rv;
89 nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
90 NS_ENSURE_SUCCESS(rv, rv);
92 nsCOMPtr<nsIFile> file;
93 rv = mConnection->GetDatabaseFile(getter_AddRefs(file));
94 NS_ENSURE_SUCCESS(rv, rv);
96 rv = ios->NewFileURI(file, _retval);
97 NS_ENSURE_SUCCESS(rv, rv);
99 return NS_OK;
102 NS_IMETHODIMP
103 aaSession::Load(aaISqlRequest *aRequest, nsIArray * * _retval)
105 NS_ENSURE_ARG_POINTER(_retval);
106 nsresult rv;
107 if (! mLoader) {
108 mLoader = do_CreateInstance(AA_SQLSIMPLELOADER_CONTRACT, &rv);
109 NS_ENSURE_SUCCESS(rv, rv);
111 nsCOMPtr<nsISupports> param = do_QueryInterface(aRequest);
112 rv = mLoader->SetParam(param);
113 NS_ENSURE_SUCCESS(rv, rv);
114 nsCOMPtr<nsISupports> retval;
115 rv = Execute(mLoader, getter_AddRefs(retval));
116 NS_ENSURE_SUCCESS(rv, rv);
117 return CallQueryInterface(retval, _retval);
120 NS_IMETHODIMP
121 aaSession::Execute(aaISqlTransaction *aTransaction, nsISupports * * _retval)
123 NS_ENSURE_ARG_POINTER(aTransaction);
124 NS_ENSURE_STATE(mConnection);
125 nsresult rv;
127 nsRefPtr<aaSqlChannel> channel = new aaSqlChannel(this);
128 NS_ENSURE_TRUE(channel, NS_ERROR_OUT_OF_MEMORY);
130 rv = mConnection->BeginTransaction();
131 NS_ENSURE_SUCCESS(rv, rv);
133 aaGuard guard(mConnection);
134 rv = aTransaction->Execute(channel, _retval);
135 if (NS_FAILED(rv)) return rv;
137 return guard.Dismiss();
140 /* aaISaveQuery */
141 NS_IMETHODIMP
142 aaSession::Save(aaIDataNode *aNode, aaIDataNode *aOldNode)
144 nsresult rv;
145 if (! mDispatcher) {
146 mDispatcher = do_CreateInstance("@aasii.org/storage/save-dispatcher;1",
147 this, &rv);
148 NS_ENSURE_SUCCESS(rv, rv);
150 return mDispatcher->Save(aNode, aOldNode);
153 /* Public methods */
155 /* Private methods */
156 struct aaTable {
157 const char *name;
158 const char *sql;
161 const struct aaTable tables[] =
163 {"entity",
164 "id INTEGER PRIMARY KEY AUTOINCREMENT,\
165 tag CHAR (47) UNIQUE"}
167 ,{"resource",
168 "type INTEGER NOT NULL, id INTEGER NOT NULL,\
169 PRIMARY KEY (type, id)"}
171 ,{"asset",
172 "id INTEGER PRIMARY KEY AUTOINCREMENT,\
173 tag CHAR (47) UNIQUE"}
175 ,{"money",
176 "id INTEGER PRIMARY KEY NOT NULL,\
177 alpha_code CHAR (3) UNIQUE NOT NULL"}
179 ,{"flow",
180 "id INTEGER PRIMARY KEY AUTOINCREMENT,\
181 tag CHAR (47) UNIQUE, entity_id INTEGER NOT NULL, rate DOUBLE NOT NULL,\
182 off_balance BOOLEAN NOT NULL"}
184 ,{"term",
185 "flow_id INTEGER NOT NULL, side BOOLEAN NOT\
186 NULL, resource_type INTEGER NOT NULL, resource_id INTEGER NOT NULL,\
187 PRIMARY KEY (flow_id, side)"}
189 ,{"fact",
190 "day INTEGER NOT NULL, event_id INTEGER NOT NULL,\
191 transfer_id INTEGER NOT NULL, side BOOLEAN NOT NULL, flow_id INTEGER\
192 NOT NULL, PRIMARY KEY (day, event_id, transfer_id, side)"}
194 ,{"norm",
195 "flow_id INTEGER NOT NULL,\
196 id INTEGER NOT NULL,\
197 fact_side BOOLEAN NOT NULL,\
198 change_side BOOLEAN NOT NULL,\
199 rate DOUBLE NOT NULL,\
200 tag CHAR (47),\
201 PRIMARY KEY (flow_id, id)"}
203 ,{"clause",
204 "flow_id INTEGER NOT NULL, norm_id INTEGER NOT NULL,\
205 side BOOLEAN NOT NULL, link_flow_id BOOLEAN NOT NULL,\
206 PRIMARY KEY (flow_id, norm_id, side)"}
208 ,{"state",
209 "id INTEGER PRIMARY KEY AUTOINCREMENT,\
210 flow_id INTEGER NOT NULL, side INTEGER NOT NULL,\
211 amount DOUBLE NOT NULL, start INTEGER NOT NULL, paid INTEGER"}
213 ,{"event",
214 "day INTEGER NOT NULL, id INTEGER NOT NULL,\
215 PRIMARY KEY (day, id)"}
217 ,{"transfer",
218 "day INTEGER NOT NULL, event_id INTEGER\
219 NOT NULL, id INTEGER NOT NULL, amount DOUBLE NOT NULL,\
220 PRIMARY KEY (day, event_id, id)"}
222 /* XXX _acc This belongs to a separate module */
223 ,{"txn",
224 "day INTEGER NOT NULL, event_id INTEGER\
225 NOT NULL, transfer_id INTEGER NOT NULL, value DOUBLE NOT NULL,\
226 status INTEGER NOT NULL DEFAULT 0, earnings DOUBLE,\
227 PRIMARY KEY (day, event_id, transfer_id)"}
229 ,{"quote",
230 "resource_id INTEGER NOT NULL,\
231 day INTEGER NOT NULL, rate DOUBLE NOT NULL,\
232 diff DOUBLE NOT NULL, PRIMARY KEY (resource_id, day)"}
234 ,{"balance",
235 "id INTEGER PRIMARY KEY AUTOINCREMENT,\
236 flow_id INTEGER NOT NULL, side INTEGER NOT NULL,\
237 amount DOUBLE NOT NULL, value DOUBLE NOT NULL, start INTEGER NOT NULL,\
238 paid INTEGER, UNIQUE (flow_id, start)"}
240 ,{"income",
241 "start INTEGER PRIMARY KEY NOT NULL,\
242 side INTEGER NOT NULL,\
243 value DOUBLE NOT NULL,\
244 paid INTEGER"}
246 ,{"chart",
247 "id INTEGER PRIMARY KEY NOT NULL,\
248 resource_id INTEGER NOT NULL"}
251 nsresult
252 aaSession::getDatabase(nsISupports *dbFile)
254 nsresult rv;
256 nsCOMPtr<nsIFile> file = do_QueryInterface(dbFile);
258 if (!file) {
259 nsCOMPtr<aaIManager> manager =
260 do_CreateInstance(AA_MANAGER_CONTRACT, &rv);
261 NS_ENSURE_SUCCESS(rv, rv);
263 nsCOMPtr<nsIFile> file;
264 rv = manager->TmpFileFromString("default.sqlite", PR_FALSE,
265 getter_AddRefs(file));
266 NS_ENSURE_SUCCESS(rv, rv);
269 nsCOMPtr<mozIStorageService> storageSvc;
270 storageSvc = do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
271 NS_ENSURE_SUCCESS(rv, rv);
273 nsCOMPtr<mozIStorageConnection> connection;
274 rv = storageSvc->OpenDatabase(file, getter_AddRefs( connection ));
275 NS_ENSURE_SUCCESS(rv, rv);
277 PRUint32 i;
278 for (i = 0; i < sizeof(tables) / sizeof(struct aaTable); i++) {
279 rv = checkTable(connection, tables[i].name, tables[i].sql);
280 NS_ENSURE_SUCCESS(rv, rv);
282 mConnection = connection;
284 return NS_OK;
287 nsresult
288 aaSession::checkTable(mozIStorageConnection *aConnection,
289 const char *tableName, const char *createString)
291 nsresult rv;
292 PRBool hasTable;
294 rv = aConnection->TableExists(nsDependentCString(tableName), &hasTable);
295 NS_ENSURE_SUCCESS(rv, rv);
296 if (! hasTable ) {
297 rv = aConnection->CreateTable(tableName, createString);
298 NS_ENSURE_SUCCESS(rv, rv);
301 return NS_OK;