mirror of
https://github.com/matrix-construct/construct
synced 2025-03-13 21:10:32 +01:00
ircd:Ⓜ️ Simplify the event query interface by making more internal decisions from query data.
This commit is contained in:
parent
c4a6addd5a
commit
5d7eee1937
10 changed files with 503 additions and 447 deletions
|
@ -83,7 +83,8 @@ struct ircd::m::event
|
|||
using cursor = db::cursor<events, event>;
|
||||
using const_iterator = cursor::const_iterator;
|
||||
using iterator = const_iterator;
|
||||
using where = cursor::where_type;
|
||||
using where = db::where;
|
||||
template<enum db::where w = where::noop> using query = cursor::query_type<w>;
|
||||
|
||||
// Queue of contexts waiting to see the next inserted event
|
||||
static ctx::view<const event> inserted;
|
||||
|
|
|
@ -25,37 +25,20 @@
|
|||
#pragma once
|
||||
#define HAVE_IRCD_M_EVENTS_H
|
||||
|
||||
namespace ircd::m
|
||||
namespace ircd::m::events
|
||||
{
|
||||
struct events;
|
||||
}
|
||||
using closure = std::function<void (const event &)>;
|
||||
using closure_bool = std::function<bool (const event &)>;
|
||||
|
||||
struct ircd::m::events
|
||||
{
|
||||
using event_closure = std::function<void (const event &)>;
|
||||
using event_closure_bool = std::function<bool (const event &)>;
|
||||
bool query(const event::query<> &, const closure_bool &);
|
||||
bool query(const closure_bool &);
|
||||
|
||||
virtual bool _query_(const event::where &, const event_closure_bool &) const;
|
||||
virtual bool _rquery_(const event::where &, const event_closure_bool &) const;
|
||||
void for_each(const event::query<> &, const closure &);
|
||||
void for_each(const closure &);
|
||||
|
||||
bool query(const event::where &, const event_closure_bool &) const;
|
||||
bool query(const event_closure_bool &) const;
|
||||
size_t count(const event::query<> &, const closure_bool &);
|
||||
size_t count(const event::query<> &);
|
||||
|
||||
bool rquery(const event::where &, const event_closure_bool &) const;
|
||||
bool rquery(const event_closure_bool &) const;
|
||||
|
||||
void for_each(const event::where &, const event_closure &) const;
|
||||
void for_each(const event_closure &) const;
|
||||
|
||||
void rfor_each(const event::where &, const event_closure &) const;
|
||||
void rfor_each(const event_closure &) const;
|
||||
|
||||
size_t count(const event::where &, const event_closure_bool &) const;
|
||||
size_t count(const event::where &) const;
|
||||
|
||||
bool test(const event::where &, const event_closure_bool &) const;
|
||||
bool test(const event::where &) const;
|
||||
|
||||
events() = default;
|
||||
virtual ~events() noexcept;
|
||||
bool test(const event::query<> &, const closure_bool &);
|
||||
bool test(const event::query<> &);
|
||||
};
|
||||
|
|
|
@ -37,8 +37,6 @@ namespace ircd::m
|
|||
struct ircd::m::room
|
||||
{
|
||||
struct alias;
|
||||
struct events;
|
||||
struct state;
|
||||
struct members;
|
||||
|
||||
using id = m::id::room;
|
||||
|
@ -63,47 +61,12 @@ struct ircd::m::room
|
|||
{}
|
||||
};
|
||||
|
||||
struct ircd::m::room::events
|
||||
:m::events
|
||||
{
|
||||
id room_id;
|
||||
|
||||
bool _query_(const event::where &, const event_closure_bool &) const override;
|
||||
bool _rquery_(const event::where &, const event_closure_bool &) const override;
|
||||
|
||||
events(const id &room_id)
|
||||
:room_id{room_id}
|
||||
{}
|
||||
|
||||
events(const room &room)
|
||||
:room_id{room.room_id}
|
||||
{}
|
||||
};
|
||||
|
||||
struct ircd::m::room::state
|
||||
:m::events
|
||||
{
|
||||
id room_id;
|
||||
|
||||
bool _query_(const event::where &, const event_closure_bool &) const override;
|
||||
bool _rquery_(const event::where &, const event_closure_bool &) const override;
|
||||
|
||||
state(const id &room_id)
|
||||
:room_id{room_id}
|
||||
{}
|
||||
|
||||
state(const room &room)
|
||||
:room_id{room.room_id}
|
||||
{}
|
||||
};
|
||||
|
||||
struct ircd::m::room::members
|
||||
:m::events
|
||||
{
|
||||
id room_id;
|
||||
|
||||
bool _query_(const event::where &, const event_closure_bool &) const override;
|
||||
bool _rquery_(const event::where &, const event_closure_bool &) const override;
|
||||
bool is_member(const m::id::user &) const;
|
||||
bool membership(const m::id::user &, const string_view & = "join") const;
|
||||
|
||||
members(const id &room_id)
|
||||
:room_id{room_id}
|
||||
|
|
|
@ -31,13 +31,10 @@ namespace ircd::m
|
|||
|
||||
extern user me;
|
||||
extern room my_room;
|
||||
extern room filters;
|
||||
}
|
||||
|
||||
struct ircd::m::user
|
||||
{
|
||||
struct rooms;
|
||||
|
||||
using id = m::id::user;
|
||||
|
||||
id user_id;
|
||||
|
@ -56,16 +53,3 @@ struct ircd::m::user
|
|||
:user_id{user_id}
|
||||
{}
|
||||
};
|
||||
|
||||
struct ircd::m::user::rooms
|
||||
:m::events
|
||||
{
|
||||
id user_id;
|
||||
|
||||
bool _query_(const event::where &, const event_closure_bool &) const override;
|
||||
bool _rquery_(const event::where &, const event_closure_bool &) const override;
|
||||
|
||||
rooms(const id &user_id)
|
||||
:user_id{user_id}
|
||||
{}
|
||||
};
|
||||
|
|
743
ircd/matrix.cc
743
ircd/matrix.cc
|
@ -340,27 +340,12 @@ bool
|
|||
ircd::m::room::is_member(const m::id::user &user_id,
|
||||
const string_view &membership)
|
||||
{
|
||||
const m::event::where::equal query
|
||||
const members members
|
||||
{
|
||||
{ "type", "m.room.member" },
|
||||
{ "state_key", user_id }
|
||||
room_id
|
||||
};
|
||||
|
||||
return events{*this}.test(query, [&membership]
|
||||
(const auto &event)
|
||||
{
|
||||
const json::object &content
|
||||
{
|
||||
json::val<m::name::content>(event)
|
||||
};
|
||||
|
||||
const auto &existing
|
||||
{
|
||||
unquote(content["membership"])
|
||||
};
|
||||
|
||||
return membership == existing;
|
||||
});
|
||||
return members.membership(user_id, membership);
|
||||
}
|
||||
|
||||
ircd::m::event::id::buf
|
||||
|
@ -398,143 +383,51 @@ ircd::m::room::send(json::iov &event)
|
|||
}
|
||||
|
||||
bool
|
||||
ircd::m::room::members::_rquery_(const event::where &where,
|
||||
const event_closure_bool &closure)
|
||||
ircd::m::room::members::membership(const m::id::user &user_id,
|
||||
const string_view &membership)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
if(membership.empty())
|
||||
return is_member(user_id);
|
||||
|
||||
const event::query<event::where::equal> member_event
|
||||
{
|
||||
"event_id for type,state_key in room_id",
|
||||
&where
|
||||
{ "room_id", room_id },
|
||||
{ "type", "m.room.member" },
|
||||
{ "state_key", user_id },
|
||||
};
|
||||
|
||||
//TODO: ???
|
||||
static const size_t max_type_size
|
||||
const event::query<event::where::test> membership_test{[&membership]
|
||||
(const auto &event)
|
||||
{
|
||||
256
|
||||
};
|
||||
const json::object &content
|
||||
{
|
||||
json::at<m::name::content>(event)
|
||||
};
|
||||
|
||||
const auto key_max
|
||||
{
|
||||
room::id::buf::SIZE + max_type_size
|
||||
};
|
||||
const auto &existing_membership
|
||||
{
|
||||
unquote(content.at("membership"))
|
||||
};
|
||||
|
||||
size_t key_len;
|
||||
char key[key_max]; key[0] = '\0';
|
||||
key_len = strlcat(key, room_id, sizeof(key));
|
||||
key_len = strlcat(key, "..m.room.member", sizeof(key)); //TODO: prefix protocol
|
||||
return membership == existing_membership;
|
||||
}};
|
||||
|
||||
for(auto it(cursor.rbegin(key)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return m::events::test(member_event && membership_test);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::room::members::_query_(const event::where &where,
|
||||
const event_closure_bool &closure)
|
||||
ircd::m::room::members::is_member(const m::id::user &user_id)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
const event::query<event::where::equal> member_event
|
||||
{
|
||||
"event_id for type,state_key in room_id",
|
||||
&where
|
||||
{ "room_id", room_id },
|
||||
{ "type", "m.room.member" },
|
||||
{ "state_key", user_id },
|
||||
};
|
||||
|
||||
//TODO: ???
|
||||
static const size_t max_type_size
|
||||
{
|
||||
256
|
||||
};
|
||||
|
||||
const auto key_max
|
||||
{
|
||||
room::id::buf::SIZE + max_type_size
|
||||
};
|
||||
|
||||
size_t key_len;
|
||||
char key[key_max]; key[0] = '\0';
|
||||
key_len = strlcat(key, room_id, sizeof(key));
|
||||
key_len = strlcat(key, "..m.room.member", sizeof(key)); //TODO: prefix protocol
|
||||
|
||||
for(auto it(cursor.begin(key)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::room::state::_rquery_(const event::where &where,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id for type,state_key in room_id",
|
||||
&where
|
||||
};
|
||||
|
||||
for(auto it(cursor.rbegin(room_id)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::room::state::_query_(const event::where &where,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id for type,state_key in room_id",
|
||||
&where
|
||||
};
|
||||
|
||||
for(auto it(cursor.begin(room_id)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::room::events::_rquery_(const event::where &where,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id in room_id",
|
||||
&where
|
||||
};
|
||||
|
||||
for(auto it(cursor.rbegin(room_id)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::room::events::_query_(const event::where &where,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id in room_id",
|
||||
&where
|
||||
};
|
||||
|
||||
for(auto it(cursor.begin(room_id)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return m::events::test(member_event);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -623,13 +516,14 @@ bool
|
|||
ircd::m::user::is_password(const string_view &supplied_password)
|
||||
const
|
||||
{
|
||||
const m::event::where::equal member_event
|
||||
const event::query<event::where::equal> member_event
|
||||
{
|
||||
{ "type", "ircd.password" },
|
||||
{ "state_key", user_id }
|
||||
{ "room_id", accounts.room_id },
|
||||
{ "type", "ircd.password" },
|
||||
{ "state_key", user_id },
|
||||
};
|
||||
|
||||
const m::event::where::test correct_password{[&supplied_password]
|
||||
const event::query<event::where::test> correct_password{[&supplied_password]
|
||||
(const auto &event)
|
||||
{
|
||||
const json::object &content
|
||||
|
@ -650,27 +544,22 @@ const
|
|||
member_event && correct_password
|
||||
};
|
||||
|
||||
// The query to the database is made here. Know that this ircd::ctx
|
||||
// may suspend and global state may have changed after this call.
|
||||
const room::events events
|
||||
{
|
||||
accounts
|
||||
};
|
||||
|
||||
return events.test(member_event && correct_password);
|
||||
return m::events::test(member_event && correct_password);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::user::is_active()
|
||||
const
|
||||
{
|
||||
const m::event::where::equal member_event
|
||||
const auto &room_id{accounts.room_id};
|
||||
const m::event::query<event::where::equal> member_event
|
||||
{
|
||||
{ "room_id", room_id },
|
||||
{ "type", "m.room.member" },
|
||||
{ "state_key", user_id }
|
||||
{ "state_key", user_id },
|
||||
};
|
||||
|
||||
const m::event::where::test is_joined{[]
|
||||
const m::event::query<event::where::test> is_joined{[]
|
||||
(const auto &event)
|
||||
{
|
||||
const json::object &content
|
||||
|
@ -686,23 +575,161 @@ const
|
|||
return membership == "join";
|
||||
}};
|
||||
|
||||
const room::events events
|
||||
return events::test(member_event && is_joined);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// query lib
|
||||
//
|
||||
/*
|
||||
bool
|
||||
ircd::m::room::members::_rquery_(const event::query<> &query,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
accounts
|
||||
"event_id for type,state_key in room_id",
|
||||
&query
|
||||
};
|
||||
|
||||
return events.test(member_event && is_joined);
|
||||
//TODO: ???
|
||||
static const size_t max_type_size
|
||||
{
|
||||
256
|
||||
};
|
||||
|
||||
const auto key_max
|
||||
{
|
||||
room::id::buf::SIZE + max_type_size
|
||||
};
|
||||
|
||||
size_t key_len;
|
||||
char key[key_max]; key[0] = '\0';
|
||||
key_len = strlcat(key, room_id, sizeof(key));
|
||||
key_len = strlcat(key, "..m.room.member", sizeof(key)); //TODO: prefix protocol
|
||||
for(auto it(cursor.rbegin(key)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::user::rooms::_rquery_(const event::where &where,
|
||||
ircd::m::room::members::_query_(const event::query<> &query,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id for type,state_key in room_id",
|
||||
&query
|
||||
};
|
||||
|
||||
//TODO: ???
|
||||
static const size_t max_type_size
|
||||
{
|
||||
256
|
||||
};
|
||||
|
||||
const auto key_max
|
||||
{
|
||||
room::id::buf::SIZE + max_type_size
|
||||
};
|
||||
|
||||
size_t key_len;
|
||||
char key[key_max]; key[0] = '\0';
|
||||
key_len = strlcat(key, room_id, sizeof(key));
|
||||
key_len = strlcat(key, "..m.room.member", sizeof(key)); //TODO: prefix protocol
|
||||
for(auto it(cursor.begin(key)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::room::state::_rquery_(const event::query<> &query,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id for type,state_key in room_id",
|
||||
&query
|
||||
};
|
||||
|
||||
for(auto it(cursor.rbegin(room_id)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::room::state::_query_(const event::query<> &query,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id for type,state_key in room_id",
|
||||
&query
|
||||
};
|
||||
|
||||
for(auto it(cursor.begin(room_id)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::room::events::_rquery_(const event::query<> &query,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id in room_id",
|
||||
&query
|
||||
};
|
||||
|
||||
for(auto it(cursor.rbegin(room_id)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::room::events::_query_(const event::query<> &query,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id in room_id",
|
||||
&query
|
||||
};
|
||||
|
||||
for(auto it(cursor.begin(room_id)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::user::rooms::_rquery_(const event::query<> &query,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id for room_id in sender",
|
||||
&where
|
||||
&query
|
||||
};
|
||||
|
||||
for(auto it(cursor.rbegin(user_id)); bool(it); ++it)
|
||||
|
@ -713,14 +740,14 @@ const
|
|||
}
|
||||
|
||||
bool
|
||||
ircd::m::user::rooms::_query_(const event::where &where,
|
||||
ircd::m::user::rooms::_query_(const event::query<> &query,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id for room_id in sender",
|
||||
&where
|
||||
&query
|
||||
};
|
||||
|
||||
for(auto it(cursor.begin(user_id)); bool(it); ++it)
|
||||
|
@ -730,140 +757,8 @@ const
|
|||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// m/events.h
|
||||
//
|
||||
|
||||
ircd::m::events::~events()
|
||||
noexcept
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::test(const event::where &where)
|
||||
const
|
||||
{
|
||||
return test(where, [](const auto &event)
|
||||
{
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::test(const event::where &where,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
bool ret{false};
|
||||
query(where, [&ret, &closure]
|
||||
(const auto &event)
|
||||
{
|
||||
ret = closure(event);
|
||||
return true;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::m::events::count(const event::where &where)
|
||||
const
|
||||
{
|
||||
return count(where, [](const auto &event)
|
||||
{
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::m::events::count(const event::where &where,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
size_t i(0);
|
||||
for_each(where, [&closure, &i](const auto &event)
|
||||
{
|
||||
i += closure(event);
|
||||
});
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::events::rfor_each(const event_closure &closure)
|
||||
const
|
||||
{
|
||||
const m::event::where::noop where{};
|
||||
rfor_each(where, closure);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::events::rfor_each(const event::where &where,
|
||||
const event_closure &closure)
|
||||
const
|
||||
{
|
||||
rquery(where, [&closure](const auto &event)
|
||||
{
|
||||
closure(event);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::events::for_each(const event::where &where,
|
||||
const event_closure &closure)
|
||||
const
|
||||
{
|
||||
query(where, [&closure](const auto &event)
|
||||
{
|
||||
closure(event);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::events::for_each(const event_closure &closure)
|
||||
const
|
||||
{
|
||||
const m::event::where::noop where{};
|
||||
for_each(where, closure);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::rquery(const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
const m::event::where::noop where{};
|
||||
return rquery(where, closure);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::rquery(const event::where &where,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
return _rquery_(where, closure);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::query(const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
const m::event::where::noop where{};
|
||||
return query(where, closure);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::query(const event::where &where,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
return _query_(where, closure);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::_rquery_(const event::where &where,
|
||||
ircd::m::events::_rquery_(const event::query<> &where,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
|
@ -881,7 +776,7 @@ const
|
|||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::_query_(const event::where &where,
|
||||
ircd::m::events::_query_(const event::query<> &where,
|
||||
const event_closure_bool &closure)
|
||||
const
|
||||
{
|
||||
|
@ -897,6 +792,257 @@ const
|
|||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// m/events.h
|
||||
//
|
||||
|
||||
bool
|
||||
ircd::m::events::test(const event::query<> &where)
|
||||
{
|
||||
return test(where, [](const auto &event)
|
||||
{
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::test(const event::query<> &where,
|
||||
const closure_bool &closure)
|
||||
{
|
||||
bool ret{false};
|
||||
query(where, [&ret, &closure]
|
||||
(const auto &event)
|
||||
{
|
||||
ret = closure(event);
|
||||
return true;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::m::events::count(const event::query<> &where)
|
||||
{
|
||||
return count(where, [](const auto &event)
|
||||
{
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::m::events::count(const event::query<> &where,
|
||||
const closure_bool &closure)
|
||||
{
|
||||
size_t i(0);
|
||||
for_each(where, [&closure, &i](const auto &event)
|
||||
{
|
||||
i += closure(event);
|
||||
});
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
ircd::m::events::rfor_each(const closure &closure)
|
||||
{
|
||||
const event::query<event::where::noop> where{};
|
||||
rfor_each(where, closure);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::events::rfor_each(const event::query<> &where,
|
||||
const closure &closure)
|
||||
{
|
||||
rquery(where, [&closure](const auto &event)
|
||||
{
|
||||
closure(event);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::rquery(const closure_bool &closure)
|
||||
{
|
||||
const event::query<event::where::noop> where{};
|
||||
return rquery(where, closure);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::rquery(const event::query<> &where,
|
||||
const closure_bool &closure)
|
||||
{
|
||||
//return _rquery_(where, closure);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
void
|
||||
ircd::m::events::for_each(const event::query<> &where,
|
||||
const closure &closure)
|
||||
{
|
||||
query(where, [&closure](const auto &event)
|
||||
{
|
||||
closure(event);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::events::for_each(const closure &closure)
|
||||
{
|
||||
const event::query<event::where::noop> where{};
|
||||
for_each(where, closure);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::query(const closure_bool &closure)
|
||||
{
|
||||
const event::query<event::where::noop> where{};
|
||||
return query(where, closure);
|
||||
}
|
||||
|
||||
namespace ircd::m::events
|
||||
{
|
||||
bool _query_event_id(const event::query<> &, const closure_bool &);
|
||||
bool _query_in_room_id(const event::query<> &, const closure_bool &, const room::id &);
|
||||
bool _query_for_type_state_key_in_room_id(const event::query<> &, const closure_bool &, const room::id &, const string_view &type = {}, const string_view &state_key = {});
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::query(const event::query<> &where,
|
||||
const closure_bool &closure)
|
||||
{
|
||||
switch(where.type)
|
||||
{
|
||||
case event::where::equal:
|
||||
{
|
||||
auto &clause
|
||||
{
|
||||
dynamic_cast<const event::query<event::where::equal> &>(where)
|
||||
};
|
||||
|
||||
const auto &value{clause.value};
|
||||
const auto &room_id{json::val<name::room_id>(value)};
|
||||
const auto &type{json::val<name::type>(value)};
|
||||
const auto &state_key{json::val<name::state_key>(value)};
|
||||
if(room_id && type && state_key.defined())
|
||||
return _query_for_type_state_key_in_room_id(where, closure, room_id, type, state_key);
|
||||
|
||||
if(room_id && state_key.defined())
|
||||
return _query_for_type_state_key_in_room_id(where, closure, room_id, type, state_key);
|
||||
|
||||
if(room_id)
|
||||
return _query_in_room_id(where, closure, room_id);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case event::where::logical_and:
|
||||
{
|
||||
auto &clause
|
||||
{
|
||||
dynamic_cast<const event::query<event::where::logical_and> &>(where)
|
||||
};
|
||||
|
||||
const auto &lhs{*clause.a}, &rhs{*clause.b};
|
||||
const auto reclosure{[&lhs, &rhs, &closure]
|
||||
(const auto &event)
|
||||
{
|
||||
if(!rhs(event))
|
||||
return false;
|
||||
|
||||
return closure(event);
|
||||
}};
|
||||
|
||||
return events::query(lhs, reclosure);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return _query_event_id(where, closure);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::_query_event_id(const event::query<> &where,
|
||||
const closure_bool &closure)
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id",
|
||||
&where
|
||||
};
|
||||
|
||||
for(auto it(cursor.begin()); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::_query_in_room_id(const event::query<> &query,
|
||||
const closure_bool &closure,
|
||||
const room::id &room_id)
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id in room_id",
|
||||
&query
|
||||
};
|
||||
|
||||
for(auto it(cursor.begin(room_id)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::_query_for_type_state_key_in_room_id(const event::query<> &query,
|
||||
const closure_bool &closure,
|
||||
const room::id &room_id,
|
||||
const string_view &type,
|
||||
const string_view &state_key)
|
||||
{
|
||||
event::cursor cursor
|
||||
{
|
||||
"event_id for type,state_key in room_id",
|
||||
&query
|
||||
};
|
||||
|
||||
static const size_t max_type_size
|
||||
{
|
||||
255
|
||||
};
|
||||
|
||||
static const size_t max_state_key_size
|
||||
{
|
||||
255
|
||||
};
|
||||
|
||||
const auto key_max
|
||||
{
|
||||
room::id::buf::SIZE + max_type_size + max_state_key_size + 2
|
||||
};
|
||||
|
||||
size_t key_len;
|
||||
char key[key_max]; key[0] = '\0';
|
||||
key_len = strlcat(key, room_id, sizeof(key));
|
||||
key_len = strlcat(key, "..", sizeof(key)); //TODO: prefix protocol
|
||||
key_len = strlcat(key, type, sizeof(key)); //TODO: prefix protocol
|
||||
key_len = strlcat(key, state_key, sizeof(key)); //TODO: prefix protocol
|
||||
for(auto it(cursor.begin(key)); bool(it); ++it)
|
||||
if(closure(*it))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -908,6 +1054,9 @@ namespace ircd::m
|
|||
void append_indexes(const event &, db::iov &);
|
||||
}
|
||||
|
||||
// vtable for the db::query partially specialized to m::event as its tuple
|
||||
template ircd::db::query<ircd::m::event, ircd::db::where::noop>::~query();
|
||||
|
||||
ircd::database *
|
||||
ircd::m::event::events
|
||||
{};
|
||||
|
@ -1045,7 +1194,7 @@ const
|
|||
index[0] = '\0';
|
||||
const auto function
|
||||
{
|
||||
[&index, &buf_max](const auto &val)
|
||||
[&index](const auto &val)
|
||||
{
|
||||
strlcat(index, byte_view<string_view>{val}, buf_max);
|
||||
}
|
||||
|
@ -1101,7 +1250,7 @@ const
|
|||
index[0] = '\0';
|
||||
const auto concat
|
||||
{
|
||||
[&index, &buf_max](const auto &val)
|
||||
[&index](const auto &val)
|
||||
{
|
||||
strlcat(index, byte_view<string_view>{val}, buf_max);
|
||||
}
|
||||
|
@ -1166,7 +1315,7 @@ const
|
|||
index[0] = '\0';
|
||||
const auto concat
|
||||
{
|
||||
[&index, &buf_max](const auto &val)
|
||||
[&index](const auto &val)
|
||||
{
|
||||
strlcat(index, byte_view<string_view>{val}, buf_max);
|
||||
}
|
||||
|
|
|
@ -117,21 +117,17 @@ try
|
|||
request.query.at("access_token")
|
||||
};
|
||||
|
||||
static const m::room::state sessions
|
||||
{
|
||||
m::id::room{"!sessions:cdc.z"}
|
||||
};
|
||||
|
||||
// Sets up the query to find the access_token in the sessions rooms
|
||||
const m::event::where::equal query
|
||||
const m::event::query<m::event::where::equal> query
|
||||
{
|
||||
{ "type", "ircd.access_token" },
|
||||
{ "state_key", access_token }
|
||||
{ "state_key", access_token },
|
||||
{ "room_id", "!sessions:cdc.z" },
|
||||
};
|
||||
|
||||
const bool result
|
||||
{
|
||||
sessions.test(query, [&request, &access_token](const m::event &event)
|
||||
m::events::test(query, [&request, &access_token](const m::event &event)
|
||||
{
|
||||
// Checks if the access token has expired. Tokens are expired when
|
||||
// an m.room.redaction event is issued for the ircd.access_token
|
||||
|
|
|
@ -27,46 +27,28 @@ resource events_resource
|
|||
"Events (6.2.3) (10.x)"
|
||||
};
|
||||
|
||||
const m::id::room::buf accounts_room_id
|
||||
{
|
||||
"accounts", "cdc.z"
|
||||
};
|
||||
|
||||
const m::id::room::buf locops_room_id
|
||||
{
|
||||
"locops", "cdc.z"
|
||||
};
|
||||
|
||||
const m::id::room::buf ircd_room_id
|
||||
{
|
||||
"ircd", "cdc.z"
|
||||
};
|
||||
|
||||
resource::response
|
||||
get_events(client &client, const resource::request &request)
|
||||
{
|
||||
m::room room
|
||||
const m::room::id &room_id
|
||||
{
|
||||
m::id::room
|
||||
{
|
||||
unquote(request.at("room_id"))
|
||||
}
|
||||
unquote(request["room_id"])
|
||||
};
|
||||
|
||||
const m::room::events events
|
||||
const m::event::query<m::event::where::equal> query
|
||||
{
|
||||
room
|
||||
{ "room_id", room_id }
|
||||
};
|
||||
|
||||
size_t i(0);
|
||||
events.for_each([&i](const auto &event)
|
||||
m::events::for_each(query, [&i](const auto &event)
|
||||
{
|
||||
++i;
|
||||
});
|
||||
|
||||
size_t j(0);
|
||||
json::value ret[i];
|
||||
events.for_each([&i, &j, &ret](const m::event &event)
|
||||
m::events::for_each(query, [&i, &j, &ret](const m::event &event)
|
||||
{
|
||||
if(j < i)
|
||||
ret[j++] = event;
|
||||
|
|
|
@ -49,12 +49,11 @@ resource::response
|
|||
get_state(client &client,
|
||||
const resource::request &request,
|
||||
const string_view ¶ms,
|
||||
const m::room::state &state,
|
||||
const m::event::where &query)
|
||||
const m::event::query<> &query)
|
||||
{
|
||||
const auto count
|
||||
{
|
||||
state.count(query)
|
||||
m::events::count(query)
|
||||
};
|
||||
|
||||
if(!count)
|
||||
|
@ -65,7 +64,7 @@ get_state(client &client,
|
|||
|
||||
size_t j(0);
|
||||
json::value ret[count];
|
||||
state.for_each(query, [&count, &j, &ret]
|
||||
m::events::for_each(query, [&count, &j, &ret]
|
||||
(const auto &event)
|
||||
{
|
||||
if(j < count)
|
||||
|
@ -85,32 +84,34 @@ resource::response
|
|||
get_state(client &client,
|
||||
const resource::request &request,
|
||||
const string_view ¶ms,
|
||||
const m::room::state &state,
|
||||
const m::room::id &room_id,
|
||||
const string_view &type,
|
||||
const string_view &state_key)
|
||||
{
|
||||
const m::event::where::equal query
|
||||
const m::event::query<m::event::where::equal> query
|
||||
{
|
||||
{ "type", type },
|
||||
{ "state_key", state_key },
|
||||
{ "room_id", room_id },
|
||||
{ "type", type },
|
||||
{ "state_key", state_key },
|
||||
};
|
||||
|
||||
return get_state(client, request, params, state, query);
|
||||
return get_state(client, request, params, query);
|
||||
}
|
||||
|
||||
resource::response
|
||||
get_state(client &client,
|
||||
const resource::request &request,
|
||||
const string_view ¶ms,
|
||||
const m::room::state &state,
|
||||
const m::room::id &room_id,
|
||||
const string_view &type)
|
||||
{
|
||||
const m::event::where::equal query
|
||||
const m::event::query<m::event::where::equal> query
|
||||
{
|
||||
{ "type", type }
|
||||
{ "room_id", room_id },
|
||||
{ "type", type }
|
||||
};
|
||||
|
||||
return get_state(client, request, params, state, query);
|
||||
return get_state(client, request, params, query);
|
||||
}
|
||||
|
||||
resource::response
|
||||
|
@ -132,19 +133,19 @@ get_state(client &client,
|
|||
token[3]
|
||||
};
|
||||
|
||||
const m::room::state state
|
||||
{
|
||||
room_id
|
||||
};
|
||||
|
||||
if(type && state_key)
|
||||
return get_state(client, request, params, state, type, state_key);
|
||||
return get_state(client, request, params, room_id, type, state_key);
|
||||
|
||||
if(type)
|
||||
return get_state(client, request, params, state, type);
|
||||
return get_state(client, request, params, room_id, type);
|
||||
|
||||
const m::event::where::noop query;
|
||||
return get_state(client, request, params, state, query);
|
||||
const m::event::query<m::event::where::equal> query
|
||||
{
|
||||
{ "room_id", room_id },
|
||||
{ "state_key", "" },
|
||||
};
|
||||
|
||||
return get_state(client, request, params, query);
|
||||
}
|
||||
|
||||
resource::response
|
||||
|
|
|
@ -204,14 +204,15 @@ sync(client &client, const resource::request &request)
|
|||
};
|
||||
|
||||
// The ircd.tape.head
|
||||
const m::event::where::equal query
|
||||
const m::event::query<m::event::where::equal> query
|
||||
{
|
||||
{ "room_id", m::user::sessions.room_id },
|
||||
{ "type", "ircd.tape.head" },
|
||||
{ "state_key", request.query.at("access_token") },
|
||||
};
|
||||
|
||||
m::event::id::buf head;
|
||||
if(!sessions.test(query, [&head](const auto &event)
|
||||
if(!m::events::test(query, [&head](const auto &event)
|
||||
{
|
||||
const json::object &content
|
||||
{
|
||||
|
|
|
@ -44,11 +44,12 @@ try
|
|||
token(request.head.path, '/', 6)
|
||||
};
|
||||
|
||||
const m::event::where::equal query
|
||||
const m::event::query<m::event::where::equal> query
|
||||
{
|
||||
{ "type", "ircd.filter" },
|
||||
{ "sender", user_id },
|
||||
{ "state_key", filter_id }
|
||||
{ "room_id", m::filter::filters.room_id },
|
||||
{ "type", "ircd.filter" },
|
||||
{ "state_key", filter_id },
|
||||
{ "sender", user_id },
|
||||
};
|
||||
|
||||
const auto result{[&client]
|
||||
|
@ -67,12 +68,7 @@ try
|
|||
return true;
|
||||
}};
|
||||
|
||||
const m::room::events filters_room_events
|
||||
{
|
||||
m::filter::filters
|
||||
};
|
||||
|
||||
if(!filters_room_events.test(query, result))
|
||||
if(!m::events::test(query, result))
|
||||
throw m::NOT_FOUND("No matching filter with that ID");
|
||||
|
||||
// Response already made
|
||||
|
|
Loading…
Add table
Reference in a new issue