实现访问统计接口。

This commit is contained in:
root 2025-02-28 16:44:54 +00:00
parent e9c3cde9de
commit 63aa6a6270
17 changed files with 310053 additions and 0 deletions

View File

@ -4,6 +4,7 @@
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/3rdparty/sqlite-amalgamation-3490100",
"/opt/Libraries/boost_1_87_0/include"
],
"defines": [],

7
3rdparty/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,7 @@
add_library(sqlite3 STATIC
sqlite-amalgamation-3490100/sqlite3.h sqlite-amalgamation-3490100/sqlite3.c
)
target_include_directories(sqlite3
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/sqlite-amalgamation-3490100
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,719 @@
/*
** 2006 June 7
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the SQLite interface for use by
** shared libraries that want to be imported as extensions into
** an SQLite instance. Shared libraries that intend to be loaded
** as extensions by SQLite should #include this file instead of
** sqlite3.h.
*/
#ifndef SQLITE3EXT_H
#define SQLITE3EXT_H
#include "sqlite3.h"
/*
** The following structure holds pointers to all of the SQLite API
** routines.
**
** WARNING: In order to maintain backwards compatibility, add new
** interfaces to the end of this structure only. If you insert new
** interfaces in the middle of this structure, then older different
** versions of SQLite will not be able to load each other's shared
** libraries!
*/
struct sqlite3_api_routines {
void * (*aggregate_context)(sqlite3_context*,int nBytes);
int (*aggregate_count)(sqlite3_context*);
int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
int (*bind_double)(sqlite3_stmt*,int,double);
int (*bind_int)(sqlite3_stmt*,int,int);
int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
int (*bind_null)(sqlite3_stmt*,int);
int (*bind_parameter_count)(sqlite3_stmt*);
int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
const char * (*bind_parameter_name)(sqlite3_stmt*,int);
int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
int (*busy_timeout)(sqlite3*,int ms);
int (*changes)(sqlite3*);
int (*close)(sqlite3*);
int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
int eTextRep,const char*));
int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
int eTextRep,const void*));
const void * (*column_blob)(sqlite3_stmt*,int iCol);
int (*column_bytes)(sqlite3_stmt*,int iCol);
int (*column_bytes16)(sqlite3_stmt*,int iCol);
int (*column_count)(sqlite3_stmt*pStmt);
const char * (*column_database_name)(sqlite3_stmt*,int);
const void * (*column_database_name16)(sqlite3_stmt*,int);
const char * (*column_decltype)(sqlite3_stmt*,int i);
const void * (*column_decltype16)(sqlite3_stmt*,int);
double (*column_double)(sqlite3_stmt*,int iCol);
int (*column_int)(sqlite3_stmt*,int iCol);
sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
const char * (*column_name)(sqlite3_stmt*,int);
const void * (*column_name16)(sqlite3_stmt*,int);
const char * (*column_origin_name)(sqlite3_stmt*,int);
const void * (*column_origin_name16)(sqlite3_stmt*,int);
const char * (*column_table_name)(sqlite3_stmt*,int);
const void * (*column_table_name16)(sqlite3_stmt*,int);
const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
const void * (*column_text16)(sqlite3_stmt*,int iCol);
int (*column_type)(sqlite3_stmt*,int iCol);
sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
int (*complete)(const char*sql);
int (*complete16)(const void*sql);
int (*create_collation)(sqlite3*,const char*,int,void*,
int(*)(void*,int,const void*,int,const void*));
int (*create_collation16)(sqlite3*,const void*,int,void*,
int(*)(void*,int,const void*,int,const void*));
int (*create_function)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*));
int (*create_function16)(sqlite3*,const void*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*));
int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
int (*data_count)(sqlite3_stmt*pStmt);
sqlite3 * (*db_handle)(sqlite3_stmt*);
int (*declare_vtab)(sqlite3*,const char*);
int (*enable_shared_cache)(int);
int (*errcode)(sqlite3*db);
const char * (*errmsg)(sqlite3*);
const void * (*errmsg16)(sqlite3*);
int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
int (*expired)(sqlite3_stmt*);
int (*finalize)(sqlite3_stmt*pStmt);
void (*free)(void*);
void (*free_table)(char**result);
int (*get_autocommit)(sqlite3*);
void * (*get_auxdata)(sqlite3_context*,int);
int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
int (*global_recover)(void);
void (*interruptx)(sqlite3*);
sqlite_int64 (*last_insert_rowid)(sqlite3*);
const char * (*libversion)(void);
int (*libversion_number)(void);
void *(*malloc)(int);
char * (*mprintf)(const char*,...);
int (*open)(const char*,sqlite3**);
int (*open16)(const void*,sqlite3**);
int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
void *(*realloc)(void*,int);
int (*reset)(sqlite3_stmt*pStmt);
void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_double)(sqlite3_context*,double);
void (*result_error)(sqlite3_context*,const char*,int);
void (*result_error16)(sqlite3_context*,const void*,int);
void (*result_int)(sqlite3_context*,int);
void (*result_int64)(sqlite3_context*,sqlite_int64);
void (*result_null)(sqlite3_context*);
void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_value)(sqlite3_context*,sqlite3_value*);
void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
const char*,const char*),void*);
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
char * (*xsnprintf)(int,char*,const char*,...);
int (*step)(sqlite3_stmt*);
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
char const**,char const**,int*,int*,int*);
void (*thread_cleanup)(void);
int (*total_changes)(sqlite3*);
void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
sqlite_int64),void*);
void * (*user_data)(sqlite3_context*);
const void * (*value_blob)(sqlite3_value*);
int (*value_bytes)(sqlite3_value*);
int (*value_bytes16)(sqlite3_value*);
double (*value_double)(sqlite3_value*);
int (*value_int)(sqlite3_value*);
sqlite_int64 (*value_int64)(sqlite3_value*);
int (*value_numeric_type)(sqlite3_value*);
const unsigned char * (*value_text)(sqlite3_value*);
const void * (*value_text16)(sqlite3_value*);
const void * (*value_text16be)(sqlite3_value*);
const void * (*value_text16le)(sqlite3_value*);
int (*value_type)(sqlite3_value*);
char *(*vmprintf)(const char*,va_list);
/* Added ??? */
int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
/* Added by 3.3.13 */
int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
int (*clear_bindings)(sqlite3_stmt*);
/* Added by 3.4.1 */
int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
void (*xDestroy)(void *));
/* Added by 3.5.0 */
int (*bind_zeroblob)(sqlite3_stmt*,int,int);
int (*blob_bytes)(sqlite3_blob*);
int (*blob_close)(sqlite3_blob*);
int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
int,sqlite3_blob**);
int (*blob_read)(sqlite3_blob*,void*,int,int);
int (*blob_write)(sqlite3_blob*,const void*,int,int);
int (*create_collation_v2)(sqlite3*,const char*,int,void*,
int(*)(void*,int,const void*,int,const void*),
void(*)(void*));
int (*file_control)(sqlite3*,const char*,int,void*);
sqlite3_int64 (*memory_highwater)(int);
sqlite3_int64 (*memory_used)(void);
sqlite3_mutex *(*mutex_alloc)(int);
void (*mutex_enter)(sqlite3_mutex*);
void (*mutex_free)(sqlite3_mutex*);
void (*mutex_leave)(sqlite3_mutex*);
int (*mutex_try)(sqlite3_mutex*);
int (*open_v2)(const char*,sqlite3**,int,const char*);
int (*release_memory)(int);
void (*result_error_nomem)(sqlite3_context*);
void (*result_error_toobig)(sqlite3_context*);
int (*sleep)(int);
void (*soft_heap_limit)(int);
sqlite3_vfs *(*vfs_find)(const char*);
int (*vfs_register)(sqlite3_vfs*,int);
int (*vfs_unregister)(sqlite3_vfs*);
int (*xthreadsafe)(void);
void (*result_zeroblob)(sqlite3_context*,int);
void (*result_error_code)(sqlite3_context*,int);
int (*test_control)(int, ...);
void (*randomness)(int,void*);
sqlite3 *(*context_db_handle)(sqlite3_context*);
int (*extended_result_codes)(sqlite3*,int);
int (*limit)(sqlite3*,int,int);
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
const char *(*sql)(sqlite3_stmt*);
int (*status)(int,int*,int*,int);
int (*backup_finish)(sqlite3_backup*);
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
int (*backup_pagecount)(sqlite3_backup*);
int (*backup_remaining)(sqlite3_backup*);
int (*backup_step)(sqlite3_backup*,int);
const char *(*compileoption_get)(int);
int (*compileoption_used)(const char*);
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void(*xDestroy)(void*));
int (*db_config)(sqlite3*,int,...);
sqlite3_mutex *(*db_mutex)(sqlite3*);
int (*db_status)(sqlite3*,int,int*,int*,int);
int (*extended_errcode)(sqlite3*);
void (*log)(int,const char*,...);
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
const char *(*sourceid)(void);
int (*stmt_status)(sqlite3_stmt*,int,int);
int (*strnicmp)(const char*,const char*,int);
int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
int (*wal_autocheckpoint)(sqlite3*,int);
int (*wal_checkpoint)(sqlite3*,const char*);
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
int (*vtab_config)(sqlite3*,int op,...);
int (*vtab_on_conflict)(sqlite3*);
/* Version 3.7.16 and later */
int (*close_v2)(sqlite3*);
const char *(*db_filename)(sqlite3*,const char*);
int (*db_readonly)(sqlite3*,const char*);
int (*db_release_memory)(sqlite3*);
const char *(*errstr)(int);
int (*stmt_busy)(sqlite3_stmt*);
int (*stmt_readonly)(sqlite3_stmt*);
int (*stricmp)(const char*,const char*);
int (*uri_boolean)(const char*,const char*,int);
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
const char *(*uri_parameter)(const char*,const char*);
char *(*xvsnprintf)(int,char*,const char*,va_list);
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
/* Version 3.8.7 and later */
int (*auto_extension)(void(*)(void));
int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
void(*)(void*));
int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
void(*)(void*),unsigned char);
int (*cancel_auto_extension)(void(*)(void));
int (*load_extension)(sqlite3*,const char*,const char*,char**);
void *(*malloc64)(sqlite3_uint64);
sqlite3_uint64 (*msize)(void*);
void *(*realloc64)(void*,sqlite3_uint64);
void (*reset_auto_extension)(void);
void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
void(*)(void*));
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
void(*)(void*), unsigned char);
int (*strglob)(const char*,const char*);
/* Version 3.8.11 and later */
sqlite3_value *(*value_dup)(const sqlite3_value*);
void (*value_free)(sqlite3_value*);
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
/* Version 3.9.0 and later */
unsigned int (*value_subtype)(sqlite3_value*);
void (*result_subtype)(sqlite3_context*,unsigned int);
/* Version 3.10.0 and later */
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
int (*strlike)(const char*,const char*,unsigned int);
int (*db_cacheflush)(sqlite3*);
/* Version 3.12.0 and later */
int (*system_errno)(sqlite3*);
/* Version 3.14.0 and later */
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
char *(*expanded_sql)(sqlite3_stmt*);
/* Version 3.18.0 and later */
void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
/* Version 3.20.0 and later */
int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
sqlite3_stmt**,const char**);
int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
sqlite3_stmt**,const void**);
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
void *(*value_pointer)(sqlite3_value*,const char*);
int (*vtab_nochange)(sqlite3_context*);
int (*value_nochange)(sqlite3_value*);
const char *(*vtab_collation)(sqlite3_index_info*,int);
/* Version 3.24.0 and later */
int (*keyword_count)(void);
int (*keyword_name)(int,const char**,int*);
int (*keyword_check)(const char*,int);
sqlite3_str *(*str_new)(sqlite3*);
char *(*str_finish)(sqlite3_str*);
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
void (*str_append)(sqlite3_str*, const char *zIn, int N);
void (*str_appendall)(sqlite3_str*, const char *zIn);
void (*str_appendchar)(sqlite3_str*, int N, char C);
void (*str_reset)(sqlite3_str*);
int (*str_errcode)(sqlite3_str*);
int (*str_length)(sqlite3_str*);
char *(*str_value)(sqlite3_str*);
/* Version 3.25.0 and later */
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void (*xValue)(sqlite3_context*),
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
void(*xDestroy)(void*));
/* Version 3.26.0 and later */
const char *(*normalized_sql)(sqlite3_stmt*);
/* Version 3.28.0 and later */
int (*stmt_isexplain)(sqlite3_stmt*);
int (*value_frombind)(sqlite3_value*);
/* Version 3.30.0 and later */
int (*drop_modules)(sqlite3*,const char**);
/* Version 3.31.0 and later */
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
const char *(*uri_key)(const char*,int);
const char *(*filename_database)(const char*);
const char *(*filename_journal)(const char*);
const char *(*filename_wal)(const char*);
/* Version 3.32.0 and later */
const char *(*create_filename)(const char*,const char*,const char*,
int,const char**);
void (*free_filename)(const char*);
sqlite3_file *(*database_file_object)(const char*);
/* Version 3.34.0 and later */
int (*txn_state)(sqlite3*,const char*);
/* Version 3.36.1 and later */
sqlite3_int64 (*changes64)(sqlite3*);
sqlite3_int64 (*total_changes64)(sqlite3*);
/* Version 3.37.0 and later */
int (*autovacuum_pages)(sqlite3*,
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
void*, void(*)(void*));
/* Version 3.38.0 and later */
int (*error_offset)(sqlite3*);
int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
int (*vtab_distinct)(sqlite3_index_info*);
int (*vtab_in)(sqlite3_index_info*,int,int);
int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
/* Version 3.39.0 and later */
int (*deserialize)(sqlite3*,const char*,unsigned char*,
sqlite3_int64,sqlite3_int64,unsigned);
unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
unsigned int);
const char *(*db_name)(sqlite3*,int);
/* Version 3.40.0 and later */
int (*value_encoding)(sqlite3_value*);
/* Version 3.41.0 and later */
int (*is_interrupted)(sqlite3*);
/* Version 3.43.0 and later */
int (*stmt_explain)(sqlite3_stmt*,int);
/* Version 3.44.0 and later */
void *(*get_clientdata)(sqlite3*,const char*);
int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
};
/*
** This is the function signature used for all extension entry points. It
** is also defined in the file "loadext.c".
*/
typedef int (*sqlite3_loadext_entry)(
sqlite3 *db, /* Handle to the database. */
char **pzErrMsg, /* Used to set error string on failure. */
const sqlite3_api_routines *pThunk /* Extension API function pointers. */
);
/*
** The following macros redefine the API routines so that they are
** redirected through the global sqlite3_api structure.
**
** This header file is also used by the loadext.c source file
** (part of the main SQLite library - not an extension) so that
** it can get access to the sqlite3_api_routines structure
** definition. But the main library does not want to redefine
** the API. So the redefinition macros are only valid if the
** SQLITE_CORE macros is undefined.
*/
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
#endif
#define sqlite3_bind_blob sqlite3_api->bind_blob
#define sqlite3_bind_double sqlite3_api->bind_double
#define sqlite3_bind_int sqlite3_api->bind_int
#define sqlite3_bind_int64 sqlite3_api->bind_int64
#define sqlite3_bind_null sqlite3_api->bind_null
#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
#define sqlite3_bind_text sqlite3_api->bind_text
#define sqlite3_bind_text16 sqlite3_api->bind_text16
#define sqlite3_bind_value sqlite3_api->bind_value
#define sqlite3_busy_handler sqlite3_api->busy_handler
#define sqlite3_busy_timeout sqlite3_api->busy_timeout
#define sqlite3_changes sqlite3_api->changes
#define sqlite3_close sqlite3_api->close
#define sqlite3_collation_needed sqlite3_api->collation_needed
#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
#define sqlite3_column_blob sqlite3_api->column_blob
#define sqlite3_column_bytes sqlite3_api->column_bytes
#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
#define sqlite3_column_count sqlite3_api->column_count
#define sqlite3_column_database_name sqlite3_api->column_database_name
#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
#define sqlite3_column_decltype sqlite3_api->column_decltype
#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
#define sqlite3_column_double sqlite3_api->column_double
#define sqlite3_column_int sqlite3_api->column_int
#define sqlite3_column_int64 sqlite3_api->column_int64
#define sqlite3_column_name sqlite3_api->column_name
#define sqlite3_column_name16 sqlite3_api->column_name16
#define sqlite3_column_origin_name sqlite3_api->column_origin_name
#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
#define sqlite3_column_table_name sqlite3_api->column_table_name
#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
#define sqlite3_column_text sqlite3_api->column_text
#define sqlite3_column_text16 sqlite3_api->column_text16
#define sqlite3_column_type sqlite3_api->column_type
#define sqlite3_column_value sqlite3_api->column_value
#define sqlite3_commit_hook sqlite3_api->commit_hook
#define sqlite3_complete sqlite3_api->complete
#define sqlite3_complete16 sqlite3_api->complete16
#define sqlite3_create_collation sqlite3_api->create_collation
#define sqlite3_create_collation16 sqlite3_api->create_collation16
#define sqlite3_create_function sqlite3_api->create_function
#define sqlite3_create_function16 sqlite3_api->create_function16
#define sqlite3_create_module sqlite3_api->create_module
#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
#define sqlite3_data_count sqlite3_api->data_count
#define sqlite3_db_handle sqlite3_api->db_handle
#define sqlite3_declare_vtab sqlite3_api->declare_vtab
#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
#define sqlite3_errcode sqlite3_api->errcode
#define sqlite3_errmsg sqlite3_api->errmsg
#define sqlite3_errmsg16 sqlite3_api->errmsg16
#define sqlite3_exec sqlite3_api->exec
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_expired sqlite3_api->expired
#endif
#define sqlite3_finalize sqlite3_api->finalize
#define sqlite3_free sqlite3_api->free
#define sqlite3_free_table sqlite3_api->free_table
#define sqlite3_get_autocommit sqlite3_api->get_autocommit
#define sqlite3_get_auxdata sqlite3_api->get_auxdata
#define sqlite3_get_table sqlite3_api->get_table
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_global_recover sqlite3_api->global_recover
#endif
#define sqlite3_interrupt sqlite3_api->interruptx
#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
#define sqlite3_libversion sqlite3_api->libversion
#define sqlite3_libversion_number sqlite3_api->libversion_number
#define sqlite3_malloc sqlite3_api->malloc
#define sqlite3_mprintf sqlite3_api->mprintf
#define sqlite3_open sqlite3_api->open
#define sqlite3_open16 sqlite3_api->open16
#define sqlite3_prepare sqlite3_api->prepare
#define sqlite3_prepare16 sqlite3_api->prepare16
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_profile sqlite3_api->profile
#define sqlite3_progress_handler sqlite3_api->progress_handler
#define sqlite3_realloc sqlite3_api->realloc
#define sqlite3_reset sqlite3_api->reset
#define sqlite3_result_blob sqlite3_api->result_blob
#define sqlite3_result_double sqlite3_api->result_double
#define sqlite3_result_error sqlite3_api->result_error
#define sqlite3_result_error16 sqlite3_api->result_error16
#define sqlite3_result_int sqlite3_api->result_int
#define sqlite3_result_int64 sqlite3_api->result_int64
#define sqlite3_result_null sqlite3_api->result_null
#define sqlite3_result_text sqlite3_api->result_text
#define sqlite3_result_text16 sqlite3_api->result_text16
#define sqlite3_result_text16be sqlite3_api->result_text16be
#define sqlite3_result_text16le sqlite3_api->result_text16le
#define sqlite3_result_value sqlite3_api->result_value
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
#define sqlite3_snprintf sqlite3_api->xsnprintf
#define sqlite3_step sqlite3_api->step
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
#define sqlite3_total_changes sqlite3_api->total_changes
#define sqlite3_trace sqlite3_api->trace
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
#endif
#define sqlite3_update_hook sqlite3_api->update_hook
#define sqlite3_user_data sqlite3_api->user_data
#define sqlite3_value_blob sqlite3_api->value_blob
#define sqlite3_value_bytes sqlite3_api->value_bytes
#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
#define sqlite3_value_double sqlite3_api->value_double
#define sqlite3_value_int sqlite3_api->value_int
#define sqlite3_value_int64 sqlite3_api->value_int64
#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
#define sqlite3_value_text sqlite3_api->value_text
#define sqlite3_value_text16 sqlite3_api->value_text16
#define sqlite3_value_text16be sqlite3_api->value_text16be
#define sqlite3_value_text16le sqlite3_api->value_text16le
#define sqlite3_value_type sqlite3_api->value_type
#define sqlite3_vmprintf sqlite3_api->vmprintf
#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_overload_function sqlite3_api->overload_function
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
#define sqlite3_blob_bytes sqlite3_api->blob_bytes
#define sqlite3_blob_close sqlite3_api->blob_close
#define sqlite3_blob_open sqlite3_api->blob_open
#define sqlite3_blob_read sqlite3_api->blob_read
#define sqlite3_blob_write sqlite3_api->blob_write
#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
#define sqlite3_file_control sqlite3_api->file_control
#define sqlite3_memory_highwater sqlite3_api->memory_highwater
#define sqlite3_memory_used sqlite3_api->memory_used
#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
#define sqlite3_mutex_enter sqlite3_api->mutex_enter
#define sqlite3_mutex_free sqlite3_api->mutex_free
#define sqlite3_mutex_leave sqlite3_api->mutex_leave
#define sqlite3_mutex_try sqlite3_api->mutex_try
#define sqlite3_open_v2 sqlite3_api->open_v2
#define sqlite3_release_memory sqlite3_api->release_memory
#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
#define sqlite3_sleep sqlite3_api->sleep
#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
#define sqlite3_vfs_find sqlite3_api->vfs_find
#define sqlite3_vfs_register sqlite3_api->vfs_register
#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
#define sqlite3_threadsafe sqlite3_api->xthreadsafe
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
#define sqlite3_result_error_code sqlite3_api->result_error_code
#define sqlite3_test_control sqlite3_api->test_control
#define sqlite3_randomness sqlite3_api->randomness
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
#define sqlite3_limit sqlite3_api->limit
#define sqlite3_next_stmt sqlite3_api->next_stmt
#define sqlite3_sql sqlite3_api->sql
#define sqlite3_status sqlite3_api->status
#define sqlite3_backup_finish sqlite3_api->backup_finish
#define sqlite3_backup_init sqlite3_api->backup_init
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
#define sqlite3_backup_step sqlite3_api->backup_step
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
#define sqlite3_db_config sqlite3_api->db_config
#define sqlite3_db_mutex sqlite3_api->db_mutex
#define sqlite3_db_status sqlite3_api->db_status
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
#define sqlite3_log sqlite3_api->log
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
#define sqlite3_sourceid sqlite3_api->sourceid
#define sqlite3_stmt_status sqlite3_api->stmt_status
#define sqlite3_strnicmp sqlite3_api->strnicmp
#define sqlite3_unlock_notify sqlite3_api->unlock_notify
#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
#define sqlite3_wal_hook sqlite3_api->wal_hook
#define sqlite3_blob_reopen sqlite3_api->blob_reopen
#define sqlite3_vtab_config sqlite3_api->vtab_config
#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
/* Version 3.7.16 and later */
#define sqlite3_close_v2 sqlite3_api->close_v2
#define sqlite3_db_filename sqlite3_api->db_filename
#define sqlite3_db_readonly sqlite3_api->db_readonly
#define sqlite3_db_release_memory sqlite3_api->db_release_memory
#define sqlite3_errstr sqlite3_api->errstr
#define sqlite3_stmt_busy sqlite3_api->stmt_busy
#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
#define sqlite3_stricmp sqlite3_api->stricmp
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
#define sqlite3_uri_int64 sqlite3_api->uri_int64
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
/* Version 3.8.7 and later */
#define sqlite3_auto_extension sqlite3_api->auto_extension
#define sqlite3_bind_blob64 sqlite3_api->bind_blob64
#define sqlite3_bind_text64 sqlite3_api->bind_text64
#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
#define sqlite3_load_extension sqlite3_api->load_extension
#define sqlite3_malloc64 sqlite3_api->malloc64
#define sqlite3_msize sqlite3_api->msize
#define sqlite3_realloc64 sqlite3_api->realloc64
#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
#define sqlite3_result_blob64 sqlite3_api->result_blob64
#define sqlite3_result_text64 sqlite3_api->result_text64
#define sqlite3_strglob sqlite3_api->strglob
/* Version 3.8.11 and later */
#define sqlite3_value_dup sqlite3_api->value_dup
#define sqlite3_value_free sqlite3_api->value_free
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
/* Version 3.9.0 and later */
#define sqlite3_value_subtype sqlite3_api->value_subtype
#define sqlite3_result_subtype sqlite3_api->result_subtype
/* Version 3.10.0 and later */
#define sqlite3_status64 sqlite3_api->status64
#define sqlite3_strlike sqlite3_api->strlike
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
/* Version 3.12.0 and later */
#define sqlite3_system_errno sqlite3_api->system_errno
/* Version 3.14.0 and later */
#define sqlite3_trace_v2 sqlite3_api->trace_v2
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
/* Version 3.18.0 and later */
#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
/* Version 3.20.0 and later */
#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
#define sqlite3_result_pointer sqlite3_api->result_pointer
#define sqlite3_value_pointer sqlite3_api->value_pointer
/* Version 3.22.0 and later */
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
#define sqlite3_value_nochange sqlite3_api->value_nochange
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
/* Version 3.24.0 and later */
#define sqlite3_keyword_count sqlite3_api->keyword_count
#define sqlite3_keyword_name sqlite3_api->keyword_name
#define sqlite3_keyword_check sqlite3_api->keyword_check
#define sqlite3_str_new sqlite3_api->str_new
#define sqlite3_str_finish sqlite3_api->str_finish
#define sqlite3_str_appendf sqlite3_api->str_appendf
#define sqlite3_str_vappendf sqlite3_api->str_vappendf
#define sqlite3_str_append sqlite3_api->str_append
#define sqlite3_str_appendall sqlite3_api->str_appendall
#define sqlite3_str_appendchar sqlite3_api->str_appendchar
#define sqlite3_str_reset sqlite3_api->str_reset
#define sqlite3_str_errcode sqlite3_api->str_errcode
#define sqlite3_str_length sqlite3_api->str_length
#define sqlite3_str_value sqlite3_api->str_value
/* Version 3.25.0 and later */
#define sqlite3_create_window_function sqlite3_api->create_window_function
/* Version 3.26.0 and later */
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
/* Version 3.28.0 and later */
#define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain
#define sqlite3_value_frombind sqlite3_api->value_frombind
/* Version 3.30.0 and later */
#define sqlite3_drop_modules sqlite3_api->drop_modules
/* Version 3.31.0 and later */
#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
#define sqlite3_uri_key sqlite3_api->uri_key
#define sqlite3_filename_database sqlite3_api->filename_database
#define sqlite3_filename_journal sqlite3_api->filename_journal
#define sqlite3_filename_wal sqlite3_api->filename_wal
/* Version 3.32.0 and later */
#define sqlite3_create_filename sqlite3_api->create_filename
#define sqlite3_free_filename sqlite3_api->free_filename
#define sqlite3_database_file_object sqlite3_api->database_file_object
/* Version 3.34.0 and later */
#define sqlite3_txn_state sqlite3_api->txn_state
/* Version 3.36.1 and later */
#define sqlite3_changes64 sqlite3_api->changes64
#define sqlite3_total_changes64 sqlite3_api->total_changes64
/* Version 3.37.0 and later */
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
/* Version 3.38.0 and later */
#define sqlite3_error_offset sqlite3_api->error_offset
#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
#define sqlite3_vtab_in sqlite3_api->vtab_in
#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
/* Version 3.39.0 and later */
#ifndef SQLITE_OMIT_DESERIALIZE
#define sqlite3_deserialize sqlite3_api->deserialize
#define sqlite3_serialize sqlite3_api->serialize
#endif
#define sqlite3_db_name sqlite3_api->db_name
/* Version 3.40.0 and later */
#define sqlite3_value_encoding sqlite3_api->value_encoding
/* Version 3.41.0 and later */
#define sqlite3_is_interrupted sqlite3_api->is_interrupted
/* Version 3.43.0 and later */
#define sqlite3_stmt_explain sqlite3_api->stmt_explain
/* Version 3.44.0 and later */
#define sqlite3_get_clientdata sqlite3_api->get_clientdata
#define sqlite3_set_clientdata sqlite3_api->set_clientdata
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
/* This case when the file really is being compiled as a loadable
** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
# define SQLITE_EXTENSION_INIT3 \
extern const sqlite3_api_routines *sqlite3_api;
#else
/* This case when the file is being statically linked into the
** application */
# define SQLITE_EXTENSION_INIT1 /*no-op*/
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
# define SQLITE_EXTENSION_INIT3 /*no-op*/
#endif
#endif /* SQLITE3EXT_H */

