* update ArrayFromJSON to use LimitedReader
* update for bad merge
* fix lint errors
* update test code
* update unit tests
* update unit tests
* fix unit tests
* use consts, other cleanup
* add non sorting duplicate check
* set config to default value, then config setting if available
* fix lint errors
* fixes and debugs
* fix log test
* remove setting from Client, add unlimited Parser to client
* a couple more fixes
* another fix
* rename some variables
* remove superflous call
* check for valid MaximumPayloadSize
* update language file
* fix for e2e-tests
* update util function to return error
* lint fix
* update config property name to include unit
* fix for unit test
* add new config to telemetry
* call function to create LimitedReader
* Deprecate old function, use new function name
* return new AppError on failed parse
* return new AppError on failed parse
* return new AppError on failed parse
* add constant for i18n valid constants
* Update server/public/model/utils_test.go
Co-authored-by: Miguel de la Cruz <mgdelacroix@gmail.com>
* Apply suggestions from code review
Co-authored-by: Miguel de la Cruz <mgdelacroix@gmail.com>
* update error variable, remove unnecessary check
* Update function names
* fix errors from merge
* update unit test to create unique ids
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Miguel de la Cruz <mgdelacroix@gmail.com>
* option for auto inviting plugin to all shared channels.
* auto-invite remotes to shared channels when flag set
* fix unit test
* immediately ping new remotes; fix unique siteurl bug
* make i18n-extract
* fix translations
* fix merge conflicts
* make modules-tidy
* revert accidental go.mod change
* revert accidental go.sum changes
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* option for auto inviting plugin to all shared channels.
* auto-invite remotes to shared channels when flag set
* fix unit test
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* Expose metrics under a source available license
* do not assume Cluster()
* allow metrics if licensed or dev
* temporary vet override
* simplify BULID_TAGS handling
* auto clean old imports.go
* fix license listener
* e2e test metrics & license semantics
* update from enterprise
* switch back to mattermost-govet/v2@new now
* update metrics from upstream
* Update license_spec.js
Co-authored-by: Saturnino Abril <saturnino.abril@gmail.com>
* Update license_spec.js
Co-authored-by: Saturnino Abril <saturnino.abril@gmail.com>
* Update e2e-tests/cypress/tests/integration/channels/enterprise/metrics/license_spec.js
Co-authored-by: Saturnino Abril <saturnino.abril@gmail.com>
* Update e2e-tests/cypress/tests/integration/channels/enterprise/metrics/license_spec.js
* split up specs
* require/delete license earlier in e2e test
* expanded expect to debug failures
* more logging
* Revert "more logging"
This reverts commit 0bc513fd92.
* e2e: try deleting license first
* update from enterprise
* toggleMetricsOn to work around license delete
* eslint
* ensure admin before deleting license
* update from enterprise
* updates from enterprise
* fix cypress logging
* temp: log at DEBUG for Cypress tests
---------
Co-authored-by: Saturnino Abril <saturnino.abril@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Lock wrangler behind enterprise
* Run tests with SetupEnterprise so Thread Moving is unlocked. Tweak NewTestLicense to include a SkuShortName for 'enterprise'
* Don't set SkuShortName in NewTestLicense just in case. Fix up some old debug code in tests
* Remove checks on enterprise/e20 and just enforce that the workspace has any license
* Update admin_definition.tsx accordingly
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
PR https://github.com/mattermost/mattermost/pull/22560
introduced a regression in the case where we had
multiple connections for a single user.
Because if connIndex.Remove was called during the iteration
from connIndex.ForUser, then the slice would be modified
during iteration and if a connection got removed,
then a good connection would move from the last index
to the current index. But since we would be actively
iterating, the last index would be read as nil and we would
never be able to reach the good connection.
We fix this by returning a copy of the original slice
if there are more than one elements in the slice.
https://mattermost.atlassian.net/browse/MM-56260
```release-note
Fix a bug where if there were multiple websocket
connections from a single user, then in case one connection
got removed during a broadcast, there was a possibility
that the other good connection might not get the event.
```
* Add interface for PreferencesHaveChanged hook
* Add context to preference-related methods of App
* Implement PreferencesHaveChanged
* Re-add missing "fmt" import
* Update minimum server version for the new hook
* Remove pointers to be consistent with other preference APIs
* Improves validation in getRolesByName endpoint
* Updates the max constant and fixes linter
* Adds a mechanism to split roles in chunks in the webapp client
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
We can have 2 types of threads open at the same time. One from
the thread view, and another from RHS.
We add another variable to distinguish between the 2 states.
In future, if we have the ability for more than 2 threads, then
we would need to track by threadID.
https://mattermost.atlassian.net/browse/MM-56071
```release-note
NONE
```
* updated go mod and sum files
* fixed var-naming errors in channels/app and channels/api4 dir
* Revert "updated go mod and sum files"
This reverts commit 088dd00a84.
* renamed a cost .
* [MM-55299] Make use of GenericStoreResult
Make use of GenericStoreResult in server/channels/app/notification.go
Introduce new result variables to workaround the IncompatibleAssign
error.
* [MM-55299] Make use of GenericStoreResult
Use GenericStoreResult for profiles, cmn properties, groups map.
Introduce new result variables for them to workaround IncompatibleAssign
error.
* Resolve merge conflict. Accept incoming master's change
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
Make use of Generic store result in channels/app/webhook.go.
Introduce new variable resultU (result user) to workaround incompatible
assign error (since generics have been introduced).
* Added materialized view migration
* Renamed mat view
* Added channel membership mat view and indexes
* Added channel membership mat view and indexes
* Added new index
* WIP
* Simplifying user reporting code
* Created app and API layer for cahnnel reporting, reporting refactoring in general
* New router
* Remobved channel reporting meanwhile
* Upodated autogenerated stuff
* Lint fix
* Fixed typo
* api vet
* i18n fix
* Fixed API vetting and removed channel reporting constants
* yaml
* removed app pagination tests
While loading a thread, we were unnecessarily re-counting the replies
for all posts in a thread even if they would be the same number.
While this is needed in other queries where the posts can be from different
threads or they can be random ids, but to load a single post thread, there
is no need to recompute it again and again.
Therefore, we use a CTE to precompute the replycount and then just plug in
the value in the subsequent query. This gives an improvement in the query
plan as well:
OLD:
```
explain (analyze, buffers) SELECT p.id, p.rootid, p.createat, (SELECT count(*) FROM Posts WHERE Posts.RootId = (CASE WHEN p.RootId = '' THEN p.Id ELSE p.RootId END) AND Posts.DeleteAt = 0) as ReplyC
ount FROM Posts p WHERE (p.Id = 'h3cer597jb8abbcbitpghpomua' OR p.RootId = 'h3cer597jb8abbcbitpghpomua') AND p.DeleteAt = 0;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on posts p (cost=45.39..1042149.61 rows=2748 width=49) (actual time=3.156..7906.215 rows=5353 loops=1)
Recheck Cond: (((id)::text = 'h3cer597jb8abbcbitpghpomua'::text) OR (((rootid)::text = 'h3cer597jb8abbcbitpghpomua'::text) AND (deleteat = 0)))
Filter: (deleteat = 0)
Heap Blocks: exact=5308
Buffers: shared hit=610244
-> BitmapOr (cost=45.39..45.39 rows=2748 width=0) (actual time=0.918..0.920 rows=0 loops=1)
Buffers: shared hit=47
-> Bitmap Index Scan on posts_pkey (cost=0.00..1.68 rows=1 width=0) (actual time=0.028..0.028 rows=1 loops=1)
Index Cond: ((id)::text = 'h3cer597jb8abbcbitpghpomua'::text)
Buffers: shared hit=4
-> Bitmap Index Scan on idx_posts_root_id_delete_at (cost=0.00..42.34 rows=2747 width=0) (actual time=0.889..0.890 rows=5352 loops=1)
Index Cond: (((rootid)::text = 'h3cer597jb8abbcbitpghpomua'::text) AND (deleteat = 0))
Buffers: shared hit=43
SubPlan 1
-> Aggregate (cost=378.10..378.11 rows=1 width=8) (actual time=1.474..1.474 rows=1 loops=5353)
Buffers: shared hit=604889
-> Index Only Scan using idx_posts_root_id_delete_at on posts (cost=0.57..343.85 rows=13699 width=0) (actual time=0.016..1.039 rows=5352 loops=5353)
Index Cond: ((rootid = (CASE WHEN ((p.rootid)::text = ''::text) THEN p.id ELSE p.rootid END)::text) AND (deleteat = 0))
Heap Fetches: 0
Buffers: shared hit=604889
Planning Time: 0.194 ms
Execution Time: 7906.846 ms
```
NEW:
```
explain analyze with replycount as (select count(*) as num from posts where rootid='h3cer597jb8abbcbitpghpomua' and deleteat=0)
select id, rootid, createat, replycount.num from posts, replycount where id='h3cer597jb8abbcbitpghpomua' or rootid='h3cer597jb8abbcbitpghpomua' and deleteat=0;
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=123.16..3215.48 rows=2748 width=49) (actual time=2.960..9.775 rows=5353 loops=1)
-> Aggregate (cost=77.78..77.79 rows=1 width=8) (actual time=1.455..1.456 rows=1 loops=1)
-> Index Only Scan using idx_posts_root_id_delete_at on posts posts_1 (cost=0.57..70.91 rows=2747 width=0) (actual time=0.056..1.145 rows=5352 loops=1)
Index Cond: ((rootid = 'h3cer597jb8abbcbitpghpomua'::text) AND (deleteat = 0))
Heap Fetches: 0
-> Bitmap Heap Scan on posts (cost=45.39..3110.20 rows=2748 width=41) (actual time=1.501..7.747 rows=5353 loops=1)
Recheck Cond: (((id)::text = 'h3cer597jb8abbcbitpghpomua'::text) OR (((rootid)::text = 'h3cer597jb8abbcbitpghpomua'::text) AND (deleteat = 0)))
Heap Blocks: exact=5308
-> BitmapOr (cost=45.39..45.39 rows=2748 width=0) (actual time=0.797..0.798 rows=0 loops=1)
-> Bitmap Index Scan on posts_pkey (cost=0.00..1.68 rows=1 width=0) (actual time=0.014..0.014 rows=1 loops=1)
Index Cond: ((id)::text = 'h3cer597jb8abbcbitpghpomua'::text)
-> Bitmap Index Scan on idx_posts_root_id_delete_at (cost=0.00..42.34 rows=2747 width=0) (actual time=0.782..0.782 rows=5352 loops=1)
Index Cond: (((rootid)::text = 'h3cer597jb8abbcbitpghpomua'::text) AND (deleteat = 0))
Planning Time: 0.220 ms
Execution Time: 10.052 ms
(15 rows)
```
Observe the `loops=5353` in the first query, and `loops=1` in the next.
https://mattermost.atlassian.net/browse/MM-55476
```release-note
Optimize createPost performance
```
Co-authored-by: Mattermost Build <build@mattermost.com>