Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Open sidebar
savoirfairelinux
jami-lrc
Commits
8dfc664d
Commit
8dfc664d
authored
Mar 06, 2019
by
Andreas Traczyk
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
database: migrate to per account database
Gitlab:
#407
Change-Id: I834cf0d216dfd9e6badab8d7aab951b8875c1bd6
parent
2697394b
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
2420 additions
and
1454 deletions
+2420
-1454
CMakeLists.txt
CMakeLists.txt
+1
-1
src/api/call.h
src/api/call.h
+1
-1
src/api/contact.h
src/api/contact.h
+7
-0
src/api/contactmodel.h
src/api/contactmodel.h
+1
-13
src/api/interaction.h
src/api/interaction.h
+46
-50
src/api/lrc.h
src/api/lrc.h
+13
-1
src/api/newaccountmodel.h
src/api/newaccountmodel.h
+5
-6
src/api/newcallmodel.h
src/api/newcallmodel.h
+19
-2
src/api/profile.h
src/api/profile.h
+9
-1
src/authority/databasehelper.cpp
src/authority/databasehelper.cpp
+0
-574
src/authority/storagehelper.cpp
src/authority/storagehelper.cpp
+1283
-0
src/authority/storagehelper.h
src/authority/storagehelper.h
+192
-102
src/avmodel.cpp
src/avmodel.cpp
+2
-2
src/callbackshandler.cpp
src/callbackshandler.cpp
+9
-6
src/callbackshandler.h
src/callbackshandler.h
+4
-0
src/contactmodel.cpp
src/contactmodel.cpp
+59
-65
src/conversationmodel.cpp
src/conversationmodel.cpp
+202
-234
src/database.cpp
src/database.cpp
+279
-167
src/database.h
src/database.h
+111
-24
src/datatransfermodel.cpp
src/datatransfermodel.cpp
+0
-10
src/lrc.cpp
src/lrc.cpp
+14
-9
src/newaccountmodel.cpp
src/newaccountmodel.cpp
+112
-151
src/newcallmodel.cpp
src/newcallmodel.cpp
+20
-33
src/typedefs.h
src/typedefs.h
+3
-1
src/uri.cpp
src/uri.cpp
+20
-1
src/uri.h
src/uri.h
+3
-0
src/vcard.h
src/vcard.h
+5
-0
No files found.
CMakeLists.txt
View file @
8dfc664d
...
...
@@ -280,7 +280,7 @@ SET( libringclient_LIB_SRCS
src/conversationmodel.cpp
src/database.cpp
src/authority/daemon.cpp
src/authority/
databas
ehelper.cpp
src/authority/
storag
ehelper.cpp
src/lrc.cpp
src/newaccountmodel.cpp
src/peerdiscoverymodel.cpp
...
...
src/api/call.h
View file @
8dfc664d
...
...
@@ -131,7 +131,7 @@ struct Info
std
::
chrono
::
steady_clock
::
time_point
startTime
;
Status
status
=
Status
::
INVALID
;
Type
type
=
Type
::
INVALID
;
std
::
string
peer
;
std
::
string
peer
Uri
;
bool
isOutgoing
;
bool
audioMuted
=
false
;
bool
videoMuted
=
false
;
...
...
src/api/contact.h
View file @
8dfc664d
...
...
@@ -33,6 +33,13 @@ namespace api
namespace
contact
{
/**
* @var profileInfo
* @var registeredName
* @var isTrusted
* @var isPresent
* @var isBanned
*/
struct
Info
{
profile
::
Info
profileInfo
;
...
...
src/api/contactmodel.h
View file @
8dfc664d
...
...
@@ -57,7 +57,7 @@ public:
const
account
::
Info
&
owner
;
ContactModel
(
const
account
::
Info
&
owner
,
Database
&
d
atabase
,
Database
&
d
b
,
const
CallbacksHandler
&
callbacksHandler
,
const
BehaviorController
&
behaviorController
);
~
ContactModel
();
...
...
@@ -85,18 +85,6 @@ public:
* @return list of banned contacts uris as string
*/
const
std
::
list
<
std
::
string
>&
getBannedContacts
()
const
;
/**
* @param uri
* @param isAccount
* @return empty string if no contact, else the uri in db
*/
const
std
::
string
getProfileId
(
const
std
::
string
&
ur
,
bool
isAccount
=
false
)
const
;
/**
* @deprecated use getProfileId
* @param contactUri
* @return empty string if no contact, else the uri in db
*/
const
std
::
string
getContactProfileId
(
const
std
::
string
&
contactUri
)
const
;
/**
* @return all contacts for this account.
*/
...
...
src/api/interaction.h
View file @
8dfc664d
...
...
@@ -36,8 +36,8 @@ enum class Type {
TEXT
,
CALL
,
CONTACT
,
OUTGOING_
DATA_TRANSFER
,
INCOMING_DATA_TRANSFER
DATA_TRANSFER
,
COUNT__
};
static
inline
const
std
::
string
...
...
@@ -50,11 +50,10 @@ to_string(const Type& type)
return
"CALL"
;
case
Type
::
CONTACT
:
return
"CONTACT"
;
case
Type
::
OUTGOING_DATA_TRANSFER
:
return
"OUTGOING_DATA_TRANSFER"
;
case
Type
::
INCOMING_DATA_TRANSFER
:
return
"INCOMING_DATA_TRANSFER"
;
case
Type
::
DATA_TRANSFER
:
return
"DATA_TRANSFER"
;
case
Type
::
INVALID
:
case
Type
::
COUNT__
:
default:
return
"INVALID"
;
}
...
...
@@ -69,24 +68,19 @@ to_type(const std::string& type)
return
interaction
::
Type
::
CALL
;
else
if
(
type
==
"CONTACT"
)
return
interaction
::
Type
::
CONTACT
;
else
if
(
type
==
"OUTGOING_DATA_TRANSFER"
)
return
interaction
::
Type
::
OUTGOING_DATA_TRANSFER
;
else
if
(
type
==
"INCOMING_DATA_TRANSFER"
)
return
interaction
::
Type
::
INCOMING_DATA_TRANSFER
;
else
if
(
type
==
"DATA_TRANSFER"
)
return
interaction
::
Type
::
DATA_TRANSFER
;
else
return
interaction
::
Type
::
INVALID
;
}
enum
class
Status
{
INVALID
,
UNKNOWN
,
SENDING
,
FAILED
,
SUCCEED
,
READ
,
UNREAD
,
TRANSFER_CREATED
,
/*[jn] mettre à jour les fonctions de conversion */
FAILURE
,
SUCCESS
,
TRANSFER_CREATED
,
TRANSFER_ACCEPTED
,
TRANSFER_CANCELED
,
TRANSFER_ERROR
,
...
...
@@ -95,7 +89,8 @@ enum class Status {
TRANSFER_AWAITING_PEER
,
TRANSFER_AWAITING_HOST
,
TRANSFER_TIMEOUT_EXPIRED
,
TRANSFER_FINISHED
TRANSFER_FINISHED
,
COUNT__
};
static
inline
const
std
::
string
...
...
@@ -106,14 +101,10 @@ to_string(const Status& status)
return
"UNKNOWN"
;
case
Status
::
SENDING
:
return
"SENDING"
;
case
Status
::
FAILED
:
return
"FAILED"
;
case
Status
::
SUCCEED
:
return
"SUCCEED"
;
case
Status
::
READ
:
return
"READ"
;
case
Status
::
UNREAD
:
return
"UNREAD"
;
case
Status
::
FAILURE
:
return
"FAILURE"
;
case
Status
::
SUCCESS
:
return
"SUCCESS"
;
case
Status
::
TRANSFER_CREATED
:
return
"TRANSFER_CREATED"
;
case
Status
::
TRANSFER_ACCEPTED
:
...
...
@@ -135,6 +126,7 @@ to_string(const Status& status)
case
Status
::
TRANSFER_FINISHED
:
return
"TRANSFER_FINISHED"
;
case
Status
::
INVALID
:
case
Status
::
COUNT__
:
default:
return
"INVALID"
;
}
...
...
@@ -144,56 +136,60 @@ static inline Status
to_status
(
const
std
::
string
&
status
)
{
if
(
status
==
"UNKNOWN"
)
return
interaction
::
Status
::
UNKNOWN
;
return
Status
::
UNKNOWN
;
else
if
(
status
==
"SENDING"
)
return
interaction
::
Status
::
SENDING
;
else
if
(
status
==
"FAILED"
)
return
interaction
::
Status
::
FAILED
;
else
if
(
status
==
"SUCCEED"
)
return
interaction
::
Status
::
SUCCEED
;
else
if
(
status
==
"READ"
)
return
interaction
::
Status
::
READ
;
else
if
(
status
==
"UNREAD"
)
return
interaction
::
Status
::
UNREAD
;
return
Status
::
SENDING
;
else
if
(
status
==
"FAILURE"
)
return
Status
::
FAILURE
;
else
if
(
status
==
"SUCCESS"
)
return
Status
::
SUCCESS
;
else
if
(
status
==
"TRANSFER_CREATED"
)
return
interaction
::
Status
::
TRANSFER_CREATED
;
return
Status
::
TRANSFER_CREATED
;
else
if
(
status
==
"TRANSFER_ACCEPTED"
)
return
interaction
::
Status
::
TRANSFER_ACCEPTED
;
return
Status
::
TRANSFER_ACCEPTED
;
else
if
(
status
==
"TRANSFER_CANCELED"
)
return
interaction
::
Status
::
TRANSFER_CANCELED
;
return
Status
::
TRANSFER_CANCELED
;
else
if
(
status
==
"TRANSFER_ERROR"
)
return
interaction
::
Status
::
TRANSFER_ERROR
;
return
Status
::
TRANSFER_ERROR
;
else
if
(
status
==
"TRANSFER_UNJOINABLE_PEER"
)
return
interaction
::
Status
::
TRANSFER_UNJOINABLE_PEER
;
return
Status
::
TRANSFER_UNJOINABLE_PEER
;
else
if
(
status
==
"TRANSFER_ONGOING"
)
return
interaction
::
Status
::
TRANSFER_ONGOING
;
return
Status
::
TRANSFER_ONGOING
;
else
if
(
status
==
"TRANSFER_AWAITING_HOST"
)
return
interaction
::
Status
::
TRANSFER_AWAITING_HOST
;
return
Status
::
TRANSFER_AWAITING_HOST
;
else
if
(
status
==
"TRANSFER_AWAITING_PEER"
)
return
interaction
::
Status
::
TRANSFER_AWAITING_PEER
;
return
Status
::
TRANSFER_AWAITING_PEER
;
else
if
(
status
==
"TRANSFER_TIMEOUT_EXPIRED"
)
return
interaction
::
Status
::
TRANSFER_TIMEOUT_EXPIRED
;
return
Status
::
TRANSFER_TIMEOUT_EXPIRED
;
else
if
(
status
==
"TRANSFER_FINISHED"
)
return
interaction
::
Status
::
TRANSFER_FINISHED
;
return
Status
::
TRANSFER_FINISHED
;
else
return
interaction
::
Status
::
INVALID
;
return
Status
::
INVALID
;
}
/**
* @var authorUri
* @var body
* @var timestamp
* @var duration
* @var type
* @var status
* @var isRead
*/
struct
Info
{
std
::
string
authorUri
;
std
::
string
body
;
std
::
time_t
timestamp
=
0
;
std
::
time_t
duration
=
0
;
Type
type
=
Type
::
INVALID
;
Status
status
=
Status
::
INVALID
;
bool
isRead
=
false
;
};
static
inline
bool
isOutgoing
(
const
Info
&
interaction
)
{
return
(
interaction
.
status
!=
lrc
::
api
::
interaction
::
Status
::
READ
&&
interaction
.
status
!=
lrc
::
api
::
interaction
::
Status
::
UNREAD
&&
interaction
.
type
!=
lrc
::
api
::
interaction
::
Type
::
INCOMING_DATA_TRANSFER
)
||
interaction
.
type
==
lrc
::
api
::
interaction
::
Type
::
OUTGOING_DATA_TRANSFER
;
return
interaction
.
authorUri
.
empty
();
}
}
// namespace interaction
...
...
src/api/lrc.h
View file @
8dfc664d
...
...
@@ -41,7 +41,15 @@ class AVModel;
class
LIB_EXPORT
Lrc
{
public:
Lrc
();
/**
* Construct an Lrc object and optionally invoke callbacks
* to control ui informing the user of a possibly lengthy
* migration process.
* @param willMigrateCb
* @param didMigrateCb
*/
Lrc
(
MigrationCb
willMigrateCb
=
{},
MigrationCb
didMigrateCb
=
{});
~
Lrc
();
/**
* get a reference on account model.
...
...
@@ -77,6 +85,10 @@ public:
* Can communicate with the daemon via dbus
*/
static
bool
dbusIsValid
();
/**
* Connect to debugMessageReceived signal
*/
void
subscribeToDebugReceived
();
/**
* Helper: get call list from daemon
...
...
src/api/newaccountmodel.h
View file @
8dfc664d
...
...
@@ -53,12 +53,11 @@ class BehaviorController;
class
LIB_EXPORT
NewAccountModel
:
public
QObject
{
Q_OBJECT
public:
using
AccountInfoMap
=
std
::
map
<
std
::
string
,
account
::
Info
>
;
NewAccountModel
(
Lrc
&
lrc
,
Database
&
database
,
const
CallbacksHandler
&
callbackHandler
,
const
api
::
BehaviorController
&
behaviorController
);
const
api
::
BehaviorController
&
behaviorController
,
MigrationCb
&
willMigrateCb
,
MigrationCb
&
didMigrateCb
);
~
NewAccountModel
();
/**
...
...
@@ -173,13 +172,13 @@ public:
* Set an account to the first position
*/
void
setTopAccount
(
const
std
::
string
&
accountId
);
/**
*
Build
the vCard for an account
*
Get
the vCard for an account
* @param id
* @return vcard of the account
*/
std
::
string
accountVCard
(
const
std
::
string
&
accountId
,
bool
compressImage
=
true
)
const
;
std
::
string
compressedAvatar
(
const
std
::
string
&
img
)
const
;
Q_SIGNALS:
/**
...
...
src/api/newcallmodel.h
View file @
8dfc664d
...
...
@@ -72,11 +72,12 @@ public:
/**
* Create a new call with a contact
* @param ur
l
of the contact to call
* @param ur
i
of the contact to call
* @param isAudioOnly, set to false by default
* @return the call uid created. Empty string is returned if call couldn't be created.
*/
std
::
string
createCall
(
const
std
::
string
&
url
,
bool
isAudioOnly
=
false
);
std
::
string
createCall
(
const
std
::
string
&
uri
,
bool
isAudioOnly
=
false
);
/**
* Get the call from its call id
* @param uid
...
...
@@ -84,6 +85,7 @@ public:
* @throw out_of_range exception if not found
*/
const
call
::
Info
&
getCall
(
const
std
::
string
&
uid
)
const
;
/**
* Get the call from the peer uri
* @param uri
...
...
@@ -92,6 +94,7 @@ public:
* @throw out_of_range exception if not found
*/
const
call
::
Info
&
getCallFromURI
(
const
std
::
string
&
uri
,
bool
notOver
=
false
)
const
;
/**
* Get conference from a peer uri
* @param uri
...
...
@@ -99,11 +102,13 @@ public:
* @throw out_of_range exception if not found
*/
const
call
::
Info
&
getConferenceFromURI
(
const
std
::
string
&
uri
)
const
;
/**
* @param callId to test
* @return true if callId is presend else false.
*/
bool
hasCall
(
const
std
::
string
&
callId
)
const
;
/**
* Send a text message to a SIP call
* @param callId
...
...
@@ -116,64 +121,76 @@ public:
* @param callId
*/
void
accept
(
const
std
::
string
&
callId
)
const
;
/**
* Hang up a call
* @param callId
*/
void
hangUp
(
const
std
::
string
&
callId
)
const
;
/**
* Refuse a call
* @param callId
*/
void
refuse
(
const
std
::
string
&
callId
)
const
;
/**
* Toggle audio record on a call
* @param callId
*/
void
toggleAudioRecord
(
const
std
::
string
&
callId
)
const
;
/**
* Play DTMF in a call
* @param callId
* @param value to play
*/
void
playDTMF
(
const
std
::
string
&
callId
,
const
std
::
string
&
value
)
const
;
/**
* Toggle pause on a call
* @param callId
*/
void
togglePause
(
const
std
::
string
&
callId
)
const
;
/**
* Toggle a media on a call
* @param callId
* @param media {AUDIO, VIDEO}
*/
void
toggleMedia
(
const
std
::
string
&
callId
,
const
NewCallModel
::
Media
media
)
const
;
/**
* Not implemented yet
*/
void
setQuality
(
const
std
::
string
&
callId
,
const
double
quality
)
const
;
/**
* Blind transfer. Directly transfer a call to a sip number
* @param callId: the call to transfer
* @param to: the sip number (for example: "sip:1412")
*/
void
transfer
(
const
std
::
string
&
callId
,
const
std
::
string
&
to
)
const
;
/**
* Perform an attended. Transfer a call to another call
* @param callIdSrc: the call to transfer
* @param callIdDest: the destination's call
*/
void
transferToCall
(
const
std
::
string
&
callIdSrc
,
const
std
::
string
&
callIdDest
)
const
;
/**
* Create a conference from 2 calls.
* @param callIdA uid of the call A
* @param callIdB uid of the call B
*/
void
joinCalls
(
const
std
::
string
&
callIdA
,
const
std
::
string
&
callIdB
)
const
;
/**
* Not implemented yet
*/
void
removeParticipant
(
const
std
::
string
&
callId
,
const
std
::
string
&
participant
)
const
;
/**
* @param callId
* @return a human readable call duration (M:ss)
...
...
src/api/profile.h
View file @
8dfc664d
...
...
@@ -35,7 +35,8 @@ enum class Type {
RING
,
SIP
,
PENDING
,
TEMPORARY
TEMPORARY
,
COUNT__
};
static
inline
const
std
::
string
...
...
@@ -51,6 +52,7 @@ to_string(const Type& type)
case
Type
::
TEMPORARY
:
return
"TEMPORARY"
;
case
Type
::
INVALID
:
case
Type
::
COUNT__
:
default:
return
"INVALID"
;
}
...
...
@@ -71,6 +73,12 @@ to_type(const std::string& type)
return
Type
::
INVALID
;
}
/**
* @var uri
* @var avatar
* @var alias
* @var type
*/
struct
Info
{
std
::
string
uri
=
""
;
...
...
src/authority/databasehelper.cpp
deleted
100644 → 0
View file @
2697394b
/****************************************************************************
* Copyright (C) 2017-2019 Savoir-faire Linux Inc. *
* Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com> *
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com> *
* Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com> *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "databasehelper.h"
#include "api/profile.h"
#include "api/datatransfer.h"
#include <account_const.h>
#include <datatransfer_interface.h>
namespace
lrc
{
namespace
authority
{
namespace
database
{
std
::
string
getProfileId
(
Database
&
db
,
const
std
::
string
&
accountId
,
const
std
::
string
&
isAccount
,
const
std
::
string
&
uri
)
{
auto
accountProfiles
=
db
.
select
(
"profile_id"
,
"profiles_accounts"
,
"account_id=:account_id AND is_account=:is_account"
,
{{
":account_id"
,
accountId
},
{
":is_account"
,
isAccount
}}).
payloads
;
if
(
accountProfiles
.
empty
()
&&
(
isAccount
==
"true"
))
{
return
""
;
}
if
(
isAccount
==
"true"
)
return
accountProfiles
[
0
];
// we may have many contacts profiles for one account id,
// and need to check uri in addition to account id
auto
profiles
=
db
.
select
(
"id"
,
"profiles"
,
"uri=:uri"
,
{{
":uri"
,
uri
}}).
payloads
;
if
(
profiles
.
empty
())
return
""
;
std
::
sort
(
accountProfiles
.
begin
(),
accountProfiles
.
end
());
std
::
sort
(
profiles
.
begin
(),
profiles
.
end
());
std
::
vector
<
std
::
string
>
common
;
std
::
set_intersection
(
accountProfiles
.
begin
(),
accountProfiles
.
end
(),
profiles
.
begin
(),
profiles
.
end
(),
std
::
back_inserter
(
common
));
//if profile exists but not linked with account id,
// update profiles_accounts. Except empty uri for SIP accounts
if
(
common
.
empty
())
{
if
(
!
uri
.
empty
())
{
db
.
insertInto
(
"profiles_accounts"
,
{{
":profile_id"
,
"profile_id"
},
{
":account_id"
,
"account_id"
},
{
":is_account"
,
"is_account"
}},
{{
":profile_id"
,
profiles
[
0
]},
{
":account_id"
,
accountId
},
{
":is_account"
,
isAccount
}});
}
return
profiles
[
0
];
}
return
common
[
0
];
}
std
::
string
getOrInsertProfile
(
Database
&
db
,
const
std
::
string
&
contactUri
,
const
std
::
string
&
accountId
,
bool
isAccount
,
const
std
::
string
&
type
,
const
std
::
string
&
alias
,
const
std
::
string
&
avatar
)
{
// Check if profile is already present.
const
std
::
string
isAccountStr
=
isAccount
?
"true"
:
"false"
;
auto
profileAlreadyExists
=
getProfileId
(
db
,
accountId
,
isAccountStr
,
contactUri
);
if
(
profileAlreadyExists
.
empty
())
{
// Doesn't exists, add profile to the database
auto
row
=
db
.
insertInto
(
"profiles"
,
{{
":uri"
,
"uri"
},
{
":alias"
,
"alias"
},
{
":photo"
,
"photo"
},
{
":type"
,
"type"
},
{
":status"
,
"status"
}},
{{
":uri"
,
contactUri
},
{
":alias"
,
alias
},
{
":photo"
,
avatar
},
{
":type"
,
type
},
{
":status"
,
"TRUSTED"
}});
if
(
row
==
-
1
)
{
qDebug
()
<<
"contact not added to the database"
;
return
""
;
}
// link profile id to account id
auto
profiles
=
db
.
select
(
"profile_id"
,
"profiles_accounts"
,
"profile_id=:profile_id AND \
account_id=:account_id AND \
is_account=:is_account"
,
{{
":profile_id"
,
std
::
to_string
(
row
)},
{
":account_id"
,
accountId
},
{
":is_account"
,
isAccountStr
}})
.
payloads
;
if
(
profiles
.
empty
())
{
db
.
insertInto
(
"profiles_accounts"
,
{{
":profile_id"
,
"profile_id"
},
{
":account_id"
,
"account_id"
},
{
":is_account"
,
"is_account"
}},
{{
":profile_id"
,
std
::
to_string
(
row
)},
{
":account_id"
,
accountId
},
{
":is_account"
,
isAccountStr
}});
}
return
std
::
to_string
(
row
);
}
else
{
// Exists, update and retrieve it.
if
(
!
avatar
.
empty
()
&&
!
alias
.
empty
())
{
db
.
update
(
"profiles"
,
"alias=:alias, photo=:photo"
,
{{
":alias"
,
alias
},
{
":photo"
,
avatar
}},
"id=:id"
,
{{
":id"
,
profileAlreadyExists
}});
}
else
if
(
!
avatar
.
empty
())
{
db
.
update
(
"profiles"
,
"photo=:photo"
,
{{
":photo"
,
avatar
}},
"id=:id"
,
{{
":id"
,
profileAlreadyExists
}});
}
return
profileAlreadyExists
;
}
}
std
::
vector
<
std
::
string
>
getConversationsForProfile
(
Database
&
db
,
const
std
::
string
&
profileId
)
{
return
db
.
select
(
"id"
,
"conversations"
,
"participant_id=:participant_id"
,
{{
":participant_id"
,
profileId
}}).
payloads
;
}
std
::
vector
<
std
::
string
>
getPeerParticipantsForConversation
(
Database
&
db
,
const
std
::
string
&
profileId
,
const
std
::
string
&
conversationId
)
{
return
db
.
select
(
"participant_id"
,
"conversations"
,
"id=:id AND participant_id!=:participant_id"
,
{{
":id"
,
conversationId
},
{
":participant_id"
,
profileId
}}).
payloads
;
}
std
::
string
getAvatarForProfileId
(
Database
&
db
,
const
std
::
string
&
profileId
)
{
auto
returnFromDb
=
db
.
select
(
"photo"
,
"profiles"
,
"id=:id"
,
{{
":id"
,
profileId
}});
if
(
returnFromDb
.
nbrOfCols
==
1
&&
returnFromDb
.
payloads
.
size
()
>=
1
)
{
auto
payloads
=
returnFromDb
.
payloads
;
return
payloads
[
0
];
}
return
""
;