View File

@ -3,6 +3,7 @@
#include "Core/IoContext.h"
#include "Core/MessageManager.h"
#include "Core/Singleton.h"
#include "Database.h"
#include "HttpSession.h"
#include "Router/router.hpp"
#include "ServiceLogic.h"
@ -28,6 +29,9 @@ Application::Application() : m_d{new ApplicationPrivate()} {
m_ioContext = Singleton<IoContext>::construct(m_settings->threads());
m_database = Singleton<Database>::construct();
m_database->open(m_settings->sqlitePath());
m_corporationContext = Singleton<WeChat::Corporation::Context>::construct(*m_ioContext->ioContext());
m_corporationContext->start();
@ -79,6 +83,7 @@ int Application::exec() {
using namespace Core;
auto settings = Singleton<Settings>::instance();
ServiceLogic::live2dBackend();
ServiceLogic::visitAnalysis();
startAcceptHttpConnections(settings->server(), settings->port());
m_ioContext->run();
return 0;

View File

@ -22,6 +22,7 @@ namespace Older {
class Settings;
class ApplicationPrivate;
class HttpSession;
class Database;
class Application : public std::enable_shared_from_this<Application> {
public:
@ -42,6 +43,7 @@ private:
std::shared_ptr<Settings> m_settings;
std::shared_ptr<Core::IoContext> m_ioContext;
std::shared_ptr<Core::MessageManager> m_messageManager;
std::shared_ptr<Database> m_database;
std::shared_ptr<WeChat::Corporation::Context> m_corporationContext;
};
} // namespace Older

17
Base/DataStructure.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef __DATASTRUCTURE_H__
#define __DATASTRUCTURE_H__
#include <string>
struct VisitorStats{
std::string url;
int visitorCount=0;
int totalViews =0;
int64_t lastViewTime =0;
};
struct SiteStats{
int totalViews =0;
int totalVisitors =0;
};
#endif // __DATASTRUCTURE_H__

View File

@ -1,11 +1,13 @@
find_package(Boost REQUIRED COMPONENTS json)
add_subdirectory(/root/Projects/Kylin Kylin)
add_subdirectory(3rdparty)
add_executable(Older main.cpp
WeChat/Corporation/Context.h WeChat/Corporation/Context.cpp
Application.h Application.cpp
Database.h Database.cpp
HttpSession.h HttpSession.cpp
ResponseUtility.h ResponseUtility.cpp
ServiceLogic.h ServiceLogic.inl ServiceLogic.cpp
@ -21,4 +23,5 @@ target_link_libraries(Older
PRIVATE Kylin::Http
PRIVATE Kylin::Router
PRIVATE Boost::json
PRIVATE sqlite3
)

141
Database.cpp Normal file
View File

@ -0,0 +1,141 @@
#include "Database.h"
#include "Core/Logger.h"
#include <sqlite3.h>
#include <stdexcept>
namespace Older {
bool Database::open(const std::string &path) {
if (sqlite3_open(path.c_str(), &m_sqlite)) {
LOG(error) << "Can't open database: " << sqlite3_errmsg(m_sqlite);
return false;
}
initialize();
return true;
}
void Database::upsertVisitRecord(const std::string &url, const std::string &visitorUuid, const std::string &userAgent,
int64_t viewTime) {
sqlite3_stmt *statement = nullptr;
const char *query = "INSERT INTO visit_analysis (url, visitor_uuid, last_user_agent, last_view_time, page_view_count) "
"VALUES (?, ?, ?, ?, 1) "
"ON CONFLICT(url, visitor_uuid) DO UPDATE SET "
"last_user_agent = excluded.last_user_agent, "
"last_view_time = excluded.last_view_time, "
"page_view_count = page_view_count + 1;";
if (sqlite3_prepare_v2(m_sqlite, query, -1, &statement, nullptr) == SQLITE_OK) {
sqlite3_bind_text(statement, 1, url.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 2, visitorUuid.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 3, userAgent.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_int(statement, 4, viewTime);
if (sqlite3_step(statement) != SQLITE_DONE) {
LOG(error) << "Error inserting/updating record: " << sqlite3_errmsg(m_sqlite);
}
}
sqlite3_finalize(statement);
}
VisitorStats Database::visitorStats(const std::string &url) {
VisitorStats ret;
ret.url = url;
sqlite3_stmt *statement = nullptr;
const char *query = "SELECT COUNT(DISTINCT visitor_uuid) AS visitor_count, SUM(page_view_count) AS total_views "
"FROM visit_analysis WHERE url = ?;";
if (sqlite3_prepare_v2(m_sqlite, query, -1, &statement, nullptr) == SQLITE_OK) {
sqlite3_bind_text(statement, 1, url.c_str(), -1, SQLITE_STATIC);
if (sqlite3_step(statement) == SQLITE_ROW) {
ret.visitorCount = sqlite3_column_int(statement, 0);
ret.totalViews = sqlite3_column_int(statement, 1);
}
}
sqlite3_finalize(statement);
return ret;
}
std::list<VisitorStats> Database::mostViewedUrls(int n) {
std::list<VisitorStats> ret;
sqlite3_stmt *statement = nullptr;
const char *query = "SELECT url, SUM(page_view_count) AS total_page_views "
"FROM visit_analysis "
"GROUP BY url "
"ORDER BY total_page_views DESC "
"LIMIT ?;";
if (sqlite3_prepare_v2(m_sqlite, query, -1, &statement, nullptr) == SQLITE_OK) {
sqlite3_bind_int(statement, 1, n);
while (sqlite3_step(statement) == SQLITE_ROW) {
VisitorStats item;
item.url = reinterpret_cast<const char *>(sqlite3_column_text(statement, 0));
item.totalViews = sqlite3_column_int(statement, 1);
ret.push_back(item);
}
}
sqlite3_finalize(statement);
return ret;
}
std::list<VisitorStats> Database::latestViewedUrls(int n) {
std::list<VisitorStats> ret;
sqlite3_stmt *statement = nullptr;
const char *query = "SELECT url, last_view_time "
"FROM visit_analysis "
"ORDER BY last_view_time DESC "
"LIMIT ?;";
if (sqlite3_prepare_v2(m_sqlite, query, -1, &statement, nullptr) == SQLITE_OK) {
sqlite3_bind_int(statement, 1, n);
while (sqlite3_step(statement) == SQLITE_ROW) {
VisitorStats item;
item.url = reinterpret_cast<const char *>(sqlite3_column_text(statement, 0));
item.lastViewTime = sqlite3_column_int64(statement, 1);
ret.push_back(item);
}
}
sqlite3_finalize(statement);
return ret;
}
SiteStats Database::siteStats() {
SiteStats ret;
sqlite3_stmt *statement;
const char *query = "SELECT COUNT(DISTINCT visitor_uuid) AS total_visitors, SUM(page_view_count) AS total_page_views "
"FROM visit_analysis;";
if (sqlite3_prepare_v2(m_sqlite, query, -1, &statement, nullptr) == SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_ROW) {
ret.totalVisitors = sqlite3_column_int(statement, 0);
ret.totalViews = sqlite3_column_int(statement, 1);
}
}
sqlite3_finalize(statement);
return ret;
}
void Database::initialize() {
createVisitAnalysisTable();
}
void Database::createVisitAnalysisTable() {
const char *createTableQuery = R"(
CREATE TABLE IF NOT EXISTS visit_analysis (
id INTEGER PRIMARY KEY AUTOINCREMENT,
url TEXT NOT NULL,
visitor_uuid TEXT NOT NULL,
last_user_agent TEXT NOT NULL,
last_view_time INTEGER NOT NULL,
page_view_count INTEGER NOT NULL,
UNIQUE(url, visitor_uuid)
);
)";
char *message = nullptr;
int rc = sqlite3_exec(m_sqlite, createTableQuery, nullptr, nullptr, &message);
if (rc != SQLITE_OK) {
LOG(error) << "Error creating table: " << message;
sqlite3_free(message);
}
}
}

30
Database.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef __DATABASE_H__
#define __DATABASE_H__
#include "Base/DataStructure.h"
#include <list>
#include <string>
typedef struct sqlite3 sqlite3;
namespace Older {
class Database {
public:
bool open(const std::string &path);
void upsertVisitRecord(const std::string &url, const std::string &visitorUuid, const std::string &userAgent,
int64_t viewTime);
VisitorStats visitorStats(const std::string &url);
std::list<VisitorStats> mostViewedUrls(int n);
std::list<VisitorStats> latestViewedUrls(int n);
SiteStats siteStats();
protected:
void createVisitAnalysisTable();
void initialize();
private:
sqlite3 *m_sqlite = nullptr;
};}
#endif // __DATABASE_H__

120
Readme.md Normal file
View File

@ -0,0 +1,120 @@
## 前言
因为个人爱好,购买了云服务器,上面部署了静态博客网站,科学上网服务,内网穿透服务。
上述条件弄完之后,还剩下很多性能。所以决定自己实现一个服务器应用程序,代码比较简单,也可以说就是练练手。
## 访问统计
`/api/v1/visit_analysis`
`/api/v1/most_viewed_urls`
`/api/v1/latest_viewed_urls`
表名visit_analysis
| 字段名 | 数据类型 | 约束条件 | 解释 |
| --------------- | -------- | --------------------- | ---- |
| id | INTEGER | NOT NULLPRIMARY KEY | |
| url | TEXT | NOT NULL | |
| visitor_uuid | TEXT | NOT NULL | |
| last_user_agent | TEXT | NOT NULL | |
| last_view_time | INTEGER | NOT NULL | |
| page_view_count | INTEGER | NOT NULL | |
1. 创建table visit_analysis。
2. 插入 urlvisitor_uuidlast_user_agent last_view_time至表中如果表中已存在urlvisitor_uuid 相同的item则更新last_user_agent last_view_time并将page_view_count加1否则创建新的item并将page_view_count赋值为1。
3. 根据url 获取 不同的visitor_uuid的个数作为访客数量统计将所有 page_view_count 累加作为访问次数统计。
4. 将 url 的 所有 page_view_count 累加,统计出 n 个最大的记录。
5. 将 url 的 last_view_time进行排序统计出最新的 n 个记录。
6. 将所有记录的不同 visitor_uuid 相加作为网站总访客数将所有page_view_count相加作为网站总访问次数。
## Live2D 模型添加
在 XML 配置文件定义`Live2dModelsRoot` 字段,值默认为 `resources/live2d`
模型相关文件放置在 DocumentRoot/resources/live2d下。
## 任务清单
| 字段名 | 数据类型 | 约束条件 | 解释 |
| ------------- | ------------ | --------------------- | ---- |
| id | INTEGER | NOT NULLPRIMARY KEY | |
| create_time | INTEGER | NOT NULL | |
| parent_id | INTEGER | | |
| content | VARCHAR(512) | NOT NULL | |
| finished | BOOL | | |
| finished_time | INTEGER | | |
## Core Dump
通过命令`ulimit -a`查看:
```
real-time non-blocking time (microseconds, -R) unlimited
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 6846
max locked memory (kbytes, -l) 228312
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 6846
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
```
core file size这一项为0说明不生成core dump文件。
`/etc/profile`里面加入
```
ulimit -c unlimited
sysctl -w kernel.core_pattern=core_%t_%s_%d_%e
```
查看帮助`man 5 core`
## 微信公众号对接
1. 公众号管理网页:设置与开发→基本配置→服务器配置。
2. 由于使用的是测试公众号,因此只能够接受消息,微信服务器会将该信息发送至我们的服务器,然后我们可以对该消息进行回复,随后该连接将被关闭。
```mermaid
stateDiagram-v2
[*] --> Idle
Idle --> WaitSetAlarmClock : input 1
WaitSetAlarmClock --> Idle : process input
Idle --> WaitSetText : input 2
WaitSetText --> Idle : process input
Idle --> Idle : not found
```
## 修改历史
### 2025/02/28
1. 重新新建项目,只存放服务器业务相关代码和文件。
2. 去除Web Toolkit以后不再使用它了。
### 2021/09/03
1. 通过阿里云申请免费SSL证书放置cert目录中。
2. 修改`conf/nginx.conf`文件使http全部重定向至https。

View File

@ -1,4 +1,6 @@
#include "ServiceLogic.h"
#include "Core/Singleton.h"
#include "Database.h"
#include "HttpSession.h"
#include "Settings.h"
#include <sstream>
@ -30,6 +32,136 @@ http::response<http::string_body> badRequest(const http::request<http::string_bo
return res;
}
void visitAnalysis() {
using namespace Core;
static std::vector<std::string> urlFilter = {
"/", "/search", "/login", "/MessageBoard", "/我的笔记", "/我的笔记/", "/我的博客",
};
auto application = Singleton<Older::Application>::instance();
application->insertUrl("/api/v1/visit_analysis", [](Older::HttpSession &session, const Older::Application::Request &request,
const boost::urls::matches &matches) {
using namespace std::chrono;
using namespace boost::beast;
using namespace Core;
auto rootJson = boost::json::parse(request.body());
auto &root = rootJson.as_object();
std::string url;
if (root.contains("url")) {
url = root["url"].as_string();
}
auto database = Singleton<Older::Database>::instance();
if (std::filesystem::exists("amass_blog" + url) && (url.find("/我的博客/page") != 0) && (url.find("/wt") != 0)) {
if (url.size() > 1 && url.back() == '/') {
url.pop_back();
}
if (root.contains("visitor_uuid") && root.contains("user_agent")) {
auto timestamp = duration_cast<seconds>(system_clock::now().time_since_epoch());
auto visitorUuid = std::string(root["visitor_uuid"].as_string());
auto userAgent = std::string(root["user_agent"].as_string());
database->upsertVisitRecord(url, visitorUuid, userAgent, timestamp.count());
}
}
auto urlStats = database->visitorStats(url);
auto siteStats = database->siteStats();
boost::json::object reply;
reply["page_view_count"] = urlStats.totalViews;
reply["unique_visitor_count"] = urlStats.visitorCount;
reply["site_page_view_count"] = siteStats.totalViews;
reply["site_unique_visitor_count"] = siteStats.totalVisitors;
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
s.set(http::field::content_type, "application/json;charset=UTF-8");
s.keep_alive(request.keep_alive());
s.body() = boost::json::serialize(reply);
s.prepare_payload();
session.reply(std::move(s));
});
application->insertUrl("/api/v1/most_viewed_urls", [](Older::HttpSession &session, const Older::Application::Request &request,
const boost::urls::matches &matches) {
using namespace boost::beast;
int size = 5;
std::error_code error;
if (!request.body().empty()) {
auto rootJson = boost::json::parse(request.body(), error);
if (error) {
LOG(info) << "<" << request.body() << "> parse json error: " << error.message();
} else {
auto &root = rootJson.as_object();
if (root.contains("size")) {
size = root.at("size").as_int64();
}
}
}
auto database = Singleton<Older::Database>::instance();
auto stats = database->mostViewedUrls(size + urlFilter.size());
boost::json::array reply;
int index = 0;
for (auto stat : stats) {
if (std::find(urlFilter.cbegin(), urlFilter.cend(), stat.url) != urlFilter.cend()) continue;
boost::json::object object;
object["url"] = stat.url;
object["count"] = stat.totalViews;
reply.push_back(std::move(object));
index++;
if (index >= size) break;
}
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
s.set(http::field::content_type, "application/json;charset=UTF-8");
s.keep_alive(request.keep_alive());
s.body() = boost::json::serialize(reply);
s.prepare_payload();
session.reply(std::move(s));
});
application->insertUrl(
"/api/v1/latest_viewed_urls",
[](Older::HttpSession &session, const Older::Application::Request &request, const boost::urls::matches &matches) {
using namespace boost::beast;
using namespace std::chrono;
int size = 5;
std::error_code error;
if (!request.body().empty()) {
auto rootJson = boost::json::parse(request.body(), error);
if (error) {
LOG(info) << "<" << request.body() << "> parse json error: " << error.message();
} else {
auto &root = rootJson.as_object();
if (root.contains("size")) {
size = root.at("size").as_int64();
}
}
}
auto database = Singleton<Older::Database>::instance();
auto stats = database->latestViewedUrls(size + urlFilter.size());
boost::json::array reply;
int index = 0;
for (auto &stat : stats) {
if (std::find(urlFilter.cbegin(), urlFilter.cend(), stat.url) != urlFilter.cend()) continue;
boost::json::object object;
object["url"] = stat.url;
object["time"] = stat.lastViewTime;
reply.push_back(std::move(object));
index++;
if (index >= size) break;
}
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
s.set(http::field::content_type, "application/json;charset=UTF-8");
s.keep_alive(request.keep_alive());
s.body() = boost::json::serialize(reply);
s.prepare_payload();
session.reply(std::move(s));
});
}
void live2dBackend() {
using namespace Core;
auto application = Singleton<Older::Application>::instance();

View File

@ -42,6 +42,7 @@ boost::beast::http::response<ResponseBody> make_200(const boost::beast::http::re
}
void live2dBackend();
void visitAnalysis();

View File

@ -17,4 +17,8 @@ std::string Settings::live2dModelsRoot() const {
return m_live2dModelsRoot;
}
std::string Settings::sqlitePath() const{
return m_sqlitePath;
}
} // namespace Older

View File

@ -11,6 +11,7 @@ public:
std::string server() const;
uint16_t port() const;
std::string live2dModelsRoot() const;
std::string sqlitePath() const;
private:
uint32_t m_threads = 1;
@ -18,6 +19,7 @@ private:
uint16_t m_port = 8081;
std::string m_live2dModelsRoot = "resources/live2d";
std::string m_sqlitePath = "database.sqlite";
};
} // namespace Older