X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=src%2Fdb%2Fsqlite%2Findex.js;h=07d6633311113dcdaf2eae05dabcc912f94fdece;hb=9812213260e952ae601f94ab0915c680e8c80495;hp=a4c3d38fa0f252b94982f5b12832a4bb0815dbb7;hpb=28de4364128a4b03918a8cbe868009b5d427220a;p=websub-hub diff --git a/src/db/sqlite/index.js b/src/db/sqlite/index.js index a4c3d38..07d6633 100644 --- a/src/db/sqlite/index.js +++ b/src/db/sqlite/index.js @@ -20,7 +20,7 @@ const schemaVersionsSupported = { max: { major: 1, minor: 0, - patch: 0, + patch: 1, }, }; @@ -299,12 +299,29 @@ class DatabaseSQLite extends Database { } + /** + * Converts engine subscription fields to native types. + * @param {Object} data + */ + static _subscriptionDataToNative(data) { + const epochToDate = (epoch) => new Date(Number(epoch) * 1000); + if (data) { + ['created', 'verified', 'expires', 'contentDelivered'].forEach((field) => { + // eslint-disable-next-line security/detect-object-injection + data[field] = epochToDate(data[field]); + }); + } + return data; + } + + subscriptionsByTopicId(dbCtx, topicId) { const _scope = _fileScope('subscriptionsByTopicId'); this.logger.debug(_scope, 'called', { topicId }); try { - return this.statement.subscriptionsByTopicId.all({ topicId }); + const subscriptions = this.statement.subscriptionsByTopicId.all({ topicId }); + return subscriptions.map((s) => DatabaseSQLite._subscriptionDataToNative(s)); } catch (e) { this.logger.error(_scope, 'failed', { error: e, topicId }); throw e; @@ -342,6 +359,21 @@ class DatabaseSQLite extends Database { } + subscriptionDeleteExpired(dbCtx, topicId) { + const _scope = _fileScope('subscriptionDeleteExpired'); + this.logger.debug(_scope, 'called', { topicId }); + + try { + const result = this.statement.subscriptionDeleteExpired.run({ topicId }); + this.logger.debug(_scope, 'success', { topicId, deleted: result.changes }); + return this._engineInfo(result); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, topicId }); + throw e; + } + } + + subscriptionDeliveryClaim(dbCtx, wanted, claimTimeoutSeconds, claimant) { const _scope = _fileScope('subscriptionDeliveryClaim'); this.logger.debug(_scope, 'called', { wanted, claimTimeoutSeconds, claimant }); @@ -463,7 +495,7 @@ class DatabaseSQLite extends Database { let subscription; try { subscription = this.statement.subscriptionGet.get({ callback, topicId }); - return subscription; + return DatabaseSQLite._subscriptionDataToNative(subscription); } catch (e) { this.logger.error(_scope, 'failed', { error: e, callback, topicId }); throw e; @@ -478,7 +510,7 @@ class DatabaseSQLite extends Database { let subscription; try { subscription = this.statement.subscriptionGetById.get({ subscriptionId }); - return subscription; + return DatabaseSQLite._subscriptionDataToNative(subscription); } catch (e) { this.logger.error(_scope, 'failed', { error: e, subscriptionId }); throw e; @@ -751,6 +783,37 @@ class DatabaseSQLite extends Database { } + topicPendingDelete(dbCtx, topicId) { + const _scope = _fileScope('topicPendingDelete'); + this.logger.debug(_scope, 'called', { topicId }); + + try { + this.db.transaction(() => { + const topic = this.statement.topicGetById.get({ topicId }); + if (!topic.isDeleted) { + this.logger.debug(_scope, 'topic not set deleted, not deleting', { topicId }); + return; + } + + const { count: subscriberCount } = this.statement.subscriptionCountByTopicUrl.get({ topicUrl: topic.url }); + if (subscriberCount) { + this.logger.debug(_scope, 'topic has subscribers, not deleting', { topicId, subscriberCount }); + return; + } + + const result = this.statement.topicDeleteById.run({ topicId }); + if (result.changes !== 1) { + throw new DBErrors.UnexpectedResult('did not delete topic'); + } + })(); + this.logger.debug(_scope, 'success', { topicId }); + } catch (e) { + this.logger.error(_scope, 'failed', { error: e, topicId }); + throw e; + } + } + + topicSet(dbCtx, data) { const _scope = _fileScope('topicSet'); this.logger.debug(_scope, 'called', data);