Updated database structure, updated sqlite (don't use this source code, it may be changed)
This commit is contained in:
parent
43674c486f
commit
c6b1a3430b
File diff suppressed because it is too large
Load Diff
@ -107,9 +107,9 @@ extern "C" {
|
||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.8.4.1"
|
||||
#define SQLITE_VERSION_NUMBER 3008004
|
||||
#define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0"
|
||||
#define SQLITE_VERSION "3.8.6"
|
||||
#define SQLITE_VERSION_NUMBER 3008006
|
||||
#define SQLITE_SOURCE_ID "2014-08-15 11:46:33 9491ba7d738528f168657adb43a198238abde19e"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
@ -269,7 +269,7 @@ typedef sqlite_uint64 sqlite3_uint64;
|
||||
**
|
||||
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
|
||||
** for the [sqlite3] object.
|
||||
** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if
|
||||
** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
|
||||
** the [sqlite3] object is successfully destroyed and all associated
|
||||
** resources are deallocated.
|
||||
**
|
||||
@ -277,7 +277,7 @@ typedef sqlite_uint64 sqlite3_uint64;
|
||||
** statements or unfinished sqlite3_backup objects then sqlite3_close()
|
||||
** will leave the database connection open and return [SQLITE_BUSY].
|
||||
** ^If sqlite3_close_v2() is called with unfinalized prepared statements
|
||||
** and unfinished sqlite3_backups, then the database connection becomes
|
||||
** and/or unfinished sqlite3_backups, then the database connection becomes
|
||||
** an unusable "zombie" which will automatically be deallocated when the
|
||||
** last prepared statement is finalized or the last sqlite3_backup is
|
||||
** finished. The sqlite3_close_v2() interface is intended for use with
|
||||
@ -290,7 +290,7 @@ typedef sqlite_uint64 sqlite3_uint64;
|
||||
** with the [sqlite3] object prior to attempting to close the object. ^If
|
||||
** sqlite3_close_v2() is called on a [database connection] that still has
|
||||
** outstanding [prepared statements], [BLOB handles], and/or
|
||||
** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation
|
||||
** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
|
||||
** of resources is deferred until all [prepared statements], [BLOB handles],
|
||||
** and [sqlite3_backup] objects are also destroyed.
|
||||
**
|
||||
@ -386,16 +386,14 @@ SQLITE_API int sqlite3_exec(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Result Codes
|
||||
** KEYWORDS: SQLITE_OK {error code} {error codes}
|
||||
** KEYWORDS: {result code} {result codes}
|
||||
** KEYWORDS: {result code definitions}
|
||||
**
|
||||
** Many SQLite functions return an integer result code from the set shown
|
||||
** here in order to indicate success or failure.
|
||||
**
|
||||
** New error codes may be added in future versions of SQLite.
|
||||
**
|
||||
** See also: [SQLITE_IOERR_READ | extended result codes],
|
||||
** [sqlite3_vtab_on_conflict()] [SQLITE_ROLLBACK | result codes].
|
||||
** See also: [extended result code definitions]
|
||||
*/
|
||||
#define SQLITE_OK 0 /* Successful result */
|
||||
/* beginning-of-error-codes */
|
||||
@ -433,26 +431,19 @@ SQLITE_API int sqlite3_exec(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Extended Result Codes
|
||||
** KEYWORDS: {extended error code} {extended error codes}
|
||||
** KEYWORDS: {extended result code} {extended result codes}
|
||||
** KEYWORDS: {extended result code definitions}
|
||||
**
|
||||
** In its default configuration, SQLite API routines return one of 26 integer
|
||||
** [SQLITE_OK | result codes]. However, experience has shown that many of
|
||||
** In its default configuration, SQLite API routines return one of 30 integer
|
||||
** [result codes]. However, experience has shown that many of
|
||||
** these result codes are too coarse-grained. They do not provide as
|
||||
** much information about problems as programmers might like. In an effort to
|
||||
** address this, newer versions of SQLite (version 3.3.8 and later) include
|
||||
** support for additional result codes that provide more detailed information
|
||||
** about errors. The extended result codes are enabled or disabled
|
||||
** about errors. These [extended result codes] are enabled or disabled
|
||||
** on a per database connection basis using the
|
||||
** [sqlite3_extended_result_codes()] API.
|
||||
**
|
||||
** Some of the available extended result codes are listed here.
|
||||
** One may expect the number of extended result codes will increase
|
||||
** over time. Software that uses extended result codes should expect
|
||||
** to see new result codes in future releases of SQLite.
|
||||
**
|
||||
** The SQLITE_OK result code will never be extended. It will always
|
||||
** be exactly zero.
|
||||
** [sqlite3_extended_result_codes()] API. Or, the extended code for
|
||||
** the most recent error can be obtained using
|
||||
** [sqlite3_extended_errcode()].
|
||||
*/
|
||||
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
|
||||
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
|
||||
@ -560,7 +551,10 @@ SQLITE_API int sqlite3_exec(
|
||||
** file that were written at the application level might have changed
|
||||
** and that adjacent bytes, even bytes within the same sector are
|
||||
** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
|
||||
** flag indicate that a file cannot be deleted when open.
|
||||
** flag indicate that a file cannot be deleted when open. The
|
||||
** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
|
||||
** read-only media and cannot be changed even by processes with
|
||||
** elevated privileges.
|
||||
*/
|
||||
#define SQLITE_IOCAP_ATOMIC 0x00000001
|
||||
#define SQLITE_IOCAP_ATOMIC512 0x00000002
|
||||
@ -575,6 +569,7 @@ SQLITE_API int sqlite3_exec(
|
||||
#define SQLITE_IOCAP_SEQUENTIAL 0x00000400
|
||||
#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800
|
||||
#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
|
||||
#define SQLITE_IOCAP_IMMUTABLE 0x00002000
|
||||
|
||||
/*
|
||||
** CAPI3REF: File Locking Levels
|
||||
@ -681,7 +676,7 @@ struct sqlite3_file {
|
||||
** locking strategy (for example to use dot-file locks), to inquire
|
||||
** about the status of a lock, or to break stale locks. The SQLite
|
||||
** core reserves all opcodes less than 100 for its own use.
|
||||
** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available.
|
||||
** A [file control opcodes | list of opcodes] less than 100 is available.
|
||||
** Applications that define a custom xFileControl method should use opcodes
|
||||
** greater than 100 to avoid conflicts. VFS implementations should
|
||||
** return [SQLITE_NOTFOUND] for file control opcodes that they do not
|
||||
@ -754,6 +749,7 @@ struct sqlite3_io_methods {
|
||||
|
||||
/*
|
||||
** CAPI3REF: Standard File Control Opcodes
|
||||
** KEYWORDS: {file control opcodes} {file control opcode}
|
||||
**
|
||||
** These integer constants are opcodes for the xFileControl method
|
||||
** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
|
||||
@ -943,6 +939,12 @@ struct sqlite3_io_methods {
|
||||
** on whether or not the file has been renamed, moved, or deleted since it
|
||||
** was first opened.
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
|
||||
** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
|
||||
** opcode causes the xFileControl method to swap the file handle with the one
|
||||
** pointed to by the pArg argument. This capability is used during testing
|
||||
** and only needs to be supported when SQLITE_TEST is defined.
|
||||
**
|
||||
** </ul>
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
@ -966,6 +968,7 @@ struct sqlite3_io_methods {
|
||||
#define SQLITE_FCNTL_HAS_MOVED 20
|
||||
#define SQLITE_FCNTL_SYNC 21
|
||||
#define SQLITE_FCNTL_COMMIT_PHASETWO 22
|
||||
#define SQLITE_FCNTL_WIN32_SET_HANDLE 23
|
||||
|
||||
/*
|
||||
** CAPI3REF: Mutex Handle
|
||||
@ -2026,27 +2029,33 @@ SQLITE_API int sqlite3_complete16(const void *sql);
|
||||
/*
|
||||
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
|
||||
**
|
||||
** ^This routine sets a callback function that might be invoked whenever
|
||||
** an attempt is made to open a database table that another thread
|
||||
** or process has locked.
|
||||
** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
|
||||
** that might be invoked with argument P whenever
|
||||
** an attempt is made to access a database table associated with
|
||||
** [database connection] D when another thread
|
||||
** or process has the table locked.
|
||||
** The sqlite3_busy_handler() interface is used to implement
|
||||
** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout].
|
||||
**
|
||||
** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]
|
||||
** ^If the busy callback is NULL, then [SQLITE_BUSY]
|
||||
** is returned immediately upon encountering the lock. ^If the busy callback
|
||||
** is not NULL, then the callback might be invoked with two arguments.
|
||||
**
|
||||
** ^The first argument to the busy handler is a copy of the void* pointer which
|
||||
** is the third argument to sqlite3_busy_handler(). ^The second argument to
|
||||
** the busy handler callback is the number of times that the busy handler has
|
||||
** been invoked for this locking event. ^If the
|
||||
** been invoked for the same locking event. ^If the
|
||||
** busy callback returns 0, then no additional attempts are made to
|
||||
** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned.
|
||||
** access the database and [SQLITE_BUSY] is returned
|
||||
** to the application.
|
||||
** ^If the callback returns non-zero, then another attempt
|
||||
** is made to open the database for reading and the cycle repeats.
|
||||
** is made to access the database and the cycle repeats.
|
||||
**
|
||||
** The presence of a busy handler does not guarantee that it will be invoked
|
||||
** when there is lock contention. ^If SQLite determines that invoking the busy
|
||||
** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY]
|
||||
** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler.
|
||||
** to the application instead of invoking the
|
||||
** busy handler.
|
||||
** Consider a scenario where one process is holding a read lock that
|
||||
** it is trying to promote to a reserved lock and
|
||||
** a second process is holding a reserved lock that it is trying
|
||||
@ -2060,28 +2069,15 @@ SQLITE_API int sqlite3_complete16(const void *sql);
|
||||
**
|
||||
** ^The default busy callback is NULL.
|
||||
**
|
||||
** ^The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED]
|
||||
** when SQLite is in the middle of a large transaction where all the
|
||||
** changes will not fit into the in-memory cache. SQLite will
|
||||
** already hold a RESERVED lock on the database file, but it needs
|
||||
** to promote this lock to EXCLUSIVE so that it can spill cache
|
||||
** pages into the database file without harm to concurrent
|
||||
** readers. ^If it is unable to promote the lock, then the in-memory
|
||||
** cache will be left in an inconsistent state and so the error
|
||||
** code is promoted from the relatively benign [SQLITE_BUSY] to
|
||||
** the more severe [SQLITE_IOERR_BLOCKED]. ^This error code promotion
|
||||
** forces an automatic rollback of the changes. See the
|
||||
** <a href="/cvstrac/wiki?p=CorruptionFollowingBusyError">
|
||||
** CorruptionFollowingBusyError</a> wiki page for a discussion of why
|
||||
** this is important.
|
||||
**
|
||||
** ^(There can only be a single busy handler defined for each
|
||||
** [database connection]. Setting a new busy handler clears any
|
||||
** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()]
|
||||
** will also set or clear the busy handler.
|
||||
** or evaluating [PRAGMA busy_timeout=N] will change the
|
||||
** busy handler and thus clear any previously set busy handler.
|
||||
**
|
||||
** The busy callback should not take any actions which modify the
|
||||
** database connection that invoked the busy handler. Any such actions
|
||||
** database connection that invoked the busy handler. In other words,
|
||||
** the busy handler is not reentrant. Any such actions
|
||||
** result in undefined behavior.
|
||||
**
|
||||
** A busy handler must not close the database connection
|
||||
@ -2097,7 +2093,7 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
|
||||
** will sleep multiple times until at least "ms" milliseconds of sleeping
|
||||
** have accumulated. ^After at least "ms" milliseconds of sleeping,
|
||||
** the handler returns 0 which causes [sqlite3_step()] to return
|
||||
** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
|
||||
** [SQLITE_BUSY].
|
||||
**
|
||||
** ^Calling this routine with an argument less than or equal to zero
|
||||
** turns off all busy handlers.
|
||||
@ -2106,6 +2102,8 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
|
||||
** [database connection] any any given moment. If another busy handler
|
||||
** was defined (using [sqlite3_busy_handler()]) prior to calling
|
||||
** this routine, that other busy handler is cleared.)^
|
||||
**
|
||||
** See also: [PRAGMA busy_timeout]
|
||||
*/
|
||||
SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
|
||||
|
||||
@ -2507,8 +2505,8 @@ SQLITE_API int sqlite3_set_authorizer(
|
||||
** [sqlite3_set_authorizer | authorizer documentation] for additional
|
||||
** information.
|
||||
**
|
||||
** Note that SQLITE_IGNORE is also used as a [SQLITE_ROLLBACK | return code]
|
||||
** from the [sqlite3_vtab_on_conflict()] interface.
|
||||
** Note that SQLITE_IGNORE is also used as a [conflict resolution mode]
|
||||
** returned from the [sqlite3_vtab_on_conflict()] interface.
|
||||
*/
|
||||
#define SQLITE_DENY 1 /* Abort the SQL statement with an error */
|
||||
#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */
|
||||
@ -2779,6 +2777,30 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
|
||||
** ^If sqlite3_open_v2() is used and the "cache" parameter is present in
|
||||
** a URI filename, its value overrides any behavior requested by setting
|
||||
** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
|
||||
**
|
||||
** <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or
|
||||
** "1") or "false" (or "off" or "no" or "0") to indicate that the
|
||||
** [powersafe overwrite] property does or does not apply to the
|
||||
** storage media on which the database file resides. ^The psow query
|
||||
** parameter only works for the built-in unix and Windows VFSes.
|
||||
**
|
||||
** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
|
||||
** which if set disables file locking in rollback journal modes. This
|
||||
** is useful for accessing a database on a filesystem that does not
|
||||
** support locking. Caution: Database corruption might result if two
|
||||
** or more processes write to the same database and any one of those
|
||||
** processes uses nolock=1.
|
||||
**
|
||||
** <li> <b>immutable</b>: ^The immutable parameter is a boolean query
|
||||
** parameter that indicates that the database file is stored on
|
||||
** read-only media. ^When immutable is set, SQLite assumes that the
|
||||
** database file cannot be changed, even by a process with higher
|
||||
** privilege, and so the database is opened read-only and all locking
|
||||
** and change detection is disabled. Caution: Setting the immutable
|
||||
** property on a database file that does in fact change can result
|
||||
** in incorrect query results and/or [SQLITE_CORRUPT] errors.
|
||||
** See also: [SQLITE_IOCAP_IMMUTABLE].
|
||||
**
|
||||
** </ul>
|
||||
**
|
||||
** ^Specifying an unknown parameter in the query component of a URI is not an
|
||||
@ -2808,8 +2830,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
|
||||
** Open file "data.db" in the current directory for read-only access.
|
||||
** Regardless of whether or not shared-cache mode is enabled by
|
||||
** default, use a private cache.
|
||||
** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td>
|
||||
** Open file "/home/fred/data.db". Use the special VFS "unix-nolock".
|
||||
** <tr><td> file:/home/fred/data.db?vfs=unix-dotfile <td>
|
||||
** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile"
|
||||
** that uses dot-files in place of posix advisory locking.
|
||||
** <tr><td> file:data.db?mode=readonly <td>
|
||||
** An error. "readonly" is not a valid option for the "mode" parameter.
|
||||
** </table>
|
||||
@ -4670,6 +4693,13 @@ SQLITE_API int sqlite3_sleep(int);
|
||||
** is a NULL pointer, then SQLite performs a search for an appropriate
|
||||
** temporary file directory.
|
||||
**
|
||||
** Applications are strongly discouraged from using this global variable.
|
||||
** It is required to set a temporary folder on Windows Runtime (WinRT).
|
||||
** But for all other platforms, it is highly recommended that applications
|
||||
** neither read nor write this variable. This global variable is a relic
|
||||
** that exists for backwards compatibility of legacy applications and should
|
||||
** be avoided in new projects.
|
||||
**
|
||||
** It is not safe to read or modify this variable in more than one
|
||||
** thread at a time. It is not safe to read or modify this variable
|
||||
** if a [database connection] is being used at the same time in a separate
|
||||
@ -4688,6 +4718,11 @@ SQLITE_API int sqlite3_sleep(int);
|
||||
** Hence, if this variable is modified directly, either it should be
|
||||
** made NULL or made to point to memory obtained from [sqlite3_malloc]
|
||||
** or else the use of the [temp_store_directory pragma] should be avoided.
|
||||
** Except when requested by the [temp_store_directory pragma], SQLite
|
||||
** does not free the memory that sqlite3_temp_directory points to. If
|
||||
** the application wants that memory to be freed, it must do
|
||||
** so itself, taking care to only do so after all [database connection]
|
||||
** objects have been destroyed.
|
||||
**
|
||||
** <b>Note to Windows Runtime users:</b> The temporary directory must be set
|
||||
** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various
|
||||
@ -5822,10 +5857,12 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
|
||||
** <li> SQLITE_MUTEX_RECURSIVE
|
||||
** <li> SQLITE_MUTEX_STATIC_MASTER
|
||||
** <li> SQLITE_MUTEX_STATIC_MEM
|
||||
** <li> SQLITE_MUTEX_STATIC_MEM2
|
||||
** <li> SQLITE_MUTEX_STATIC_OPEN
|
||||
** <li> SQLITE_MUTEX_STATIC_PRNG
|
||||
** <li> SQLITE_MUTEX_STATIC_LRU
|
||||
** <li> SQLITE_MUTEX_STATIC_LRU2
|
||||
** <li> SQLITE_MUTEX_STATIC_PMEM
|
||||
** <li> SQLITE_MUTEX_STATIC_APP1
|
||||
** <li> SQLITE_MUTEX_STATIC_APP2
|
||||
** </ul>)^
|
||||
**
|
||||
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
|
||||
@ -6029,6 +6066,9 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
|
||||
#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
|
||||
#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */
|
||||
#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */
|
||||
#define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */
|
||||
#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */
|
||||
#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Retrieve the mutex for a database connection
|
||||
@ -6123,7 +6163,9 @@ SQLITE_API int sqlite3_test_control(int op, ...);
|
||||
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
|
||||
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
|
||||
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
|
||||
#define SQLITE_TESTCTRL_LAST 21
|
||||
#define SQLITE_TESTCTRL_BYTEORDER 22
|
||||
#define SQLITE_TESTCTRL_ISINIT 23
|
||||
#define SQLITE_TESTCTRL_LAST 23
|
||||
|
||||
/*
|
||||
** CAPI3REF: SQLite Runtime Status
|
||||
@ -7107,6 +7149,9 @@ SQLITE_API void *sqlite3_wal_hook(
|
||||
** ^The [wal_autocheckpoint pragma] can be used to invoke this interface
|
||||
** from SQL.
|
||||
**
|
||||
** ^Checkpoints initiated by this mechanism are
|
||||
** [sqlite3_wal_checkpoint_v2|PASSIVE].
|
||||
**
|
||||
** ^Every new [database connection] defaults to having the auto-checkpoint
|
||||
** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
|
||||
** pages. The use of this interface
|
||||
@ -7123,6 +7168,10 @@ SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
|
||||
** empty string, then a checkpoint is run on all databases of
|
||||
** connection D. ^If the database connection D is not in
|
||||
** [WAL | write-ahead log mode] then this interface is a harmless no-op.
|
||||
** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a
|
||||
** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint.
|
||||
** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL
|
||||
** or RESET checkpoint.
|
||||
**
|
||||
** ^The [wal_checkpoint pragma] can be used to invoke this interface
|
||||
** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the
|
||||
@ -7145,10 +7194,12 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
|
||||
** Checkpoint as many frames as possible without waiting for any database
|
||||
** readers or writers to finish. Sync the db file if all frames in the log
|
||||
** are checkpointed. This mode is the same as calling
|
||||
** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked.
|
||||
** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback]
|
||||
** is never invoked.
|
||||
**
|
||||
** <dt>SQLITE_CHECKPOINT_FULL<dd>
|
||||
** This mode blocks (calls the busy-handler callback) until there is no
|
||||
** This mode blocks (it invokes the
|
||||
** [sqlite3_busy_handler|busy-handler callback]) until there is no
|
||||
** database writer and all readers are reading from the most recent database
|
||||
** snapshot. It then checkpoints all frames in the log file and syncs the
|
||||
** database file. This call blocks database writers while it is running,
|
||||
@ -7156,7 +7207,8 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
|
||||
**
|
||||
** <dt>SQLITE_CHECKPOINT_RESTART<dd>
|
||||
** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after
|
||||
** checkpointing the log file it blocks (calls the busy-handler callback)
|
||||
** checkpointing the log file it blocks (calls the
|
||||
** [sqlite3_busy_handler|busy-handler callback])
|
||||
** until all readers are reading from the database file only. This ensures
|
||||
** that the next client to write to the database file restarts the log file
|
||||
** from the beginning. This call blocks database writers while it is running,
|
||||
@ -7294,6 +7346,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Conflict resolution modes
|
||||
** KEYWORDS: {conflict resolution mode}
|
||||
**
|
||||
** These constants are returned by [sqlite3_vtab_on_conflict()] to
|
||||
** inform a [virtual table] implementation what the [ON CONFLICT] mode
|
||||
@ -7346,6 +7399,16 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
|
||||
typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
|
||||
|
||||
/* The double-precision datatype used by RTree depends on the
|
||||
** SQLITE_RTREE_INT_ONLY compile-time option.
|
||||
*/
|
||||
#ifdef SQLITE_RTREE_INT_ONLY
|
||||
typedef sqlite3_int64 sqlite3_rtree_dbl;
|
||||
#else
|
||||
typedef double sqlite3_rtree_dbl;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Register a geometry callback named zGeom that can be used as part of an
|
||||
@ -7356,11 +7419,7 @@ typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
|
||||
SQLITE_API int sqlite3_rtree_geometry_callback(
|
||||
sqlite3 *db,
|
||||
const char *zGeom,
|
||||
#ifdef SQLITE_RTREE_INT_ONLY
|
||||
int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes),
|
||||
#else
|
||||
int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes),
|
||||
#endif
|
||||
int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
|
||||
void *pContext
|
||||
);
|
||||
|
||||
@ -7372,11 +7431,60 @@ SQLITE_API int sqlite3_rtree_geometry_callback(
|
||||
struct sqlite3_rtree_geometry {
|
||||
void *pContext; /* Copy of pContext passed to s_r_g_c() */
|
||||
int nParam; /* Size of array aParam[] */
|
||||
double *aParam; /* Parameters passed to SQL geom function */
|
||||
sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */
|
||||
void *pUser; /* Callback implementation user data */
|
||||
void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */
|
||||
};
|
||||
|
||||
/*
|
||||
** Register a 2nd-generation geometry callback named zScore that can be
|
||||
** used as part of an R-Tree geometry query as follows:
|
||||
**
|
||||
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
|
||||
*/
|
||||
SQLITE_API int sqlite3_rtree_query_callback(
|
||||
sqlite3 *db,
|
||||
const char *zQueryFunc,
|
||||
int (*xQueryFunc)(sqlite3_rtree_query_info*),
|
||||
void *pContext,
|
||||
void (*xDestructor)(void*)
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
** A pointer to a structure of the following type is passed as the
|
||||
** argument to scored geometry callback registered using
|
||||
** sqlite3_rtree_query_callback().
|
||||
**
|
||||
** Note that the first 5 fields of this structure are identical to
|
||||
** sqlite3_rtree_geometry. This structure is a subclass of
|
||||
** sqlite3_rtree_geometry.
|
||||
*/
|
||||
struct sqlite3_rtree_query_info {
|
||||
void *pContext; /* pContext from when function registered */
|
||||
int nParam; /* Number of function parameters */
|
||||
sqlite3_rtree_dbl *aParam; /* value of function parameters */
|
||||
void *pUser; /* callback can use this, if desired */
|
||||
void (*xDelUser)(void*); /* function to free pUser */
|
||||
sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */
|
||||
unsigned int *anQueue; /* Number of pending entries in the queue */
|
||||
int nCoord; /* Number of coordinates */
|
||||
int iLevel; /* Level of current node or entry */
|
||||
int mxLevel; /* The largest iLevel value in the tree */
|
||||
sqlite3_int64 iRowid; /* Rowid for current entry */
|
||||
sqlite3_rtree_dbl rParentScore; /* Score of parent node */
|
||||
int eParentWithin; /* Visibility of parent node */
|
||||
int eWithin; /* OUT: Visiblity */
|
||||
sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
|
||||
};
|
||||
|
||||
/*
|
||||
** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin.
|
||||
*/
|
||||
#define NOT_WITHIN 0 /* Object completely outside of query region */
|
||||
#define PARTLY_WITHIN 1 /* Object partially overlaps query region */
|
||||
#define FULLY_WITHIN 2 /* Object fully contained within query region */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of the 'extern "C"' block */
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -236,7 +236,7 @@ public class ContactsController {
|
||||
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
|
||||
|
||||
HashMap<String, Contact> shortContacts = new HashMap<String, Contact>();
|
||||
String ids = "";
|
||||
StringBuilder ids = new StringBuilder();
|
||||
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projectionPhones, null, null, null);
|
||||
if (pCur != null) {
|
||||
if (pCur.getCount() > 0) {
|
||||
@ -262,9 +262,9 @@ public class ContactsController {
|
||||
|
||||
Integer id = pCur.getInt(0);
|
||||
if (ids.length() != 0) {
|
||||
ids += ",";
|
||||
ids.append(",");
|
||||
}
|
||||
ids += id;
|
||||
ids.append(id);
|
||||
|
||||
int type = pCur.getInt(2);
|
||||
Contact contact = contactsMap.get(id);
|
||||
@ -299,7 +299,7 @@ public class ContactsController {
|
||||
pCur.close();
|
||||
}
|
||||
|
||||
pCur = cr.query(ContactsContract.Data.CONTENT_URI, projectionNames, ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " IN (" + ids + ") AND " + ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'", null, null);
|
||||
pCur = cr.query(ContactsContract.Data.CONTENT_URI, projectionNames, ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " IN (" + ids.toString() + ") AND " + ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'", null, null);
|
||||
if (pCur != null && pCur.getCount() > 0) {
|
||||
while (pCur.moveToNext()) {
|
||||
int id = pCur.getInt(0);
|
||||
@ -844,14 +844,14 @@ public class ContactsController {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
String ids = "";
|
||||
StringBuilder ids = new StringBuilder();
|
||||
for (TLRPC.TL_contact aContactsArr : contactsArr) {
|
||||
if (ids.length() != 0) {
|
||||
ids += ",";
|
||||
ids.append(",");
|
||||
}
|
||||
ids += aContactsArr.user_id;
|
||||
ids.append(aContactsArr.user_id);
|
||||
}
|
||||
UserConfig.contactsHash = Utilities.MD5(ids);
|
||||
UserConfig.contactsHash = Utilities.MD5(ids.toString());
|
||||
UserConfig.saveConfig(false);
|
||||
}
|
||||
|
||||
@ -1084,7 +1084,7 @@ public class ContactsController {
|
||||
});
|
||||
}
|
||||
|
||||
String ids = "";
|
||||
StringBuilder ids = new StringBuilder();
|
||||
final HashMap<String, ArrayList<TLRPC.TL_contact>> sectionsDict = new HashMap<String, ArrayList<TLRPC.TL_contact>>();
|
||||
final ArrayList<String> sortedSectionsArray = new ArrayList<String>();
|
||||
|
||||
@ -1114,11 +1114,11 @@ public class ContactsController {
|
||||
}
|
||||
arr.add(value);
|
||||
if (ids.length() != 0) {
|
||||
ids += ",";
|
||||
ids.append(",");
|
||||
}
|
||||
ids += value.user_id;
|
||||
ids.append(value.user_id);
|
||||
}
|
||||
UserConfig.contactsHash = Utilities.MD5(ids);
|
||||
UserConfig.contactsHash = Utilities.MD5(ids.toString());
|
||||
UserConfig.saveConfig(false);
|
||||
|
||||
Collections.sort(sortedSectionsArray, new Comparator<String>() {
|
||||
@ -1189,8 +1189,8 @@ public class ContactsController {
|
||||
}
|
||||
FileLog.e("tmessages", "process update - contacts add = " + newC.size() + " delete = " + contactsTD.size());
|
||||
|
||||
String toAdd = "";
|
||||
String toDelete = "";
|
||||
StringBuilder toAdd = new StringBuilder();
|
||||
StringBuilder toDelete = new StringBuilder();
|
||||
boolean reloadContacts = false;
|
||||
|
||||
for (TLRPC.TL_contact newContact : newC) {
|
||||
@ -1216,9 +1216,9 @@ public class ContactsController {
|
||||
}
|
||||
}
|
||||
if (toAdd.length() != 0) {
|
||||
toAdd += ",";
|
||||
toAdd.append(",");
|
||||
}
|
||||
toAdd += user.phone;
|
||||
toAdd.append(user.phone);
|
||||
}
|
||||
|
||||
for (final Integer uid : contactsTD) {
|
||||
@ -1252,14 +1252,14 @@ public class ContactsController {
|
||||
}
|
||||
}
|
||||
if (toDelete.length() != 0) {
|
||||
toDelete += ",";
|
||||
toDelete.append(",");
|
||||
}
|
||||
toDelete += user.phone;
|
||||
toDelete.append(user.phone);
|
||||
}
|
||||
}
|
||||
|
||||
if (toAdd.length() != 0 || toDelete.length() != 0) {
|
||||
MessagesStorage.getInstance().applyPhoneBookUpdates(toAdd, toDelete);
|
||||
MessagesStorage.getInstance().applyPhoneBookUpdates(toAdd.toString(), toDelete.toString());
|
||||
}
|
||||
|
||||
if (reloadContacts) {
|
||||
|
@ -69,7 +69,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
|
||||
private boolean gettingNewDeleteTask = false;
|
||||
private int currentDeletingTaskTime = 0;
|
||||
private Long currentDeletingTask = null;
|
||||
private ArrayList<Integer> currentDeletingTaskMids = null;
|
||||
|
||||
public int totalDialogsCount = 0;
|
||||
@ -322,7 +321,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
currentDeletingTaskTime = 0;
|
||||
currentDeletingTaskMids = null;
|
||||
gettingNewDeleteTask = false;
|
||||
currentDeletingTask = null;
|
||||
loadingDialogs = false;
|
||||
dialogsEndReached = false;
|
||||
gettingDifference = false;
|
||||
@ -508,14 +506,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentDeletingTask == null && !gettingNewDeleteTask || currentDeletingTaskTime != 0 && minDate < currentDeletingTaskTime) {
|
||||
if (currentDeletingTaskMids == null && !gettingNewDeleteTask || currentDeletingTaskTime != 0 && minDate < currentDeletingTaskTime) {
|
||||
getNewDeleteTask(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void getNewDeleteTask(final Long oldTask) {
|
||||
public void getNewDeleteTask(final ArrayList<Integer> oldTask) {
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -528,7 +526,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
private void checkDeletingTask() {
|
||||
int currentServerTime = ConnectionsManager.getInstance().getCurrentTime();
|
||||
|
||||
if (currentDeletingTask != null && currentDeletingTaskTime != 0 && currentDeletingTaskTime <= currentServerTime) {
|
||||
if (currentDeletingTaskMids != null && currentDeletingTaskTime != 0 && currentDeletingTaskTime <= currentServerTime) {
|
||||
currentDeletingTaskTime = 0;
|
||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||
@Override
|
||||
@ -538,9 +536,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getNewDeleteTask(currentDeletingTask);
|
||||
getNewDeleteTask(currentDeletingTaskMids);
|
||||
currentDeletingTaskTime = 0;
|
||||
currentDeletingTask = null;
|
||||
currentDeletingTaskMids = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -548,20 +546,18 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
}
|
||||
}
|
||||
|
||||
public void processLoadedDeleteTask(final Long taskId, final int taskTime, final ArrayList<Integer> messages) {
|
||||
public void processLoadedDeleteTask(final int taskTime, final ArrayList<Integer> messages) {
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
gettingNewDeleteTask = false;
|
||||
if (taskId != null) {
|
||||
if (messages != null) {
|
||||
currentDeletingTaskTime = taskTime;
|
||||
currentDeletingTask = taskId;
|
||||
currentDeletingTaskMids = messages;
|
||||
|
||||
checkDeletingTask();
|
||||
} else {
|
||||
currentDeletingTaskTime = 0;
|
||||
currentDeletingTask = null;
|
||||
currentDeletingTaskMids = null;
|
||||
}
|
||||
}
|
||||
@ -1275,10 +1271,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
}
|
||||
}
|
||||
|
||||
public void loadMessages(final long dialog_id, final int count, final int max_id, boolean fromCache, int midDate, final int classGuid, boolean from_unread, boolean forward) {
|
||||
public void loadMessages(final long dialog_id, final int count, final int max_id, boolean fromCache, int midDate, final int classGuid, boolean from_unread, boolean forward, final Semaphore semaphore) {
|
||||
int lower_part = (int)dialog_id;
|
||||
if (fromCache || lower_part == 0) {
|
||||
MessagesStorage.getInstance().getMessages(dialog_id, count, max_id, midDate, classGuid, from_unread, forward);
|
||||
MessagesStorage.getInstance().getMessages(dialog_id, count, max_id, midDate, classGuid, from_unread, forward, semaphore);
|
||||
} else {
|
||||
TLRPC.TL_messages_getHistory req = new TLRPC.TL_messages_getHistory();
|
||||
if (lower_part < 0) {
|
||||
@ -1303,7 +1299,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
if (error == null) {
|
||||
final TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
|
||||
processLoadedMessages(res, dialog_id, count, max_id, false, classGuid, 0, 0, 0, 0, false);
|
||||
processLoadedMessages(res, dialog_id, count, max_id, false, classGuid, 0, 0, 0, 0, false, semaphore);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1311,7 +1307,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
}
|
||||
}
|
||||
|
||||
public void processLoadedMessages(final TLRPC.messages_Messages messagesRes, final long dialog_id, final int count, final int max_id, final boolean isCache, final int classGuid, final int first_unread, final int last_unread, final int unread_count, final int last_date, final boolean isForward) {
|
||||
public void processLoadedMessages(final TLRPC.messages_Messages messagesRes, final long dialog_id, final int count, final int max_id, final boolean isCache, final int classGuid, final int first_unread, final int last_unread, final int unread_count, final int last_date, final boolean isForward, final Semaphore semaphore) {
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -1320,10 +1316,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
MessagesStorage.getInstance().putMessages(messagesRes, dialog_id);
|
||||
}
|
||||
if (lower_id != 0 && isCache && messagesRes.messages.size() == 0 && !isForward) {
|
||||
if (semaphore != null) {
|
||||
semaphore.release();
|
||||
}
|
||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
loadMessages(dialog_id, count, max_id, false, 0, classGuid, false, false);
|
||||
loadMessages(dialog_id, count, max_id, false, 0, classGuid, false, false, null);
|
||||
}
|
||||
});
|
||||
return;
|
||||
@ -1337,14 +1336,21 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
message.dialog_id = dialog_id;
|
||||
objects.add(new MessageObject(message, usersLocal, 2));
|
||||
}
|
||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
putUsers(messagesRes.users, isCache);
|
||||
putChats(messagesRes.chats, isCache);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesDidLoaded, dialog_id, count, objects, isCache, first_unread, last_unread, unread_count, last_date, isForward);
|
||||
}
|
||||
});
|
||||
if (semaphore != null) {
|
||||
putUsers(messagesRes.users, isCache);
|
||||
putChats(messagesRes.chats, isCache);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesDidLoaded, dialog_id, count, objects, isCache, first_unread, last_unread, unread_count, last_date, isForward);
|
||||
semaphore.release();
|
||||
} else {
|
||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
putUsers(messagesRes.users, isCache);
|
||||
putChats(messagesRes.chats, isCache);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesDidLoaded, dialog_id, count, objects, isCache, first_unread, last_unread, unread_count, last_date, isForward);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ package org.telegram.android;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import org.telegram.PhoneFormat.PhoneFormat;
|
||||
@ -90,7 +91,7 @@ public class MessagesStorage {
|
||||
database.executeFast("PRAGMA temp_store = 1").stepThis().dispose();
|
||||
if (createTable) {
|
||||
database.executeFast("CREATE TABLE users(uid INTEGER PRIMARY KEY, name TEXT, status INTEGER, data BLOB)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE messages(mid INTEGER PRIMARY KEY, uid INTEGER, read_state INTEGER, send_state INTEGER, date INTEGER, data BLOB, out INTEGER, ttl INTEGER)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE messages(mid INTEGER PRIMARY KEY, uid INTEGER, read_state INTEGER, send_state INTEGER, date INTEGER, data BLOB, out INTEGER, ttl INTEGER, media INTEGER)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE chats(uid INTEGER PRIMARY KEY, name TEXT, data BLOB)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE enc_chats(uid INTEGER PRIMARY KEY, user INTEGER, name TEXT, data BLOB, g BLOB, authkey BLOB, ttl INTEGER)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE dialogs(did INTEGER PRIMARY KEY, date INTEGER, unread_count INTEGER, last_mid INTEGER)").stepThis().dispose();
|
||||
@ -101,7 +102,7 @@ public class MessagesStorage {
|
||||
database.executeFast("CREATE TABLE media_counts(uid INTEGER PRIMARY KEY, count INTEGER)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE wallpapers(uid INTEGER PRIMARY KEY, data BLOB)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE randoms(random_id INTEGER PRIMARY KEY, mid INTEGER)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE enc_tasks(date INTEGER, data BLOB)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE enc_tasks_v2(mid INTEGER PRIMARY KEY, date INTEGER)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE params(id INTEGER PRIMARY KEY, seq INTEGER, pts INTEGER, date INTEGER, qts INTEGER, lsv INTEGER, sg INTEGER, pbytes BLOB)").stepThis().dispose();
|
||||
database.executeFast("INSERT INTO params VALUES(1, 0, 0, 0, 0, 0, 0, NULL)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE user_photos(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose();
|
||||
@ -122,7 +123,7 @@ public class MessagesStorage {
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS sphone_deleted_idx_user_phones ON user_phones_v6(sphone, deleted);").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_dialogs ON dialogs(date);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_enc_tasks ON enc_tasks(date);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_enc_tasks_v2 ON enc_tasks_v2(date);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS last_mid_idx_dialogs ON dialogs(last_mid);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS unread_count_idx_dialogs ON dialogs(unread_count);").stepThis().dispose();
|
||||
|
||||
@ -135,7 +136,7 @@ public class MessagesStorage {
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS mid_out_idx_messages ON messages(mid, out);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS task_idx_messages ON messages(uid, out, read_state, ttl, date, send_state);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_messages ON messages(mid, send_state, date) WHERE mid < 0 AND send_state = 1;").stepThis().dispose();
|
||||
database.executeFast("PRAGMA user_version = 4").stepThis().dispose();
|
||||
database.executeFast("PRAGMA user_version = 6").stepThis().dispose();
|
||||
} else {
|
||||
try {
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT seq, pts, date, qts, lsv, sg, pbytes FROM params WHERE id = 1");
|
||||
@ -167,8 +168,8 @@ public class MessagesStorage {
|
||||
}
|
||||
|
||||
int version = database.executeInt("PRAGMA user_version");
|
||||
if (version < 4) {
|
||||
updateDbToVersion4();
|
||||
if (version < 6) {
|
||||
updateDbToLastVersion(version);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -177,82 +178,113 @@ public class MessagesStorage {
|
||||
loadUnreadMessages();
|
||||
}
|
||||
|
||||
public void updateDbToVersion4() {
|
||||
public void updateDbToLastVersion(final int currentVersion) {
|
||||
storageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS user_photos(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose();
|
||||
if (currentVersion < 4) {
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS user_photos(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS mid_idx_media ON media(mid);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_mid_idx_media ON media(uid, date, mid);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS mid_idx_media ON media(mid);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_mid_idx_media ON media(uid, date, mid);").stepThis().dispose();
|
||||
|
||||
database.executeFast("DROP INDEX IF EXISTS read_state_out_idx_messages;").stepThis().dispose();
|
||||
database.executeFast("DROP INDEX IF EXISTS ttl_idx_messages;").stepThis().dispose();
|
||||
database.executeFast("DROP INDEX IF EXISTS date_idx_messages;").stepThis().dispose();
|
||||
database.executeFast("DROP INDEX IF EXISTS read_state_out_idx_messages;").stepThis().dispose();
|
||||
database.executeFast("DROP INDEX IF EXISTS ttl_idx_messages;").stepThis().dispose();
|
||||
database.executeFast("DROP INDEX IF EXISTS date_idx_messages;").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS mid_out_idx_messages ON messages(mid, out);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS task_idx_messages ON messages(uid, out, read_state, ttl, date, send_state);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_mid_idx_messages ON messages(uid, date, mid);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS mid_out_idx_messages ON messages(mid, out);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS task_idx_messages ON messages(uid, out, read_state, ttl, date, send_state);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_mid_idx_messages ON messages(uid, date, mid);").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS user_contacts_v6(uid INTEGER PRIMARY KEY, fname TEXT, sname TEXT)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS user_phones_v6(uid INTEGER, phone TEXT, sphone TEXT, deleted INTEGER, PRIMARY KEY (uid, phone))").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS sphone_deleted_idx_user_phones ON user_phones_v6(sphone, deleted);").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS user_contacts_v6(uid INTEGER PRIMARY KEY, fname TEXT, sname TEXT)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS user_phones_v6(uid INTEGER, phone TEXT, sphone TEXT, deleted INTEGER, PRIMARY KEY (uid, phone))").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS sphone_deleted_idx_user_phones ON user_phones_v6(sphone, deleted);").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS mid_idx_randoms ON randoms(mid);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS mid_idx_randoms ON randoms(mid);").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS sent_files_v2(uid TEXT, type INTEGER, data BLOB, PRIMARY KEY (uid, type))").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS sent_files_v2(uid TEXT, type INTEGER, data BLOB, PRIMARY KEY (uid, type))").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS blocked_users(uid INTEGER PRIMARY KEY)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS blocked_users(uid INTEGER PRIMARY KEY)").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS download_queue(uid INTEGER, type INTEGER, date INTEGER, data BLOB, PRIMARY KEY (uid, type));").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS type_date_idx_download_queue ON download_queue(type, date);").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS download_queue(uid INTEGER, type INTEGER, date INTEGER, data BLOB, PRIMARY KEY (uid, type));").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS type_date_idx_download_queue ON download_queue(type, date);").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS dialog_settings(did INTEGER PRIMARY KEY, flags INTEGER);").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS dialog_settings(did INTEGER PRIMARY KEY, flags INTEGER);").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_messages ON messages(mid, send_state, date) WHERE mid < 0 AND send_state = 1;").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_messages ON messages(mid, send_state, date) WHERE mid < 0 AND send_state = 1;").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS unread_count_idx_dialogs ON dialogs(unread_count);").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS unread_count_idx_dialogs ON dialogs(unread_count);").stepThis().dispose();
|
||||
|
||||
database.executeFast("UPDATE messages SET send_state = 2 WHERE mid < 0 AND send_state = 1").stepThis().dispose();
|
||||
database.executeFast("UPDATE messages SET send_state = 2 WHERE mid < 0 AND send_state = 1").stepThis().dispose();
|
||||
|
||||
database.executeFast("PRAGMA user_version = 4").stepThis().dispose();
|
||||
storageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ArrayList<Integer> ids = new ArrayList<Integer>();
|
||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
|
||||
Map<String, ?> values = preferences.getAll();
|
||||
for (Map.Entry<String, ?> entry : values.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (key.startsWith("notify2_")) {
|
||||
Integer value = (Integer)entry.getValue();
|
||||
if (value == 2) {
|
||||
key = key.replace("notify2_", "");
|
||||
try {
|
||||
ids.add(Integer.parseInt(key));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
storageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ArrayList<Integer> ids = new ArrayList<Integer>();
|
||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
|
||||
Map<String, ?> values = preferences.getAll();
|
||||
for (Map.Entry<String, ?> entry : values.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (key.startsWith("notify2_")) {
|
||||
Integer value = (Integer) entry.getValue();
|
||||
if (value == 2) {
|
||||
key = key.replace("notify2_", "");
|
||||
try {
|
||||
ids.add(Integer.parseInt(key));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
database.beginTransaction();
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO dialog_settings VALUES(?, ?)");
|
||||
for (Integer id : ids) {
|
||||
state.requery();
|
||||
state.bindLong(1, id);
|
||||
state.bindInteger(2, 1);
|
||||
state.step();
|
||||
}
|
||||
state.dispose();
|
||||
database.commitTransaction();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
database.beginTransaction();
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO dialog_settings VALUES(?, ?)");
|
||||
for (Integer id : ids) {
|
||||
});
|
||||
}
|
||||
if (currentVersion < 6) {
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS enc_tasks_v2(mid INTEGER PRIMARY KEY, date INTEGER)").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_enc_tasks_v2 ON enc_tasks_v2(date);").stepThis().dispose();
|
||||
database.beginTransaction();
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT date, data FROM enc_tasks WHERE 1");
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO enc_tasks_v2 VALUES(?, ?)");
|
||||
if (cursor.next()) {
|
||||
int date = cursor.intValue(0);
|
||||
int length = 0;
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(1));
|
||||
if ((length = cursor.byteBufferValue(1, data.buffer)) != 0) {
|
||||
for (int a = 0; a < length / 4; a++) {
|
||||
state.requery();
|
||||
state.bindLong(1, id);
|
||||
state.bindInteger(2, 1);
|
||||
state.bindInteger(1, data.readInt32());
|
||||
state.bindInteger(2, date);
|
||||
state.step();
|
||||
}
|
||||
state.dispose();
|
||||
database.commitTransaction();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
buffersStorage.reuseFreeBuffer(data);
|
||||
}
|
||||
});
|
||||
state.dispose();
|
||||
cursor.dispose();
|
||||
database.commitTransaction();
|
||||
|
||||
database.executeFast("DROP INDEX IF EXISTS date_idx_enc_tasks;").stepThis().dispose();
|
||||
database.executeFast("DROP TABLE IF EXISTS enc_tasks;").stepThis().dispose();
|
||||
|
||||
database.executeFast("ALTER TABLE messages ADD COLUMN media INTEGER").stepThis().dispose();
|
||||
database.executeFast("PRAGMA user_version = 6").stepThis().dispose();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
@ -368,16 +400,16 @@ public class MessagesStorage {
|
||||
try {
|
||||
final HashMap<Long, Integer> pushDialogs = new HashMap<Long, Integer>();
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT d.did, d.unread_count, s.flags FROM dialogs as d LEFT JOIN dialog_settings as s ON d.did = s.did WHERE d.unread_count != 0");
|
||||
String ids = "";
|
||||
StringBuilder ids = new StringBuilder();
|
||||
while (cursor.next()) {
|
||||
if (cursor.isNull(2) || cursor.intValue(2) != 1) {
|
||||
long did = cursor.longValue(0);
|
||||
int count = cursor.intValue(1);
|
||||
pushDialogs.put(did, count);
|
||||
if (ids.length() != 0) {
|
||||
ids += ",";
|
||||
ids.append(",");
|
||||
}
|
||||
ids += did;
|
||||
ids.append(did);
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
@ -391,7 +423,7 @@ public class MessagesStorage {
|
||||
ArrayList<Integer> chatIds = new ArrayList<Integer>();
|
||||
ArrayList<Integer> encryptedChatIds = new ArrayList<Integer>();
|
||||
|
||||
cursor = database.queryFinalized("SELECT read_state, data, send_state, mid, date, uid FROM messages WHERE uid IN (" + ids + ") AND out = 0 AND read_state = 0 ORDER BY date DESC LIMIT 50");
|
||||
cursor = database.queryFinalized("SELECT read_state, data, send_state, mid, date, uid FROM messages WHERE uid IN (" + ids.toString() + ") AND out = 0 AND read_state = 0 ORDER BY date DESC LIMIT 50");
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(1));
|
||||
if (data != null && cursor.byteBufferValue(1, data.buffer) != 0) {
|
||||
@ -449,14 +481,8 @@ public class MessagesStorage {
|
||||
}
|
||||
cursor.dispose();
|
||||
|
||||
String stringToLoad = "";
|
||||
if (!encryptedChatIds.isEmpty()) {
|
||||
for (int uid : encryptedChatIds) {
|
||||
if (stringToLoad.length() != 0) {
|
||||
stringToLoad += ",";
|
||||
}
|
||||
stringToLoad += uid;
|
||||
}
|
||||
String stringToLoad = TextUtils.join(",", encryptedChatIds);
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl FROM enc_chats WHERE uid IN(%s)", stringToLoad));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
@ -477,13 +503,7 @@ public class MessagesStorage {
|
||||
}
|
||||
|
||||
if (!userIds.isEmpty()) {
|
||||
stringToLoad = "";
|
||||
for (Integer uid : userIds) {
|
||||
if (stringToLoad.length() != 0) {
|
||||
stringToLoad += ",";
|
||||
}
|
||||
stringToLoad += uid;
|
||||
}
|
||||
String stringToLoad = TextUtils.join(",", userIds);
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", stringToLoad));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
@ -500,13 +520,7 @@ public class MessagesStorage {
|
||||
}
|
||||
|
||||
if (!chatIds.isEmpty()) {
|
||||
stringToLoad = "";
|
||||
for (Integer cid : chatIds) {
|
||||
if (stringToLoad.length() != 0) {
|
||||
stringToLoad += ",";
|
||||
}
|
||||
stringToLoad += cid;
|
||||
}
|
||||
String stringToLoad = TextUtils.join(",", chatIds);
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM chats WHERE uid IN(%s)", stringToLoad));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
@ -593,19 +607,19 @@ public class MessagesStorage {
|
||||
ArrayList<Integer> ids = new ArrayList<Integer>();
|
||||
ArrayList<TLRPC.User> users = new ArrayList<TLRPC.User>();
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM blocked_users WHERE 1"));
|
||||
String usersToLoad = "";
|
||||
StringBuilder usersToLoad = new StringBuilder();
|
||||
while (cursor.next()) {
|
||||
int user_id = cursor.intValue(0);
|
||||
ids.add(user_id);
|
||||
if (usersToLoad.length() != 0) {
|
||||
usersToLoad += ",";
|
||||
usersToLoad.append(",");
|
||||
}
|
||||
usersToLoad += user_id;
|
||||
usersToLoad.append(user_id);
|
||||
}
|
||||
cursor.dispose();
|
||||
|
||||
if (usersToLoad.length() != 0) {
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", usersToLoad));
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", usersToLoad.toString()));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
|
||||
@ -793,34 +807,28 @@ public class MessagesStorage {
|
||||
});
|
||||
}
|
||||
|
||||
public void getNewTask(final Long oldTask) {
|
||||
public void getNewTask(final ArrayList<Integer> oldTask) {
|
||||
storageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (oldTask != null) {
|
||||
database.executeFast("DELETE FROM enc_tasks WHERE rowid = " + oldTask).stepThis().dispose();
|
||||
String ids = TextUtils.join(",", oldTask);
|
||||
database.executeFast(String.format(Locale.US, "DELETE FROM enc_tasks_v2 WHERE mid IN(%s)", ids)).stepThis().dispose();
|
||||
}
|
||||
Long taskId = null;
|
||||
int date = 0;
|
||||
ArrayList<Integer> arr = null;
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT rowid, date, data FROM enc_tasks ORDER BY date ASC LIMIT 1");
|
||||
if (cursor.next()) {
|
||||
taskId = cursor.longValue(0);
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT mid, date FROM enc_tasks_v2 WHERE date = (SELECT min(date) FROM enc_tasks_v2)");
|
||||
while (cursor.next()) {
|
||||
Integer mid = cursor.intValue(0);
|
||||
date = cursor.intValue(1);
|
||||
|
||||
int length = 0;
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(2));
|
||||
if ((length = cursor.byteBufferValue(2, data.buffer)) != 0) {
|
||||
if (arr == null) {
|
||||
arr = new ArrayList<Integer>();
|
||||
for (int a = 0; a < length / 4; a++) {
|
||||
arr.add(data.readInt32());
|
||||
}
|
||||
}
|
||||
buffersStorage.reuseFreeBuffer(data);
|
||||
arr.add(mid);
|
||||
}
|
||||
cursor.dispose();
|
||||
MessagesController.getInstance().processLoadedDeleteTask(taskId, date, arr);
|
||||
MessagesController.getInstance().processLoadedDeleteTask(date, arr);
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
@ -835,13 +843,11 @@ public class MessagesStorage {
|
||||
try {
|
||||
int minDate = Integer.MAX_VALUE;
|
||||
SparseArray<ArrayList<Integer>> messages = new SparseArray<ArrayList<Integer>>();
|
||||
String mids = "";
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, ttl, read_state FROM messages WHERE uid = %d AND out = %d AND ttl > 0 AND date <= %d AND send_state = 0", ((long)chat_id) << 32, isOut, time));
|
||||
StringBuilder mids = new StringBuilder();
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, ttl FROM messages WHERE uid = %d AND out = %d AND read_state = 1 AND ttl > 0 AND date <= %d AND send_state = 0 AND media != 1", ((long)chat_id) << 32, isOut, time));
|
||||
while (cursor.next()) {
|
||||
int mid = cursor.intValue(0);
|
||||
int ttl = cursor.intValue(1);
|
||||
int read_state = cursor.intValue(2);
|
||||
int date = readTime + ttl;
|
||||
int date = readTime + cursor.intValue(1);
|
||||
minDate = Math.min(minDate, date);
|
||||
ArrayList<Integer> arr = messages.get(date);
|
||||
if (arr == null) {
|
||||
@ -849,38 +855,28 @@ public class MessagesStorage {
|
||||
messages.put(date, arr);
|
||||
}
|
||||
if (mids.length() != 0) {
|
||||
mids += ",";
|
||||
mids.append(",");
|
||||
}
|
||||
mids += "" + mid;
|
||||
mids.append(mid);
|
||||
arr.add(mid);
|
||||
}
|
||||
cursor.dispose();
|
||||
if (messages.size() != 0) {
|
||||
database.beginTransaction();
|
||||
SQLitePreparedStatement state = database.executeFast("INSERT INTO enc_tasks VALUES(?, ?)");
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO enc_tasks_v2 VALUES(?, ?)");
|
||||
for (int a = 0; a < messages.size(); a++) {
|
||||
int key = messages.keyAt(a);
|
||||
ArrayList<Integer> arr = messages.get(key);
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(404);
|
||||
int count = 0;
|
||||
for (int b = 0; b < arr.size(); b++) {
|
||||
int mid = arr.get(b);
|
||||
data.writeInt32(mid);
|
||||
count++;
|
||||
if (b == arr.size() - 1 || b != 0 && b % 100 == 0) {
|
||||
state.requery();
|
||||
data.limit(count * 4);
|
||||
state.bindInteger(1, key);
|
||||
state.bindByteBuffer(2, data.buffer);
|
||||
state.step();
|
||||
count = 0;
|
||||
}
|
||||
for (Integer mid : arr) {
|
||||
state.requery();
|
||||
state.bindInteger(1, mid);
|
||||
state.bindInteger(2, key);
|
||||
state.step();
|
||||
}
|
||||
buffersStorage.reuseFreeBuffer(data);
|
||||
}
|
||||
state.dispose();
|
||||
database.commitTransaction();
|
||||
database.executeFast(String.format(Locale.US, "UPDATE messages SET ttl = 0 WHERE mid IN(%s)", mids)).stepThis().dispose();
|
||||
database.executeFast(String.format(Locale.US, "UPDATE messages SET ttl = 0 WHERE mid IN(%s)", mids.toString())).stepThis().dispose();
|
||||
MessagesController.getInstance().didAddedNewTask(minDate);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -896,15 +892,9 @@ public class MessagesStorage {
|
||||
}
|
||||
try {
|
||||
HashMap<Long, Integer> dialogsToUpdate = new HashMap<Long, Integer>();
|
||||
String dialogsToReload = "";
|
||||
if (messages != null && !messages.isEmpty()) {
|
||||
String ids = "";
|
||||
for (int uid : messages) {
|
||||
if (ids.length() != 0) {
|
||||
ids += ",";
|
||||
}
|
||||
ids += uid;
|
||||
}
|
||||
StringBuilder dialogsToReload = new StringBuilder();
|
||||
String ids = TextUtils.join(",", messages);
|
||||
int totalCount = 0;
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, read_state, out FROM messages WHERE mid IN(%s)", ids));
|
||||
while (cursor.next()) {
|
||||
@ -922,20 +912,16 @@ public class MessagesStorage {
|
||||
if (currentCount == null) {
|
||||
dialogsToUpdate.put(uid, 1);
|
||||
if (dialogsToReload.length() != 0) {
|
||||
dialogsToReload += ",";
|
||||
dialogsToReload.append(",");
|
||||
}
|
||||
dialogsToReload += uid;
|
||||
dialogsToReload.append(uid);
|
||||
} else {
|
||||
dialogsToUpdate.put(uid, currentCount + 1);
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
|
||||
if (totalCount != messages.size()) {
|
||||
FileLog.e("tmessages", "messages read mismatch!");
|
||||
}
|
||||
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT did, unread_count FROM dialogs WHERE did IN(%s)", dialogsToReload));
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT did, unread_count FROM dialogs WHERE did IN(%s)", dialogsToReload.toString()));
|
||||
while (cursor.next()) {
|
||||
long did = cursor.longValue(0);
|
||||
int count = cursor.intValue(1);
|
||||
@ -1098,7 +1084,7 @@ public class MessagesStorage {
|
||||
if (info != null) {
|
||||
boolean modified = false;
|
||||
ArrayList<Integer> usersArr = new ArrayList<Integer>();
|
||||
String usersToLoad = "";
|
||||
StringBuilder usersToLoad = new StringBuilder();
|
||||
for (int a = 0; a < info.participants.size(); a++) {
|
||||
TLRPC.TL_chatParticipant c = info.participants.get(a);
|
||||
if (usersArr.contains(c.user_id)) {
|
||||
@ -1107,14 +1093,14 @@ public class MessagesStorage {
|
||||
a--;
|
||||
} else {
|
||||
if (usersToLoad.length() != 0) {
|
||||
usersToLoad += ",";
|
||||
usersToLoad.append(",");
|
||||
}
|
||||
usersArr.add(c.user_id);
|
||||
usersToLoad += c.user_id;
|
||||
usersToLoad.append(c.user_id);
|
||||
}
|
||||
}
|
||||
if (usersToLoad.length() != 0) {
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", usersToLoad));
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", usersToLoad.toString()));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
|
||||
@ -1322,13 +1308,7 @@ public class MessagesStorage {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
String ids = "";
|
||||
for (Integer uid : uids) {
|
||||
if (ids.length() != 0) {
|
||||
ids += ",";
|
||||
}
|
||||
ids += "" + uid;
|
||||
}
|
||||
String ids = TextUtils.join(",", uids);
|
||||
database.executeFast("DELETE FROM contacts WHERE uid IN(" + ids + ")").stepThis().dispose();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
@ -1446,7 +1426,7 @@ public class MessagesStorage {
|
||||
ArrayList<TLRPC.User> users = new ArrayList<TLRPC.User>();
|
||||
try {
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT * FROM contacts WHERE 1");
|
||||
String uids = "";
|
||||
StringBuilder uids = new StringBuilder();
|
||||
while (cursor.next()) {
|
||||
int user_id = cursor.intValue(0);
|
||||
if (user_id == UserConfig.getClientUserId()) {
|
||||
@ -1456,15 +1436,15 @@ public class MessagesStorage {
|
||||
contact.user_id = user_id;
|
||||
contact.mutual = cursor.intValue(1) == 1;
|
||||
if (uids.length() != 0) {
|
||||
uids += ",";
|
||||
uids.append(",");
|
||||
}
|
||||
contacts.add(contact);
|
||||
uids += contact.user_id;
|
||||
uids.append(contact.user_id);
|
||||
}
|
||||
cursor.dispose();
|
||||
|
||||
if (uids.length() != 0) {
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", uids));
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", uids.toString()));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
|
||||
@ -1574,18 +1554,18 @@ public class MessagesStorage {
|
||||
}
|
||||
cursor.dispose();
|
||||
|
||||
String usersToLoad = "";
|
||||
StringBuilder usersToLoad = new StringBuilder();
|
||||
for (int uid : fromUser) {
|
||||
if (!loadedUsers.contains(uid)) {
|
||||
if (usersToLoad.length() != 0) {
|
||||
usersToLoad += ",";
|
||||
usersToLoad.append(",");
|
||||
}
|
||||
usersToLoad += uid;
|
||||
usersToLoad.append(uid);
|
||||
loadedUsers.add(uid);
|
||||
}
|
||||
}
|
||||
if (usersToLoad.length() != 0) {
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", usersToLoad));
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", usersToLoad.toString()));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
|
||||
@ -1722,14 +1702,9 @@ public class MessagesStorage {
|
||||
}
|
||||
cursor.dispose();
|
||||
|
||||
String stringToLoad = "";
|
||||
|
||||
if (!encryptedChatIds.isEmpty()) {
|
||||
for (int uid : encryptedChatIds) {
|
||||
if (stringToLoad.length() != 0) {
|
||||
stringToLoad += ",";
|
||||
}
|
||||
stringToLoad += uid;
|
||||
}
|
||||
String stringToLoad = TextUtils.join(",", encryptedChatIds);
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl FROM enc_chats WHERE uid IN(%s)", stringToLoad));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
@ -1751,13 +1726,7 @@ public class MessagesStorage {
|
||||
|
||||
|
||||
if (!userIds.isEmpty()) {
|
||||
stringToLoad = "";
|
||||
for (Integer uid : userIds) {
|
||||
if (stringToLoad.length() != 0) {
|
||||
stringToLoad += ",";
|
||||
}
|
||||
stringToLoad += uid;
|
||||
}
|
||||
String stringToLoad = TextUtils.join(",", userIds);
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", stringToLoad));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
@ -1774,20 +1743,20 @@ public class MessagesStorage {
|
||||
}
|
||||
|
||||
if (!chatIds.isEmpty() || !broadcastIds.isEmpty()) {
|
||||
stringToLoad = "";
|
||||
StringBuilder stringToLoad = new StringBuilder();
|
||||
for (Integer cid : chatIds) {
|
||||
if (stringToLoad.length() != 0) {
|
||||
stringToLoad += ",";
|
||||
stringToLoad.append(",");
|
||||
}
|
||||
stringToLoad += cid;
|
||||
stringToLoad.append(cid);
|
||||
}
|
||||
for (Integer cid : broadcastIds) {
|
||||
if (stringToLoad.length() != 0) {
|
||||
stringToLoad += ",";
|
||||
stringToLoad.append(",");
|
||||
}
|
||||
stringToLoad += (-cid);
|
||||
stringToLoad.append(-cid);
|
||||
}
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM chats WHERE uid IN(%s)", stringToLoad));
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM chats WHERE uid IN(%s)", stringToLoad.toString()));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
|
||||
@ -1807,7 +1776,7 @@ public class MessagesStorage {
|
||||
});
|
||||
}
|
||||
|
||||
public void getMessages(final long dialog_id, final int count, final int max_id, final int minDate, final int classGuid, final boolean from_unread, final boolean forward) {
|
||||
public void getMessages(final long dialog_id, final int count, final int max_id, final int minDate, final int classGuid, final boolean from_unread, final boolean forward, final Semaphore semaphore) {
|
||||
storageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -1991,18 +1960,18 @@ public class MessagesStorage {
|
||||
}
|
||||
cursor.dispose();
|
||||
|
||||
String usersToLoad = "";
|
||||
StringBuilder usersToLoad = new StringBuilder();
|
||||
for (int uid : fromUser) {
|
||||
if (!loadedUsers.contains(uid)) {
|
||||
if (usersToLoad.length() != 0) {
|
||||
usersToLoad += ",";
|
||||
usersToLoad.append(",");
|
||||
}
|
||||
usersToLoad += uid;
|
||||
usersToLoad.append(uid);
|
||||
loadedUsers.add(uid);
|
||||
}
|
||||
}
|
||||
if (usersToLoad.length() != 0) {
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", usersToLoad));
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", usersToLoad.toString()));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
|
||||
@ -2023,7 +1992,7 @@ public class MessagesStorage {
|
||||
res.users.clear();
|
||||
FileLog.e("tmessages", e);
|
||||
} finally {
|
||||
MessagesController.getInstance().processLoadedMessages(res, dialog_id, count_query, max_id, true, classGuid, min_unread_id, max_unread_id, count_unread, max_unread_date, forward);
|
||||
MessagesController.getInstance().processLoadedMessages(res, dialog_id, count_query, max_id, true, classGuid, min_unread_id, max_unread_id, count_unread, max_unread_date, forward, semaphore);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -2448,6 +2417,18 @@ public class MessagesStorage {
|
||||
});
|
||||
}
|
||||
|
||||
private int getMessageMediaType(TLRPC.Message message) {
|
||||
if (message.media == null) {
|
||||
return 0;
|
||||
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||
return 1;
|
||||
} else if (message.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||
return 2;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void putMessagesInternal(final ArrayList<TLRPC.Message> messages, final boolean withTransaction, final boolean isBroadcast, final int downloadMask) {
|
||||
try {
|
||||
if (withTransaction) {
|
||||
@ -2458,9 +2439,9 @@ public class MessagesStorage {
|
||||
HashMap<Long, Integer> mediaCounts = new HashMap<Long, Integer>();
|
||||
HashMap<Integer, Long> messagesIdsMap = new HashMap<Integer, Long>();
|
||||
HashMap<Integer, Long> messagesMediaIdsMap = new HashMap<Integer, Long>();
|
||||
String messageIds = "";
|
||||
String messageMediaIds = "";
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
StringBuilder messageIds = new StringBuilder();
|
||||
StringBuilder messageMediaIds = new StringBuilder();
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO media VALUES(?, ?, ?, ?)");
|
||||
SQLitePreparedStatement state3 = database.executeFast("REPLACE INTO randoms VALUES(?, ?)");
|
||||
SQLitePreparedStatement state4 = database.executeFast("REPLACE INTO download_queue VALUES(?, ?, ?, ?)");
|
||||
@ -2477,23 +2458,23 @@ public class MessagesStorage {
|
||||
|
||||
if (message.unread && !message.out) {
|
||||
if (messageIds.length() > 0) {
|
||||
messageIds += ",";
|
||||
messageIds.append(",");
|
||||
}
|
||||
messageIds += message.id;
|
||||
messageIds.append(message.id);
|
||||
messagesIdsMap.put(message.id, dialog_id);
|
||||
}
|
||||
|
||||
if (message.media instanceof TLRPC.TL_messageMediaVideo || message.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||
if (message.ttl == 0 && (message.media instanceof TLRPC.TL_messageMediaVideo || message.media instanceof TLRPC.TL_messageMediaPhoto)) {
|
||||
if (messageMediaIds.length() > 0) {
|
||||
messageMediaIds += ",";
|
||||
messageMediaIds.append(",");
|
||||
}
|
||||
messageMediaIds += message.id;
|
||||
messageMediaIds.append(message.id);
|
||||
messagesMediaIdsMap.put(message.id, dialog_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (messageIds.length() > 0) {
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT mid FROM messages WHERE mid IN(" + messageIds + ")");
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT mid FROM messages WHERE mid IN(" + messageIds.toString() + ")");
|
||||
while (cursor.next()) {
|
||||
int mid = cursor.intValue(0);
|
||||
messagesIdsMap.remove(mid);
|
||||
@ -2510,7 +2491,7 @@ public class MessagesStorage {
|
||||
}
|
||||
|
||||
if (messageMediaIds.length() > 0) {
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT mid FROM media WHERE mid IN(" + messageMediaIds + ")");
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT mid FROM media WHERE mid IN(" + messageMediaIds.toString() + ")");
|
||||
while (cursor.next()) {
|
||||
int mid = cursor.intValue(0);
|
||||
messagesMediaIdsMap.remove(mid);
|
||||
@ -2557,6 +2538,7 @@ public class MessagesStorage {
|
||||
state.bindByteBuffer(6, data.buffer);
|
||||
state.bindInteger(7, (message.out ? 1 : 0));
|
||||
state.bindInteger(8, message.ttl);
|
||||
state.bindInteger(9, getMessageMediaType(message));
|
||||
state.step();
|
||||
|
||||
if (message.random_id != 0) {
|
||||
@ -2566,7 +2548,7 @@ public class MessagesStorage {
|
||||
state3.step();
|
||||
}
|
||||
|
||||
if (message.media instanceof TLRPC.TL_messageMediaVideo || message.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||
if (message.ttl == 0 && (message.media instanceof TLRPC.TL_messageMediaVideo || message.media instanceof TLRPC.TL_messageMediaPhoto)) {
|
||||
state2.requery();
|
||||
state2.bindInteger(1, messageId);
|
||||
state2.bindLong(2, dialog_id);
|
||||
@ -2862,17 +2844,17 @@ public class MessagesStorage {
|
||||
database.commitTransaction();
|
||||
}
|
||||
} else {
|
||||
String ids = "";
|
||||
StringBuilder ids = new StringBuilder();
|
||||
HashMap<Integer, TLRPC.User> usersDict = new HashMap<Integer, TLRPC.User>();
|
||||
for (TLRPC.User user : users) {
|
||||
if (ids.length() != 0) {
|
||||
ids += ",";
|
||||
ids.append(",");
|
||||
}
|
||||
ids += user.id;
|
||||
ids.append(user.id);
|
||||
usersDict.put(user.id, user);
|
||||
}
|
||||
ArrayList<TLRPC.User> loadedUsers = new ArrayList<TLRPC.User>();
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", ids));
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", ids.toString()));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
|
||||
@ -2950,13 +2932,7 @@ public class MessagesStorage {
|
||||
}
|
||||
try {
|
||||
if (messages != null && !messages.isEmpty()) {
|
||||
String ids = "";
|
||||
for (int uid : messages) {
|
||||
if (ids.length() != 0) {
|
||||
ids += ",";
|
||||
}
|
||||
ids += uid;
|
||||
}
|
||||
String ids = TextUtils.join(",", messages);
|
||||
database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = 1 WHERE mid IN(%s)", ids)).stepThis().dispose();
|
||||
}
|
||||
if (encryptedMessages != null && !encryptedMessages.isEmpty()) {
|
||||
@ -2997,13 +2973,7 @@ public class MessagesStorage {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
String ids = "";
|
||||
for (long uid : messages) {
|
||||
if (ids.length() != 0) {
|
||||
ids += ",";
|
||||
}
|
||||
ids += uid;
|
||||
}
|
||||
String ids = TextUtils.join(",", messages);
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid FROM randoms WHERE random_id IN(%s)", ids));
|
||||
final ArrayList<Integer> mids = new ArrayList<Integer>();
|
||||
while (cursor.next()) {
|
||||
@ -3038,13 +3008,7 @@ public class MessagesStorage {
|
||||
throw new RuntimeException("wrong db thread");
|
||||
}
|
||||
try {
|
||||
String ids = "";
|
||||
for (int uid : messages) {
|
||||
if (ids.length() != 0) {
|
||||
ids += ",";
|
||||
}
|
||||
ids += uid;
|
||||
}
|
||||
String ids = TextUtils.join(",", messages);
|
||||
database.executeFast(String.format(Locale.US, "DELETE FROM messages WHERE mid IN(%s)", ids)).stepThis().dispose();
|
||||
database.executeFast(String.format(Locale.US, "DELETE FROM media WHERE mid IN(%s)", ids)).stepThis().dispose();
|
||||
database.executeFast("DELETE FROM media_counts WHERE 1").stepThis().dispose();
|
||||
@ -3059,13 +3023,7 @@ public class MessagesStorage {
|
||||
throw new RuntimeException("wrong db thread");
|
||||
}
|
||||
try {
|
||||
String ids = "";
|
||||
for (int uid : messages) {
|
||||
if (ids.length() != 0) {
|
||||
ids += ",";
|
||||
}
|
||||
ids += uid;
|
||||
}
|
||||
String ids = TextUtils.join(",", messages);
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT did FROM dialogs WHERE last_mid IN(%s)", ids));
|
||||
ArrayList<Long> dialogsToUpdate = new ArrayList<Long>();
|
||||
while (cursor.next()) {
|
||||
@ -3084,13 +3042,7 @@ public class MessagesStorage {
|
||||
state.dispose();
|
||||
database.commitTransaction();
|
||||
|
||||
ids = "";
|
||||
for (long uid : dialogsToUpdate) {
|
||||
if (ids.length() != 0) {
|
||||
ids += ",";
|
||||
}
|
||||
ids += uid;
|
||||
}
|
||||
ids = TextUtils.join(",", dialogsToUpdate);
|
||||
|
||||
TLRPC.messages_Dialogs dialogs = new TLRPC.messages_Dialogs();
|
||||
ArrayList<TLRPC.EncryptedChat> encryptedChats = new ArrayList<TLRPC.EncryptedChat>();
|
||||
@ -3157,13 +3109,7 @@ public class MessagesStorage {
|
||||
cursor.dispose();
|
||||
|
||||
if (!encryptedToLoad.isEmpty()) {
|
||||
String toLoad = "";
|
||||
for (int uid : encryptedToLoad) {
|
||||
if (toLoad.length() != 0) {
|
||||
toLoad += ",";
|
||||
}
|
||||
toLoad += uid;
|
||||
}
|
||||
String toLoad = TextUtils.join(",", encryptedToLoad);
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl FROM enc_chats WHERE uid IN(%s)", toLoad));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
@ -3184,13 +3130,7 @@ public class MessagesStorage {
|
||||
}
|
||||
|
||||
if (!chatsToLoad.isEmpty()) {
|
||||
String toLoad = "";
|
||||
for (int uid : chatsToLoad) {
|
||||
if (toLoad.length() != 0) {
|
||||
toLoad += ",";
|
||||
}
|
||||
toLoad += uid;
|
||||
}
|
||||
String toLoad = TextUtils.join(",", chatsToLoad);
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM chats WHERE uid IN(%s)", toLoad));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
@ -3204,13 +3144,7 @@ public class MessagesStorage {
|
||||
}
|
||||
|
||||
if (!usersToLoad.isEmpty()) {
|
||||
String toLoad = "";
|
||||
for (int uid : usersToLoad) {
|
||||
if (toLoad.length() != 0) {
|
||||
toLoad += ",";
|
||||
}
|
||||
toLoad += uid;
|
||||
}
|
||||
String toLoad = TextUtils.join(",", usersToLoad);
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", toLoad));
|
||||
while (cursor.next()) {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
|
||||
@ -3276,7 +3210,7 @@ public class MessagesStorage {
|
||||
try {
|
||||
database.beginTransaction();
|
||||
if (!messages.messages.isEmpty()) {
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO media VALUES(?, ?, ?, ?)");
|
||||
for (TLRPC.Message message : messages.messages) {
|
||||
state.requery();
|
||||
@ -3290,6 +3224,7 @@ public class MessagesStorage {
|
||||
state.bindByteBuffer(6, data.buffer);
|
||||
state.bindInteger(7, (message.out ? 1 : 0));
|
||||
state.bindInteger(8, 0);
|
||||
state.bindInteger(9, getMessageMediaType(message));
|
||||
state.step();
|
||||
|
||||
if (message.media instanceof TLRPC.TL_messageMediaVideo || message.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||
@ -3430,13 +3365,7 @@ public class MessagesStorage {
|
||||
cursor.dispose();
|
||||
|
||||
if (!encryptedToLoad.isEmpty()) {
|
||||
String toLoad = "";
|
||||
for (int uid : encryptedToLoad) {
|
||||
if (toLoad.length() != 0) {
|
||||
toLoad += ",";
|
||||
}
|
||||
toLoad += uid;
|
||||
}
|
||||
String toLoad = TextUtils.join(",", encryptedToLoad);
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl FROM enc_chats WHERE uid IN(%s)", toLoad));
|
||||
while (cursor.next()) {
|
||||
try {
|
||||
@ -3463,13 +3392,7 @@ public class MessagesStorage {
|
||||
}
|
||||
|
||||
if (!chatsToLoad.isEmpty()) {
|
||||
String toLoad = "";
|
||||
for (int uid : chatsToLoad) {
|
||||
if (toLoad.length() != 0) {
|
||||
toLoad += ",";
|
||||
}
|
||||
toLoad += uid;
|
||||
}
|
||||
String toLoad = TextUtils.join(",", chatsToLoad);
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM chats WHERE uid IN(%s)", toLoad));
|
||||
while (cursor.next()) {
|
||||
try {
|
||||
@ -3489,13 +3412,7 @@ public class MessagesStorage {
|
||||
}
|
||||
|
||||
if (!usersToLoad.isEmpty()) {
|
||||
String toLoad = "";
|
||||
for (int uid : usersToLoad) {
|
||||
if (toLoad.length() != 0) {
|
||||
toLoad += ",";
|
||||
}
|
||||
toLoad += uid;
|
||||
}
|
||||
String toLoad = TextUtils.join(",", usersToLoad);
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN(%s)", toLoad));
|
||||
while (cursor.next()) {
|
||||
try {
|
||||
@ -3549,7 +3466,7 @@ public class MessagesStorage {
|
||||
}
|
||||
|
||||
if (!dialogs.dialogs.isEmpty()) {
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO dialogs(did, date, unread_count, last_mid) VALUES(?, ?, ?, ?)");
|
||||
SQLitePreparedStatement state3 = database.executeFast("REPLACE INTO media VALUES(?, ?, ?, ?)");
|
||||
SQLitePreparedStatement state4 = database.executeFast("REPLACE INTO dialog_settings VALUES(?, ?)");
|
||||
@ -3574,6 +3491,7 @@ public class MessagesStorage {
|
||||
state.bindByteBuffer(6, data.buffer);
|
||||
state.bindInteger(7, (message.out ? 1 : 0));
|
||||
state.bindInteger(8, 0);
|
||||
state.bindInteger(9, getMessageMediaType(message));
|
||||
state.step();
|
||||
|
||||
state2.bindLong(1, uid);
|
||||
@ -3683,14 +3601,7 @@ public class MessagesStorage {
|
||||
public ArrayList<TLRPC.User> getUsers(final ArrayList<Integer> uids, final boolean[] error) {
|
||||
ArrayList<TLRPC.User> users = new ArrayList<TLRPC.User>();
|
||||
try {
|
||||
String uidsStr = "";
|
||||
|
||||
for (Integer uid : uids) {
|
||||
if (uidsStr.length() != 0) {
|
||||
uidsStr += ",";
|
||||
}
|
||||
uidsStr += uid;
|
||||
}
|
||||
String uidsStr = TextUtils.join(",", uids);
|
||||
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN (%s)", uidsStr));
|
||||
while (cursor.next()) {
|
||||
|
@ -24,9 +24,9 @@ import java.util.zip.ZipFile;
|
||||
public class NativeLoader {
|
||||
|
||||
private static final long sizes[] = new long[] {
|
||||
946908, //armeabi
|
||||
1028848, //armeabi-v7a
|
||||
1603780, //x86
|
||||
951052, //armeabi
|
||||
1032992, //armeabi-v7a
|
||||
1612020, //x86
|
||||
0, //mips
|
||||
};
|
||||
|
||||
|
@ -9000,6 +9000,41 @@ public class TLRPC {
|
||||
}
|
||||
}
|
||||
|
||||
public static class TL_message_secret extends TL_message {
|
||||
public static int constructor = 0x555555F8;
|
||||
|
||||
public void readParams(AbsSerializedData stream) {
|
||||
id = stream.readInt32();
|
||||
from_id = stream.readInt32();
|
||||
to_id = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
out = stream.readBool();
|
||||
unread = stream.readBool();
|
||||
date = stream.readInt32();
|
||||
message = stream.readString();
|
||||
media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.startsWith("-1"))) {
|
||||
attachPath = stream.readString();
|
||||
}
|
||||
if (id < 0 && message.length() > 6 && media instanceof TL_messageMediaVideo) {
|
||||
videoEditedInfo = new VideoEditedInfo();
|
||||
videoEditedInfo.parseString(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void serializeToStream(AbsSerializedData stream) {
|
||||
stream.writeInt32(constructor);
|
||||
stream.writeInt32(id);
|
||||
stream.writeInt32(from_id);
|
||||
to_id.serializeToStream(stream);
|
||||
stream.writeBool(out);
|
||||
stream.writeBool(unread);
|
||||
stream.writeInt32(date);
|
||||
stream.writeString(message);
|
||||
media.serializeToStream(stream);
|
||||
stream.writeString(attachPath);
|
||||
}
|
||||
}
|
||||
|
||||
public static class TL_messages_deleteMessages extends TLObject {
|
||||
public static int constructor = 0x14f2dd0a;
|
||||
|
||||
|
@ -117,6 +117,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
private TypingDotsDrawable typingDotsDrawable;
|
||||
private View emptyViewContainer;
|
||||
private ArrayList<View> actionModeViews = new ArrayList<View>();
|
||||
private Semaphore testSemaphore = new Semaphore(0);
|
||||
|
||||
private TextView bottomOverlayText;
|
||||
|
||||
@ -352,7 +353,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
super.onFragmentCreate();
|
||||
|
||||
loading = true;
|
||||
MessagesController.getInstance().loadMessages(dialog_id, 30, 0, true, 0, classGuid, true, false);
|
||||
|
||||
MessagesController.getInstance().loadMessages(dialog_id, AndroidUtilities.isTablet() ? 30 : 20, 0, true, 0, classGuid, true, false, testSemaphore);
|
||||
try {
|
||||
testSemaphore.acquire();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
|
||||
if (currentUser != null) {
|
||||
userBlocked = MessagesController.getInstance().blockedUsers.contains(currentUser.id);
|
||||
}
|
||||
@ -766,16 +774,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
if (firstVisibleItem <= 4) {
|
||||
if (!endReached && !loading) {
|
||||
if (messagesByDays.size() != 0) {
|
||||
MessagesController.getInstance().loadMessages(dialog_id, 20, maxMessageId, !cacheEndReaced, minDate, classGuid, false, false);
|
||||
MessagesController.getInstance().loadMessages(dialog_id, 20, maxMessageId, !cacheEndReaced, minDate, classGuid, false, false, null);
|
||||
} else {
|
||||
MessagesController.getInstance().loadMessages(dialog_id, 20, 0, !cacheEndReaced, minDate, classGuid, false, false);
|
||||
MessagesController.getInstance().loadMessages(dialog_id, 20, 0, !cacheEndReaced, minDate, classGuid, false, false, null);
|
||||
}
|
||||
loading = true;
|
||||
}
|
||||
}
|
||||
if (firstVisibleItem + visibleItemCount >= totalItemCount - 6) {
|
||||
if (!unread_end_reached && !loadingForward) {
|
||||
MessagesController.getInstance().loadMessages(dialog_id, 20, minMessageId, true, maxDate, classGuid, false, true);
|
||||
MessagesController.getInstance().loadMessages(dialog_id, 20, minMessageId, true, maxDate, classGuid, false, true, null);
|
||||
loadingForward = true;
|
||||
}
|
||||
}
|
||||
@ -896,7 +904,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
unread_end_reached = true;
|
||||
loading = true;
|
||||
chatAdapter.notifyDataSetChanged();
|
||||
MessagesController.getInstance().loadMessages(dialog_id, 30, 0, true, 0, classGuid, true, false);
|
||||
MessagesController.getInstance().loadMessages(dialog_id, 30, 0, true, 0, classGuid, true, false, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2249,7 +2257,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
}
|
||||
maxDate = Integer.MIN_VALUE;
|
||||
minDate = 0;
|
||||
MessagesController.getInstance().loadMessages(dialog_id, 30, 0, !cacheEndReaced, minDate, classGuid, false, false);
|
||||
MessagesController.getInstance().loadMessages(dialog_id, 30, 0, !cacheEndReaced, minDate, classGuid, false, false, null);
|
||||
loading = true;
|
||||
}
|
||||
}
|
||||
|
@ -2138,7 +2138,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
||||
float ai = -1;
|
||||
if (System.currentTimeMillis() - animationStartTime < animationDuration) {
|
||||
ai = interpolator.getInterpolation((float)(System.currentTimeMillis() - animationStartTime) / animationDuration);
|
||||
if (ai >= 0.95) {
|
||||
if (ai >= 0.999f) {
|
||||
ai = -1;
|
||||
}
|
||||
}
|
||||
|
3
TMessagesProj/src/main/res/anim/decelerate_cubic.xml
Normal file
3
TMessagesProj/src/main/res/anim/decelerate_cubic.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<decelerateInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:factor="1.5" />
|
@ -1,15 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<scale android:fromXScale="0.9"
|
||||
android:fromYScale="0.9"
|
||||
android:toXScale="1.0"
|
||||
android:toYScale="1.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="150"/>
|
||||
<!--<scale-->
|
||||
<!--android:fromXScale="0.9"-->
|
||||
<!--android:fromYScale="0.9"-->
|
||||
<!--android:toXScale="1.0"-->
|
||||
<!--android:toYScale="1.0"-->
|
||||
<!--android:pivotX="50%"-->
|
||||
<!--android:pivotY="50%"-->
|
||||
<!--android:interpolator="@android:anim/decelerate_interpolator"-->
|
||||
<!--android:duration="220"/>-->
|
||||
|
||||
<!--<alpha android:fromAlpha="0.0"-->
|
||||
<!--android:toAlpha="1.0"-->
|
||||
<!--android:interpolator="@android:anim/decelerate_interpolator"-->
|
||||
<!--android:duration="@android:integer/config_mediumAnimTime" />-->
|
||||
|
||||
|
||||
<alpha android:fromAlpha="0.0"
|
||||
android:toAlpha="1.0"
|
||||
android:duration="150" />
|
||||
<alpha
|
||||
android:fromAlpha="0.0"
|
||||
android:toAlpha="1.0"
|
||||
android:interpolator="@anim/decelerate_cubic"
|
||||
android:duration="220"/>
|
||||
|
||||
<scale
|
||||
android:fromXScale=".8" android:toXScale="1.0"
|
||||
android:fromYScale=".8" android:toYScale="1.0"
|
||||
android:pivotX="50%p" android:pivotY="50%p"
|
||||
android:interpolator="@anim/decelerate_cubic"
|
||||
android:duration="220"/>
|
||||
</set>
|
@ -1,16 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<scale android:fromXScale="1.0"
|
||||
android:fromYScale="1.0"
|
||||
android:toXScale="0.9"
|
||||
android:toYScale="0.9"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||
android:duration="150"/>
|
||||
<!--<scale-->
|
||||
<!--android:fromXScale="1.0"-->
|
||||
<!--android:fromYScale="1.0"-->
|
||||
<!--android:toXScale="0.9"-->
|
||||
<!--android:toYScale="0.9"-->
|
||||
<!--android:pivotX="50%"-->
|
||||
<!--android:pivotY="50%"-->
|
||||
<!--android:interpolator="@android:anim/decelerate_interpolator"-->
|
||||
<!--android:duration="220"/>-->
|
||||
|
||||
<alpha android:fromAlpha="1.0"
|
||||
<!--<alpha-->
|
||||
<!--android:fromAlpha="1.0"-->
|
||||
<!--android:toAlpha="0.0"-->
|
||||
<!--android:interpolator="@android:anim/decelerate_interpolator"-->
|
||||
<!--android:duration="220" />-->
|
||||
|
||||
<alpha
|
||||
android:fromAlpha="1.0"
|
||||
android:toAlpha="0.0"
|
||||
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||
android:duration="150" />
|
||||
android:interpolator="@anim/decelerate_cubic"
|
||||
android:duration="220"/>
|
||||
|
||||
<scale
|
||||
android:fromXScale="1.0"
|
||||
android:toXScale=".8"
|
||||
android:fromYScale="1.0"
|
||||
android:toYScale=".8"
|
||||
android:pivotX="50%p"
|
||||
android:pivotY="50%p"
|
||||
android:interpolator="@anim/decelerate_cubic"
|
||||
android:duration="220"/>
|
||||
</set>
|
BIN
TMessagesProj/src/main/res/drawable-hdpi/burn.png
Executable file
BIN
TMessagesProj/src/main/res/drawable-hdpi/burn.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
TMessagesProj/src/main/res/drawable-ldpi/burn.png
Executable file
BIN
TMessagesProj/src/main/res/drawable-ldpi/burn.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
BIN
TMessagesProj/src/main/res/drawable-mdpi/burn.png
Executable file
BIN
TMessagesProj/src/main/res/drawable-mdpi/burn.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
TMessagesProj/src/main/res/drawable-xhdpi/burn.png
Executable file
BIN
TMessagesProj/src/main/res/drawable-xhdpi/burn.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
BIN
TMessagesProj/src/main/res/drawable-xxhdpi/burn.png
Executable file
BIN
TMessagesProj/src/main/res/drawable-xxhdpi/burn.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
Loading…
Reference in New Issue
Block a user