]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/account/account-follow.ts
Put activity pub sends inside transactions
[github/Chocobozzz/PeerTube.git] / server / models / account / account-follow.ts
index 6d7592326d7ad3cb8fc8a6ff940ceeb352dbb9a5..724f37baa6b6038815611ab1d8f5cf652f70e8b0 100644 (file)
@@ -11,6 +11,8 @@ let listFollowingForApi: AccountFollowMethods.ListFollowingForApi
 let listFollowersForApi: AccountFollowMethods.ListFollowersForApi
 let listAcceptedFollowerUrlsForApi: AccountFollowMethods.ListAcceptedFollowerUrlsForApi
 let listAcceptedFollowingUrlsForApi: AccountFollowMethods.ListAcceptedFollowingUrlsForApi
+let listAcceptedFollowerSharedInboxUrls: AccountFollowMethods.ListAcceptedFollowerSharedInboxUrls
+let toFormattedJSON: AccountFollowMethods.ToFormattedJSON
 
 export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
   AccountFollow = sequelize.define<AccountFollowInstance, AccountFollowAttributes>('AccountFollow',
@@ -42,9 +44,13 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
     listFollowingForApi,
     listFollowersForApi,
     listAcceptedFollowerUrlsForApi,
-    listAcceptedFollowingUrlsForApi
+    listAcceptedFollowingUrlsForApi,
+    listAcceptedFollowerSharedInboxUrls
   ]
-  addMethodsToModel(AccountFollow, classMethods)
+  const instanceMethods = [
+    toFormattedJSON
+  ]
+  addMethodsToModel(AccountFollow, classMethods, instanceMethods)
 
   return AccountFollow
 }
@@ -71,12 +77,41 @@ function associate (models) {
   })
 }
 
-loadByAccountAndTarget = function (accountId: number, targetAccountId: number) {
+toFormattedJSON = function (this: AccountFollowInstance) {
+  const follower = this.AccountFollower.toFormattedJSON()
+  const following = this.AccountFollowing.toFormattedJSON()
+
+  const json = {
+    id: this.id,
+    follower,
+    following,
+    state: this.state,
+    createdAt: this.createdAt,
+    updatedAt: this.updatedAt
+  }
+
+  return json
+}
+
+loadByAccountAndTarget = function (accountId: number, targetAccountId: number, t?: Sequelize.Transaction) {
   const query = {
     where: {
       accountId,
       targetAccountId
-    }
+    },
+    include: [
+      {
+        model: AccountFollow[ 'sequelize' ].models.Account,
+        required: true,
+        as: 'AccountFollower'
+      },
+      {
+        model: AccountFollow['sequelize'].models.Account,
+        required: true,
+        as: 'AccountFollowing'
+      }
+    ],
+    transaction: t
   }
 
   return AccountFollow.findOne(query)
@@ -101,14 +136,14 @@ listFollowingForApi = function (id: number, start: number, count: number, sort:
         model: AccountFollow['sequelize'].models.Account,
         as: 'AccountFollowing',
         required: true,
-        include: [ AccountFollow['sequelize'].models.Pod ]
+        include: [ AccountFollow['sequelize'].models.Server ]
       }
     ]
   }
 
   return AccountFollow.findAndCountAll(query).then(({ rows, count }) => {
     return {
-      data: rows.map(r => r.AccountFollowing),
+      data: rows,
       total: count
     }
   })
@@ -125,7 +160,7 @@ listFollowersForApi = function (id: number, start: number, count: number, sort:
         model: AccountFollow[ 'sequelize' ].models.Account,
         required: true,
         as: 'AccountFollower',
-        include: [ AccountFollow['sequelize'].models.Pod ]
+        include: [ AccountFollow['sequelize'].models.Server ]
       },
       {
         model: AccountFollow['sequelize'].models.Account,
@@ -140,23 +175,34 @@ listFollowersForApi = function (id: number, start: number, count: number, sort:
 
   return AccountFollow.findAndCountAll(query).then(({ rows, count }) => {
     return {
-      data: rows.map(r => r.AccountFollower),
+      data: rows,
       total: count
     }
   })
 }
 
-listAcceptedFollowerUrlsForApi = function (id: number, start: number, count?: number) {
-  return createListAcceptedFollowForApiQuery('followers', id, start, count)
+listAcceptedFollowerUrlsForApi = function (accountIds: number[], t: Sequelize.Transaction, start?: number, count?: number) {
+  return createListAcceptedFollowForApiQuery('followers', accountIds, t, start, count)
+}
+
+listAcceptedFollowerSharedInboxUrls = function (accountIds: number[], t: Sequelize.Transaction) {
+  return createListAcceptedFollowForApiQuery('followers', accountIds, t, undefined, undefined, 'sharedInboxUrl')
 }
 
-listAcceptedFollowingUrlsForApi = function (id: number, start: number, count?: number) {
-  return createListAcceptedFollowForApiQuery('following', id, start, count)
+listAcceptedFollowingUrlsForApi = function (accountIds: number[], t: Sequelize.Transaction, start?: number, count?: number) {
+  return createListAcceptedFollowForApiQuery('following', accountIds, t, start, count)
 }
 
 // ------------------------------ UTILS ------------------------------
 
-async function createListAcceptedFollowForApiQuery (type: 'followers' | 'following', id: number, start: number, count?: number) {
+async function createListAcceptedFollowForApiQuery (
+  type: 'followers' | 'following',
+  accountIds: number[],
+  t: Sequelize.Transaction,
+  start?: number,
+  count?: number,
+  columnUrl = 'url'
+) {
   let firstJoin: string
   let secondJoin: string
 
@@ -168,21 +214,22 @@ async function createListAcceptedFollowForApiQuery (type: 'followers' | 'followi
     secondJoin = 'targetAccountId'
   }
 
-  const selections = [ '"Followers"."url" AS "url"', 'COUNT(*) AS "total"' ]
+  const selections = [ '"Follows"."' + columnUrl + '" AS "url"', 'COUNT(*) AS "total"' ]
   const tasks: Promise<any>[] = []
 
   for (const selection of selections) {
-    let query = 'SELECT ' + selection + ' FROM "Account" ' +
-      'INNER JOIN "AccountFollow" ON "AccountFollow"."' + firstJoin + '" = "Account"."id" ' +
-      'INNER JOIN "Account" AS "Follows" ON "Followers"."id" = "Follows"."' + secondJoin + '" ' +
-      'WHERE "Account"."id" = $id AND "AccountFollow"."state" = \'accepted\' ' +
-      'LIMIT ' + start
+    let query = 'SELECT ' + selection + ' FROM "Accounts" ' +
+      'INNER JOIN "AccountFollows" ON "AccountFollows"."' + firstJoin + '" = "Accounts"."id" ' +
+      'INNER JOIN "Accounts" AS "Follows" ON "AccountFollows"."' + secondJoin + '" = "Follows"."id" ' +
+      'WHERE "Accounts"."id" = ANY ($accountIds) AND "AccountFollows"."state" = \'accepted\' '
 
-    if (count !== undefined) query += ', ' + count
+    if (count !== undefined) query += 'LIMIT ' + count
+    if (start !== undefined) query += ' OFFSET ' + start
 
     const options = {
-      bind: { id },
-      type: Sequelize.QueryTypes.SELECT
+      bind: { accountIds },
+      type: Sequelize.QueryTypes.SELECT,
+      transaction: t
     }
     tasks.push(AccountFollow['sequelize'].query(query, options))
   }