From 56b77a536ff1a4d23a211ca6cb333a5f20278be6 Mon Sep 17 00:00:00 2001 From: Scott Ehlert Date: Sun, 14 Sep 2008 02:55:49 -0500 Subject: [PATCH] Removed files for dead branch: refac-jit --HG-- branch : refac-jit --- NOTICE.txt | 36 - changelog.txt | 75 - configs/admin_groups.cfg | 36 - configs/admin_levels.cfg | 49 - configs/admin_overrides.cfg | 21 - configs/adminmenu_cfgs.txt | 10 - configs/adminmenu_custom.txt | 12 - configs/adminmenu_grouping.txt | 20 - configs/adminmenu_sorting.txt | 39 - configs/admins.cfg | 39 - configs/admins_simple.ini | 46 - configs/cfg/sm_warmode_off.cfg | 4 - configs/cfg/sm_warmode_on.cfg | 9 - configs/cfg/sourcemod.cfg | 109 - configs/core.cfg | 105 - configs/databases.cfg | 32 - configs/geoip/GeoIP.dat | Bin 1104406 -> 0 bytes configs/languages.cfg | 6 - configs/maplists.cfg | 59 - configs/metamod/sourcemod.vdf | 5 - configs/plugin_settings.cfg | 38 - .../mysql/clientprefs-mysql.sql | 17 - .../sql-init-scripts/mysql/create_admins.sql | 56 - .../mysql/update_admins_r1409.sql | 15 - .../sql-init-scripts/sqlite/admins-sqlite.sq3 | Bin 17408 -> 0 bytes .../sqlite/clientprefs-sqlite.sq3 | Bin 6144 -> 0 bytes .../sqlite/clientprefs-sqlite.sql | 16 - .../sql-init-scripts/sqlite/create_admins.sql | 54 - .../sqlite/update_admins-r1409.sql | 23 - core/ADTFactory.cpp | 96 - core/ADTFactory.h | 70 - core/AdminCache.cpp | 2081 ----- core/AdminCache.h | 208 - core/CDataPack.cpp | 259 - core/CDataPack.h | 71 - core/CellArray.h | 206 - core/CellRecipientFilter.h | 107 - core/ChatTriggers.cpp | 450 -- core/ChatTriggers.h | 91 - core/ConCmdManager.cpp | 991 --- core/ConCmdManager.h | 161 - core/ConVarManager.cpp | 707 -- core/ConVarManager.h | 165 - core/CoreConfig.cpp | 524 -- core/CoreConfig.h | 74 - core/CrazyDebugger.cpp | 199 - core/Database.cpp | 725 -- core/Database.h | 150 - core/DebugReporter.cpp | 184 - core/DebugReporter.h | 55 - core/EventManager.cpp | 461 -- core/EventManager.h | 128 - core/GameConfigs.cpp | 694 -- core/GameConfigs.h | 112 - core/GameDataFetcher.cpp | 693 -- core/GameDataFetcher.h | 185 - core/HalfLife2.cpp | 541 -- core/HalfLife2.h | 142 - core/Logger.cpp | 520 -- core/Logger.h | 106 - core/Makefile | 136 - core/MemoryUtils.cpp | 220 - core/MemoryUtils.h | 60 - core/MenuManager.cpp | 802 -- core/MenuManager.h | 119 - core/MenuStyle_Base.cpp | 837 -- core/MenuStyle_Base.h | 157 - core/MenuStyle_Radio.cpp | 566 -- core/MenuStyle_Radio.h | 151 - core/MenuStyle_Valve.cpp | 445 -- core/MenuStyle_Valve.h | 141 - core/MenuVoting.cpp | 491 -- core/MenuVoting.h | 104 - core/NativeOwner.cpp | 140 - core/NativeOwner.h | 57 - core/NextMap.cpp | 90 - core/NextMap.h | 52 - core/PhraseCollection.cpp | 131 - core/PhraseCollection.h | 65 - core/PlayerManager.cpp | 1579 ---- core/PlayerManager.h | 203 - core/Profiler.cpp | 487 -- core/Profiler.h | 131 - core/TextParsers.cpp | 1087 --- core/TextParsers.h | 91 - core/ThreadSupport.cpp | 52 - core/ThreadSupport.h | 41 - core/TimerSys.cpp | 487 -- core/TimerSys.h | 110 - core/Translator.cpp | 1076 --- core/Translator.h | 177 - core/UserMessages.cpp | 477 -- core/UserMessages.h | 104 - core/concmd_cleaner.cpp | 175 - core/concmd_cleaner.h | 46 - core/convar_sm.h | 551 -- core/convar_sm_ob.h | 709 -- core/frame_hooks.cpp | 64 - core/frame_hooks.h | 37 - core/md5.cpp | 485 -- core/md5.h | 106 - core/msvc8/sourcemod_mm.sln | 41 - core/msvc8/sourcemod_mm.vcproj | 1755 ----- core/sm_autonatives.cpp | 43 - core/sm_autonatives.h | 57 - core/sm_crc32.cpp | 96 - core/sm_crc32.h | 40 - core/sm_fastlink.h | 218 - core/sm_globals.h | 181 - core/sm_memtable.cpp | 112 - core/sm_memtable.h | 114 - core/sm_queue.h | 333 - core/sm_simple_prioqueue.h | 66 - core/sm_srvcmds.cpp | 358 - core/sm_srvcmds.h | 88 - core/sm_stringutil.cpp | 1582 ---- core/sm_stringutil.h | 64 - core/sm_trie.cpp | 121 - core/sm_trie.h | 53 - core/sm_version.h | 46 - core/sm_version.tpl | 46 - core/smn_admin.cpp | 572 -- core/smn_adt_array.cpp | 588 -- core/smn_adt_stack.cpp | 309 - core/smn_adt_trie.cpp | 532 -- core/smn_banning.cpp | 401 - core/smn_bitbuffer.cpp | 705 -- core/smn_console.cpp | 1307 ---- core/smn_core.cpp | 650 -- core/smn_database.cpp | 1321 ---- core/smn_datapacks.cpp | 328 - core/smn_entities.cpp | 1795 ----- core/smn_events.cpp | 369 - core/smn_fakenatives.cpp | 454 -- core/smn_filesystem.cpp | 963 --- core/smn_float.cpp | 314 - core/smn_functions.cpp | 609 -- core/smn_gameconfigs.cpp | 139 - core/smn_halflife.cpp | 501 -- core/smn_handles.cpp | 117 - core/smn_hudtext.cpp | 475 -- core/smn_keyvalues.cpp | 1122 --- core/smn_lang.cpp | 116 - core/smn_maplists.cpp | 668 -- core/smn_menus.cpp | 1569 ---- core/smn_nextmap.cpp | 63 - core/smn_player.cpp | 1524 ---- core/smn_profiler.cpp | 185 - core/smn_sorting.cpp | 579 -- core/smn_string.cpp | 622 -- core/smn_textparse.cpp | 325 - core/smn_timers.cpp | 346 - core/smn_usermsgs.cpp | 544 -- core/smn_usermsgs.h | 59 - core/smn_vector.cpp | 199 - core/sourcemm_api.cpp | 240 - core/sourcemm_api.h | 109 - core/sourcemod.cpp | 647 -- core/sourcemod.h | 139 - core/systems/ExtensionSys.cpp | 1205 --- core/systems/ExtensionSys.h | 186 - core/systems/ForwardSys.cpp | 737 -- core/systems/ForwardSys.h | 158 - core/systems/HandleSys.cpp | 1067 --- core/systems/HandleSys.h | 225 - core/systems/LibrarySys.cpp | 441 -- core/systems/LibrarySys.h | 103 - core/systems/PluginInfoDatabase.cpp | 349 - core/systems/PluginInfoDatabase.h | 106 - core/systems/PluginSys.cpp | 2692 ------- core/systems/PluginSys.h | 458 -- core/systems/ShareSys.cpp | 515 -- core/systems/ShareSys.h | 150 - core/thread/BaseWorker.cpp | 303 - core/thread/BaseWorker.h | 104 - core/thread/PosixThreads.cpp | 309 - core/thread/PosixThreads.h | 115 - core/thread/ThreadWorker.cpp | 320 - core/thread/ThreadWorker.h | 71 - core/thread/WinThreads.cpp | 320 - core/thread/WinThreads.h | 113 - core/version.rc | 104 - editor/crimson/link/extension.sp | 2 - editor/crimson/spec/sourcepawn.key | 48 - editor/crimson/spec/sourcepawn.spc | 21 - editor/crimson/tools/compile.cmd | Bin 553 -> 0 bytes editor/ida/linux_vtable_dump.idc | 102 - editor/textpad/reg_class.reg | Bin 2958 -> 0 bytes editor/textpad/sourcepawn.syn | 533 -- editor/ultraedit/wordfile.txt | 70 - extensions/bintools/CallMaker.cpp | 65 - extensions/bintools/CallMaker.h | 61 - extensions/bintools/CallWrapper.cpp | 111 - extensions/bintools/CallWrapper.h | 72 - extensions/bintools/Makefile | 127 - extensions/bintools/extension.cpp | 52 - extensions/bintools/extension.h | 121 - extensions/bintools/jit_call.cpp | 651 -- extensions/bintools/jit_call.h | 40 - extensions/bintools/msvc8/bintools.sln | 20 - extensions/bintools/msvc8/bintools.vcproj | 283 - extensions/bintools/sdk/smsdk_config.h | 69 - extensions/bintools/sdk/smsdk_ext.cpp | 416 - extensions/bintools/sdk/smsdk_ext.h | 300 - extensions/bintools/svn_version.h | 42 - extensions/bintools/svn_version.tpl | 42 - extensions/bintools/version.rc | 104 - extensions/clientprefs/Makefile | 127 - extensions/clientprefs/cookie.cpp | 413 - extensions/clientprefs/cookie.h | 144 - extensions/clientprefs/extension.cpp | 315 - extensions/clientprefs/extension.h | 172 - extensions/clientprefs/menus.cpp | 179 - extensions/clientprefs/menus.h | 103 - extensions/clientprefs/msvc8/clientprefs.sln | 20 - .../clientprefs/msvc8/clientprefs.vcproj | 261 - extensions/clientprefs/msvc9/clientprefs.sln | 20 - .../clientprefs/msvc9/clientprefs.vcproj | 260 - extensions/clientprefs/natives.cpp | 361 - extensions/clientprefs/query.cpp | 115 - extensions/clientprefs/query.h | 79 - extensions/clientprefs/sdk/smsdk_config.h | 82 - extensions/clientprefs/sdk/smsdk_ext.cpp | 461 -- extensions/clientprefs/sdk/smsdk_ext.h | 333 - extensions/clientprefs/svn_version.h | 42 - extensions/clientprefs/svn_version.tpl | 42 - extensions/clientprefs/version.rc | 104 - extensions/cstrike/Makefile | 125 - extensions/cstrike/RegNatives.cpp | 50 - extensions/cstrike/RegNatives.h | 48 - extensions/cstrike/extension.cpp | 252 - extensions/cstrike/extension.h | 132 - extensions/cstrike/msvc8/cstrike.sln | 32 - extensions/cstrike/msvc8/cstrike.vcproj | 581 -- extensions/cstrike/natives.cpp | 173 - extensions/cstrike/sdk/smsdk_config.h | 76 - extensions/cstrike/sdk/smsdk_ext.cpp | 422 - extensions/cstrike/sdk/smsdk_ext.h | 310 - extensions/cstrike/svn_version.h | 42 - extensions/cstrike/svn_version.tpl | 42 - extensions/cstrike/timeleft.cpp | 74 - extensions/cstrike/timeleft.h | 48 - extensions/cstrike/version.rc | 104 - extensions/geoip/GeoIP.c | 969 --- extensions/geoip/GeoIP.h | 169 - extensions/geoip/Makefile | 126 - extensions/geoip/extension.cpp | 133 - extensions/geoip/extension.h | 121 - extensions/geoip/msvc8/geoip.sln | 20 - extensions/geoip/msvc8/geoip.vcproj | 246 - extensions/geoip/sdk/smsdk_config.h | 69 - extensions/geoip/sdk/smsdk_ext.cpp | 416 - extensions/geoip/sdk/smsdk_ext.h | 300 - extensions/geoip/svn_version.h | 42 - extensions/geoip/svn_version.tpl | 42 - extensions/geoip/version.rc | 104 - extensions/mysql/Makefile | 133 - extensions/mysql/extension.cpp | 60 - extensions/mysql/extension.h | 119 - extensions/mysql/msvc8/sm_mysql.sln | 20 - extensions/mysql/msvc8/sm_mysql.vcproj | 293 - extensions/mysql/mysql/MyBasicResults.cpp | 367 - extensions/mysql/mysql/MyBasicResults.h | 95 - extensions/mysql/mysql/MyBoundResults.cpp | 686 -- extensions/mysql/mysql/MyBoundResults.h | 103 - extensions/mysql/mysql/MyDatabase.cpp | 318 - extensions/mysql/mysql/MyDatabase.h | 82 - extensions/mysql/mysql/MyDriver.cpp | 233 - extensions/mysql/mysql/MyDriver.h | 79 - extensions/mysql/mysql/MyStatement.cpp | 288 - extensions/mysql/mysql/MyStatement.h | 82 - extensions/mysql/sdk/smsdk_config.h | 74 - extensions/mysql/sdk/smsdk_ext.cpp | 416 - extensions/mysql/sdk/smsdk_ext.h | 300 - extensions/mysql/svn_version.h | 42 - extensions/mysql/svn_version.tpl | 42 - extensions/mysql/version.rc | 104 - extensions/regex/CRegEx.cpp | 155 - extensions/regex/CRegEx.h | 59 - extensions/regex/Makefile | 126 - extensions/regex/extension.cpp | 188 - extensions/regex/extension.h | 133 - extensions/regex/lib_linux/libpcre.a | Bin 161018 -> 0 bytes extensions/regex/lib_win/pcre.lib | Bin 172300 -> 0 bytes extensions/regex/msvc8/regex.sln | 20 - extensions/regex/msvc8/regex.vcproj | 247 - extensions/regex/pcre.h | 305 - extensions/regex/sdk/smsdk_config.h | 81 - extensions/regex/sdk/smsdk_ext.cpp | 455 -- extensions/regex/sdk/smsdk_ext.h | 327 - extensions/regex/svn_version.h | 42 - extensions/regex/svn_version.tpl | 42 - extensions/regex/version.rc | 104 - extensions/sdktools/CellRecipientFilter.h | 107 - extensions/sdktools/Makefile | 129 - extensions/sdktools/detours.h | 98 - extensions/sdktools/extension.cpp | 345 - extensions/sdktools/extension.h | 124 - extensions/sdktools/inputnatives.cpp | 288 - extensions/sdktools/msvc8/sdktools.sln | 32 - extensions/sdktools/msvc8/sdktools.vcproj | 665 -- extensions/sdktools/msvc9/sdktools.sln | 32 - extensions/sdktools/msvc9/sdktools.vcproj | 660 -- extensions/sdktools/output.cpp | 489 -- extensions/sdktools/output.h | 148 - extensions/sdktools/outputnatives.cpp | 278 - extensions/sdktools/sdk/smsdk_config.h | 75 - extensions/sdktools/sdk/smsdk_ext.cpp | 422 - extensions/sdktools/sdk/smsdk_ext.h | 310 - extensions/sdktools/svn_version.h | 42 - extensions/sdktools/svn_version.tpl | 42 - extensions/sdktools/teamnatives.cpp | 177 - extensions/sdktools/tempents.cpp | 493 -- extensions/sdktools/tempents.h | 118 - extensions/sdktools/tenatives.cpp | 561 -- extensions/sdktools/trnatives.cpp | 577 -- extensions/sdktools/util.h | 72 - extensions/sdktools/vcallbuilder.cpp | 369 - extensions/sdktools/vcallbuilder.h | 74 - extensions/sdktools/vcaller.cpp | 455 -- extensions/sdktools/vdecoder.cpp | 612 -- extensions/sdktools/vdecoder.h | 151 - extensions/sdktools/version.rc | 104 - extensions/sdktools/vglobals.cpp | 162 - extensions/sdktools/vglobals.h | 41 - extensions/sdktools/vhelpers.cpp | 826 -- extensions/sdktools/vhelpers.h | 75 - extensions/sdktools/vnatives.cpp | 1006 --- extensions/sdktools/vnatives.h | 41 - extensions/sdktools/voice.cpp | 285 - extensions/sdktools/vsound.cpp | 789 -- extensions/sdktools/vsound.h | 76 - extensions/sdktools/vstringtable.cpp | 266 - extensions/sqlite/Makefile | 155 - extensions/sqlite/driver/SqDatabase.cpp | 247 - extensions/sqlite/driver/SqDatabase.h | 71 - extensions/sqlite/driver/SqDriver.cpp | 285 - extensions/sqlite/driver/SqDriver.h | 82 - extensions/sqlite/driver/SqQuery.cpp | 205 - extensions/sqlite/driver/SqQuery.h | 95 - extensions/sqlite/driver/SqResults.cpp | 482 -- extensions/sqlite/driver/SqResults.h | 100 - extensions/sqlite/extension.cpp | 72 - extensions/sqlite/extension.h | 121 - extensions/sqlite/msvc8/sm_sqlite.sln | 20 - extensions/sqlite/msvc8/sm_sqlite.vcproj | 893 --- extensions/sqlite/sdk/sm_memtable.cpp | 112 - extensions/sqlite/sdk/sm_memtable.h | 105 - extensions/sqlite/sdk/smsdk_config.h | 75 - extensions/sqlite/sdk/smsdk_ext.cpp | 415 - extensions/sqlite/sdk/smsdk_ext.h | 300 - extensions/sqlite/sqlite-source/alter.c | 622 -- extensions/sqlite/sqlite-source/analyze.c | 418 - extensions/sqlite/sqlite-source/attach.c | 521 -- extensions/sqlite/sqlite-source/auth.c | 234 - extensions/sqlite/sqlite-source/btmutex.c | 315 - extensions/sqlite/sqlite-source/btree.c | 6890 ----------------- extensions/sqlite/sqlite-source/btree.h | 204 - extensions/sqlite/sqlite-source/btreeInt.h | 648 -- extensions/sqlite/sqlite-source/build.c | 3409 -------- extensions/sqlite/sqlite-source/callback.c | 378 - extensions/sqlite/sqlite-source/complete.c | 271 - extensions/sqlite/sqlite-source/date.c | 1045 --- extensions/sqlite/sqlite-source/delete.c | 467 -- extensions/sqlite/sqlite-source/expr.c | 2617 ------- extensions/sqlite/sqlite-source/func.c | 1509 ---- extensions/sqlite/sqlite-source/hash.c | 418 - extensions/sqlite/sqlite-source/hash.h | 110 - extensions/sqlite/sqlite-source/insert.c | 1605 ---- extensions/sqlite/sqlite-source/journal.c | 238 - extensions/sqlite/sqlite-source/keywordhash.h | 112 - extensions/sqlite/sqlite-source/legacy.c | 134 - extensions/sqlite/sqlite-source/main.c | 1485 ---- extensions/sqlite/sqlite-source/malloc.c | 240 - extensions/sqlite/sqlite-source/mem1.c | 229 - extensions/sqlite/sqlite-source/mem2.c | 546 -- extensions/sqlite/sqlite-source/mutex.c | 126 - extensions/sqlite/sqlite-source/mutex.h | 82 - extensions/sqlite/sqlite-source/mutex_unix.c | 223 - extensions/sqlite/sqlite-source/mutex_w32.c | 208 - extensions/sqlite/sqlite-source/opcodes.c | 151 - extensions/sqlite/sqlite-source/opcodes.h | 160 - extensions/sqlite/sqlite-source/os.c | 282 - extensions/sqlite/sqlite-source/os.h | 284 - extensions/sqlite/sqlite-source/os_common.h | 127 - extensions/sqlite/sqlite-source/os_unix.c | 2749 ------- extensions/sqlite/sqlite-source/os_win.c | 1545 ---- extensions/sqlite/sqlite-source/pager.c | 5104 ------------ extensions/sqlite/sqlite-source/pager.h | 125 - extensions/sqlite/sqlite-source/parse.c | 3505 --------- extensions/sqlite/sqlite-source/parse.h | 152 - extensions/sqlite/sqlite-source/pragma.c | 1186 --- extensions/sqlite/sqlite-source/prepare.c | 742 -- extensions/sqlite/sqlite-source/printf.c | 907 --- extensions/sqlite/sqlite-source/random.c | 103 - extensions/sqlite/sqlite-source/select.c | 3539 --------- extensions/sqlite/sqlite-source/sqlite3.h | 3552 --------- extensions/sqlite/sqlite-source/sqlite3ext.h | 350 - extensions/sqlite/sqlite-source/sqliteInt.h | 1972 ----- extensions/sqlite/sqlite-source/sqliteLimit.h | 169 - extensions/sqlite/sqlite-source/table.c | 206 - extensions/sqlite/sqlite-source/tokenize.c | 508 -- extensions/sqlite/sqlite-source/trigger.c | 839 -- extensions/sqlite/sqlite-source/update.c | 630 -- extensions/sqlite/sqlite-source/utf.c | 545 -- extensions/sqlite/sqlite-source/util.c | 706 -- extensions/sqlite/sqlite-source/vacuum.c | 262 - extensions/sqlite/sqlite-source/vdbe.c | 5279 ------------- extensions/sqlite/sqlite-source/vdbe.h | 151 - extensions/sqlite/sqlite-source/vdbeInt.h | 427 - extensions/sqlite/sqlite-source/vdbeapi.c | 1066 --- extensions/sqlite/sqlite-source/vdbeaux.c | 2243 ------ extensions/sqlite/sqlite-source/vdbeblob.c | 340 - extensions/sqlite/sqlite-source/vdbefifo.c | 114 - extensions/sqlite/sqlite-source/vdbemem.c | 1017 --- extensions/sqlite/sqlite-source/vtab.c | 797 -- extensions/sqlite/sqlite-source/where.c | 2773 ------- extensions/sqlite/svn_version.h | 42 - extensions/sqlite/svn_version.tpl | 42 - extensions/sqlite/version.rc | 104 - extensions/tf2/CDetour/detourhelpers.h | 98 - extensions/tf2/CDetour/detours.cpp | 372 - extensions/tf2/CDetour/detours.h | 196 - extensions/tf2/Makefile | 128 - extensions/tf2/RegNatives.cpp | 52 - extensions/tf2/RegNatives.h | 48 - extensions/tf2/asm/asm.c | 329 - extensions/tf2/asm/asm.h | 38 - extensions/tf2/criticals.cpp | 163 - extensions/tf2/criticals.h | 49 - extensions/tf2/extension.cpp | 364 - extensions/tf2/extension.h | 162 - extensions/tf2/msvc8/tf2.sln | 20 - extensions/tf2/msvc8/tf2.vcproj | 289 - extensions/tf2/msvc9/tf2.sln | 20 - extensions/tf2/msvc9/tf2.vcproj | 288 - extensions/tf2/natives.cpp | 227 - extensions/tf2/sdk/smsdk_config.h | 76 - extensions/tf2/sdk/smsdk_ext.cpp | 422 - extensions/tf2/sdk/smsdk_ext.h | 310 - extensions/tf2/svn_version.h | 42 - extensions/tf2/svn_version.tpl | 42 - extensions/tf2/util.cpp | 134 - extensions/tf2/util.h | 57 - extensions/tf2/version.rc | 104 - extensions/topmenus/Makefile | 128 - extensions/topmenus/TopMenu.cpp | 1142 --- extensions/topmenus/TopMenu.h | 181 - extensions/topmenus/TopMenuManager.cpp | 119 - extensions/topmenus/TopMenuManager.h | 67 - extensions/topmenus/extension.cpp | 66 - extensions/topmenus/extension.h | 66 - extensions/topmenus/msvc8/topmenus.sln | 20 - extensions/topmenus/msvc8/topmenus.vcproj | 274 - extensions/topmenus/sdk/sm_memtable.cpp | 112 - extensions/topmenus/sdk/sm_memtable.h | 109 - extensions/topmenus/sdk/smsdk_config.h | 80 - extensions/topmenus/sdk/smsdk_ext.cpp | 440 -- extensions/topmenus/sdk/smsdk_ext.h | 321 - extensions/topmenus/smn_topmenus.cpp | 388 - extensions/topmenus/smn_topmenus.h | 41 - extensions/topmenus/svn_version.h | 42 - extensions/topmenus/svn_version.tpl | 42 - extensions/topmenus/version.rc | 104 - gamedata/core.games.txt | 135 - gamedata/sdktools.games.ep2.txt | 444 -- gamedata/sdktools.games.txt | 1801 ----- gamedata/sm-cstrike.games.txt | 21 - gamedata/sm-tf2.games.txt | 54 - loader/Makefile | 72 - loader/loader.cpp | 318 - loader/msvc8/loader.sln | 20 - loader/msvc8/loader.vcproj | 206 - loader/svn_version.h | 46 - loader/svn_version.tpl | 46 - loader/version.rc | 104 - modules.versions | 76 - plugins/admin-flatfile/admin-flatfile.sp | 96 - plugins/admin-flatfile/admin-groups.sp | 244 - plugins/admin-flatfile/admin-overrides.sp | 213 - plugins/admin-flatfile/admin-simple.sp | 223 - plugins/admin-flatfile/admin-users.sp | 247 - plugins/admin-sql-prefetch.sp | 386 - plugins/admin-sql-threaded.sp | 855 -- plugins/adminhelp.sp | 155 - plugins/adminmenu.sp | 290 - plugins/adminmenu/dynamicmenu.sp | 646 -- plugins/antiflood.sp | 118 - plugins/basebans.sp | 296 - plugins/basebans/ban.sp | 270 - plugins/basechat.sp | 479 -- plugins/basecomm.sp | 230 - plugins/basecomm/gag.sp | 580 -- plugins/basecommands.sp | 399 - plugins/basecommands/cancelvote.sp | 75 - plugins/basecommands/execcfg.sp | 158 - plugins/basecommands/kick.sp | 193 - plugins/basecommands/map.sp | 150 - plugins/basecommands/reloadadmins.sp | 67 - plugins/basecommands/who.sp | 262 - plugins/basetriggers.sp | 327 - plugins/basevotes.sp | 430 - plugins/basevotes/voteban.sp | 182 - plugins/basevotes/votekick.sp | 171 - plugins/basevotes/votemap.sp | 283 - plugins/clientprefs.sp | 156 - plugins/compile.sh | 11 - plugins/funcommands.sp | 412 - plugins/funcommands/beacon.sp | 280 - plugins/funcommands/blind.sp | 279 - plugins/funcommands/drug.sp | 315 - plugins/funcommands/fire.sp | 504 -- plugins/funcommands/gravity.sp | 252 - plugins/funcommands/ice.sp | 573 -- plugins/funcommands/noclip.sp | 175 - plugins/funcommands/timebomb.sp | 365 - plugins/funvotes.sp | 355 - plugins/funvotes/votealltalk.sp | 104 - plugins/funvotes/voteburn.sp | 178 - plugins/funvotes/voteff.sp | 103 - plugins/funvotes/votegravity.sp | 139 - plugins/funvotes/voteslay.sp | 179 - plugins/include/admin.inc | 622 -- plugins/include/adminmenu.inc | 153 - plugins/include/adt.inc | 40 - plugins/include/adt_array.inc | 283 - plugins/include/adt_stack.inc | 154 - plugins/include/adt_trie.inc | 158 - plugins/include/banning.inc | 157 - plugins/include/bitbuffer.inc | 325 - plugins/include/clientprefs.inc | 230 - plugins/include/clients.inc | 684 -- plugins/include/commandfilters.inc | 134 - plugins/include/console.inc | 771 -- plugins/include/core.inc | 141 - plugins/include/cstrike.inc | 88 - plugins/include/datapack.inc | 142 - plugins/include/dbi.inc | 633 -- plugins/include/entity.inc | 679 -- plugins/include/entity_prop_stocks.inc | 324 - plugins/include/events.inc | 243 - plugins/include/files.inc | 388 - plugins/include/float.inc | 415 - plugins/include/functions.inc | 489 -- plugins/include/geoip.inc | 102 - plugins/include/halflife.inc | 544 -- plugins/include/handles.inc | 96 - plugins/include/helpers.inc | 294 - plugins/include/keyvalues.inc | 429 - plugins/include/lang.inc | 96 - plugins/include/logging.inc | 153 - plugins/include/mapchooser.inc | 80 - plugins/include/menus.inc | 809 -- plugins/include/nextmap.inc | 54 - plugins/include/profiler.inc | 77 - plugins/include/regex.inc | 173 - plugins/include/sdktools.inc | 212 - plugins/include/sdktools_engine.inc | 69 - plugins/include/sdktools_entinput.inc | 116 - plugins/include/sdktools_entoutput.inc | 91 - plugins/include/sdktools_functions.inc | 322 - plugins/include/sdktools_sound.inc | 442 -- plugins/include/sdktools_stocks.inc | 76 - plugins/include/sdktools_stringtables.inc | 180 - plugins/include/sdktools_tempents.inc | 229 - plugins/include/sdktools_tempents_stocks.inc | 458 -- plugins/include/sdktools_trace.inc | 367 - plugins/include/sdktools_voice.inc | 85 - plugins/include/sorting.inc | 176 - plugins/include/sourcemod.inc | 555 -- plugins/include/string.inc | 557 -- plugins/include/textparse.inc | 203 - plugins/include/tf2.inc | 137 - plugins/include/tf2_stocks.inc | 219 - plugins/include/timers.inc | 208 - plugins/include/topmenus.inc | 290 - plugins/include/usermessages.inc | 202 - plugins/include/vector.inc | 188 - plugins/include/version.inc | 42 - plugins/include/version.tpl | 42 - plugins/mapchooser.sp | 957 --- plugins/nextmap.sp | 213 - plugins/nominations.sp | 323 - plugins/playercommands.sp | 103 - plugins/playercommands/slap.sp | 217 - plugins/playercommands/slay.sp | 159 - plugins/randomcycle.sp | 119 - plugins/reservedslots.sp | 310 - plugins/rockthevote.sp | 305 - plugins/sql-admin-manager.sp | 894 --- plugins/testsuite/benchmark.sp | 157 - plugins/testsuite/callfunctest.sp | 169 - plugins/testsuite/clientprefstest.sp | 59 - plugins/testsuite/fakenative1.sp | 85 - plugins/testsuite/fakenative2.sp | 87 - plugins/testsuite/fwdtest1.sp | 167 - plugins/testsuite/fwdtest2.sp | 43 - plugins/testsuite/goto_test.sp | 28 - plugins/testsuite/outputtest.sp | 59 - plugins/testsuite/sorttest.sp | 331 - plugins/testsuite/sqltest.sp | 178 - plugins/testsuite/sqltest.sql | 7 - plugins/testsuite/stacktest.sp | 53 - plugins/testsuite/tf2-test.sp | 167 - public/IADTFactory.h | 114 - public/IAdminSystem.h | 724 -- public/IDBDriver.h | 882 --- public/IDataPack.h | 166 - public/IExtensionSys.h | 439 -- public/IForwardSys.h | 424 - public/IGameConfigs.h | 148 - public/IGameHelpers.h | 151 - public/IHandleSys.h | 363 - public/ILibrarySys.h | 229 - public/IMemoryUtils.h | 71 - public/IMenuManager.h | 920 --- public/IPlayerHelpers.h | 478 -- public/IPluginSys.h | 359 - public/IRootConsoleMenu.h | 105 - public/IShareSys.h | 227 - public/ISourceMod.h | 254 - public/ITextParsers.h | 432 -- public/IThreader.h | 455 -- public/ITimerSystem.h | 209 - public/ITranslator.h | 329 - public/IUserMessages.h | 157 - public/compat_wrappers.h | 79 - public/doxygen/SourceMod.doxyfile | 262 - public/extensions/IBinTools.h | 201 - public/extensions/ITopMenus.h | 317 - public/jit/jit_helpers.h | 134 - public/jit/x86/x86_macros.h | 1517 ---- public/licenses/GPLv2.txt | 339 - public/licenses/GPLv3.txt | 674 -- public/licenses/LICENSE.txt | 39 - public/metamod_wrappers.h | 50 - public/mms_sample_ext/Makefile | 108 - public/mms_sample_ext/sm_ext.cpp | 176 - public/mms_sample_ext/sm_ext.h | 69 - public/mms_sample_ext/sm_sdk_config.cpp | 190 - public/mms_sample_ext/sm_sdk_config.h | 165 - public/mms_sample_ext/stub_mm.cpp | 144 - public/mms_sample_ext/stub_mm.h | 54 - public/mms_sample_ext/stub_util.cpp | 38 - public/mms_sample_ext/stub_util.h | 31 - public/sample_ext/Makefile | 126 - public/sample_ext/extension.cpp | 41 - public/sample_ext/extension.h | 119 - public/sample_ext/msvc8/sdk.sln | 38 - public/sample_ext/msvc8/sdk.vcproj | 718 -- public/sample_ext/sdk/smsdk_config.h | 80 - public/sample_ext/sdk/smsdk_ext.cpp | 461 -- public/sample_ext/sdk/smsdk_ext.h | 333 - public/sm_platform.h | 82 - public/sm_trie_tpl.h | 1102 --- public/sourcepawn/sp_file_headers.h | 227 - public/sourcepawn/sp_typeutil.h | 65 - public/sourcepawn/sp_vm_api.h | 1231 --- public/sourcepawn/sp_vm_base.h | 51 - public/sourcepawn/sp_vm_types.h | 207 - sourcepawn/batchtool/compile.cfg | 38 - sourcepawn/batchtool/compile.dpr | 101 - sourcepawn/batchtool/compile.exe | Bin 113664 -> 0 bytes sourcepawn/batchtool/icon.rc | 1 - sourcepawn/batchtool/icon.res | Bin 8696 -> 0 bytes sourcepawn/batchtool/pawn.ico | Bin 8478 -> 0 bytes sourcepawn/batchtool/uFunc.pas | 224 - sourcepawn/batchtool/version.rc | 33 - sourcepawn/batchtool/version.res | Bin 832 -> 0 bytes sourcepawn/compiler/Makefile | 74 - sourcepawn/compiler/amx.h | 630 -- sourcepawn/compiler/amxdbg.h | 173 - sourcepawn/compiler/binreloc.c | 766 -- sourcepawn/compiler/binreloc.h | 80 - sourcepawn/compiler/getch.h | 15 - sourcepawn/compiler/libpawnc.c | 270 - sourcepawn/compiler/libpawnc.rc | 52 - sourcepawn/compiler/lstring.c | 124 - sourcepawn/compiler/lstring.h | 18 - sourcepawn/compiler/memfile.c | 116 - sourcepawn/compiler/memfile.h | 55 - sourcepawn/compiler/msvc8/spcomp.sln | 20 - sourcepawn/compiler/msvc8/spcomp.vcproj | 466 -- sourcepawn/compiler/osdefs.h | 109 - sourcepawn/compiler/pawn.ico | Bin 8478 -> 0 bytes sourcepawn/compiler/pawncc.c | 501 -- sourcepawn/compiler/sc.h | 863 --- sourcepawn/compiler/sc1.c | 6665 ---------------- sourcepawn/compiler/sc2.c | 2900 ------- sourcepawn/compiler/sc3.c | 2826 ------- sourcepawn/compiler/sc4.c | 1378 ---- sourcepawn/compiler/sc5.c | 228 - sourcepawn/compiler/sc5.scp | 360 - sourcepawn/compiler/sc6.c | 1308 ---- sourcepawn/compiler/sc7.c | 703 -- sourcepawn/compiler/sc7.scp | 2022 ----- sourcepawn/compiler/scexpand.c | 68 - sourcepawn/compiler/sci18n.c | 428 - sourcepawn/compiler/sclinux.h | 47 - sourcepawn/compiler/sclist.c | 531 -- sourcepawn/compiler/scmemfil.c | 167 - sourcepawn/compiler/scpack.c | 450 -- sourcepawn/compiler/scstate.c | 375 - sourcepawn/compiler/sctracker.c | 429 - sourcepawn/compiler/sctracker.h | 117 - sourcepawn/compiler/scvars.c | 113 - sourcepawn/compiler/sp_file.c | 276 - sourcepawn/compiler/sp_file.h | 81 - sourcepawn/compiler/svn_version.h | 25 - sourcepawn/compiler/svn_version.tpl | 25 - sourcepawn/compiler/zlib/adler32.c | 149 - sourcepawn/compiler/zlib/compress.c | 79 - sourcepawn/compiler/zlib/crc32.c | 423 - sourcepawn/compiler/zlib/crc32.h | 441 -- sourcepawn/compiler/zlib/deflate.c | 1736 ----- sourcepawn/compiler/zlib/deflate.h | 331 - sourcepawn/compiler/zlib/gzio.c | 1026 --- sourcepawn/compiler/zlib/infback.c | 623 -- sourcepawn/compiler/zlib/inffast.c | 318 - sourcepawn/compiler/zlib/inffast.h | 11 - sourcepawn/compiler/zlib/inffixed.h | 94 - sourcepawn/compiler/zlib/inflate.c | 1368 ---- sourcepawn/compiler/zlib/inflate.h | 115 - sourcepawn/compiler/zlib/inftrees.c | 329 - sourcepawn/compiler/zlib/inftrees.h | 55 - sourcepawn/compiler/zlib/trees.c | 1219 --- sourcepawn/compiler/zlib/trees.h | 128 - sourcepawn/compiler/zlib/uncompr.c | 61 - sourcepawn/compiler/zlib/zconf.h | 281 - sourcepawn/compiler/zlib/zlib.h | 1357 ---- sourcepawn/compiler/zlib/zutil.c | 318 - sourcepawn/compiler/zlib/zutil.h | 269 - sourcepawn/jit/BaseRuntime.cpp | 357 - sourcepawn/jit/BaseRuntime.h | 60 - sourcepawn/jit/Makefile | 98 - sourcepawn/jit/dll_exports.cpp | 76 - sourcepawn/jit/dll_exports.h | 47 - sourcepawn/jit/engine2.cpp | 278 - sourcepawn/jit/engine2.h | 35 - sourcepawn/jit/jit_shared.h | 95 - sourcepawn/jit/jit_version.h | 38 - sourcepawn/jit/jit_version.tpl | 38 - sourcepawn/jit/msvc8/jit-x86.sln | 20 - sourcepawn/jit/msvc8/jit-x86.vcproj | 364 - sourcepawn/jit/sp_vm_basecontext.cpp | 810 -- sourcepawn/jit/sp_vm_basecontext.h | 114 - sourcepawn/jit/sp_vm_engine.cpp | 456 -- sourcepawn/jit/sp_vm_engine.h | 123 - sourcepawn/jit/sp_vm_function.cpp | 355 - sourcepawn/jit/sp_vm_function.h | 104 - sourcepawn/jit/version.rc | 103 - sourcepawn/jit/x86/jit_x86.cpp | 3049 -------- sourcepawn/jit/x86/jit_x86.h | 164 - sourcepawn/jit/x86/opcode_helpers.cpp | 912 --- sourcepawn/jit/x86/opcode_helpers.h | 321 - sourcepawn/jit/x86/opcode_switch.inc | 779 -- sourcepawn/jit/x86/ungen_opcode_switch.inc | 121 - sourcepawn/jit/x86/ungen_opcodes.h | 325 - sourcepawn/jit/zlib/adler32.c | 149 - sourcepawn/jit/zlib/compress.c | 79 - sourcepawn/jit/zlib/crc32.c | 423 - sourcepawn/jit/zlib/crc32.h | 441 -- sourcepawn/jit/zlib/deflate.c | 1736 ----- sourcepawn/jit/zlib/deflate.h | 331 - sourcepawn/jit/zlib/gzio.c | 1026 --- sourcepawn/jit/zlib/infback.c | 623 -- sourcepawn/jit/zlib/inffast.c | 318 - sourcepawn/jit/zlib/inffast.h | 11 - sourcepawn/jit/zlib/inffixed.h | 94 - sourcepawn/jit/zlib/inflate.c | 1368 ---- sourcepawn/jit/zlib/inflate.h | 115 - sourcepawn/jit/zlib/inftrees.c | 329 - sourcepawn/jit/zlib/inftrees.h | 55 - sourcepawn/jit/zlib/trees.c | 1219 --- sourcepawn/jit/zlib/trees.h | 128 - sourcepawn/jit/zlib/uncompr.c | 61 - sourcepawn/jit/zlib/zconf.h | 281 - sourcepawn/jit/zlib/zlib.h | 1357 ---- sourcepawn/jit/zlib/zutil.c | 318 - sourcepawn/jit/zlib/zutil.h | 269 - tools/Vtable scanner/Makefile | 76 - tools/Vtable scanner/dodscan.sh | 16 - tools/Vtable scanner/libiberty.a | Bin 261460 -> 0 bytes tools/Vtable scanner/main.cpp | 184 - tools/Vtable scanner/tfscan.sh | 17 - tools/builder/ABuilder.cs | 199 - tools/builder/AssemblyInfo.cs | 58 - tools/builder/Config.cs | 110 - tools/builder/LinuxBuilder.cs | 118 - tools/builder/Main.cs | 50 - tools/builder/Makefile | 15 - tools/builder/Package.cs | 103 - tools/builder/PkgCore.cs | 328 - tools/builder/Win32Builder.cs | 116 - tools/builder/build-linux.cfg | 4 - tools/builder/build-win32.cfg | 3 - tools/builder/builder.csproj | 130 - tools/builder/builder.sln | 23 - tools/crc32/build.sh | 2 - tools/crc32/main.cpp | 46 - tools/daemon/Makefile | 76 - tools/daemon/smud.cpp | 130 - tools/daemon/smud.h | 25 - tools/daemon/smud_connections.cpp | 404 - tools/daemon/smud_connections.h | 109 - tools/daemon/smud_threads.cpp | 86 - tools/daemon/smud_threads.h | 41 - tools/daemon/updateGameData.sh | 30 - tools/fetchdlls/fetchdlls.sln | 20 - tools/fetchdlls/fetchdlls.vcproj | 196 - tools/fetchdlls/main.cpp | 192 - tools/gamedata md5/Makefile | 74 - tools/gamedata md5/TextParsers.cpp | 1082 --- tools/gamedata md5/TextParsers.h | 87 - tools/gamedata md5/main.cpp | 45 - tools/gamedata md5/main.h | 88 - tools/gamedata md5/md5.cpp | 485 -- tools/gamedata md5/md5.h | 106 - tools/gamedata md5/msvc9/gamedatamd5.sln | 20 - tools/gamedata md5/msvc9/gamedatamd5.vcproj | 219 - tools/gamedata md5/sm_memtable.cpp | 112 - tools/gamedata md5/sm_memtable.h | 114 - tools/incparser/IncParser.cs | 1342 ---- tools/incparser/ParseWriter.cs | 174 - tools/incparser/Program.cs | 183 - tools/incparser/Properties/AssemblyInfo.cs | 33 - tools/incparser/incparser.csproj | 55 - tools/incparser/incparser.sln | 20 - tools/installer/CCriticalSection.h | 37 - tools/installer/CFileList.cpp | 151 - tools/installer/CFileList.h | 40 - tools/installer/ChooseMethod.cpp | 235 - tools/installer/ChooseMethod.h | 11 - tools/installer/GamesList.cpp | 574 -- tools/installer/GamesList.h | 72 - tools/installer/ICopyMethod.h | 25 - tools/installer/InstallerMain.cpp | 142 - tools/installer/InstallerMain.h | 14 - tools/installer/InstallerUtil.cpp | 312 - tools/installer/InstallerUtil.h | 20 - tools/installer/LocalCopyMethod.cpp | 167 - tools/installer/LocalCopyMethod.h | 29 - tools/installer/PerformInstall.cpp | 438 -- tools/installer/PerformInstall.h | 22 - tools/installer/Resource.h | 65 - tools/installer/SelectGame.cpp | 169 - tools/installer/SelectGame.h | 8 - tools/installer/Welcome.cpp | 60 - tools/installer/Welcome.h | 6 - tools/installer/installer.ico | Bin 23558 -> 0 bytes tools/installer/installer.rc | 222 - tools/installer/installer.sln | 20 - tools/installer/installer.vcproj | 298 - tools/installer/platform_headers.h | 33 - tools/profiler/csharp/Comparators.cs | 85 - tools/profiler/csharp/Form1.Designer.cs | 243 - tools/profiler/csharp/Form1.cs | 98 - tools/profiler/csharp/Form1.resx | 126 - tools/profiler/csharp/ProfReport.cs | 159 - tools/profiler/csharp/Program.cs | 20 - tools/profiler/csharp/profviewer.csproj | 80 - tools/profiler/csharp/profviewer.sln | 20 - tools/profiler/php/ProfFileParser.class.php | 73 - tools/versionchanger.pl | 165 - translations/adminhelp.phrases.txt | 34 - translations/adminmenu.phrases.txt | 22 - translations/antiflood.phrases.txt | 7 - translations/basebans.phrases.txt | 52 - translations/basecomm.phrases.txt | 48 - translations/basetriggers.phrases.txt | 74 - translations/basevotes.phrases.txt | 83 - translations/clientprefs.phrases.txt | 43 - translations/common.phrases.txt | 242 - translations/core.phrases.txt | 59 - translations/funcommands.phrases.txt | 174 - translations/funvotes.phrases.txt | 102 - translations/mapchooser.phrases.txt | 40 - translations/nextmap.phrases.txt | 13 - translations/nominations.phrases.txt | 48 - translations/plugin.basecommands.txt | 138 - translations/reservedslots.phrases.txt | 7 - translations/rockthevote.phrases.txt | 74 - translations/slapslay.phrases.txt | 29 - translations/sqladmins.phrases.txt | 80 - 884 files changed, 297368 deletions(-) delete mode 100644 NOTICE.txt delete mode 100644 changelog.txt delete mode 100644 configs/admin_groups.cfg delete mode 100644 configs/admin_levels.cfg delete mode 100644 configs/admin_overrides.cfg delete mode 100644 configs/adminmenu_cfgs.txt delete mode 100644 configs/adminmenu_custom.txt delete mode 100644 configs/adminmenu_grouping.txt delete mode 100644 configs/adminmenu_sorting.txt delete mode 100644 configs/admins.cfg delete mode 100644 configs/admins_simple.ini delete mode 100644 configs/cfg/sm_warmode_off.cfg delete mode 100644 configs/cfg/sm_warmode_on.cfg delete mode 100644 configs/cfg/sourcemod.cfg delete mode 100644 configs/core.cfg delete mode 100644 configs/databases.cfg delete mode 100644 configs/geoip/GeoIP.dat delete mode 100644 configs/languages.cfg delete mode 100644 configs/maplists.cfg delete mode 100644 configs/metamod/sourcemod.vdf delete mode 100644 configs/plugin_settings.cfg delete mode 100644 configs/sql-init-scripts/mysql/clientprefs-mysql.sql delete mode 100644 configs/sql-init-scripts/mysql/create_admins.sql delete mode 100644 configs/sql-init-scripts/mysql/update_admins_r1409.sql delete mode 100644 configs/sql-init-scripts/sqlite/admins-sqlite.sq3 delete mode 100644 configs/sql-init-scripts/sqlite/clientprefs-sqlite.sq3 delete mode 100644 configs/sql-init-scripts/sqlite/clientprefs-sqlite.sql delete mode 100644 configs/sql-init-scripts/sqlite/create_admins.sql delete mode 100644 configs/sql-init-scripts/sqlite/update_admins-r1409.sql delete mode 100644 core/ADTFactory.cpp delete mode 100644 core/ADTFactory.h delete mode 100644 core/AdminCache.cpp delete mode 100644 core/AdminCache.h delete mode 100644 core/CDataPack.cpp delete mode 100644 core/CDataPack.h delete mode 100644 core/CellArray.h delete mode 100644 core/CellRecipientFilter.h delete mode 100644 core/ChatTriggers.cpp delete mode 100644 core/ChatTriggers.h delete mode 100644 core/ConCmdManager.cpp delete mode 100644 core/ConCmdManager.h delete mode 100644 core/ConVarManager.cpp delete mode 100644 core/ConVarManager.h delete mode 100644 core/CoreConfig.cpp delete mode 100644 core/CoreConfig.h delete mode 100644 core/CrazyDebugger.cpp delete mode 100644 core/Database.cpp delete mode 100644 core/Database.h delete mode 100644 core/DebugReporter.cpp delete mode 100644 core/DebugReporter.h delete mode 100644 core/EventManager.cpp delete mode 100644 core/EventManager.h delete mode 100644 core/GameConfigs.cpp delete mode 100644 core/GameConfigs.h delete mode 100644 core/GameDataFetcher.cpp delete mode 100644 core/GameDataFetcher.h delete mode 100644 core/HalfLife2.cpp delete mode 100644 core/HalfLife2.h delete mode 100644 core/Logger.cpp delete mode 100644 core/Logger.h delete mode 100644 core/Makefile delete mode 100644 core/MemoryUtils.cpp delete mode 100644 core/MemoryUtils.h delete mode 100644 core/MenuManager.cpp delete mode 100644 core/MenuManager.h delete mode 100644 core/MenuStyle_Base.cpp delete mode 100644 core/MenuStyle_Base.h delete mode 100644 core/MenuStyle_Radio.cpp delete mode 100644 core/MenuStyle_Radio.h delete mode 100644 core/MenuStyle_Valve.cpp delete mode 100644 core/MenuStyle_Valve.h delete mode 100644 core/MenuVoting.cpp delete mode 100644 core/MenuVoting.h delete mode 100644 core/NativeOwner.cpp delete mode 100644 core/NativeOwner.h delete mode 100644 core/NextMap.cpp delete mode 100644 core/NextMap.h delete mode 100644 core/PhraseCollection.cpp delete mode 100644 core/PhraseCollection.h delete mode 100644 core/PlayerManager.cpp delete mode 100644 core/PlayerManager.h delete mode 100644 core/Profiler.cpp delete mode 100644 core/Profiler.h delete mode 100644 core/TextParsers.cpp delete mode 100644 core/TextParsers.h delete mode 100644 core/ThreadSupport.cpp delete mode 100644 core/ThreadSupport.h delete mode 100644 core/TimerSys.cpp delete mode 100644 core/TimerSys.h delete mode 100644 core/Translator.cpp delete mode 100644 core/Translator.h delete mode 100644 core/UserMessages.cpp delete mode 100644 core/UserMessages.h delete mode 100644 core/concmd_cleaner.cpp delete mode 100644 core/concmd_cleaner.h delete mode 100644 core/convar_sm.h delete mode 100644 core/convar_sm_ob.h delete mode 100644 core/frame_hooks.cpp delete mode 100644 core/frame_hooks.h delete mode 100644 core/md5.cpp delete mode 100644 core/md5.h delete mode 100644 core/msvc8/sourcemod_mm.sln delete mode 100644 core/msvc8/sourcemod_mm.vcproj delete mode 100644 core/sm_autonatives.cpp delete mode 100644 core/sm_autonatives.h delete mode 100644 core/sm_crc32.cpp delete mode 100644 core/sm_crc32.h delete mode 100644 core/sm_fastlink.h delete mode 100644 core/sm_globals.h delete mode 100644 core/sm_memtable.cpp delete mode 100644 core/sm_memtable.h delete mode 100644 core/sm_queue.h delete mode 100644 core/sm_simple_prioqueue.h delete mode 100644 core/sm_srvcmds.cpp delete mode 100644 core/sm_srvcmds.h delete mode 100644 core/sm_stringutil.cpp delete mode 100644 core/sm_stringutil.h delete mode 100644 core/sm_trie.cpp delete mode 100644 core/sm_trie.h delete mode 100644 core/sm_version.h delete mode 100644 core/sm_version.tpl delete mode 100644 core/smn_admin.cpp delete mode 100644 core/smn_adt_array.cpp delete mode 100644 core/smn_adt_stack.cpp delete mode 100644 core/smn_adt_trie.cpp delete mode 100644 core/smn_banning.cpp delete mode 100644 core/smn_bitbuffer.cpp delete mode 100644 core/smn_console.cpp delete mode 100644 core/smn_core.cpp delete mode 100644 core/smn_database.cpp delete mode 100644 core/smn_datapacks.cpp delete mode 100644 core/smn_entities.cpp delete mode 100644 core/smn_events.cpp delete mode 100644 core/smn_fakenatives.cpp delete mode 100644 core/smn_filesystem.cpp delete mode 100644 core/smn_float.cpp delete mode 100644 core/smn_functions.cpp delete mode 100644 core/smn_gameconfigs.cpp delete mode 100644 core/smn_halflife.cpp delete mode 100644 core/smn_handles.cpp delete mode 100644 core/smn_hudtext.cpp delete mode 100644 core/smn_keyvalues.cpp delete mode 100644 core/smn_lang.cpp delete mode 100644 core/smn_maplists.cpp delete mode 100644 core/smn_menus.cpp delete mode 100644 core/smn_nextmap.cpp delete mode 100644 core/smn_player.cpp delete mode 100644 core/smn_profiler.cpp delete mode 100644 core/smn_sorting.cpp delete mode 100644 core/smn_string.cpp delete mode 100644 core/smn_textparse.cpp delete mode 100644 core/smn_timers.cpp delete mode 100644 core/smn_usermsgs.cpp delete mode 100644 core/smn_usermsgs.h delete mode 100644 core/smn_vector.cpp delete mode 100644 core/sourcemm_api.cpp delete mode 100644 core/sourcemm_api.h delete mode 100644 core/sourcemod.cpp delete mode 100644 core/sourcemod.h delete mode 100644 core/systems/ExtensionSys.cpp delete mode 100644 core/systems/ExtensionSys.h delete mode 100644 core/systems/ForwardSys.cpp delete mode 100644 core/systems/ForwardSys.h delete mode 100644 core/systems/HandleSys.cpp delete mode 100644 core/systems/HandleSys.h delete mode 100644 core/systems/LibrarySys.cpp delete mode 100644 core/systems/LibrarySys.h delete mode 100644 core/systems/PluginInfoDatabase.cpp delete mode 100644 core/systems/PluginInfoDatabase.h delete mode 100644 core/systems/PluginSys.cpp delete mode 100644 core/systems/PluginSys.h delete mode 100644 core/systems/ShareSys.cpp delete mode 100644 core/systems/ShareSys.h delete mode 100644 core/thread/BaseWorker.cpp delete mode 100644 core/thread/BaseWorker.h delete mode 100644 core/thread/PosixThreads.cpp delete mode 100644 core/thread/PosixThreads.h delete mode 100644 core/thread/ThreadWorker.cpp delete mode 100644 core/thread/ThreadWorker.h delete mode 100644 core/thread/WinThreads.cpp delete mode 100644 core/thread/WinThreads.h delete mode 100644 core/version.rc delete mode 100644 editor/crimson/link/extension.sp delete mode 100644 editor/crimson/spec/sourcepawn.key delete mode 100644 editor/crimson/spec/sourcepawn.spc delete mode 100644 editor/crimson/tools/compile.cmd delete mode 100644 editor/ida/linux_vtable_dump.idc delete mode 100644 editor/textpad/reg_class.reg delete mode 100644 editor/textpad/sourcepawn.syn delete mode 100644 editor/ultraedit/wordfile.txt delete mode 100644 extensions/bintools/CallMaker.cpp delete mode 100644 extensions/bintools/CallMaker.h delete mode 100644 extensions/bintools/CallWrapper.cpp delete mode 100644 extensions/bintools/CallWrapper.h delete mode 100644 extensions/bintools/Makefile delete mode 100644 extensions/bintools/extension.cpp delete mode 100644 extensions/bintools/extension.h delete mode 100644 extensions/bintools/jit_call.cpp delete mode 100644 extensions/bintools/jit_call.h delete mode 100644 extensions/bintools/msvc8/bintools.sln delete mode 100644 extensions/bintools/msvc8/bintools.vcproj delete mode 100644 extensions/bintools/sdk/smsdk_config.h delete mode 100644 extensions/bintools/sdk/smsdk_ext.cpp delete mode 100644 extensions/bintools/sdk/smsdk_ext.h delete mode 100644 extensions/bintools/svn_version.h delete mode 100644 extensions/bintools/svn_version.tpl delete mode 100644 extensions/bintools/version.rc delete mode 100644 extensions/clientprefs/Makefile delete mode 100644 extensions/clientprefs/cookie.cpp delete mode 100644 extensions/clientprefs/cookie.h delete mode 100644 extensions/clientprefs/extension.cpp delete mode 100644 extensions/clientprefs/extension.h delete mode 100644 extensions/clientprefs/menus.cpp delete mode 100644 extensions/clientprefs/menus.h delete mode 100644 extensions/clientprefs/msvc8/clientprefs.sln delete mode 100644 extensions/clientprefs/msvc8/clientprefs.vcproj delete mode 100644 extensions/clientprefs/msvc9/clientprefs.sln delete mode 100644 extensions/clientprefs/msvc9/clientprefs.vcproj delete mode 100644 extensions/clientprefs/natives.cpp delete mode 100644 extensions/clientprefs/query.cpp delete mode 100644 extensions/clientprefs/query.h delete mode 100644 extensions/clientprefs/sdk/smsdk_config.h delete mode 100644 extensions/clientprefs/sdk/smsdk_ext.cpp delete mode 100644 extensions/clientprefs/sdk/smsdk_ext.h delete mode 100644 extensions/clientprefs/svn_version.h delete mode 100644 extensions/clientprefs/svn_version.tpl delete mode 100644 extensions/clientprefs/version.rc delete mode 100644 extensions/cstrike/Makefile delete mode 100644 extensions/cstrike/RegNatives.cpp delete mode 100644 extensions/cstrike/RegNatives.h delete mode 100644 extensions/cstrike/extension.cpp delete mode 100644 extensions/cstrike/extension.h delete mode 100644 extensions/cstrike/msvc8/cstrike.sln delete mode 100644 extensions/cstrike/msvc8/cstrike.vcproj delete mode 100644 extensions/cstrike/natives.cpp delete mode 100644 extensions/cstrike/sdk/smsdk_config.h delete mode 100644 extensions/cstrike/sdk/smsdk_ext.cpp delete mode 100644 extensions/cstrike/sdk/smsdk_ext.h delete mode 100644 extensions/cstrike/svn_version.h delete mode 100644 extensions/cstrike/svn_version.tpl delete mode 100644 extensions/cstrike/timeleft.cpp delete mode 100644 extensions/cstrike/timeleft.h delete mode 100644 extensions/cstrike/version.rc delete mode 100644 extensions/geoip/GeoIP.c delete mode 100644 extensions/geoip/GeoIP.h delete mode 100644 extensions/geoip/Makefile delete mode 100644 extensions/geoip/extension.cpp delete mode 100644 extensions/geoip/extension.h delete mode 100644 extensions/geoip/msvc8/geoip.sln delete mode 100644 extensions/geoip/msvc8/geoip.vcproj delete mode 100644 extensions/geoip/sdk/smsdk_config.h delete mode 100644 extensions/geoip/sdk/smsdk_ext.cpp delete mode 100644 extensions/geoip/sdk/smsdk_ext.h delete mode 100644 extensions/geoip/svn_version.h delete mode 100644 extensions/geoip/svn_version.tpl delete mode 100644 extensions/geoip/version.rc delete mode 100644 extensions/mysql/Makefile delete mode 100644 extensions/mysql/extension.cpp delete mode 100644 extensions/mysql/extension.h delete mode 100644 extensions/mysql/msvc8/sm_mysql.sln delete mode 100644 extensions/mysql/msvc8/sm_mysql.vcproj delete mode 100644 extensions/mysql/mysql/MyBasicResults.cpp delete mode 100644 extensions/mysql/mysql/MyBasicResults.h delete mode 100644 extensions/mysql/mysql/MyBoundResults.cpp delete mode 100644 extensions/mysql/mysql/MyBoundResults.h delete mode 100644 extensions/mysql/mysql/MyDatabase.cpp delete mode 100644 extensions/mysql/mysql/MyDatabase.h delete mode 100644 extensions/mysql/mysql/MyDriver.cpp delete mode 100644 extensions/mysql/mysql/MyDriver.h delete mode 100644 extensions/mysql/mysql/MyStatement.cpp delete mode 100644 extensions/mysql/mysql/MyStatement.h delete mode 100644 extensions/mysql/sdk/smsdk_config.h delete mode 100644 extensions/mysql/sdk/smsdk_ext.cpp delete mode 100644 extensions/mysql/sdk/smsdk_ext.h delete mode 100644 extensions/mysql/svn_version.h delete mode 100644 extensions/mysql/svn_version.tpl delete mode 100644 extensions/mysql/version.rc delete mode 100644 extensions/regex/CRegEx.cpp delete mode 100644 extensions/regex/CRegEx.h delete mode 100644 extensions/regex/Makefile delete mode 100644 extensions/regex/extension.cpp delete mode 100644 extensions/regex/extension.h delete mode 100644 extensions/regex/lib_linux/libpcre.a delete mode 100644 extensions/regex/lib_win/pcre.lib delete mode 100644 extensions/regex/msvc8/regex.sln delete mode 100644 extensions/regex/msvc8/regex.vcproj delete mode 100644 extensions/regex/pcre.h delete mode 100644 extensions/regex/sdk/smsdk_config.h delete mode 100644 extensions/regex/sdk/smsdk_ext.cpp delete mode 100644 extensions/regex/sdk/smsdk_ext.h delete mode 100644 extensions/regex/svn_version.h delete mode 100644 extensions/regex/svn_version.tpl delete mode 100644 extensions/regex/version.rc delete mode 100644 extensions/sdktools/CellRecipientFilter.h delete mode 100644 extensions/sdktools/Makefile delete mode 100644 extensions/sdktools/detours.h delete mode 100644 extensions/sdktools/extension.cpp delete mode 100644 extensions/sdktools/extension.h delete mode 100644 extensions/sdktools/inputnatives.cpp delete mode 100644 extensions/sdktools/msvc8/sdktools.sln delete mode 100644 extensions/sdktools/msvc8/sdktools.vcproj delete mode 100644 extensions/sdktools/msvc9/sdktools.sln delete mode 100644 extensions/sdktools/msvc9/sdktools.vcproj delete mode 100644 extensions/sdktools/output.cpp delete mode 100644 extensions/sdktools/output.h delete mode 100644 extensions/sdktools/outputnatives.cpp delete mode 100644 extensions/sdktools/sdk/smsdk_config.h delete mode 100644 extensions/sdktools/sdk/smsdk_ext.cpp delete mode 100644 extensions/sdktools/sdk/smsdk_ext.h delete mode 100644 extensions/sdktools/svn_version.h delete mode 100644 extensions/sdktools/svn_version.tpl delete mode 100644 extensions/sdktools/teamnatives.cpp delete mode 100644 extensions/sdktools/tempents.cpp delete mode 100644 extensions/sdktools/tempents.h delete mode 100644 extensions/sdktools/tenatives.cpp delete mode 100644 extensions/sdktools/trnatives.cpp delete mode 100644 extensions/sdktools/util.h delete mode 100644 extensions/sdktools/vcallbuilder.cpp delete mode 100644 extensions/sdktools/vcallbuilder.h delete mode 100644 extensions/sdktools/vcaller.cpp delete mode 100644 extensions/sdktools/vdecoder.cpp delete mode 100644 extensions/sdktools/vdecoder.h delete mode 100644 extensions/sdktools/version.rc delete mode 100644 extensions/sdktools/vglobals.cpp delete mode 100644 extensions/sdktools/vglobals.h delete mode 100644 extensions/sdktools/vhelpers.cpp delete mode 100644 extensions/sdktools/vhelpers.h delete mode 100644 extensions/sdktools/vnatives.cpp delete mode 100644 extensions/sdktools/vnatives.h delete mode 100644 extensions/sdktools/voice.cpp delete mode 100644 extensions/sdktools/vsound.cpp delete mode 100644 extensions/sdktools/vsound.h delete mode 100644 extensions/sdktools/vstringtable.cpp delete mode 100644 extensions/sqlite/Makefile delete mode 100644 extensions/sqlite/driver/SqDatabase.cpp delete mode 100644 extensions/sqlite/driver/SqDatabase.h delete mode 100644 extensions/sqlite/driver/SqDriver.cpp delete mode 100644 extensions/sqlite/driver/SqDriver.h delete mode 100644 extensions/sqlite/driver/SqQuery.cpp delete mode 100644 extensions/sqlite/driver/SqQuery.h delete mode 100644 extensions/sqlite/driver/SqResults.cpp delete mode 100644 extensions/sqlite/driver/SqResults.h delete mode 100644 extensions/sqlite/extension.cpp delete mode 100644 extensions/sqlite/extension.h delete mode 100644 extensions/sqlite/msvc8/sm_sqlite.sln delete mode 100644 extensions/sqlite/msvc8/sm_sqlite.vcproj delete mode 100644 extensions/sqlite/sdk/sm_memtable.cpp delete mode 100644 extensions/sqlite/sdk/sm_memtable.h delete mode 100644 extensions/sqlite/sdk/smsdk_config.h delete mode 100644 extensions/sqlite/sdk/smsdk_ext.cpp delete mode 100644 extensions/sqlite/sdk/smsdk_ext.h delete mode 100644 extensions/sqlite/sqlite-source/alter.c delete mode 100644 extensions/sqlite/sqlite-source/analyze.c delete mode 100644 extensions/sqlite/sqlite-source/attach.c delete mode 100644 extensions/sqlite/sqlite-source/auth.c delete mode 100644 extensions/sqlite/sqlite-source/btmutex.c delete mode 100644 extensions/sqlite/sqlite-source/btree.c delete mode 100644 extensions/sqlite/sqlite-source/btree.h delete mode 100644 extensions/sqlite/sqlite-source/btreeInt.h delete mode 100644 extensions/sqlite/sqlite-source/build.c delete mode 100644 extensions/sqlite/sqlite-source/callback.c delete mode 100644 extensions/sqlite/sqlite-source/complete.c delete mode 100644 extensions/sqlite/sqlite-source/date.c delete mode 100644 extensions/sqlite/sqlite-source/delete.c delete mode 100644 extensions/sqlite/sqlite-source/expr.c delete mode 100644 extensions/sqlite/sqlite-source/func.c delete mode 100644 extensions/sqlite/sqlite-source/hash.c delete mode 100644 extensions/sqlite/sqlite-source/hash.h delete mode 100644 extensions/sqlite/sqlite-source/insert.c delete mode 100644 extensions/sqlite/sqlite-source/journal.c delete mode 100644 extensions/sqlite/sqlite-source/keywordhash.h delete mode 100644 extensions/sqlite/sqlite-source/legacy.c delete mode 100644 extensions/sqlite/sqlite-source/main.c delete mode 100644 extensions/sqlite/sqlite-source/malloc.c delete mode 100644 extensions/sqlite/sqlite-source/mem1.c delete mode 100644 extensions/sqlite/sqlite-source/mem2.c delete mode 100644 extensions/sqlite/sqlite-source/mutex.c delete mode 100644 extensions/sqlite/sqlite-source/mutex.h delete mode 100644 extensions/sqlite/sqlite-source/mutex_unix.c delete mode 100644 extensions/sqlite/sqlite-source/mutex_w32.c delete mode 100644 extensions/sqlite/sqlite-source/opcodes.c delete mode 100644 extensions/sqlite/sqlite-source/opcodes.h delete mode 100644 extensions/sqlite/sqlite-source/os.c delete mode 100644 extensions/sqlite/sqlite-source/os.h delete mode 100644 extensions/sqlite/sqlite-source/os_common.h delete mode 100644 extensions/sqlite/sqlite-source/os_unix.c delete mode 100644 extensions/sqlite/sqlite-source/os_win.c delete mode 100644 extensions/sqlite/sqlite-source/pager.c delete mode 100644 extensions/sqlite/sqlite-source/pager.h delete mode 100644 extensions/sqlite/sqlite-source/parse.c delete mode 100644 extensions/sqlite/sqlite-source/parse.h delete mode 100644 extensions/sqlite/sqlite-source/pragma.c delete mode 100644 extensions/sqlite/sqlite-source/prepare.c delete mode 100644 extensions/sqlite/sqlite-source/printf.c delete mode 100644 extensions/sqlite/sqlite-source/random.c delete mode 100644 extensions/sqlite/sqlite-source/select.c delete mode 100644 extensions/sqlite/sqlite-source/sqlite3.h delete mode 100644 extensions/sqlite/sqlite-source/sqlite3ext.h delete mode 100644 extensions/sqlite/sqlite-source/sqliteInt.h delete mode 100644 extensions/sqlite/sqlite-source/sqliteLimit.h delete mode 100644 extensions/sqlite/sqlite-source/table.c delete mode 100644 extensions/sqlite/sqlite-source/tokenize.c delete mode 100644 extensions/sqlite/sqlite-source/trigger.c delete mode 100644 extensions/sqlite/sqlite-source/update.c delete mode 100644 extensions/sqlite/sqlite-source/utf.c delete mode 100644 extensions/sqlite/sqlite-source/util.c delete mode 100644 extensions/sqlite/sqlite-source/vacuum.c delete mode 100644 extensions/sqlite/sqlite-source/vdbe.c delete mode 100644 extensions/sqlite/sqlite-source/vdbe.h delete mode 100644 extensions/sqlite/sqlite-source/vdbeInt.h delete mode 100644 extensions/sqlite/sqlite-source/vdbeapi.c delete mode 100644 extensions/sqlite/sqlite-source/vdbeaux.c delete mode 100644 extensions/sqlite/sqlite-source/vdbeblob.c delete mode 100644 extensions/sqlite/sqlite-source/vdbefifo.c delete mode 100644 extensions/sqlite/sqlite-source/vdbemem.c delete mode 100644 extensions/sqlite/sqlite-source/vtab.c delete mode 100644 extensions/sqlite/sqlite-source/where.c delete mode 100644 extensions/sqlite/svn_version.h delete mode 100644 extensions/sqlite/svn_version.tpl delete mode 100644 extensions/sqlite/version.rc delete mode 100644 extensions/tf2/CDetour/detourhelpers.h delete mode 100644 extensions/tf2/CDetour/detours.cpp delete mode 100644 extensions/tf2/CDetour/detours.h delete mode 100644 extensions/tf2/Makefile delete mode 100644 extensions/tf2/RegNatives.cpp delete mode 100644 extensions/tf2/RegNatives.h delete mode 100644 extensions/tf2/asm/asm.c delete mode 100644 extensions/tf2/asm/asm.h delete mode 100644 extensions/tf2/criticals.cpp delete mode 100644 extensions/tf2/criticals.h delete mode 100644 extensions/tf2/extension.cpp delete mode 100644 extensions/tf2/extension.h delete mode 100644 extensions/tf2/msvc8/tf2.sln delete mode 100644 extensions/tf2/msvc8/tf2.vcproj delete mode 100644 extensions/tf2/msvc9/tf2.sln delete mode 100644 extensions/tf2/msvc9/tf2.vcproj delete mode 100644 extensions/tf2/natives.cpp delete mode 100644 extensions/tf2/sdk/smsdk_config.h delete mode 100644 extensions/tf2/sdk/smsdk_ext.cpp delete mode 100644 extensions/tf2/sdk/smsdk_ext.h delete mode 100644 extensions/tf2/svn_version.h delete mode 100644 extensions/tf2/svn_version.tpl delete mode 100644 extensions/tf2/util.cpp delete mode 100644 extensions/tf2/util.h delete mode 100644 extensions/tf2/version.rc delete mode 100644 extensions/topmenus/Makefile delete mode 100644 extensions/topmenus/TopMenu.cpp delete mode 100644 extensions/topmenus/TopMenu.h delete mode 100644 extensions/topmenus/TopMenuManager.cpp delete mode 100644 extensions/topmenus/TopMenuManager.h delete mode 100644 extensions/topmenus/extension.cpp delete mode 100644 extensions/topmenus/extension.h delete mode 100644 extensions/topmenus/msvc8/topmenus.sln delete mode 100644 extensions/topmenus/msvc8/topmenus.vcproj delete mode 100644 extensions/topmenus/sdk/sm_memtable.cpp delete mode 100644 extensions/topmenus/sdk/sm_memtable.h delete mode 100644 extensions/topmenus/sdk/smsdk_config.h delete mode 100644 extensions/topmenus/sdk/smsdk_ext.cpp delete mode 100644 extensions/topmenus/sdk/smsdk_ext.h delete mode 100644 extensions/topmenus/smn_topmenus.cpp delete mode 100644 extensions/topmenus/smn_topmenus.h delete mode 100644 extensions/topmenus/svn_version.h delete mode 100644 extensions/topmenus/svn_version.tpl delete mode 100644 extensions/topmenus/version.rc delete mode 100644 gamedata/core.games.txt delete mode 100644 gamedata/sdktools.games.ep2.txt delete mode 100644 gamedata/sdktools.games.txt delete mode 100644 gamedata/sm-cstrike.games.txt delete mode 100644 gamedata/sm-tf2.games.txt delete mode 100644 loader/Makefile delete mode 100644 loader/loader.cpp delete mode 100644 loader/msvc8/loader.sln delete mode 100644 loader/msvc8/loader.vcproj delete mode 100644 loader/svn_version.h delete mode 100644 loader/svn_version.tpl delete mode 100644 loader/version.rc delete mode 100644 modules.versions delete mode 100644 plugins/admin-flatfile/admin-flatfile.sp delete mode 100644 plugins/admin-flatfile/admin-groups.sp delete mode 100644 plugins/admin-flatfile/admin-overrides.sp delete mode 100644 plugins/admin-flatfile/admin-simple.sp delete mode 100644 plugins/admin-flatfile/admin-users.sp delete mode 100644 plugins/admin-sql-prefetch.sp delete mode 100644 plugins/admin-sql-threaded.sp delete mode 100644 plugins/adminhelp.sp delete mode 100644 plugins/adminmenu.sp delete mode 100644 plugins/adminmenu/dynamicmenu.sp delete mode 100644 plugins/antiflood.sp delete mode 100644 plugins/basebans.sp delete mode 100644 plugins/basebans/ban.sp delete mode 100644 plugins/basechat.sp delete mode 100644 plugins/basecomm.sp delete mode 100644 plugins/basecomm/gag.sp delete mode 100644 plugins/basecommands.sp delete mode 100644 plugins/basecommands/cancelvote.sp delete mode 100644 plugins/basecommands/execcfg.sp delete mode 100644 plugins/basecommands/kick.sp delete mode 100644 plugins/basecommands/map.sp delete mode 100644 plugins/basecommands/reloadadmins.sp delete mode 100644 plugins/basecommands/who.sp delete mode 100644 plugins/basetriggers.sp delete mode 100644 plugins/basevotes.sp delete mode 100644 plugins/basevotes/voteban.sp delete mode 100644 plugins/basevotes/votekick.sp delete mode 100644 plugins/basevotes/votemap.sp delete mode 100644 plugins/clientprefs.sp delete mode 100755 plugins/compile.sh delete mode 100644 plugins/funcommands.sp delete mode 100644 plugins/funcommands/beacon.sp delete mode 100644 plugins/funcommands/blind.sp delete mode 100644 plugins/funcommands/drug.sp delete mode 100644 plugins/funcommands/fire.sp delete mode 100644 plugins/funcommands/gravity.sp delete mode 100644 plugins/funcommands/ice.sp delete mode 100644 plugins/funcommands/noclip.sp delete mode 100644 plugins/funcommands/timebomb.sp delete mode 100644 plugins/funvotes.sp delete mode 100644 plugins/funvotes/votealltalk.sp delete mode 100644 plugins/funvotes/voteburn.sp delete mode 100644 plugins/funvotes/voteff.sp delete mode 100644 plugins/funvotes/votegravity.sp delete mode 100644 plugins/funvotes/voteslay.sp delete mode 100644 plugins/include/admin.inc delete mode 100644 plugins/include/adminmenu.inc delete mode 100644 plugins/include/adt.inc delete mode 100644 plugins/include/adt_array.inc delete mode 100644 plugins/include/adt_stack.inc delete mode 100644 plugins/include/adt_trie.inc delete mode 100644 plugins/include/banning.inc delete mode 100644 plugins/include/bitbuffer.inc delete mode 100644 plugins/include/clientprefs.inc delete mode 100644 plugins/include/clients.inc delete mode 100644 plugins/include/commandfilters.inc delete mode 100644 plugins/include/console.inc delete mode 100644 plugins/include/core.inc delete mode 100644 plugins/include/cstrike.inc delete mode 100644 plugins/include/datapack.inc delete mode 100644 plugins/include/dbi.inc delete mode 100644 plugins/include/entity.inc delete mode 100644 plugins/include/entity_prop_stocks.inc delete mode 100644 plugins/include/events.inc delete mode 100644 plugins/include/files.inc delete mode 100644 plugins/include/float.inc delete mode 100644 plugins/include/functions.inc delete mode 100644 plugins/include/geoip.inc delete mode 100644 plugins/include/halflife.inc delete mode 100644 plugins/include/handles.inc delete mode 100644 plugins/include/helpers.inc delete mode 100644 plugins/include/keyvalues.inc delete mode 100644 plugins/include/lang.inc delete mode 100644 plugins/include/logging.inc delete mode 100644 plugins/include/mapchooser.inc delete mode 100644 plugins/include/menus.inc delete mode 100644 plugins/include/nextmap.inc delete mode 100644 plugins/include/profiler.inc delete mode 100644 plugins/include/regex.inc delete mode 100644 plugins/include/sdktools.inc delete mode 100644 plugins/include/sdktools_engine.inc delete mode 100644 plugins/include/sdktools_entinput.inc delete mode 100644 plugins/include/sdktools_entoutput.inc delete mode 100644 plugins/include/sdktools_functions.inc delete mode 100644 plugins/include/sdktools_sound.inc delete mode 100644 plugins/include/sdktools_stocks.inc delete mode 100644 plugins/include/sdktools_stringtables.inc delete mode 100644 plugins/include/sdktools_tempents.inc delete mode 100644 plugins/include/sdktools_tempents_stocks.inc delete mode 100644 plugins/include/sdktools_trace.inc delete mode 100644 plugins/include/sdktools_voice.inc delete mode 100644 plugins/include/sorting.inc delete mode 100644 plugins/include/sourcemod.inc delete mode 100644 plugins/include/string.inc delete mode 100644 plugins/include/textparse.inc delete mode 100644 plugins/include/tf2.inc delete mode 100644 plugins/include/tf2_stocks.inc delete mode 100644 plugins/include/timers.inc delete mode 100644 plugins/include/topmenus.inc delete mode 100644 plugins/include/usermessages.inc delete mode 100644 plugins/include/vector.inc delete mode 100644 plugins/include/version.inc delete mode 100644 plugins/include/version.tpl delete mode 100644 plugins/mapchooser.sp delete mode 100644 plugins/nextmap.sp delete mode 100644 plugins/nominations.sp delete mode 100644 plugins/playercommands.sp delete mode 100644 plugins/playercommands/slap.sp delete mode 100644 plugins/playercommands/slay.sp delete mode 100644 plugins/randomcycle.sp delete mode 100644 plugins/reservedslots.sp delete mode 100644 plugins/rockthevote.sp delete mode 100644 plugins/sql-admin-manager.sp delete mode 100644 plugins/testsuite/benchmark.sp delete mode 100644 plugins/testsuite/callfunctest.sp delete mode 100644 plugins/testsuite/clientprefstest.sp delete mode 100644 plugins/testsuite/fakenative1.sp delete mode 100644 plugins/testsuite/fakenative2.sp delete mode 100644 plugins/testsuite/fwdtest1.sp delete mode 100644 plugins/testsuite/fwdtest2.sp delete mode 100644 plugins/testsuite/goto_test.sp delete mode 100644 plugins/testsuite/outputtest.sp delete mode 100644 plugins/testsuite/sorttest.sp delete mode 100644 plugins/testsuite/sqltest.sp delete mode 100644 plugins/testsuite/sqltest.sql delete mode 100644 plugins/testsuite/stacktest.sp delete mode 100644 plugins/testsuite/tf2-test.sp delete mode 100644 public/IADTFactory.h delete mode 100644 public/IAdminSystem.h delete mode 100644 public/IDBDriver.h delete mode 100644 public/IDataPack.h delete mode 100644 public/IExtensionSys.h delete mode 100644 public/IForwardSys.h delete mode 100644 public/IGameConfigs.h delete mode 100644 public/IGameHelpers.h delete mode 100644 public/IHandleSys.h delete mode 100644 public/ILibrarySys.h delete mode 100644 public/IMemoryUtils.h delete mode 100644 public/IMenuManager.h delete mode 100644 public/IPlayerHelpers.h delete mode 100644 public/IPluginSys.h delete mode 100644 public/IRootConsoleMenu.h delete mode 100644 public/IShareSys.h delete mode 100644 public/ISourceMod.h delete mode 100644 public/ITextParsers.h delete mode 100644 public/IThreader.h delete mode 100644 public/ITimerSystem.h delete mode 100644 public/ITranslator.h delete mode 100644 public/IUserMessages.h delete mode 100644 public/compat_wrappers.h delete mode 100644 public/doxygen/SourceMod.doxyfile delete mode 100644 public/extensions/IBinTools.h delete mode 100644 public/extensions/ITopMenus.h delete mode 100644 public/jit/jit_helpers.h delete mode 100644 public/jit/x86/x86_macros.h delete mode 100644 public/licenses/GPLv2.txt delete mode 100644 public/licenses/GPLv3.txt delete mode 100644 public/licenses/LICENSE.txt delete mode 100644 public/metamod_wrappers.h delete mode 100644 public/mms_sample_ext/Makefile delete mode 100644 public/mms_sample_ext/sm_ext.cpp delete mode 100644 public/mms_sample_ext/sm_ext.h delete mode 100644 public/mms_sample_ext/sm_sdk_config.cpp delete mode 100644 public/mms_sample_ext/sm_sdk_config.h delete mode 100644 public/mms_sample_ext/stub_mm.cpp delete mode 100644 public/mms_sample_ext/stub_mm.h delete mode 100644 public/mms_sample_ext/stub_util.cpp delete mode 100644 public/mms_sample_ext/stub_util.h delete mode 100644 public/sample_ext/Makefile delete mode 100644 public/sample_ext/extension.cpp delete mode 100644 public/sample_ext/extension.h delete mode 100644 public/sample_ext/msvc8/sdk.sln delete mode 100644 public/sample_ext/msvc8/sdk.vcproj delete mode 100644 public/sample_ext/sdk/smsdk_config.h delete mode 100644 public/sample_ext/sdk/smsdk_ext.cpp delete mode 100644 public/sample_ext/sdk/smsdk_ext.h delete mode 100644 public/sm_platform.h delete mode 100644 public/sm_trie_tpl.h delete mode 100644 public/sourcepawn/sp_file_headers.h delete mode 100644 public/sourcepawn/sp_typeutil.h delete mode 100644 public/sourcepawn/sp_vm_api.h delete mode 100644 public/sourcepawn/sp_vm_base.h delete mode 100644 public/sourcepawn/sp_vm_types.h delete mode 100644 sourcepawn/batchtool/compile.cfg delete mode 100644 sourcepawn/batchtool/compile.dpr delete mode 100644 sourcepawn/batchtool/compile.exe delete mode 100644 sourcepawn/batchtool/icon.rc delete mode 100644 sourcepawn/batchtool/icon.res delete mode 100644 sourcepawn/batchtool/pawn.ico delete mode 100644 sourcepawn/batchtool/uFunc.pas delete mode 100644 sourcepawn/batchtool/version.rc delete mode 100644 sourcepawn/batchtool/version.res delete mode 100644 sourcepawn/compiler/Makefile delete mode 100644 sourcepawn/compiler/amx.h delete mode 100644 sourcepawn/compiler/amxdbg.h delete mode 100644 sourcepawn/compiler/binreloc.c delete mode 100644 sourcepawn/compiler/binreloc.h delete mode 100644 sourcepawn/compiler/getch.h delete mode 100644 sourcepawn/compiler/libpawnc.c delete mode 100644 sourcepawn/compiler/libpawnc.rc delete mode 100644 sourcepawn/compiler/lstring.c delete mode 100644 sourcepawn/compiler/lstring.h delete mode 100644 sourcepawn/compiler/memfile.c delete mode 100644 sourcepawn/compiler/memfile.h delete mode 100644 sourcepawn/compiler/msvc8/spcomp.sln delete mode 100644 sourcepawn/compiler/msvc8/spcomp.vcproj delete mode 100644 sourcepawn/compiler/osdefs.h delete mode 100644 sourcepawn/compiler/pawn.ico delete mode 100644 sourcepawn/compiler/pawncc.c delete mode 100644 sourcepawn/compiler/sc.h delete mode 100644 sourcepawn/compiler/sc1.c delete mode 100644 sourcepawn/compiler/sc2.c delete mode 100644 sourcepawn/compiler/sc3.c delete mode 100644 sourcepawn/compiler/sc4.c delete mode 100644 sourcepawn/compiler/sc5.c delete mode 100644 sourcepawn/compiler/sc5.scp delete mode 100644 sourcepawn/compiler/sc6.c delete mode 100644 sourcepawn/compiler/sc7.c delete mode 100644 sourcepawn/compiler/sc7.scp delete mode 100644 sourcepawn/compiler/scexpand.c delete mode 100644 sourcepawn/compiler/sci18n.c delete mode 100644 sourcepawn/compiler/sclinux.h delete mode 100644 sourcepawn/compiler/sclist.c delete mode 100644 sourcepawn/compiler/scmemfil.c delete mode 100644 sourcepawn/compiler/scpack.c delete mode 100644 sourcepawn/compiler/scstate.c delete mode 100644 sourcepawn/compiler/sctracker.c delete mode 100644 sourcepawn/compiler/sctracker.h delete mode 100644 sourcepawn/compiler/scvars.c delete mode 100644 sourcepawn/compiler/sp_file.c delete mode 100644 sourcepawn/compiler/sp_file.h delete mode 100644 sourcepawn/compiler/svn_version.h delete mode 100644 sourcepawn/compiler/svn_version.tpl delete mode 100644 sourcepawn/compiler/zlib/adler32.c delete mode 100644 sourcepawn/compiler/zlib/compress.c delete mode 100644 sourcepawn/compiler/zlib/crc32.c delete mode 100644 sourcepawn/compiler/zlib/crc32.h delete mode 100644 sourcepawn/compiler/zlib/deflate.c delete mode 100644 sourcepawn/compiler/zlib/deflate.h delete mode 100644 sourcepawn/compiler/zlib/gzio.c delete mode 100644 sourcepawn/compiler/zlib/infback.c delete mode 100644 sourcepawn/compiler/zlib/inffast.c delete mode 100644 sourcepawn/compiler/zlib/inffast.h delete mode 100644 sourcepawn/compiler/zlib/inffixed.h delete mode 100644 sourcepawn/compiler/zlib/inflate.c delete mode 100644 sourcepawn/compiler/zlib/inflate.h delete mode 100644 sourcepawn/compiler/zlib/inftrees.c delete mode 100644 sourcepawn/compiler/zlib/inftrees.h delete mode 100644 sourcepawn/compiler/zlib/trees.c delete mode 100644 sourcepawn/compiler/zlib/trees.h delete mode 100644 sourcepawn/compiler/zlib/uncompr.c delete mode 100644 sourcepawn/compiler/zlib/zconf.h delete mode 100644 sourcepawn/compiler/zlib/zlib.h delete mode 100644 sourcepawn/compiler/zlib/zutil.c delete mode 100644 sourcepawn/compiler/zlib/zutil.h delete mode 100644 sourcepawn/jit/BaseRuntime.cpp delete mode 100644 sourcepawn/jit/BaseRuntime.h delete mode 100644 sourcepawn/jit/Makefile delete mode 100644 sourcepawn/jit/dll_exports.cpp delete mode 100644 sourcepawn/jit/dll_exports.h delete mode 100644 sourcepawn/jit/engine2.cpp delete mode 100644 sourcepawn/jit/engine2.h delete mode 100644 sourcepawn/jit/jit_shared.h delete mode 100644 sourcepawn/jit/jit_version.h delete mode 100644 sourcepawn/jit/jit_version.tpl delete mode 100644 sourcepawn/jit/msvc8/jit-x86.sln delete mode 100644 sourcepawn/jit/msvc8/jit-x86.vcproj delete mode 100644 sourcepawn/jit/sp_vm_basecontext.cpp delete mode 100644 sourcepawn/jit/sp_vm_basecontext.h delete mode 100644 sourcepawn/jit/sp_vm_engine.cpp delete mode 100644 sourcepawn/jit/sp_vm_engine.h delete mode 100644 sourcepawn/jit/sp_vm_function.cpp delete mode 100644 sourcepawn/jit/sp_vm_function.h delete mode 100644 sourcepawn/jit/version.rc delete mode 100644 sourcepawn/jit/x86/jit_x86.cpp delete mode 100644 sourcepawn/jit/x86/jit_x86.h delete mode 100644 sourcepawn/jit/x86/opcode_helpers.cpp delete mode 100644 sourcepawn/jit/x86/opcode_helpers.h delete mode 100644 sourcepawn/jit/x86/opcode_switch.inc delete mode 100644 sourcepawn/jit/x86/ungen_opcode_switch.inc delete mode 100644 sourcepawn/jit/x86/ungen_opcodes.h delete mode 100644 sourcepawn/jit/zlib/adler32.c delete mode 100644 sourcepawn/jit/zlib/compress.c delete mode 100644 sourcepawn/jit/zlib/crc32.c delete mode 100644 sourcepawn/jit/zlib/crc32.h delete mode 100644 sourcepawn/jit/zlib/deflate.c delete mode 100644 sourcepawn/jit/zlib/deflate.h delete mode 100644 sourcepawn/jit/zlib/gzio.c delete mode 100644 sourcepawn/jit/zlib/infback.c delete mode 100644 sourcepawn/jit/zlib/inffast.c delete mode 100644 sourcepawn/jit/zlib/inffast.h delete mode 100644 sourcepawn/jit/zlib/inffixed.h delete mode 100644 sourcepawn/jit/zlib/inflate.c delete mode 100644 sourcepawn/jit/zlib/inflate.h delete mode 100644 sourcepawn/jit/zlib/inftrees.c delete mode 100644 sourcepawn/jit/zlib/inftrees.h delete mode 100644 sourcepawn/jit/zlib/trees.c delete mode 100644 sourcepawn/jit/zlib/trees.h delete mode 100644 sourcepawn/jit/zlib/uncompr.c delete mode 100644 sourcepawn/jit/zlib/zconf.h delete mode 100644 sourcepawn/jit/zlib/zlib.h delete mode 100644 sourcepawn/jit/zlib/zutil.c delete mode 100644 sourcepawn/jit/zlib/zutil.h delete mode 100644 tools/Vtable scanner/Makefile delete mode 100755 tools/Vtable scanner/dodscan.sh delete mode 100644 tools/Vtable scanner/libiberty.a delete mode 100644 tools/Vtable scanner/main.cpp delete mode 100644 tools/Vtable scanner/tfscan.sh delete mode 100644 tools/builder/ABuilder.cs delete mode 100644 tools/builder/AssemblyInfo.cs delete mode 100644 tools/builder/Config.cs delete mode 100644 tools/builder/LinuxBuilder.cs delete mode 100644 tools/builder/Main.cs delete mode 100644 tools/builder/Makefile delete mode 100644 tools/builder/Package.cs delete mode 100644 tools/builder/PkgCore.cs delete mode 100644 tools/builder/Win32Builder.cs delete mode 100644 tools/builder/build-linux.cfg delete mode 100644 tools/builder/build-win32.cfg delete mode 100644 tools/builder/builder.csproj delete mode 100644 tools/builder/builder.sln delete mode 100755 tools/crc32/build.sh delete mode 100644 tools/crc32/main.cpp delete mode 100644 tools/daemon/Makefile delete mode 100644 tools/daemon/smud.cpp delete mode 100644 tools/daemon/smud.h delete mode 100644 tools/daemon/smud_connections.cpp delete mode 100644 tools/daemon/smud_connections.h delete mode 100644 tools/daemon/smud_threads.cpp delete mode 100644 tools/daemon/smud_threads.h delete mode 100644 tools/daemon/updateGameData.sh delete mode 100644 tools/fetchdlls/fetchdlls.sln delete mode 100644 tools/fetchdlls/fetchdlls.vcproj delete mode 100644 tools/fetchdlls/main.cpp delete mode 100644 tools/gamedata md5/Makefile delete mode 100644 tools/gamedata md5/TextParsers.cpp delete mode 100644 tools/gamedata md5/TextParsers.h delete mode 100644 tools/gamedata md5/main.cpp delete mode 100644 tools/gamedata md5/main.h delete mode 100644 tools/gamedata md5/md5.cpp delete mode 100644 tools/gamedata md5/md5.h delete mode 100644 tools/gamedata md5/msvc9/gamedatamd5.sln delete mode 100644 tools/gamedata md5/msvc9/gamedatamd5.vcproj delete mode 100644 tools/gamedata md5/sm_memtable.cpp delete mode 100644 tools/gamedata md5/sm_memtable.h delete mode 100644 tools/incparser/IncParser.cs delete mode 100644 tools/incparser/ParseWriter.cs delete mode 100644 tools/incparser/Program.cs delete mode 100644 tools/incparser/Properties/AssemblyInfo.cs delete mode 100644 tools/incparser/incparser.csproj delete mode 100644 tools/incparser/incparser.sln delete mode 100644 tools/installer/CCriticalSection.h delete mode 100644 tools/installer/CFileList.cpp delete mode 100644 tools/installer/CFileList.h delete mode 100644 tools/installer/ChooseMethod.cpp delete mode 100644 tools/installer/ChooseMethod.h delete mode 100644 tools/installer/GamesList.cpp delete mode 100644 tools/installer/GamesList.h delete mode 100644 tools/installer/ICopyMethod.h delete mode 100644 tools/installer/InstallerMain.cpp delete mode 100644 tools/installer/InstallerMain.h delete mode 100644 tools/installer/InstallerUtil.cpp delete mode 100644 tools/installer/InstallerUtil.h delete mode 100644 tools/installer/LocalCopyMethod.cpp delete mode 100644 tools/installer/LocalCopyMethod.h delete mode 100644 tools/installer/PerformInstall.cpp delete mode 100644 tools/installer/PerformInstall.h delete mode 100644 tools/installer/Resource.h delete mode 100644 tools/installer/SelectGame.cpp delete mode 100644 tools/installer/SelectGame.h delete mode 100644 tools/installer/Welcome.cpp delete mode 100644 tools/installer/Welcome.h delete mode 100644 tools/installer/installer.ico delete mode 100644 tools/installer/installer.rc delete mode 100644 tools/installer/installer.sln delete mode 100644 tools/installer/installer.vcproj delete mode 100644 tools/installer/platform_headers.h delete mode 100644 tools/profiler/csharp/Comparators.cs delete mode 100644 tools/profiler/csharp/Form1.Designer.cs delete mode 100644 tools/profiler/csharp/Form1.cs delete mode 100644 tools/profiler/csharp/Form1.resx delete mode 100644 tools/profiler/csharp/ProfReport.cs delete mode 100644 tools/profiler/csharp/Program.cs delete mode 100644 tools/profiler/csharp/profviewer.csproj delete mode 100644 tools/profiler/csharp/profviewer.sln delete mode 100644 tools/profiler/php/ProfFileParser.class.php delete mode 100644 tools/versionchanger.pl delete mode 100644 translations/adminhelp.phrases.txt delete mode 100644 translations/adminmenu.phrases.txt delete mode 100644 translations/antiflood.phrases.txt delete mode 100644 translations/basebans.phrases.txt delete mode 100644 translations/basecomm.phrases.txt delete mode 100644 translations/basetriggers.phrases.txt delete mode 100644 translations/basevotes.phrases.txt delete mode 100644 translations/clientprefs.phrases.txt delete mode 100644 translations/common.phrases.txt delete mode 100644 translations/core.phrases.txt delete mode 100644 translations/funcommands.phrases.txt delete mode 100644 translations/funvotes.phrases.txt delete mode 100644 translations/mapchooser.phrases.txt delete mode 100644 translations/nextmap.phrases.txt delete mode 100644 translations/nominations.phrases.txt delete mode 100644 translations/plugin.basecommands.txt delete mode 100644 translations/reservedslots.phrases.txt delete mode 100644 translations/rockthevote.phrases.txt delete mode 100644 translations/slapslay.phrases.txt delete mode 100644 translations/sqladmins.phrases.txt diff --git a/NOTICE.txt b/NOTICE.txt deleted file mode 100644 index 480f0b5b..00000000 --- a/NOTICE.txt +++ /dev/null @@ -1,36 +0,0 @@ -We now use svn:keywords "Id" on all .c/.cpp/.h/.inc/.sp/ files. -Please make sure your client is configured properly. - -WINDOWS: - - Open your Application Data directory. - Windows XP/2000: C:\Documents and Settings\\Application Data - Windows Vista: C:\Users\\AppData\Roaming - - - Now go to the Subversion directory. - - Open the "config" file with a text editor. - -LINUX: - - Open ~/.subversion/config with your favorite text editor. - -Under [miscellany], uncomment this line: -# enable-auto-props = yes - -Under [auto-props], add these lines: -*.c = svn:keywords=Id -*.cpp = svn:keywords=Id -*.h = svn:keywords=Id -*.inc = svn:keywords=Id -*.sp = svn:keywords=Id - - -If you find a file with one of the above extensions that does not have the svn:keywords property... - -TORTOISE SVN: - - Right click on the file(s) that do not have the property. - - In the context menu that appears, select TortoiseSVN -> Properties. - - A properties window should appear. Click the Add button. - - Select "svn:keywords" from the "Property name" combo box and type "Id" in the "Property value" text area. - - Click OK on both windows and commit the change(s). - -CLI SVN CLIENT: - - Execute the following command: svn propset svn:keywords Id diff --git a/changelog.txt b/changelog.txt deleted file mode 100644 index 7c48dee8..00000000 --- a/changelog.txt +++ /dev/null @@ -1,75 +0,0 @@ -SourceMod Changelog - ----------------------------- - -SourceMod 1.0.3 [2008-06-21] - -Changes: - - - Fixed SDKTools compatibility for latest TF2 update. - - Fixed amb1750: OnAutoConfigsBuffered() inserted before "exec server.cfg". - - Fixed a logic bug where OnConfigsExecuted() could be executed before "exec server.cfg" finished. - - Fixed a rare crash in the event manager that manifested on Zombie Panic! Source. - ----------------------------- - -SourceMod 1.0.2 [2008-05-31] - -Changes: - - - The admin menu is now user-modifiable (the "Dynamic Admin Menu"). - - Added a TF2 extension with Team Fortress functions. - - Added a RegEx extension with regular expression functions. - - Added functions to SDKTools for hooking entity outputs. - - Added preliminary support for the DoD:S Orange Box beta. - - Added a forward for map config plugins for preventing race conditions. - - Added a %b format specifier for binary printing. - - Added sm_dump_datamaps command (SDKTools) for enumerating datamap properties. - - Added sm_dump_admcache command for debugging the admin cache. - - Added amb1715 - TraceHull functions to SDKTools (complementing TraceRay). - - Added amb1694 - FindCharInString() function. - - Added amb1685 - GetTickInterval() function. - - Added amb1620 - ActivateEntity() function to SDKTools (for Orange Box particle system). - - Added amb1610 - StripQuotes() function. - - Added amb1558 - Compiler now has __BINARY_PATH__ and __BINARY_FILE__ macros. - - Fixed amb1686 - ReplaceString* with an empty search string crashed; it now throws an error. - - Fixed amb1684 - Blank passwords required an empty but set password. - - Fixed amb1595 - Extension load failures did not show a platform error message. - - Fixed amb1583 - MySQL string fetch from prepared queries returned corrupted data. - - Fixed amb1358 - Timeleft did not reset on TF2 restarts. - - Fixed cases where the JIT was too cautious in space optimizations. - - Fixed TF2/Cstrike extensions being loadable on incompatible games. - - Fixed various documentation inconsistencies and typos. - - Fixed internal bugs with file extension handling. - -Notes: - - There is a possible compatibility regression from amb1684. SetAdminPassword() - has been modified to remove any set password when given an empty string. Previously, - a blank password ("") would force an admin to use "setinfo" to set an empty password, - but this functionality was deemed unuseful and unintended. Blank passwords now - remove any set password. - ----------------------------- - -SourceMod 1.0.1 [2008-05-20] - -Changes: - - - Fixed SDKTools compatibility for latest TF2 update. - - Removed GivePlayerItem from TF2 (TF2 update broke functionality). - - Fixed amb1688: GivePlayerItem offset was wrong for DoD:S Linux. - - Fixed amb1657: Server console did not see admin version of sm_who. - - Fixed amb1648: Stack corruption from GetClientEyeAngles() on Windows. - - Fixed amb1646: NetFlow_Both did not work for client network statistics. - - Fixed amb1601: Vote FF menu reading from sv_alltalk cvar instead of mp_friendlyfire. - - Fixed amb1591: Fixed listen server crashes on mods like IOS:S which pre-add more than one bot. - - Fixed amb1586: GetTeamName() could crash the server if called on load. - - Fixed mapchooser's round counting for TF2. - - Fixed a bug where an RTE on plugin load would throw a message referring to the plugin as "-1". - - Symbols are no longer stripped on Linux. - - Minor SourceMod SDK fixes. - -Notes: - - The extension interface version has been bumped. Any extensions compiled against 1.0.1 will require 1.0.1 or higher to run. Extensions against 1.0.0 will continue to run normally. diff --git a/configs/admin_groups.cfg b/configs/admin_groups.cfg deleted file mode 100644 index d464d27c..00000000 --- a/configs/admin_groups.cfg +++ /dev/null @@ -1,36 +0,0 @@ -Groups -{ - /** - * Allowed properties for a group: - * - * "flags" - Flag string. - * "immunity" - Immunity level number, or a group name. - * If the group name is a number, prepend it with an - * '@' symbol similar to admins_simple.ini. Users - * will only inherit the level number if it's higher - * than their current value. - */ - "Default" - { - "immunity" "1" - } - - "Full Admins" - { - /** - * You can override commands and command groups here. - * Specify a command name or group and either "allow" or "deny" - * Examples: - * ":CSDM" "allow" - * "csdm_enable" "deny" - */ - Overrides - { - } - "flags" "abcdefghiz" - - /* Largish number for lots of in-between values. */ - "immunity" "99" - } -} - diff --git a/configs/admin_levels.cfg b/configs/admin_levels.cfg deleted file mode 100644 index 3c2c5769..00000000 --- a/configs/admin_levels.cfg +++ /dev/null @@ -1,49 +0,0 @@ -/** - * There is no reason to edit this file. Core uses this to map each named - * access type to a given ASCII character. The names are all pre-defined. - */ -Levels -{ - /** - * These are the default role flag mappings. - * You can assign new letters for custom purposes, however you should - * not change the default names, as SourceMod hardcodes these. - */ - Flags - { - "reservation" "a" //Reserved slots - "generic" "b" //Generic admin, required for admins - "kick" "c" //Kick other players - "ban" "d" //Banning other players - "unban" "e" //Removing bans - "slay" "f" //Slaying other players - "changemap" "g" //Changing the map - "cvars" "h" //Changing cvars - "config" "i" //Changing configs - "chat" "j" //Special chat privileges - "vote" "k" //Voting - "password" "l" //Password the server - "rcon" "m" //Remote console - "cheats" "n" //Change sv_cheats and related commands - - /** - * Custom flags can be used by plugins, but they can also be used to - * for you to expand on the previous groups, using Overrides. - */ - - "custom1" "o" - "custom2" "p" - "custom3" "q" - "custom4" "r" - "custom5" "s" - "custom6" "t" - - /** - * Root is a magic access flag that grants all permissions. - * This should only be given to trusted administrators. - * Root users can target anyone regardless of immunity, - * however, they themselves are not automatically immune. - */ - "root" "z" - } -} diff --git a/configs/admin_overrides.cfg b/configs/admin_overrides.cfg deleted file mode 100644 index 73404659..00000000 --- a/configs/admin_overrides.cfg +++ /dev/null @@ -1,21 +0,0 @@ -Overrides -{ - /** - * By default, commands are registered with three pieces of information: - * 1)Command Name (for example, "csdm_enable") - * 2)Command Group Name (for example, "CSDM") - * 3)Command Level (for example, "changemap") - * - * You can override the default flags assigned to individual commands or command groups in this way. - * To override a group, use the "@" character before the name. Example: - * Examples: - * "@CSDM" "b" // Override the CSDM group to 'b' flag - * "csdm_enable" "bgi" // Override the csdm_enable command to 'bgi' flags - * - * Note that for overrides, order is important. In the above example, csdm_enable overwrites - * any setting that csdm_enable previously had. - * - * You can make a command completely public by using an empty flag string. - */ -} - diff --git a/configs/adminmenu_cfgs.txt b/configs/adminmenu_cfgs.txt deleted file mode 100644 index 644c6d71..00000000 --- a/configs/adminmenu_cfgs.txt +++ /dev/null @@ -1,10 +0,0 @@ -/** - * List config files here (relative to moddir) to have them added to the exec config menu list - * Left side is the filename, right side is the text to be added to the menu - */ -Configs -{ - "cfg/server.cfg" "Standard Server Setup" - "cfg/sourcemod/sm_warmode_on.cfg" "War Mode On" - "cfg/sourcemod/sm_warmode_off.cfg" "War Mode Off" -} diff --git a/configs/adminmenu_custom.txt b/configs/adminmenu_custom.txt deleted file mode 100644 index 16f3e6fe..00000000 --- a/configs/adminmenu_custom.txt +++ /dev/null @@ -1,12 +0,0 @@ -// Custom admin menu commands. -// For more information: -// -// http://wiki.alliedmods.net/Custom_Admin_Menu_%28SourceMod%29 -// -// Note: This file must be in Valve KeyValues format (no multiline comments) -// - -"Commands" -{ - -} diff --git a/configs/adminmenu_grouping.txt b/configs/adminmenu_grouping.txt deleted file mode 100644 index 84e6e29f..00000000 --- a/configs/adminmenu_grouping.txt +++ /dev/null @@ -1,20 +0,0 @@ -/* Add group options to be added to 'group' or 'groupplayer' type submenus - * The left side is the name that will show in the menu, right is the command that will be fired - * - * For more information: http://wiki.alliedmods.net/Custom_Admin_Menu_%28SourceMod%29 - */ - -Groups -{ - "All" "@all" - "Bots" "@bots" - "Alive" "@alive" - "Dead" "@dead" - "Humans" "@humans" - "Current aim" "@aim" - - /* You can enable these if you are using Counter-Strike Source and running the cstrike extension */ -// "Terrorists" "@t" -// "Counter-Terrorists" "@ct" - -} \ No newline at end of file diff --git a/configs/adminmenu_sorting.txt b/configs/adminmenu_sorting.txt deleted file mode 100644 index 24a9dbee..00000000 --- a/configs/adminmenu_sorting.txt +++ /dev/null @@ -1,39 +0,0 @@ -/** - * The default sorting is designed to look familiar to Mani's admin menu. - * You may re-order items here for your own menu. Any items not explicitly - * sorted will be sorted by their final translated phrases for each given client. - */ - -"Menu" -{ - "PlayerCommands" - { - "item" "sm_slay" - "item" "sm_slap" - "item" "sm_kick" - "item" "sm_ban" - "item" "sm_gag" - "item" "sm_burn" - "item" "sm_beacon" - "item" "sm_freeze" - "item" "sm_timebomb" - "item" "sm_firebomb" - "item" "sm_freezebomb" - } - - "ServerCommands" - { - "item" "sm_map" - "item" "sm_execcfg" - "item" "sm_reloadadmins" - } - - "VotingCommands" - { - "item" "sm_cancelvote" - "item" "sm_votemap" - "item" "sm_votekick" - "item" "sm_voteban" - } -} - diff --git a/configs/admins.cfg b/configs/admins.cfg deleted file mode 100644 index ed1e481f..00000000 --- a/configs/admins.cfg +++ /dev/null @@ -1,39 +0,0 @@ - -/** - * USE THIS SECTION TO DECLARE DETAILED ADMIN PROPERTIES. - * - * Each admin should have its own "Admin" section, followed by a name. - * The name does not have to be unique. - * - * Available properties: (Anything else is filtered as custom) - * "auth" - REQUIRED - Auth method to use. Built-in methods are: - * "steam" - Steam based authentication - * "name" - Name based authentication - * "ip" - IP based authentication - * Anything else is treated as custom. - * Note: Only one auth method is allowed per entry. - * - * "identity" - REQUIRED - Identification string, for example, a steamid or name. - * Note: Only one identity is allowed per entry. - * - * "password" - Optional password to require. - * "group" - Adds one group to the user's group table. - * "flags" - Adds one or more flags to the user's permissions. - * "immunity" - Sets the user's immunity level (0 = no immunity). - * Immunity can be any value. Admins with higher - * values cannot be targetted. See sm_immunity_mode - * to tweak the rules. Default value is 0. - * - * Example: - "BAILOPAN" - { - "auth" "steam" - "identity" "STEAM_0:1:16" - "flags" "abcdef" - } - * - */ -Admins -{ -} - diff --git a/configs/admins_simple.ini b/configs/admins_simple.ini deleted file mode 100644 index 9c88bbe6..00000000 --- a/configs/admins_simple.ini +++ /dev/null @@ -1,46 +0,0 @@ -// -// READ THIS CAREFULLY! SEE BOTTOM FOR EXAMPLES -// -// For each admin, you need three settings: -// "identity" "permissions" "password" -// -// For the Identity, you can use a SteamID or Name. To use an IP address, prepend a ! character. -// For the Permissions, you can use a flag string and an optional password. -// -// PERMISSIONS: -// Flag definitions are in "admin_levels.cfg" -// You can combine flags into a string like this: -// "abcdefgh" -// -// If you want to specify a group instead of a flag, use an @ symbol. Example: -// "@Full Admins" -// -// You can also specify immunity values. Two examples: -// "83:abcdefg" //Immunity is 83, flags are abcefgh -// "6:@Full Admins" //Immunity is 6, group is "Full Admins" -// -// Immunity values can be any number. An admin cannot target an admin with -// a higher access value (see sm_immunity_mode to tweak the rules). Default -// immunity value is 0 (no immunity). -// -// PASSWORDS: -// Passwords are generally not needed unless you have name-based authentication. -// In this case, admins must type this in their console: -// -// setinfo "KEY" "PASSWORD" -// -// Where KEY is the "PassInfoVar" setting in your core.cfg file, and "PASSWORD" -// is their password. With name based authentication, this must be done before -// changing names or connecting. Otherwise, SourceMod will automatically detect -// the password being set. -// -//////////////////////////////// -// Examples: (do not put // in front of real lines, as // means 'comment') -// -// "STEAM_0:1:16" "bce" //kick, ban, slay for this steam ID, no immunity -// "!127.0.0.1" "99:z" //all permissions for this ip, immunity value is 99 -// "BAILOPAN" "abc" "Gab3n" //name BAILOPAN, password "Gab3n": gets reservation, kick, ban -// -//////////////////////////////// - - diff --git a/configs/cfg/sm_warmode_off.cfg b/configs/cfg/sm_warmode_off.cfg deleted file mode 100644 index 278c925a..00000000 --- a/configs/cfg/sm_warmode_off.cfg +++ /dev/null @@ -1,4 +0,0 @@ -//This file re-enables a server from "war mode" by unlocking plugin loading -//and refreshing the plugins list. -sm plugins load_unlock -sm plugins refresh diff --git a/configs/cfg/sm_warmode_on.cfg b/configs/cfg/sm_warmode_on.cfg deleted file mode 100644 index ebc3c6f6..00000000 --- a/configs/cfg/sm_warmode_on.cfg +++ /dev/null @@ -1,9 +0,0 @@ -//This file unloads all plugins, re-loads a few "safe" ones, and then prevents -//any more plugins from being loaded. -sm plugins unload_all -sm plugins load basebans.smx -sm plugins load basecommands.smx -sm plugins load admin-flatfile.smx -sm plugins load adminhelp.smx -sm plugins load adminmenu.smx -sm plugins load_lock diff --git a/configs/cfg/sourcemod.cfg b/configs/cfg/sourcemod.cfg deleted file mode 100644 index 0c4f4dd7..00000000 --- a/configs/cfg/sourcemod.cfg +++ /dev/null @@ -1,109 +0,0 @@ -// SourceMod Configuration File -// This file is automatically executed by SourceMod every mapchange. - - -// Specifies how admin activity should be relayed to users. Add up the values -// below to get the functionality you want. -// 1: Show admin activity to non-admins anonymously. -// 2: If 1 is specified, admin names will be shown. -// 4: Show admin activity to admins anonymously. -// 8: If 4 is specified, admin names will be shown. -// 16: Always show admin names to root users. -// -- -// Default: 13 (1+4+8) -sm_show_activity 13 - -// Specifies whether menu sounds are enabled for menus created by SourceMod. -// Menu sounds can be further configured in addons/sourcemod/configs/core.cfg. -// -- -// Default: 1 -sm_menu_sounds 1 - -// Specifies how long of a delay, in seconds, should be used in between votes -// that are "public" or can be spammed. Whether or not this delay is obeyed -// is dependent on the menu/command. -// -- -// Default: 30 -sm_vote_delay 30 - -// Default datetime formatting rules when displaying to clients. -// For full options, see: http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html -// -- -// Default: %m/%d/%Y - %H:%M:%S -// 12 hour format: %m/%d/%Y - %I:%M:%S %p -sm_datetime_format "%m/%d/%Y - %H:%M:%S" - -// Sets how SourceMod should check immunity levels when administrators target -// each other. -// 0: Ignore immunity levels (except for specific group immunities). -// 1: Protect from admins of lower access only. -// 2: Protect from admins of equal to or lower access. -// 3: Same as 2, except admins with no immunity can affect each other. -// -- -// Default: 1 -sm_immunity_mode 1 - -// Sets how many seconds SourceMod should adjust time values for incorrect -// server clocks. This can be positive or negative and will affect every -// system time in SourceMod, including logging stamps. -// -- -// Default: 0 -sm_time_adjustment 0 - -// Specifies the amount of time that is allowed between chat messages. This -// includes the say and say_team commands. If a client sends a message faster -// than this time, they receive a flood token. When the client has accumulated -// 3 or more tokens, a warning message is shown instead of the chat message. -// -- -// Requires: antiflood.smx -// Default: 0.75 -sm_flood_time 0.75 - -// Specifies how the reserved slots plugin operates. Valid values are: -// 0 : Public slots are used in preference to reserved slots. Reserved slots are freed before public slots. -// 1 : If someone with reserve access joins into a reserved slot, the player with the highest latency and -// no reserved slot access (spectator players are selected first) is kicked to make room. Thus, the reserved -// slots always remains free. The only situation where the reserved slot(s) can become properly occupied is -// if the server is full with reserve slot access clients. -// -- -// Requires: reservedslots.smx -// Default: 0 -sm_reserve_type 0 - -// Specifies the number of reserved player slots. Users with the reservation -// admin flag set will be able to join the server when there are no public slots -// remaining. If someone does not have this flag, they will be kicked. -// (Public slots are defined as: maxplayers - number of reserved slots) -// -- -// Requires: reservedslots.smx -// Default: 0 -sm_reserved_slots 0 - -// Specifies whether or not reserved slots will be hidden (subtracted from max -// slot count). Valid values are 0 (visible) or 1 (hidden). -// -- -// Requires: reservedslots.smx -// Default: 0 -sm_hide_slots 0 - -// Specifies whether or not non-admins can send messages to admins using -// say_team @. Valid values are 0 (disabled) or 1 (enabled) -// -- -// Requires: basechat.smx -// Default: 1 -sm_chat_mode 1 - -// Specifies whether or not "timeleft" will automaticly be triggered every -// x seconds. Valid values are 0 (disabled) to 1800 seconds. -// -- -// Requires: basetriggers.smx -// Default: 0 -sm_timeleft_interval 0 - -// Specifies whether or not chat triggers are broadcast to the server or just -// the player who requested the info trigger. Valid values are 0 (Disabled) or -// 1 (Enabled) -// -- -// Requires: basetriggers.smx -// Default: 1 -sm_trigger_show 1 diff --git a/configs/core.cfg b/configs/core.cfg deleted file mode 100644 index 8969cdff..00000000 --- a/configs/core.cfg +++ /dev/null @@ -1,105 +0,0 @@ -/** - * This file is used to set various options that are important to SourceMod's core. - * If this file is missing or an option in this file is missing, then the default values will be used. - */ -"Core" -{ - /** - * Relative path to SourceMod's base directory. This is relative to the game/mod directory. - * Only change this if you have installed SourceMod in a non-default location. - * - * The default value is "addons/sourcemod" - */ - "BasePath" "addons/sourcemod" - - /** - * This option determines if SourceMod logging is enabled. - * - * "on" - Logging is enabled (default) - * "off" - Logging is disabled - */ - "Logging" "on" - - /** - * This option determines how SourceMod logging should be handled. - * - * "daily" - New log file is created for each day (default) - * "map" - New log file is created for each map change - * "game" - Use game's log files - */ - "LogMode" "daily" - - /** - * Language that multilingual enabled plugins and extensions will use to print messages. - * Only languages listed in languages.cfg are valid. - * - * The default value is "en" - */ - "ServerLang" "en" - - /** - * String to use as the public chat trigger. Set an empty string to disable. - */ - "PublicChatTrigger" "!" - - /** - * String to use as the silent chat trigger. Set an empty string to disable. - */ - "SilentChatTrigger" "/" - - /** - * If a say command is a silent chat trigger, and is used by an admin, - * but it does not evaluate to an actual command, it will be displayed - * publicly. This setting allows you to suppress accidental typings. - * - * The default value is "no". A value of "yes" will supress. - */ - "SilentFailSuppress" "no" - - /** - * Password setinfo key that clients must set. You must change this in order for - * passwords to work, for security reasons. - */ - "PassInfoVar" "_password" - - /** - * Specifies the sound that gets played when an item is selected from a menu. - */ - "MenuItemSound" "buttons/button14.wav" - - /** - * Specifies the sound that gets played when an "Exit" button is selected - * from a menu. - */ - "MenuExitSound" "buttons/combine_button7.wav" - - /** - * Specifies the sound that gets played when an "Exit Back" button is selected - * from a menu. This is the special "Back" button that is intended to roll back - * to a previous menu. - */ - "MenuExitBackSound" "buttons/combine_button7.wav" - - /** - * Enables or disables whether SourceMod reads a client's cl_language cvar to set - * their language for server-side phrase translation. - * - * "on" - Translate using the client's language (default) - * "off" - Translate using default server's language - */ - "AllowClLanguageVar" "On" - - /** - * Enables or Disables SourceMod's automatic gamedata updating. - * - * The default value is "no". A value of "yes" will block the Auto Updater. - */ - "DisableAutoUpdate" "no" - - /** - * Enables or disables automatic restarting of the server after a successful update. - * - * The default value is "no". A value of "yes" will let the server automatically restart. - */ - "ForceRestartAfterUpdate" "no" -} diff --git a/configs/databases.cfg b/configs/databases.cfg deleted file mode 100644 index 072c27f7..00000000 --- a/configs/databases.cfg +++ /dev/null @@ -1,32 +0,0 @@ -"Databases" -{ - "driver_default" "mysql" - - "default" - { - "driver" "default" - "host" "localhost" - "database" "sourcemod" - "user" "root" - "pass" "" - //"timeout" "0" - //"port" "0" - } - - "storage-local" - { - "driver" "sqlite" - "database" "sourcemod-local" - } - - "clientprefs" - { - "driver" "sqlite" - "host" "localhost" - "database" "clientprefs-sqlite" - "user" "root" - "pass" "" - //"timeout" "0" - //"port" "0" - } -} diff --git a/configs/geoip/GeoIP.dat b/configs/geoip/GeoIP.dat deleted file mode 100644 index e05bf098e71798f98f8c94ddf1f1446651f4812f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1104406 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¬TLd_MB|+UH}RuY5j{!R7O*&u7|SYd5fN1M4^N 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 z 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 ^>W0xMjCxW; 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%0Aep8 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 GP3tK}ecehYn%~kx1@; zPMpSxhJ*R?@1V^=#X*&`7TKhFY7Xj7_Bf-lndYtz_HeM9gWY9j;xOZ$4)#(vn2sdp zvbTfd9qi-aFb4x29Oz(>gZ&-s>tH|i)=ZFL4^SwR;vffyIyl(DAtKpW8nDTO9Sl*g z7@76cc&LNn4i0y4l!GH29BI46V%Vi&G`3l2%s3+)9P8j12P4%h9$Yjdf1DE0i;+h; z80X*w2d6qX(ZMMWPI7Rvjm%1DGupuzwneR`q~mE0&fwm5FxJW5c^H-%2lC}#X2i4^ z@8Em~XE`{>!PyQbH0){yIoH8?c6PMqicEBHk%J2yTxhfNW;CHLR>AD^r4H_LaG8Va z9bE2Ul7lN8T%}oGY2&kC#=qLZweq^g$^Kt6#vyr~A`j%tzk^#G+{m^#nC##tRYDu% zOE5+ABDmGT9S&}DaJza)172L6I~`25-RAUJ+uaTxbui7rgAVR-Fr9b0gZsD{^!{&b z?sxEja&faUIA{HkgNIco!;*PKvtajTIC#pzV-B8h@VJASvN1OuwNE;j!cC9}6B-;wOamwyKf9n5p^k%RXge88hj#veME?_dWTf#k;yK9$!el2`Nd z9|B?H!WV$g9em?pk%O-seBt0rX_b)&A%n1233m0ml4bMU8w-yQs6w=uiNR{Z7QZ@WWydXxN@XS<7KJn&sC zcd&w+oyj}|%(BA8N^W+}^VZ;E-OTrY7ad%z>S8sw{nTP=MyA*5ZuZyaY17fg1}@fg zv9^m&F1ott?4pb8XL{Zd3(9o#BKj!#GGS{)7!;nF8YW!Cm#Qt$QCXl7hAg6#l==G`nl-q zVp|tmyV%Cfo?@l|K8Ux|kXhL0?Op8XqQ8qB-0UZg|IBuBv9lQ3kJOJ3O)g3XQ_&X@5yslY|30yreeGGZ5dxJX>o zT$HJDk-DhZdQ3lQS*4?DuDjS(U2U`LwVR9G-Ry%k&XE^qv8RiDUF_vz9~T2$?5(ac z6jzpJ16>SK4eS65Ai1B516}Oz;s9kK$y^L|kc)%0TR7xJ{!kaEF_(+uTnuqB%*A0Y zj&L#5#o-LX@3inUSl;sd@W;hbE(rQ-csSi%9OGiRixDnpM%71>BV8P885&b{yo=E; zM!7i2#R)D>bU{ntdXkGbGQHq}O;CXS+Dd z4jFuci*qzISs3a(7ZqAR;9`=CYh7H;$!dMsd9$mpb8)@)2^qGX>vE%un_NuRG|ho}i@u=Nz48=Y6n2X2dMHe#6@`Q_7E}j(0APoK#yJx-3yk@(2 z$;BKO&%1cm#dDf9jRz{o3oc%?JCoC7mX}@3b@7UeR~3g3ERwW;&Bg0V#38f4;o?nO z3=_TWVyTOFTr70)u8a9D-sA1*VxEil?cD$C)rYokAG!F{#m6o_QB|g3%FkRZP*ud7 z6f=JA;#(JsTzuu?3m0E10(oj#%-1fyQMF{u`hLd)-^F4V-`gV18vW>EiS9T?Hq1{h zR`Bq%i$7ib;^H^i|7z>`-Nhd~cvS;~)8#K0|GN0w#Xoiy48VGS?aQO1A~2q-&w*vdm^4;y;u;$dA6 zT|KPrWlx#4WY5)EM?-?A`1!ww?jF|ju)atpWeUm-JoHcvj7eY0jXd=B(9^>v9ya#S z%gfGfmPBJ?u&LMngxbu*<{tVept(D?@UW$_bI823@9Uw-!`2@9llQQlhizp~6&IzS zhwZ)gw|z6g9X#yhVMp1RS?}y&7saHDx#@Bq92$5icxdsEw;5@`AVm))F=mb=T@Sto zPt!Er3y781#N-5H4~Ke4JnZG6?4iv=>Y?hP!s)9RPKN<$S>pn!1H_ERS?uaz4-dO} z*j>FcDHxg8p2|Ys0Uq}Au(yXn9`^At(952`G@y#p+*c_WpMBfk!$BSn@Nl4fnT2MI zd9a5=WJboU#b6J|dKltin1{nW9N}T8hr{i9(S>G5dN|6?lyMmUXb;DD817*N_k+DP zs2V9p0?z0-4<~sz-opvXI7*f*^+bg-YkjhZ(H>5b0q4R!HpauL+P%CrOcPG`aJh%E z9?ti0hKI8~oate_m%UGptui5@QUaDj%5aG{5* z72#qJmwLFwdUX=rB!@$k6#M?K8&@R%@{j9$!3In%=vBF*e(d3e^t zQy!iX`Lyl%Y!7q9a0({la~@vw@Vti?Y-fy$+LvU>N?!5so`+XGyd`F?hu1v3A^f`a zdQ(G_oxX2t_>Sbel5EjD41P5T8>Ewt;q zh{vgqFFgFh74h)Bhp#+*>)~q;-)J|QJE+dj|2-@g!;bOd-SLBmr5=9tu*9B$=H~i| zhrc#9w=pjo|LWl%55IZ%)5Gr`{;)R-?X&aW!{5BA?c;;wzaCcbvCPAA#i5P4XDL_o z+uwv&^0Bs$m3?&dv5JolK34Uynx8!p%;8MAx{o#d>?Z}*&mgR1O&?u+bn?;J#-WOL zTvs1!`R$+l@KyX~p8r02_*mD+`aZh(SkG^Nhi4F0*xknlvgZUDnL#%6v9XVheDoAg z8y*E_`n}{!vrT>M?4!4j?R;$JV=Ethd~D%kb01yxCP}%aFv0CS|9x!ZW9tTHTVbkb z&`)@KA3ONy-@xzaV<$VjTb8@{DEesf(IP&_3I$9S%Dj()b>Xn&!}H;YaT|EwN8}@5 zlSQ%>|3x59d>rbd>|=nB)W@zqDn4rLvyZBuy+!lI(!77xeYA<`FNXYXKKAsnyN^9M z7g>_zOZZ-X`zz}-e*WWQe;@n!7$kC_B;R}Y^|7Cy{Z4@{95TfLJ`VD;_wxfK$sFwC z5Mdgy5~djJ<5(XrNDFds+w7|MWt_LgpnBsfwyIH z%g~YJaXwD=alDTc#E-Jt6MdW{%pWlroE`xqnszr3ee7sem!<9i=x_;|#} znLe)bG0w*&KF0ev&&OFlCTPE%ZTIInKF$@xJ!!Vz`93c6G112b+)lbXcxy2GMLsUp z{W4w~n9QXSK4$oM-p6A;p7Qayk0*W1^znqe z2I{*^rp{UNB7WM(93Rj4nC)lJU#2q!KkMT;O^S)g(DDTzbA7z%<7FQ&DIg1@_7xwm z+Uc`qo;k1ictZxSD+}k&2yd!m1aC8uk9T~0=;K`<@B4Vq$2=Zinkml~+I%2)CZ+Fu zAD?jd`uJERna5=LsgKWWd|I;dg+9LV@wtyLeJtYPZ>ypUgMa1YYa5nlDU1Ks$9I-l zEI^*wfAFzsfFF6r23X?bUmr_-{O;o?AHT@#XUV}l|9$*s9oY)H|Ka0rAAkDzi(AFE zjxqm{8S7-;Wjx*kEcdZufE9vl`_Yl^2(VI+oz-SK!}$46fYk!5Dv~zjI|Nug$WDHm z(UI-y7-0PXYX(?5K&Jp*WZXH(?g+;08elCkG&Ygf3D8Zu(sX-iUBqY&@Vur0DS{&9$-tkY@vEsz*ZVE zAo11#wlzaZR=Ax2RZO~lfL#Lg53r-i9gOAj_xNWi~3n_y8vaI5ohD0Zs{UQh<|fPt0Z;9bgRCMayI+ zds=`q0-PRTto9y5nXqRD7^l2h|5fu@0nQI_c7SsOObBp}&1=pF7JQx}Fww*S7X`Q= zz=g6gYt0}R2e?F)n}V6>vH(*9TpnO@fGYxA8{oZWssFtI9|xEh;KKm#2lzk{n4RvN`1}AL zX}&ZzJ^v)Yf&iZe_^hF;tbd`s?`XCtz)u0b2(UQ7mjS*B@Ku1X6`65pOq*{5d}ntN z6R|Dd^Vrvneo))l&m{qt%FFbJ%+CRS3-F7~*s)*LD}vtx{1xDj0Dmeb?M?ArNB4u>H28*GeH)){rg?%OICFvzAMHVe@^Z2!=PrS=K2xrQbS3)nJ5zYtq7 zQHZ`FwpK>+riN`pY-i)sg_Ud{Vh1t()eTzis3C*XVCN7whu9^=ks+Ew>>45$BA`Kt zg3MY%LwO;5+kEnzS{R}dA_|d&h^>m2!=Xth8PxNH0KrK_z=TG zj0`a%#4*}$bmXnd$sQZxIMu)+xwXiQ3UN}16GEJ*EaP=tu%#!5I7L~^%}(PnA~xj_m*~S=D(Vt_*R0h)Y6D3~^D2 z3qo9|)iHU^3)01k&y(cR5SL4PnXT;#0XBg%x+=tVAtr^mHpJB-uCcjTB-627l-Gy2 zF~kjO3#%eCImAth&mgpfCZ9td$;h-o2i4>2{w9U<=2o;OpVyeq`r zc1Ll@Aoqm0PlerUJ2O4R{qh>9dy`on4Don~heA9W;^7dFgxPzhSz^v*Mu^8$B+I5T z`!F-alOdi^Kw~zGM~7^7(dktW6B5Z|jOoCq17Z$F0kEyR)#KZjTv;wPRbayJIQg!t9&69%Nq?;-vQ z@kfY1ZBNKE``d9Fp=4cO(OJ;u&K<je*`bWP7zun>>Qyf z!Y*=WlWCSCW)tLS)+isL6rm8IsG6zb#mb!su6jZ**4&HV|BO(M5JZU7*f7GQDld+Z z*jCe#1*a@VNh^xLR#YR@*g$WZu6zs{${O~8jVG$0BaA<^sBOGGq!qhYv9ASv+;gCy4 zW@v;XBODw9rcY?RgQNj&Od2+agSiaCL+WB3u^X!Uz{fxJW5X-b*4}YQ0!C8*+JsDN-`AfAG6tKMtCy96Dp59)6I(TRFu5|(vrPp#%CgY9AS2Z zHzLf5@N$G_BfJpdxd_i|FPR;}6YRwZFY%aC3PvOUN`$$}^{QR3*CM>GbX;Q7v^OKX zAK|SC??!k#!aIt|f{{*16njK6r)NBBF!zq0>Fb2LFHmq$R16=JLy zx8Et8`*VE%kFj!`Jrp>k+c&2(%a|MTA%c`^LtnZ6VF{vX4Q zQHtTj*;#EYxdXizzOp>8jmKGsEI39KqZ}iSk;MOd-qAjdQBfz^b4Fgk^Pd4@)D)Jh zz%trm?5dciY%;sY*e}K&F$Rd=Q*tj`$==)mG4`>IVhw|0?8|krFFyqP#~2*rfEWkI zI55URioiY0?LqrPVjL=WVqVNRB*x(}4vR6Atxz12tmlXrN2)XIJbl@RVKHtY6JtV* z;W18%F(SrsF^*A+kui=HpgX6`4S#%$6U2;)+usjQ)X?NTImXx+r^Gll#^@Mhq+BH#*}Bo7$4)z7~>R;HcZ3?IxEK6>N9Q3_B$uW6*10@aZ!x(VoZ#2z9vEg z&f<5C%1q8iw%%VJzEhW1QEd1Z|2V_X&Eni!K}Ty1-3wAaSCPWBw~ zVi`BYxGBbsF(xY}Zx&X|0&b2mMGVb29LU2z#*;B_i*bL9+hg1%?Hw`hj4{=&2z$aE zbvGv-V_J-Rl#Aqe1-UQAblU+okmLg~X7CP;@vx#jWUGB7#-n0bA=jD(JQibSjK@WC znq;03Cg38@iZM6FQ!$>8@pOziF`kJrTe;XJPJ!v3jq#l7q02ydy%6K&7%#?nNq2-v zMB`UtysFOAl0(YZV!RXM^%!r)ctb%rP0s7B7;oDd(TvQyG2V~yUW|FxjFwcf$Peu7 z=JT#k@DUHI1RwKgjqyp0#W6mO@kNZ!Vl33u7N`bx>GK$ibdE8O$?|24Z(@8E<7;JM zaHgi}+Zf-;mviAd4&&!PF@A~hLyV;{evGk1dyWEN(oj@+J6e5%7j`q zY5y%%hXh>`te#-a1ZyPdm}IAf*@Oh05_G14Wyp6;uy&F?P1cfRmUR-WD=!8&eONES z&I#5}uz7;+33?^iAi+indL-CTl`sw~WRRW-HcqnV2=@tx?As;@dMDUaB=a)nW(oQz zmvN!oBEfbEwoI^ff~^wtwOWQ{sBIE#D|g;atcR=9FToB8wolMMY5zHemOR6EOt4e( zzqd-J+a*DepeaEyK`ud_krT8e?VpzLhd5J1K^YmOl)y{iBybg()iMYt;>&=5^@N;q zf+#^bL7X5_=czK)rU@#lmP5l-nNIFC+pD$&yNY1}3`n!x6P%M^j|3wU?3v(@1bZde zFTns#C&Atc_DQlQFISL>Sk<5e`zF~pz)cFaW&Z>RD&_&29c>OuaIn0HIZaOF&;&;$ z7)-|mL+p%L!_WkWt7gVAF^^0zEWuH-;kM6amteStjK(2X;g|%cB^a6Dqy)z%7?t3- z1jpN*$&7>f{-5APyGEu(Cnp%4;FKhLX!0UCCc&vTvRRJP6P%S`Y=ScroFNsvG@f7n zNibfsA=F5G~${F*91UDtPF~MZTF{{Hw zHz$~)$_L7f%&iF?NN`(%yA#}=U}}Op65J^-=H+iNO@()fVWXxcxG%vy3GTIbx~XA$ zg8Lgf%*r23@OXlU5E*1Cd1SW{#1ge z6`4~r>oPmR(gbr7%un!af_D-;m*AxY&+C|aLGndOCR)JneI68vjP+AQZ$U&adM>=CeH z87QMyL+ePcT*fNW5;MYTWppZ|gP7IJ=qRv;B+FY1xg>EUsDbbiVa@O;*{ZvF)92q%4Gy)#ASqKL~ON9P2)tCOh=rS z(W+s^&Z24~vuX7*4l1Lqj6r4WTE<>w>{iAeGT2>`Hhap^#2-+`KH~S5oScxV|z${1`_G&`&Tb9i_eN0f1t$Rln2%FXqrRI^SQg!lMBkY zsEiAh+Ay@a*j9UK8CRBZSs7Q9ak(vz?!0Jrm6%DAowWn6DdT}Mt}WxvGOjD*<}$7? z<3<_WAW5&uW!zMT`GO^fta(Zqx0P{A8Ml_fA<5y2c6%9j*h-j@?YbQ#ZBp68DVGRNk6u8bGTcwPn!xR9U!2phAP%lNpASIT(1j91Hey^OhX zd`+@w_v#yEyjjLuBI#&Oxp&H#C+6KU-V-n#c)yJKWqeS^hun&GfvDp3QMvuQyPuTt zO&On-v8asC%2;UJ?fFT|&#mPbWqc*=msb0=&BbpHe_O^6WqhYCw787#rDE&M{`s+t zrDZI!B<+6^Cg7s~QpQRtel6qAGJX^PyW}5|oZ}jN|L5_Z;_ot+mGMs*|JoW@Aq|#W zOEzl7G!;{0m04VF;2tSxt=lZc=3@G!*$Oh+7Ady0Sxj&Hrs$Vq>lE9j*ha>j6zkbenBaa5w@=YO#SS7F zhta6oDMcy8&MBJ3?~TFom1K7wNGWbv3ZYG>cM{ zQ^Y9}I}1i;oHRv6W@aK>cX3iF?oRPQifJkCOL0$%d(-yc3(%24rl+_+%{~p_ zOFP@hTo0yrB*jB19!|5L5NXDX29Ktgk+y&5kPPh~Pw{k$nJH$acp}A4x6#hdB|=T<3CZsEDfKO(r}p^@UexdfTNSgDf4Lz( zhYZDM^xO(wt7H#rUat$hQNaui8TKvRGPLZ@uYgwYF3&pQ_bQkt+^pdTD(pi^8qZhv z2tF3`iR7n}pGhu|q`|@pK39>%T$(Q`_^yI4EBK~@uT<^VlB|~6Z-ogsTwK8q6@1^o z{8+(K4VTzi|5U-x4F+`lwSvDY_^pCJWb?b#QuU|Be^>C2jbL&ut6;fhn0kfQ?53v5 zXo**9%}y`^c4L*+>_}f#ay7{gt?gg_Swll=JGN#|5Q0vY>D-Dg!d)fJXNhYIuOqpx zWH(9f9Qv*=Owe6mgI4sg3=Md~Y}A^aGd(5OP_?~O=O(S#RDf?IW)_=i*ryen3y@@l zEnBf&E4FIIHm&F@p3$~eG#YGc8RC8on0uywD|Tqj9woduP0F1#U&HJoRZ|1gET*Lu z`Ty@#Y(+^7i=nS8?8(uDB^ik1Flt4)HQUByXt=O{_vG~2j46s9z`-m}GMjO zmWA*9x#a=DJ?^ zhF08YwUb-h-*|5pGez{Rd;47_oRVSE$A4FO~dBlEa?`SR3)Lt@y1Ke~9_r zW??Ai`b*RKTSfjO%=q-8T-J)^tyrPj{(D~5uwpg)i~X#2r7BjbV&!W4Gn8>wt!591 z)g(JevM@4hRI#Qabd=;a>r_RTDmqu&e_2eXYZYrN@>MAYnEhlKJIayScdBA%@w=!(GOROKMS%vgX_0$g zwXqUv*>eJ3C8-=6->V|3!q+g6Z>SCrR?T!|4fIN?C|6ObB2`8*>|tv)+Z)8Dt2G8u zgf>OnwTj&YOln&0AuX%jvx>c{*jw5GcCk#5fwCE7E%%kytPvd#5YOR(0(3c8;1J6n zTE$?CX@8h{PP3t!6ag>tM{0PKw8N|o`Qg>nFk;haqQblr6IL+fk9$(EqcAyQ* zI6?d2M9GsRPgZ1x;>z+GUBwvjr)rCmq3`KcoL$A(D#l55MipoNf3NXXoFx_QO{fV~ zoFkiaB@NGAaefsO#Sqi-!YZz;;-V@pt>R*>)Fo;lwXC1=vMMgG;tIQMNOBfeRWV6R z$p~B~%4^g^+FvU`@_K35Bk6Pw20eUeY<;*Ic zsA5(XPb!O9JC@DqQ~R`xpV5q%o!1It{dTe5$W#c$S;HE`+wv~y?hzZE3g8~pG`W=zMDcrCADg(#P9QM-OEdl+?>%2e2+hRtf&u!fCm*hqX&xiB>ideyM0D%qr# z{d~s>_EsfSaSDB;+FUVN*cKLWA-1YzM|xj{+Pa2qY(|Eq<90Rlt6>L`+t<+FYB_zD z$AXz?r&@MQ?W_p9)Y`uh#Jss$_Mry>FGe#i#7t)#ON!>y;M!8X8hnds8CV?EP*(S1 z$wZO`q>50nRkdnfbY%PmOj^rc?|HS=u&eNHlDkWC?o`p3#qXsE10*>lxlav)G#n_& z`u7!}YCl_*NyIn@)^L#3nyDS4o*XJUSaOJJWALFG5*%K`5f&d=%U%*l4y(1lX&ha{ zaEnK9UG)Al(xzrT$Eo4ROOBFcYVwpP)^Jh{C#xh5d9l>dHJqun9#g}qHJo0rouxT}Uc)!3<)WdCV-cMa2Ie2?{Ii|!MiZW%^?fHztV57zLo$cH4!^Lj-1Q5%*q z9~1L<4Kr(aLYNICPh$q3#pcv7TZ{N~4bRxsq;`(5S=Q%-pReJi8eXtAFDeUz@OoJ! zyV?|yyh%To0Re5k(1u~3zp^|3Yngo`n{TalaScD#@V&M9L0Wn( z5wo<0pKJI@m@&!o`o#`^lkxA?g{}M3#`#O}|JIP*_*eUCndI^sR;XtuAp;tTdUj~@ zqUFkUtXj|R!Br$lu4c6z#H?=lj&*daW6e6c*3qes&h_jgHQG~lv3RXI)~RD{JEUse z2E3jkuP@o%NJZ#T$HsMRSVzw~HmbKjELa;a#_v@}Zy9eQxvAuT+CH-1Tyl##wi4K~ z!KQD${WGp@>ex=&Z6z7GUmZILZ!g*3dhJ-p&UNf$hwSq%GBEYz46dU^fN}EHlDJrh zQ%9-6-mSy4mVSdJqlI-ubyVtz>qzTJ>L^=FhWc-gCT~@~wL023qlWmj+_jF~tRs#0 zsADe;_q6E-G-&q`Ik1lXL=KYNS6woRC=U>MU>yh92u5{C9fwJEXdQzEhDe%fhYBAq zc|;vYT9wfbtK*nDj;?37C$Hgkj1Z=l!;zNf@HopKFEC2-1XV&yR>BoIxsK6woMK56 zWQ=v>^ZhjD;*S7zjIHBL;WH#@$s2Z@9BFV?J$oBDyN(G0MthF5P8uIcwuCC(>F;~`cl>m)-O|sZnUaOeb)p27T*9$Z64fX6_-ljK*yJ)G7%X3746bj>zFG*<~0UX-Z$!ar;a!4*^4Nzx9WIXm~l9y zd{@Kw>X;`$Uy>ix@v(*<)-m7Oe`LWYbu6gk(>gx03`2267B;NKqB_2;;|pzd#^mPY z^;I2Ti!pc2w{?-yJD0lJ_qJO5W|!^#3Idli9IC5>f=Hmuo()!WcVS=MMn z$F^)kntJHcsSTam&_ynMtLK$P=I?*ou(n8IhBD3XW+SiHmi_M1Sa!E0hdtV`VS`ss z;f)&%HW3~u-`>`8GnS`-o7=DqzGYkcdnUv7mF3ow+q7k0ecx7+Dq_lhZP>o;fBzrZ z4sF>>zR9waymq$CE}TBIi2To{McTY%L8_uK`||<6|0Bkg^dyopFP@Wowq^Ii zUNRUU$vcz`wfiusvJA5JJe17+yT6zNBoCBiopf1G1s|d~hc@t34Qaz+ZP_ctP|3q3 zv)S?UpEe9@!%_0$PrD?K79Oq$BZSS5DkIx)oXBG($Lj~l}NgeUGMOXdpP^vd#;dsW2ov6lb20DT8823iD`@Yco{}0c%+(mqRjb2 z*HK(7+s`rbn#CGdhKXf(Qp!_hm{5lC;!g`XF7xV=xs#-@KKB3*D(u_jGCapUAQw#@ zOnJTx^UCl-8D^JZS{Y`PVS1VKYL{N7^O#wNS+*MMyjX^pG$;nl5t&=!Wx@Fp7YLcY zunbEyXcScaoqI8=sz70;1UKU{_?E@x-5 z8_v|ZaI6bQyKs!lxe+kt$km(PYA)xD<5As(;}mebu$|IRbm0^iYPg*9{UjGob~#U3 ztWZ;g)p)Z$)rDFv=OT8Rt8(2rQfKvDsN+IyRik;P8e+;>F4TA7Y!}XPp{~63gicqL z$ay$d%6YEJhk0J{Sm6Q}E|fy^A_ZJ5WZxR7KMh^DQ~?}LBNrOm;3ifyV{ht0GsR!7 zbXMlo`$`wCap5W#n!9kdboPgJIE@Twp?Hq#S{JTUwU!zV754cC7uvbd%7r#^wYILd zF5Jj?T^loc<;X>E&skD^ax+mkyU2~D=*H<%@$N3%=W?#t_o&Xj zF7$Arr#L&tcy^$d3-`OwTN{i@A8kc?AFzEU@9V5^NQxG>SP~MBaDQIwR-1oM#N)_!hYEvgUT7 zbunwP_!8+$#aV~?a&4*=!j-~TgyvH7nhURU^3}c7(%BQb-f&^93vascmRxIGm2VPE z7Gqd>o#Nk7TkVwfo(mti@V@$B>Tr#i@}Uc#@C- z@3m6w!)^tT{3wM5_h>ChIPGj=A6H6~&kDb2LMZ;K4shQdaN!RZesekBZ~VLJbEFLT zQ@ffwe4skX+<#m+tgM4B=bn4Wg@09zE}HCf6}NM>XFS}f>c-LT%AW!p0{3*FA;^dcpiWxAw< zH*}+s8<)B(pNcsgcDS+IxiYZAWo|T8Fc+ekVtDFh?6|IU<7zjqay$1;_LK3=)tPJ5 z4VrCu@mD&%*GX*YcAm*;-rz=CxmvLU{1qTK+Ncg&XIsp@(e0d`jHI`{B0IQolloxV z>Zrs{Dtk*wA3D38%j0cQxDz-tF2%T2gw;H5c%}H<@QZL-7{*2eieVpUhTN5(DZ(NV zVbqP7QcQeYV#1A-8%Z0_6->LGCxnbuvTo-B%ldgYif$BSvcgn8|Et9=>Mi@$RfFOr zGyP86P&d28tiYqY%97mcb{->pxY5(?T&b9TpBufD#pYO_*vE|r+_+yY(rm}?|4{%p zJmaabLO<;gj+#r;-;E(|3{cEKHwLSTN8A`Bg~4X>NqB%Sf85Rk49TPF`EbS4r1-cS zBT9Pyg!(YbjnOuRrN)SlRdIIUNo^0NKjp@FJ4-a#PZpf0Fm`*A+M3EA{#s?S8_y}8 zTaoco-I%5+ecp{16wFhGy7A6%<0Us{x-nb(e3lYfpOs&<1*V7CzU zmlbJdgFR>E#cnK-Nbgb&ghi+?SN#=ktW>%=2Vb?392$$T_0{U|>u$X1#vAf>u@^3O zj5XhKW36JysjO2Bw>r&t-FQ!nNX{1Dmy2h;88y-LbAwGc<|hi<=*H)6d@BB#aFg)J z3~Y8|ixd{$D#AX0snhc-YkqAPjxlC{-^#@kaJw73+}NR}*|(iKg-Q4pi@4kE{KDi9 zni+2UAKlm^PLZA5E55Hp`NfR`Zv5)TekC%-ME>T+?^a=1>VGQhuaew<+&JXMK`A^D zxN85poyV%f>QWVta}8u7ks=3jw8yy}9OFS%59;t0kW9KvE?tZ~&V%DU&ehT+vgs2& zsG(8}ILU*W$~sxtMP*O1{4`JHySQ2&oURlGuqG30D~8qTh@9m?JrB-SOkHKMInzmE zeGkr67)8@7BJ~R-Ug*Ka9$e&cZaqA~%@|E?0|hkn;8GE0ajP`;psCCz9$cmt8O*F^ zs&KgnSBhLAWC{<{?$sVNr>K-`Y~r;ZXML|zLDT2!#c$9kOh1VncpK?$g*OV@3EK-h z2yZgF8tteiI;qYr!dpG)>~U^(Y>3FRWr`@ZV89>ipZ zJ&1S^RdaJxfmk6|Toq_Co<~w*%H!NP(!z{pi6)z7uks4GTfs#STJy%oTYv{$#JdXb z5b}aR*IjCqx!pXt+w$%rta-0U53BdIdM~T=7U`oUV37yZnFodJOka=lO!$zH=EEKg z^Ps;6gFMb-&j5uDRE0-8&h3m-#|=5ygCQR0mOWHq6dC-e2O~Wg?!n_8=f9ghrfH!* zLNO$)|AYslWsb6mV=Q67IPoVv7%%dat-uzS@t1$>h$eb4$%AJ-c*ZIW;Ls+kwxuXEHYlKesWP zRi9oSTP1!W{8IRp$N4yByxX|bY}U6T-&yYttM3#EDdl_d-NGL{_|e92EG+nw2Yaou z&x4=E2imrNmAT)812*P25$>fwtn#PGUmpA|V)}Vd{E&_LS7!&CtKxO8kUWm^0^&zo zh5P4NFRII|Dy$|n`|3FHzI??MaM-3s#Nh16m>6%`g;l(LloaV);-paQ$T+>=? zj?e!>n&iaV3OLh>XL+5s?q>^0PUB}HegyF194|=f3rWuPI#)lE^S!9W>%Z_q;SM&$ zU;gppQZFv?qM;WJyw0B+^Wbb7Y~)1~iH(KSFY}_Q*SUb3fM!;wd4(5O%5_yqKy$D2 zl^s0zx3ph!GQA*9=Fcu=PSmsg^AOSCeB4+rZ!%3WS`^WtuC zHetN?c+tm;d%fu8MGv`pdT}2&m=bfgLT|70uWeZBelPlZ@qi*}J}APiPX3S={bZWT z{k<3_bAT5Ey%;S1h;Wd0GE;aAkup^H60iSWj1V90#bY9m3%Ly#JkpD?UOeH&XfH-d zzg+qlasKZcQ*)e5o-$8)@v0Z&y_n|3(-J3mF~y6CUOX#vk{8d2m~F}Q$zD7s#Z;y; zRp#@;7j!mJobJUUFJ^c#SNcpZW_j_V_-vg!oP?LWm?P!LWX|KRmNH++DScUl1s95N zCKr3L+>0evU+Tp&aWktc#8+DHD#=Ie7F6?W>-|}Lu zh^e{Gi}$^FN6Ndx_k>60OP#}!*M>GDDik7P7pCYui?YVKAa?l zmCZ!e^f{M(ny313x?HFEQ0u=jXZTQCiaCqx_;8L7XW5vueW+`BJrOQA49aUa%8A89La zwnvGNwhBkb%421Y^WjO6r>xi98lLuHf)A5@m}vD$BF_k)<(5#9=d5>%$W-C;KA7vw zG?~+Vm?bj9hnXU5ox`7PhxVec^5-mbd|2SaT*b^2&KEM6DLh`bDddZMSZu2;5ixsU znfL+4uMl79gE3!~`I>N*aJA4(2y4FK!<$mp2>DD!ajiJX+dixlf2YJt{XLoQ`|yE{ zT+jWl+znRw$cK+DXLB1Z|5T(Vum4v0+=tELe12o`tv-A$^9vuo6#1&eyG{HXAHEa$ zR@g-!?U~DChtK(3Z1^sDITdC$DDt_znY?@C`pJi%ec0=B-f-@-r!#ljFY;1k%6?Ns zNb@%v_J5YKlNA-*S4#qZn#TJibcU+Fs9 zkLrFL<3}|=j+M8n-}$lyhM8RQBmg|^1twE;T8Oy3jToAkBj&d2R{FcTq~sB(hpAW^}-sO>Q;W| zYYAHmN!p0C_2V4AC)BqXwevgQG}YdZ4kDcPo3uIVu z+?IPR@%iDm+?-zlbs%W_6A}pvxy0XU=~<10U&2EYS1So2O~&vbG2CF*U-_9R=SN<= z;K%JEMIj%OyI8_*+@UVrDZEQqUuEz1qlX{e{kYeUd(`5Qwiv*+dRnoU9}kH4_M?x; z{dSl<%S=|^lFI%3805#pemvqwe?JCrN2%aI<+3tO(}%%+43#)UF{acoTbz-@<$cVL z$89cGocc&Vp0ElRm&$0FV}xUcoYg073^y2K#`{5$gvSKACJHC{@r;e+qSHHB=5xX+ z!o~dk9}!cE-I!)K9#dv;yV^Z7%a7UOtV7pJe$16QN9k1N*~s}^rjkgy7W%QsdYQh& zkJtQI>c>hymie*5kL4xtrv587{#9F_b?D-;TFUFfH>`J!A0PVhmLKmZajhS3`?1cJ zH8tP$;{z%0`SHGWvF!R1zCrw>66F&=HriG`^<$GCpOtu-{<-yT@jH(|TZLZ;&C>;2 z=K_7LtZhPOeZ$KLbs^2|e(d&RhacZ7V5c9uL>NP_!5?hyk0N_)?p~Sugg*;^5t^+1 ze*EFb0V%%;S@3t8`==iV{rF4z-+ugK6HV?RKdO}DUq252S3lAvvm!Lj3?EzWTu-VB zjY6zmj^m^pFEqiG-g4){#p5LFswr}c(8Qc(V`!dUj@sooLyGa5YIVv{w;X5Ltg~%E zJ)3)utv!-eIz$i_3w)HkOgdBbvCYU?)=XwrTrbYY44OPz$!slbQ;xPGHwx)(C(>THniqeo^HG5h z10Bnq=lo9P&VT+TxmBdIVs0ymq}L^vyWIKTyEJ)t%i)t~l=5Gvc~p>;JI@R}Xl8k@FGs2z*>a?b{Q0kt9V5?)=ZzvP3U4=xV!D>&u5#Q_jytVr za*5qE(!0yi-MU!wUUiaV=^@fn9i!Pxz3MIOBfMXDy1M$HcwgZ|<>*(AjrXj_3x z%nlRBX}z8lK4sT#d^t{%cY^9n6f%C22wa!j|C zXNb(S@v}u>m z9##og+d1jQhyQY{k@=>O%3C69g>MVj3EvUED`c42neWT|Kn+p(Q04|9&5uMr7II@# z*(m;LIX)}LCUNdA>c{f;e`Ibc$F_28EytHU3(7&ATY~siIlk70BscNIZxlen<2$8q zFUJlMDoos^Q|Wu*?sEJfV&d5!9(&61lf=E{*jEldRT|xpU&`^Ty!*>>;J@DArT-!P zQ^<3ZxqoXa{t+G&9B9906&^@_)Ioz7TwOJjK<^i+};FD?MD6?6vl6a3e>v(OVUrKoZfq-)#p(`lmY4LCX z6#+z~&>K}u%tpqgCxlF7Kq`QI0O)fa@}j2=xK@R2C;Vl4+PLB;QW*N`%CJWarF(Le*g~!&`++K z{P}Od`3*WA-2Y4;5WqmI(4SNUylDeW%v&Kn;Nntzf{q-+$j0+r7+In3P@a6YuM+GYiBVT*EYRW<4(<(6xpKWxB}M*mVMa95LX1zAc!VGGz_AV;xDyXjg`d|MqU;~Gnq|=Out-VBh<+&gSa+` ztAc1Q@71=#H9@opf-$T>(D-4cX5h+Bgw3!-xnx7nT;uS)}GL7E=9yg~SEP3l~N@*sji z^y6NzvlLRKnK2H8BwC_Wa3C~;NCm+KN(8|fPO9f@B^?C2&6JE%sN{mUJ&1e|#UKi5 zf{pUQo|WnC62u*vnXZawDdtkYD~N8kKX;2zXLI)`jJa&3M-UGM(KCoXLEINaZ#CUZ zqvO!bO5GpCgF!r?Ni*xx*H&XpzaSn7;^80$1kqnHY=U8IYoL0?t_})f2zS0rc8uPk zb_p2vXb?{YF+7OTK|B`3$RHkP2kdOHldSMW5TopDm{E@jVq6eoRg(o-mSIn-ECa@K zAml+j8^nYlCaN0SniRw{N@0wdfyqHUXZOsMAf{>^S&9b(UI=1V5YvK~Zd;!b#7sLb zHp-aUnl$!-U41Et1zb%9&kbUJ5c9OSCX&GS!#M&TU58@50vp;VJu|~z;5>jEow}W_3)z$^^j;8Bf zAt%RdX5t4ytXB-4#cClOA3}ABG>;RZ>jbNuXqA&fI5mWmjc&cCSnp{nSj+0H za7GCALZ}_W*>as3LLGU}Dv4o>b!|`13E}(@>dSj>2P%f|N(InOG6)ESZoLg*jDgX(pZ~+gfJw8fgubE;SuQ!po_;~6*qjST*EX2RECEzE`-NI7#+gnA&iuFgpfUaB7{*T zxm3njbF7Vdl5-{TsSw6nFC!;}FiGY_8~IF$cX9|Xh45SmGeVdW!V4ixv=)go+~B2S7pWWFg}Bc!-Cgm*%CTc^M}?Rf_C6nHm; z4?}n_g!frT$_F8=S3omWV+_+bDDfkn%R03`QNTvwrzO=kh45tvpR3g75WWauO9)$S zWz#)Ya4!BKe50CQhpA4Av?!uKKUl)g))7{-q?yF>Uvi8OgI zeNPDcLikDIUbe2DQ~x=HUzAAxYY6)_CpGmhh4@+2!CoIe+b#bze4z1SsXqO z)4hZ89^$sqTpgBKB@BddRM@$6uqUiZa&#ESgq;hHQL2VGZj&Lme?Bx8;XJ9i2O zoDjxI5>FJ?2s`u4fRk0BrqJ|(@u!Ayni9!tg>kz08DZ28S6&{eGneso!Z=If*+MFH zMe2o}Nv2sp>|C=KX5!?>bEF*yi*IxNG@nMySUxuaumM*52J@nvuecq!syLiAJQx z%PtblHSL|7*V3I z0>^H$MoS+f92>@yBIAVIoKK0E_@~2oE{q9bJR8QuFrJZXlKQ{^Gla=94WFWbsbM^C zV@%kzFlKSB!e4o$>Cd+c`!0;_Hs0)tonh<=V^63pJDtP#$RFlBmHm1aNq~SIAkNuJRG*wszfT^ z03(8G5gZ*s)d-G>;MmCjugPqb2NQWzkKj0^kaK=ch@e&kCq{5`1T~a$Ql#=d5>skM zaH_;pgp5B;#Ejzf2XBf#@5!97gQ**^ri8sn#5!@d^Z=2gEQu&;~Iy?;@l-}2R9}+Q_<%c8aAHgFL4A9mZC^Yjh zNMYoI?XEM`xa)?=^=JgcBX~^QY(>@_5y7a4^OQAG`V-r9Y2QOI;E&xk)8!DOar>YkHg_|ynyMeuwCGb4C`nj=IR*~ZR@d@JO{ zGHbi|4&hFrDfqqk?g)MmVbec~?6D@(dF+i~Uj)BK@Us@0>-&oWNcM{y5dLOGru-q! zf`3{<@o$|e{|FC8a7eCyg@=VzqRvI$oQ4oLt9DEj)uK2y>RidI3K>RTT`|WAX;S2I zg3J@6s3CHa;!T~JQJgOElqgP(;xwCBON8^u^fRKU6GiPP&a__B7V#{r)Qvhfsd~b5 zg!P5zMsc2E=;d*K6c@;3F3pR?FOH&d6qiKNP-X)myLV|6jiQym8$*-vO{|OQO~pyr z$;&OjB3gMLxhjg5QCuBG3%QyLuMsl-S{rtqRj!YsZ4@^|(K?D&@-mDQ*hT@S6)HDI z(axq&>|nh&MRBvZnN=osisF_i%A>e73b!V_v+y=ynb0L{rjKc!sPnnZEA$EdLcZb% zD2yZ+1u-NH3nM}{7mFehMTL4EFXx(xdX%p3LlALSQLYz7#hXkD27Cx>p5c#8e%v{G(3vOG&;UFqse20%#qyu zRv8t=Xo*LZu~CeZ@}!ViEK3|OlP_&1h)j%PvIaFtGyF^x&&p&ZC!eExE{Z8uVFfDB zNAZFb@@Y{_x11YbrbahQI9vE4hsNnu(@dWe#auNsPe_HWEQn%R6fZ}ySSbsIi-hdP z67_RwNgtL+vBG*;VWqAAs>IiXtAwWh>#FdE@J%7hu8HC;^?@Cr$>VLg)~TU)qIlOv zz9+)452Dzhl=V@3D8iMc{*kToaTK3ezR?DJ7RA;mHd+01kTQS6C2_qApk=3bqc`=aAw>)BlwDmyjlx^`9t?is4`shod;8?s3ll)#TGl zUM1$-0t`nCN0*q##&BE=Ri#vmRX$Kvw*kkCoFF_gR(WA$os(iXHHMR=*Nov5L(~?% zr&+UB%(?b*T%3?IVyGQMofytk9V(pRv&7F9))ku7r1u<|^!}q-S$8f92Eiq@?P~p+paw=uwE}>iKiQ#xX=lEg>$KaP)E({2R!jO;^ z7;NInqcOx{NW@T~QdHt1n|bjUNm-prMm!rsP9)Fge@mEH6u({AMR>7#HCcFP4BgoZ zKLW_rErz>An0SH$?up@EDJH(B_x{sTiilFg}J!F+3f^1nZh;bC>h^KZeONpS9lSVwfU6MU~s};vd8G z7+#P#O~`hq^Z7r9Su$s8ER1I-XWMbTB-b3_T${y!`3fLeAo8+YG#AM{gMR`XtNi*1Kt!_6T{jV-m>27c=3;6-G6Jo8^e1x z%e3-A3?Ig@-eytUU<261$1!|jO%qT2)YjZ&U5wlu!xpR4WSEIJ{Hqvt#PD?t-^H*k zhHn{Jl51kN+jNt=GlpF;?3Vbwb^TxoWA?=GTMR$N@JkGPRc&7kKijgV^82=K^w+5EVFDguy2M*a}pyK-CIVtEl`h z?I!CunI^_4CsyF}3e>1TO}S1Io@}d~Qi0RNPqlSwl~g!GytY-&v@vH@;GzngU4e5e zP`3i-RG^-XF^$%@_0Oxo1r<2|zupUNor^2bumYD@Z-XPcUDiewXk39N|J9pTpqW)n zb5~U0Dk)dmb~yuA+n8%A(86*vGo|xGetiXQC<$m?f%Y=nRG_U2-dKTlB>`--gLIOc zDsZ!HlxC+2++rhdt-x(^b+$^G&0?eO3V5Y^te5G&5?-$0u6D&ka)oU`MBb<{CS=XH zB`lS!K*|QwOj}o0Bqz*UkpaaDbg97YN;xt=U2VXf6}ZcC1~cI93fxnH?j`XQ@3k>K zD{!A}-BdH!rvm*daDN3JtiS^$xqU0}kj*vqAFjXv1@yOd1}eaK2UTFOjUQ5hp_ZFg z9<9J|n`M;86)-|LQh1y87=Npf1xHI6BOEInCtM}(Q{v-=41T%-6D((uNtQoTfoCnB zEW)OzSY@gRSCbW95T7QTE@b3Pky%2<%&x$T;-(LC#ODg<3Fiw<{~7;s1r|yn@5hTj z_dK8fg-eCYgv*8e)=+v^YKmSFzAAi8xJtNM__~la%{0ELCe~EoEfL;8>3Un-%qPuv zWWFoRE8u!j_Ue^CX0VI2*{8Taz`)th5BEQ(k{W1?&?{6Z% z3)u=w{aJy(toQE{{h;`v3jAxmjIR=RF6>7MNg#4`+-;b{t>$m8@l&XCDqn#40@))Ag1tSY^39Q9*I%KGCdFEQClFpi2i zLUBY?A#AaXcKy{c-e-;{oXp3Qe7dEbnJi`g6MC7!b#x zI0nY?h}BIzad6!E4il20at*T;*!1v{;K$<_sVG|q7-iYJ% z66MVj{#G1oWwM~Dxz3tQf7eF7XDfeT6%+iS%ncxCFJpeQ-akbC6!KjJU4O@MR099R@oyXlZM%nT`eBhOiT`{b8WK1< zfnyUmrbMrrK(&N(NoQw{^y;_-j#tbH37jZG*AeeYQcf1uwBAz_I6Z;WWU^E(Ta)|@ ziM6d#$Htg~XWI<S5esu)gqI>pfq@bn-&+i;Q9e=;F~pW<%kn2{bY>>U@&~E|+(@A^@1SR?tC>IIXm}?Xe zk{K38gsc-wAd^5v0?7p8R!msJvMKSja3$aWi{uh0B#^fv!-@&qo&W>LdGJ+O*95vL z;En|D6uC=yvKH%Z@$N##Gx6R8`X$gKfj$ZJOrV!s_X%08w@4!uzdwP#2|SR%gA$L- z6BsO=uX=_gK%|$)Fo}-}dAdC&^0;t>@Ii$= zAwDXBaU!D=7?Z$QagK$@423~B=B(pn-cgWfzJ}yn82qB zlOm6;*8DPoZJNEW68Kso-zYjU34AC0TRXQDS$0PP`x4lh zz>f*+O5leCzE5Dc?G7wQ3{5T%F!a! zk4@sZB&sGWPuOZnRJSqo9xr}^(9BhhBu+`vSOVx)epM39lepUI9NjhI=CkUx;@4Sk z%OtM1oRO`PxKU>7B-)6ywO&qRJMs3y4pyJS>pzE|M8_m~SrMTS}Z z(WG+`W&n@JBtD*We(FSXq>Xt(WR!4p$r_DKVw{a(%2P>9Ok%uMo)($F9m1z06`UmH z8R4@@=ihdlcAraPip`pu#Pj0JGTv!POqVi4I8)d{-r3>|dr{;i;T)k^j(OtqlUN|~ zvhc{ephZb6mcj~4l2~dvbC-*+u*yo2S4zhIS`w?QcQxzV-o7ERhRikMJH^)~@wUu$ zHp?vQyE570`&KtSU!TN>Nqj7ELlPf}nCG8QY$R{8pC+*{iO-VQp2Vgkw#xN6=hj|o zwn$-HUyvm6WfEV@^_30a*taPr#NYq7{(NMg6dok{FUR(^5l_fnSg!Lg9Zuq?6sn~D|E`9QPpo!y3RP1$CI!w9C-c~p^V4DK)lxVih3Y9BFV}HG*5|QI z$B8ND|FG9cIlnqZ@nlu5sjyRoEOM$uR<0#t&Yd&FdFQH~!kLP!BRtDyF}^N)rI#o5 zQZVmZ>ZhF7O6HZ(c`4_cn$A}pk_%+Axr6>!C z<%#iT?>(Ht;1v3&Fiov%ptn=+ej0$Ugn3w4Z@EUe>s2oGlkDm*qFkn(z)5#TYg~Nl)~pJtTNXwmEEEh z+?sM8Q@>C!37aE+CDF9bpSe3k0eA2W;`jfgusv1zWAPo*c?aJm!nPQ^JB2+d{2+zq zk0NZEJg?5M&c2lM|7U-;F>K{m@%bHLw3E9MtvD zEbAejzx+}7VSZwFuKZQfI694^(hlc=bmcR-S;u43&add0`)0K?j!Qeg0#seW3^-mU zOYsJAV%quTiW+h;hNVsxuPHPgqj;)PNNS~VdfNG&I@8b@Y3Hs%{meAZN~4Z7S=s1y z(>N!Mda7pjYJKr@g-kRzsqHj}tGyUo`u1TZ0TxR375WiN)%4XZQlzF|)ZIwnFDXr7aHSkE- zjcMGHM!Pg_PNRJqHz}rrkgH(ocTA&`rkbrA+No5?_McA(&(A4{Dx{X551)K7WNUEK0F}K zo;;XFU&|k|)!5v_Y4n#lKuBev!bk?$_`zumv3#4BY*-qPT4i_|kJ*Bz(Gh8kwB7}Z zA0=~i8e^05B{G~oicX`zZdQn9$DER)7T^BC*fWp>$KqY zU;LLe4y5s`)%T|>pXGi_({g)V&LZ7YQ#GULs_DHrh~iE)_NsHWoG!9vK}^jb>7qb$O=pzcXB!!Bv^cZ(pZw zrnkmWpHZ-Wf^p~{k+ZgjSn`g@6Ny@*D7_DqEF_LF_vc#$RKFf zH?OR42Js9c8ALOccc_@MDum`b&*BN0$&#_BGssA!H!D&@1@l}@s~1Ja^M}6~+$r8w zc!$-QdshbCN=z!YiUX3a`6=z zypqAnOy#4UnU+^|c9?3bGFY9#>vqOWoi{UhOX+K@&fv9D*tc~Vyss1a9ZnQ~1dzdd znaYcpsn1DRuV7+Bafka1ogF^tFW8T?_rtVZRp4F0ytKN;sgDVxYc8T>0fB&AB$ zx$+;CbuRA^H*HZoCW}>ysVcpikb3njme^{?XK{knO=1m|V%W*jYg+Fq*~;tZX;Nyb z`03Wm+}h%2TBT0bnPk@CadsAUv#2K*MWZvNeirAdx$}gk0~c6+VHOwJ&d|l{u&$8!YZtAop?*(^;z6d;%Y74 zMuTFcseGdiXrIN+;vKTMNyNl-6z^n}TWoq~tK241mW4~il=X;vt>Uw!T!fVaSp+RN zDd8+4Qli4xf4%W65>k@?)zevIY?oLkm&NT_f ze~-+2g*}8v=Iy>LdP(VR^*&jw(IPVD0f`T0(O1M2r`}KI!?yl_EQVzwN1bAG#jR;&Ca%g^y*O7rf2*$6r~D%3@>|PjKvZ5AzN_I*T!iJl);} z#%1xelqZExWieia?J{OU7SG6>n8hR!_L)DFdDg~E7GV=pvY4I4)GTIX@q8B3q`zQO zri<{_!;f{WJTr?~Qpn9quots~Tei+xk zoiD||vfi&nw%JYfZ5BJT_|AH_i|pWq%l;>Gfh>NLi;KbsMe2VjV6OOISs;hMvp6L2AK^i+yT<-+7FBXM zYzwljqjJt&z}zv9&Y@}!$4EI=XlA&Yc=a5P6EQ2xNjo8jQ*$^mhm&)tA=gPl7Ubzr z)ACb9cw0QpDz$Pr-E!UpYg>M%NFCu>!n@S%y5jYO=j2dd#O&Df#M$EcIb0wUpZ`0fojdRYcttLXwLl<8BbGSnB&4icdD&LH; zl`9o?m5^rh9IngZ8ilnGQoJ@-`RT7^4sCL{K8IF0+#v5x^^F^#b*}OU>usgqDCFIZ z6W%_DPBJ^>a8nK)bGTWi887Q|Zg0uKmBXz$bhdrFEr&9NvHy(WNZm3$Ie2r%# zQq1A@9J(r|ORn;VVytTi+$Um&+&hPdbLf-9 zgE`zU{Q;pFIJ5fZ@K6r@Byt0o4)@Ptpp*eQ=PT?O#^VtwgSe|@4#{D-l%c|5IXo)D z$Pj<{EB<&6BXbxb&h@41NVQQCN9Qm`WNZ%OMaJduBst&z3zebC}5Ie<35uc}&Y;x&mehsnEq^Rt~eJyqLp$k(Y#Xa+u3gMltiG zkS`E<*_sP;SY)}Wwj_t8QfMyYn&$9|%oW_>xylbj+(obE@S4n(_O~?{zgm&63*QjF znZueK-p=8zT;)rEwbHqW>nwT4x>(^oiSG+P5U$VR!yG;q-;l#cM@|r3#y^p{(Tblb zjCD5U@VWSAt1RFz|L8*Th44$^SHiD_+l1d3w4Wc%>}^+(9Xae2VX0k~>=yY!_@fos zfuF=l_Sz*N|2cwE%HOlPE{}G3w9KPz9@pp5I*%LjXk}AO@isDfI=sP`Kehr}Y@f%?d32C+Q;FU& zk6UDR67mPrx8~7VoLSr+>_Ax_zC2ucc=B-PD__>}`O_=Twix4AO1aSVBq$y#Q6l2e zJd%0D@`&eAA%*E|D`7b=?JbLDxpV5D#NP2ta(c7*pn`Zj`w)F>8hmn2r z7?8(9c|0svzdSxuh5j~@=0NdBtZR@ZL!=M2k;6nx`T<`5Wj-z(Asi_*r`ss;(ZVq$ zI=eJZ=976mB{E*f;n2myq)(JMDUWAFo)wyxuFr`xa!MXk#h(`*sld}`dLA$3F(Z%J zdCau&vqZRIUbKp7YmUsh!g=}-9BL=v{UOslY5xFV00 zc2P{1URC02d92Fgb@A2t%Ae!BA(KV=YV2!dz9n2Md|Sv@H}8lr@?DYlgzpPEiuHMX zn#YHEe4NJyi603WZ^rnE%#FfUeE%=9$;Oy|Zq8$il&wOFU)X_smB)@ezLvf%k8e$) z4f`&S?fJ@g7v_B2na6HQwpQqcP!AuFR$`HA%ys~lTE)dH%? zWJ-0b^K-}X1)L=FgaS?!sbRgG=aa>23QrN5ah+B`?E-2^IbFzh&nQ&BkvmgL9ji~_ z%bxakbt>N4P&XZ{tm(?yP;6f=E*?9K+67dFBX()23kR59*(xiZ9 zB9|4=RD{)@)^5DKfGY~Pl4#FO-o>si;Q9iZ7jUhDuPLB~h#4t!uPdOX6b^(Yj~fbT zRX`hwt%a=5qivz`C#~%ywlCo30y>D_BxEkjb`DboD~1Pdsa5)gLP*%1;C3z-!WVX2r%MFGhI;?|oe{QtKfQw5}@nRnZmV=J;2z8KeE2V*x6Gae+-LP(wm*HO z++V;0BD`Xlf_)3sDX`r*R^L*}wty!K7$?pXpRT9G&GXFD;uC}ug_DFFxY_g17BE=~ z6Q5%%;&W8z`2wcPd_g#^Q2F@H$QcF9v{|!6xUw&byd<1cz+7%l)nWWRiCoYHA}I`6o*9urwaGu##3ttx+*PFJ^O#c5b z=?q&d^0shY!FiKRk@4>qoO{Q6!uN$A2-gcg6mAeQ_~U}}V>>?We8T;v-QK~D^fM_f z`1}91^(k^~DL8M=%|h^+aI%?c?v!!Q4_J>Ma+Q^?@&3)oY@ZtML) z+DH>atf~n-Z1tmx z&RXz55l35oj0pSe#9Lmyh+0J)S9Iw=vkJWZCkHb#JLjBDWZO{@&gO6f#*piVa*GQXj;UD zMO-TJB2%P@ONwY%M1x}G3kSYG;lWe5kpdbEn-rZNW>LJX=$zf;&7`yJaH!f$7< zTneWySVTlTR79AgP$Dr}L`0i{+xsPw zFzmr12FUDN#6vc>pVsc-BKk|=YBF+Q5yNFZQpBJlhN|G;B8Esb)fhHR=A*(qpZ|*( zRm9^(jNo`xXC#Nr@BbGvp4{9S#}qN6h_OXXEn-{|&lK@w5l^emQ#@bnB68s-6fsdI zAG3K(;+|J!R(rOH$wf>l;<=LXn!Y`+QZERn@eEbUbeZHcMP?N-uZY=2yd?8QA@{(X zBKT3AWUjUc`TQal%DbS5m$|)Fjku_Y#WMTpiy)R1LBftLD`ErtT*TTURur+ih?PaW zrV6hV@v6=*hVjf=C6R>Y>qWdFvj+e9OA&7svBsM8@;H~@|4_txMXZzlj;4a*ySyN1 za^5fEL%BW>t`~Ab%$$5A^J5{aeNx0md)j^~kxRcxgYA9zdknV9@Xr|htI^WN(QfDS&g3LS_^^XQ z9^XbjH1=UfpZA>{hD2_(?Ic4}A9nF!XKUNcS9!m~Mcdqm7ShSR%0BGxLn|Nl@?ke0 z+W4@$53POJ!}p)_A)Re~-faWPo@!3Mw-4>b+xf7MukwV4*M)t3=%A2CjoW^{${Dz$ z%$kkuN2no;lpu0^i=a+W zbKYNvfQHk|dAi5|AI|W34?xZo(m;N;4;LtVj&Pt4gM1h)ey;F2e*eeF`M%1x3oev$ zk#LA*FZN-maTez`%!lDpF7@GZk;`}>lwy`saiv7^5h5df80EuNK8&_G;cSfY!S935 z=iPYIN#s_eu+~KC0Uv@sgnbC96g?CpKGgdV^?5g_F=1TD6qSUWBn(qNc7f5PNom*|0`~=@H-!V^x=Dj?CuBaWup(9B>rRy zvp-v_Uw!z;hs`|6`|z6&TcrPP*+108?aN=r|F-PEK5XyDRv)(WdnbRE^0!8Fm$Mty=l9habC1+1(6GwH9yVM_UuOjb|?_ z*iNZ^{Mc8dy*WD=VV(WS{pje&fqr!I|Gi(etU(qFkaveigGMp*^gt};GG#OH@!WZU%CszRL~0g<2|ArY1e z8;MvGwu(uN`%y2F@FVR<(qDNbm6FI??u-#O$%!`z^L~{4C~yt)t*_l>h;ph7;|j|csj;$t9>KoB|lzOYK8D+;VZThUi0G(KUPX)+1EvQ z)qYci3*aqV63o7%1O2X2Jgo1Fd?5T#=vF?L+$ujlRu|--SYPCy`LSBz8sX;2fEF1``+xP0r!cRXWgHolkWR@#r^9PLJ~AMs75@YrqUN5Bey^?T2z zHuH2Ru`xda@M8~DHUkxn(0@7^3(gG1<)c#wGx7U2r%V#=X4ILtT?!4bxf6zMAD8`W+i zM_cxo8gv(5ry1)h-m3=3)!# z9xtjv4;$gd5{FhDyJ0mLZccW6nfT?VxQ16M9HHW@Jj$}8MXsu;d{^98gE}ex8r0OF zR-DV&6$#WJBqbT3|;}8M0%*7$nXEu;2MczYjAB1#)*#?GV5%_2~w^XGQ6P%H;TK%cXJKysKG=j zx0vVF8ceFe?KPNe6Mmag-2Ev=rdsMwYc);eE*+64`TIXLm@Q?xaE5SZ4eqV+zSuTP zc%P7?qB2K@`-O9b6d#b`LE$_zFQ~zjHCR}KMKyS+29NO7BtK`Er5>%pV+w-`r|`pH zP4W{$=UFVnQ&p|l@R=GsD`kmr+xma52G2`bR)ZHrmfNaxbNG_I*jFga1NVxNS1q;D z6n6B6_?yDFYVfwmNW06W;aw^33E#KAK2*r;M>SYw{9_UK;O%q zv(Nf&qMeHW--l6Xy&dRN8(Z;y@YRaAp_o~I-BF#1OeazFo z7W*3SP+PgO>@TIG>77hx{R1U-uEjwj2b+hBzl-rhYjK#ko4_MXKe85GjUQE2^Jt03 z2)oyMFE@6?t*4Y;wK!JfI3acJa&PeyOz9(XVlB>9!+r`+vh2yVIK{YI5~tSUG*jG! z3{ZH6@Jt~Gf40auwHPEakn?Y2J6B3Cp8rKSDp&aeg%{T1B9S3g*`eZ>m@>?cGTUA% z@iO7%!YhQ0`0z($q;OO%t`ZqtTluVTjEd04BHaA7sF8uZwib2b?kEJsL&C6m+?b=a zh?(Mcu)Y=vDM_Id)8d(0WNRxA8`(>)77f;x)e7Q8Q%WM`+RE>+T~mweYcaMK*GeB( zi}4~n>9N#x)@nj+Un9rQBm{a)!d0wYaYq_lk3PvpD%S&$DeM+;7>rA`b{3tgZaT==@qN zti=L}?mqk>^FLgRN5tJBVExBxvBr{8D5mmzFrbpQHz(&N%7SxzEb@4TD-wkWPAOl@wY{&zf+5M#ox0O#Sg?k zG|xx1SY_Pp>?gJORQ1^@5B+L!zLeI~R_@-vu0|ndB7LnbM|)BoPL}8v zK!5R5g{KMKaU39ihVV?`4F3O@y2|qh);XsR1ErG>s>8X)+59~5^Mw}(UCoQkGeqQK zp___J>M+c*!|QOVab_ME~-tLnTT-WenG2{|?@+g4_+{B^>B zFj!Z)zK0dk9}#hHTi7tJu->w(HH>5(Ql_LuGD0_{Iq`-%RRMXsyE1XJA0?FNN63U3nLES$+N|A^cwoFrsr?!|55x0^CW#EtfjI^1cx zo2a|$aJQ6g^EO@K452$-_tsVJ$5{V9>9gxFM`X0^?_7ls2p_Eb-{%_h>##uLLLn<~ zBoB+bAyIj>4v$G$^k4l6g-_ODv50H?wDD&|_$*?HDN9Xx-jrn`Zjdk3;YEcn3Elp_ zEdGk{RpDzw*VpUD->Acz#@XZB;_sO9t_UxV?`xu1`2#5=ADObs6juJE4xiRxwUp25 z;L{wgQOK-&%kzc8wN*3!m6WgRuujA+5Bk4RxIy@>`M+2AgOHvdMch36REJFpf41x| zb@=8gKiMt7RHv>Cu9l)Le zZ(wZ#Xe)i&c=l4bw{SLp|3RdE0Q&~KZ`Wt}s8h;*LWXWHItI`wfCD6Q_Bxy1Ie>#C zx;1=A09^yhBbL$hRd@HYS0H;dt7r;rbiSQIood(}uA^B+moE^aF z3I_tSeeU~^ z0EVjh#X_F7E(u_`_%NZHKsqlAz%S+U0ImpNl=zjx5dn;}@pI&(C0-T47>PVfbMpl% zU;e2HAS6Sruud2d28BG_VUdW19DFQ*VgPX|^_+nK5&@(YCId)mk zRC$qtg*2A}m=HiYfN>J94&WN@qvmR?6!P&R9RIZeTxXnZxm~aD1|BB<32*>6DRk2{ zQT!Gmowo)sDS*iehw%I_a=V4D+SCBb#q1Y@&H~4;3cJAB$t!=3a%^hSCo3y+BUaU{koJlgg?poRsioP zd|Sv~Sm#~w_k`|>`GGi}t~2|Q_$nb^ET4$Dhh3j>(b@}qO#o|^`kW}@=GGzWd=-Yo!fO@PqVErEk>E&J*7hz-I0UKmQHj7kSv~S1BZy z%JaMQEdlQlt5c@xcO?D_;O{`?dm8RJ%)fGO4Pd*VcfH^{n(c#txHC9xB!x53ScJ|d z!OF)>Zw@pIV%H#c38F<1&4d5z$Q@0VY8gbUpm&mY^RPR)3hog^>#9!MS}$zk z+V0J2L9`2^eb9SN?V}>>n%llXEEOT&PYr4481#Nuho>fr3=dE%9@EY;xc9RM2hm00 zAy)0sAPyHl%oH|1!g$vpjtW+u+jkS$_6+}+Ai7so?kUc;y@EKFPWA3aLhNnX6Ksk& z!V`n&E1fm_1uLiMlY{6V#3|C<-RY^~rv-6(u=0MBZCR7Mc7~1fEP2ij;v5n0k}A)j zAT9{v+#m*<^SmI=H|{*{xLl-$LxQ+igr6r44dSvOF5wL5n;yf0-uu4c!b^o512-P8 zE7ZiDDo2Qq6f!%?#(b5O8GH*M;tT%o-AWDjJ%~DW#3lh5+}Id~f(To+h*gV8i3{t6 zZZDGJsUR{U>0srTnz9PH2Kb%rh9Js8XV`Ug8953W? zVd^^Z2|--1ec=h`1}SXF#d%W@6BXVZ!~zw(CFnh7xmBWDjg!UQQNBHhsX^~|gQp0& zHM0I}Ta7$3+#kf;ARY)-&ZX|8H&4}Ae?CWR zoJAfIe>jMzMIH&_(IB1(;xR3uMZ(9cmeZ56Efzi{+;$wF3F6rxo)2P){7Z$;Rkd9v z|8n6ARc&7qUlGJBA}w@arJfRXM*2;=3R= zNcq5RHZi#VYd*Pgs@8pJB83Jgr*_v9IAYF!0BZZ zZYv@+)^*>(?M&k*(qp^coaL*5NDo42j%ajy{Cg|N32x03e> zp}p0iLVt%44h~_z5DpAs{}4Kb&{2Ljk^{uuj#KHZ@SsrT8;^&CaAXKwLO4wNp&{=q zLEGUW9AUk1cUJTJpCNP$;V6mxgA|HKR~fp8a9jvILg*DjPwU+s#AD6o#?xEb6GG@0 zLZ1-&Dm?MO9_Kt+sZ&BYHH7|Fll`*y)673W`WcozGla83I9nl|ti#5RcE0d}Q002Whjfap5p+1C!=}9AOm=-6=SnuSy5E`WCE$d1ZSaAZoTUPBIiSJgWIA9t+kn&-bPH|NTA4?&p?b8s}DEush)m8fE zA*^Nns%*@bbf3;pVi~MGlw}|`^ z!k<-5Sp08={|NuBN^KYRE(hGU4+G+^K9xomHV&hyc#|-8GLeRz!`MY(vvB2FK(Toh zXQ`H9wEC~&>hBRon=o3dIa^U|8^+#Y>>0*hRb5bT7sfvSRrU>IKPeslU*(QrbPA)3 z^aH{;kT!ANRvi?^!QsmPWnkGur1Mg8sFB0MI9&V)Q)ufNM*lF53gdW*-NHCJjGp4h zgwZ|hy)o$_q?w#suP}}^5J8pZ&H zrwLCNUcr;Rku$?!NGG?mC7vT3DCEAM8^*9O1}i*Ics{2hj0-f47YZ*DvH}ms#qtal zULthIh}q#`TpGqzVO$o*h%heKj$9$U(sqiIFjCb<2}cVlvd9=!^9lXJnyUJBVPq5r z!U%?u5D$eB4kIQW2_qV=d<@FB!`$Ku>rLbclVPN6U(!}Q8^%pxvFa58X-k0C^A_Q) z!bw8+Uh=ju?g-=du=nO}ig2os6{v8#Q{gn>U6#5hjD=xLSDhJQ%noCwQuhjH3GXvA zi_8h*!7%RE%*+)&AY_WiWuEHH7cLOGBmPhrk1Kpw_(&L!s?}q{MM92~W^PX?d{Ver z_>}NzA#Klw@j@6&!gxN6r7HNGaK5eHWnnCrGFvaD7sGfhjF-ZAS>g&IJ9;IISH*dQ z=e{(;;w!^=JzRMcP4UezJ`CfnFy6M_>3JuNcNM-Td|&v18CdzFFun|9RT!(o_&AI= z`20ussqix)ZPeFj0G|uL5Uv$6#g4dr6~@XDyG7z3Vf-1!KjMFd@prg#>&v%$-2PR# z)x_;1-U%GS9U^EPL8AzERM=HthjV+>B;uX!xcf~b*foNkBbB$1%_7*vc=HHa80W*f zmJ#e7L8}N_N3fd;Qrta)J&e1`Z6au^R(lHfs;WSLJB9m1&|ai}bdvE7&K36HVzGK|gVKxKEDYvC2m!xlq)nQV5=lppF@kOq1kqvWv`9k#t5!cI3a=?M6TxwQ4zk+rTL}^ZjpX- z1QSJCOTRUON!lHH*wN%j<%M~B1b53eC4#9DOpD--2=25w;d^Axz+DmV!y5Nkd^c_D}?mMeuM0k3=fJRrsi0CT?HcQ}M@{ir|R|7OUSUg>JT=5^tpX&qVNS1WTnX zvDeyj3a9Y0%bWiQURJm~f)^rqN&Ll#_cs)e^WlF40o8G1dnHo&Xoe$yP0p1Oye{&F zkU9^f^Q?%RAe^IN zY!r9B5sB^NAR2Jzelh|oSo7}!=DlF_WrL3nkxK9;lD!aTO-&mTDkwH zAI5ixqEQq(Dx~g8HL;Klx$#^@JE+WwT7){0B<)hJdfd`-xYHr!6V z5yjh5-W0wiWWVo-u$Om5xL@x_u{w$mqF5EhhnD?FgqOCDdAOta#B}Zp+kR%RrZrKl zRqAu12$vZRUq1;w zCUKIVMSig(yIJ9HQT!Ff?@|1rv2D>rakPIb%ew{M@U!jTQT$_dctzeSzFo{a-EAN9 z&f)9}B7OPrCx(_W>=?sNQX0q5BgXEhJCFpvpn3Rm<}H!$L%F&q}d;Z>D6wj*OWI)<+1JSv86 z#@Y2TF&q~|cQ%QkM+`lc;&p_}l38xY#wzD<^5bLZEyDpy^$|Z&$ZTJce!?j-oGgAy z4EKzsdvQ|? zQ)0L|hRHEZjN#T8Zc)}9;z{D{h;47v;k#YvN=;Svju`F~;pc;NP7~)_jJso)8^b*@ z%!*-p3^QYxVb$E};$DR;bzcl~_zJR+MeY}OHii!Rur?1BFK@6|O@Ma7v`7(*&b=g>xPTon9ycNT{F}xkaJF&{| zE4mladojEptNfLRHwOOxPYfTc`A5Q4vC20GnEfP%PhI*Z?7*m!i_QftmZ!nH(B-< zg}(~f3lHUQ#($4t3r|!0`(G(;E&Ub4_Hq0j!&Zs^#PF~AY1l4ad34WGh+{{EJH*jQ z#9dDti_^d<-ATNuaA#pN;Z*H%^Eg_^(ISrBTTj^E5)s=z2aye$KF!f3HK3l=6NQke_z$<5XXMfn@j8{-bqN$0dX8C-dT8%=?9DO z!qLT)Lq!gY|L=@_L>xy-baTjRM=9(UuY6nbm^gY$=`QSH=3XN7A1mT^=lD2!n|^}z z!U536t#2Its>~y?U-e9xxzV=stTE|I*GyeN(#t^%L`#BoU+L*w9$s9Wu<#;F({$A~yCjpOn-E|Zx$ z_wkB2u2ksucZhl)DaD;?Mzf&P{ zt|qtH;HQ|=4S@51r<7^JyM(Uad&H;5F*A-CRXTg2VV0EpgtM!%?%Xn03Y`y#JScR- zo-e*2j)fwwuZP9yei>pCZ7;_Qs`PeCH}OKZJ)8!5|O3C=Pc`*EUP+K zyr9&JalG_j&&vv5iR0BOeWj-HbsyXuE%CR7@2Ck4({$rC}yG{xTJ>SIfZ5$h_Jg(pG zguPjIMcnSV`+;UMut(>oxkWv8RjHOrwGzH#z3**1q zBLa6dJWd`?EU$OH>v3YecYQgb9(|;{mz%?WQchw8o=mJVd+A?~)9P`mcFpa@>BkMap!qD;R~OqV50q_?kRnfggX?jgCh&ZTRM^n@d9A;w9z&$N>;BMs?_0Z<)ML1s z46FB^RC8Z0mFF^{`$XUhjoi)QhC$Itw%OxMBeUvpzf$+rW3~vhb3}Lq zxk}x#e4xH^S3IvC3+uhVNtv&syg|DS>RE^Wu0nQAzO>%^xQEvxrk=0IavkMm^_5=;VT!gFRpF(2tk8jDD{e1a*?D{f zB<=>YQk=W?hRB=sc)K2NY4Gm#=*GZSt`6&WF#bV3K2$5FI@>FPoCb!@|7krwlV`PX zou#J8z|-Se)9I)9mBO!uuA}w!mG94QsK@v9__iM3)q9_*aU^^dbL2m0hTZOL)Zt($ z4t|r0{4BG3#W~z8-R;-!_1L0S&E|hdcQgN2J^s-o{9Rx9bi?UetJ-d#@XqkACTD(! z1R6;p-!Xy4;!T7*37cA$tz0#?qF7Bej;@Dc6dAEdjaCc95r;$A*x^>RB zZ6vzpY_*rNEWURF?Zn*#wog?4g&D&R3GeQd8wW`zNk=(5Rr#qOsIarl47nYgz#)ms zWp1vNL*?NCWs$?>Y|fLv#I8cNazk}jRfoqU&|PL%gdQIBUe?jEYRH1eC(v7bTiZSg zX=Y8%9v39fz?_qlq*FOrJdDRqso_G3+%B{16$$Tc9sdoA z!x0ILOdy`Xs08W~7@Yu9S0&(2V2n6zJ|j%kh}TvrfdqmHgcAr=RgNSOH4iJqEX4}- z(i6g@FeOY2X?6qKh7D?)7ZwsIiZEMBpe%m1DJ(uVfol^Om%#XhcR_5a>q}D8a-D3P zKyKG3aDyi2#suz2;HCs_P2lE)chR3HyhTVSl}QQQp1@@JZxd2vYKlBltDJW#J56|( z@a`)A^aLJII72v7cy9u;5}1>~eX29Ns@nY;@LVB#$XPDts(~ClXkc@ZMlPE~J6{No5xc8B%;Yf%g?YlfbhHypq6@1eQrz%2$2DySO|r zq?vqq0xu=-f($PTDKfP}o|mhfuO{$D0jR`NwksDR=B5duO#+KV(+B4HrfeUlf1pM`wF-1 z#eNF+PokqprzAQjaR8Age<9nFAEfNTLO1`^yCiXF61|c*O#0zT9FxQmNgS2Lk?OZ= zRqx%H;`jfB?47*3TJ;e26jEf_W5th4qL0Y&N%U5$6NEI-cA`>!h5dxC?a4`;q3{%8 zf8nXZ(~>w{;~7vjsxy^3D~WTHI9vQ2;XvUa;kLONoWyxaT$sf9s&GM7or~lg@?ZZ@ zg_k5TEQu?U7_Q@csqix4kEQbrNHeNG0J*BAkR@*_tE* zNz^92e@|H_1 zAr0gOrHaCmuqt(n>=z4$6D%_mJMCq({OA_v{ zNXREioSejMBJ1RzB0g1khtT<_iQgr>TgVDbO&6b$#LTM7EHx{M*-6}IPAW9dQRoWJ zP2z#7aGv;l^V74?_(LMB@Q5jonzG0U2jj-`q2} z{#BMgqH>RZIF#5&94RzPf#D898d#IqIOSanng~gD5@{-Azs*E;5pFxrv{1OK6I0%4 zyp=fpyQk1Lg*_DZ;!i-N&_vuN2y)u(x?;Xe9fjFj$1neN*UQtypva z6b?wCqbZ$4czbi8NN3?emR+nOhosQOltWWEOq{pDtad~S$E0wil&&cpox)KmbW_Nh z+!vyIQqf&vj}&^QD&NEGmBO(Sd2l(-4!r+Qp|6zQDV&f(A8~hRP84US{ZcqJg_BY^ zC54ksWb^(h@9vRr4aiSRVL%F}D?8fe;S7Z{`0yu%^Tf|i;hYo(i4U|E|+0FpZ}*YB84jzGE2|M z6h@`~_xU@Ot5T?uVN43X6#OLT2XvDg(Xs+ z5k4zq+od8jJZH+X6jr3LJcSoic)>&(UNWcKg_jk+V)b8BxH5&;O>s6hd{e2nQg}Os zcf?(a_+APhrtp3WA6P5;sedG!R7M|)Q{*l6;B7gnY^G^!@ zrm%e)TT|FB?VZ@!(6xny6dR?{B#j-@-r?rf*it*Cv2z+trEhE7%(BhR-@=rZrnC~- z&GbFeXq!fB%eE2Wxo*!i+NH5q8he}5jcp%ux=!~^ql1+Fs`QR&9GOO^G!9AQfHV$D z<3MI*U@O<~U<+BcOB#o#acCNcRf*1agehG`juLh=k!_Djqld!oHqM@D^r|v!>+yJr zY|{I`*%Q+^GmXA!^iQK-8Ye4zl2tp!TCvWlX$(l?v@}k)tQ#cp46Auo8t0~Qb{Yfa zImdMNJIMH8k@JMq+5CbuE=}XYG%il#BI!fSOvBJLhNW>yRj0$N+Fq8%l}cTn#uZhq zMu?BBQdnxV!mH94BeK+1oj;A5G-|C2I_s($22BrFiBa*GFkYo6#91L(C8otQX=E+S zy>1ZCSJ{ebj7_7I#?@(*t8`Yo#=>!FTq{1_Ms-~p6O6kfazh%oq;X>!H_LgGwPl@& z#&1nyavGBqQlG(-zi}3slEz(WOikm?H14n_v~ine;oauH$9iX$ZD*QJJ}Zs;)3{H{ zY~h@$?A$cwrSX822dxNO%}?W@G!~?>P$??hT<;H?&Gq$I8cWhxl*W^CJ}!L1Jd4wK zCXJ`kc-j=oX&Nu4@mw0q(|A6OWmPG5@q!BSicJ1e8ZRqcQRR8X_-kpbRMvGt zd?SrFE$hU$(|9+HcVu(pf6sWbY9BweI;+xHoyNy$e4555=47eQs`wi5&#ei|uC?r! z*1PL#T^j4FY^<}v4Bw{lopCqRAO0Kul*X1cHl^{4D*SA9eof;y@y+J{U7_po595EP z@mCsuTPxQE@n5ytD%>tp`4d#?$aq(T9WrPnLcXI&O0(2Nd?#Vk3=Wh?PctdIWYAoM zN{bAJ^22T!T1sq{!ETn_U0K>%o5B+Ux3-ze(`IsJ_g1!@kP2_H#_|zRrgEoEr2|K< zCi@Frt4>u#4piIDQVy!}9FoDI8FZ;q*!Hjt4zFr^Bs{1B_yr;t z+FsB+B!i134mA(QJS>Be84SWi?Ev8sVfzZuvXMZ86Ta&RmQ3NjQcaF z5wA6c*+2%741!WZ8H6=~92ir?Xa;eOHYS6g5C26H7SfZ-prA0FK_-KS46+&Is`ink z@-ooOHweWHuFjw&rEEGsoniKx491$m-5j66%^6&q!3`N)Cw)Q&*Jr%HMWWe_@J8u3 zSu2VYGnkaYEvDS6kt|S?$r;?1!R<O>eRBrCiMX92 zZpmQ#EdI#gZ|Q#u{}OTm{FA{}@qdN9_HCE-&O&^|M1=SbLWW$QJ7&GhLE|i%iZsb$ zClO|;bKBX%T|}rfS96!$HH((gTM2hF51a3iMQer4RcDH@Z5Df)XD^YxS;6|+CyVx$ z-B+YT);j~Uul-HuyHtjq6ml(*Q|Vk4QaLz_L(Jc$YP2KdKRk;gl%1ilt2vL#qMPxf zvz6~Av0C>mdPwhS*Ja6moVnD2wy6I9JMG;dz$j1^R+4hGcP}l#7I1 z32b<=_)v~eA5~D{HY|(b(k~TWCUod`*j#QTMFh4W>2P<&n%3$mCm&NB~}!9wxY@^F72&f<|Q7G?3MbSjUD z(D}G2Pw+)8|Kcp3&*G^pmSpj?vd?7ktX{3_bgE%`>3zE#w$EXQ9H7vx3hIp%a&b1!p;-=1a%d`LC*j#V`R6L9U+(fQ5}W6| z|INxdVe?(3v=p`y?k03!gV`g8Jr%YVwh^`!^1QT{2#f43(oX26rF{89{#;W5JQHVHiy z_7bw%u{j(k&I7@)xA+N`?IXfDWU6lt{S=;L*^_gX?*#VG;mjOP&Ea&VP80IFHbCSI z3t8l>9M0uPau}GyInuZNF3O->Sw2lP@|RVvcsW!b^p2@R#Q>Du*j_7$Nb>T;+N_(x!z|=VtG!9BSklBlP9qw}Ek} z+-eopnHbC=mP06qi2Pw8uNT~+Iqz=)c;?|2&v}2vQ!h*iIdW!G@}z~C9I`p&RDot1 zxT^CC3&NtXBxG9}xLvLAnjFUFFkXC|kOP=wp6ha$Ao2PfZWOt}Rt_uNq~1v;<}f*j zTXNo)EpN?Xl8uvdNQK*NIoz)1+j^gx!yQuY6tc)Po6@^g=N{p7;fx$+sxMcK=2_P2 zK9Siu%rV8CJ?7^A_j{)gDm70yU&w(i6nRLUV%wb6m&sf`MMch|PmgexBLUzZt+?FX^E_{JYi(diF;U$GDgs$N$IlQUx)f`^S z;q@F=D%@7*4IXh7d@F}{b9h@>)_*5g`Q7#Ra`-^v`$C$zeQ2##cTqTzR}GbFDZQ2XC-L)N z@jV*Qp#iNM(7pj}q_l0o-XeQ8V6O&jP;(-;b`97^DJOD-`zqv>Za`COle5@fb7oP+9iU zvjM%7B|p~4@yhl#&j})ZEZbLvL+WSM$WNBYY3$#Cvl?(}0|qqUG&MY3NDsR>!)l&s z;@KkSG+KXn38Nj z%J_PXGovso%r&5)0eNvZGc3!k*npD6ve4bbTqDlx*anOfA1yPLYZYGCfC(bk3uh>M zqxeliI(Zx?8o#9hw;Fd{OjdZC@b(5w5plz2+dCR?r}?Leup0Hd8*q=p=~W_kXJ!NL z)q$I3$MHTpj?B&xzh5}FN`Fv%o^ZYj(!5Y1$wML!3m*}30FQ|*5R7CvJJrk044EH&|Y>vUNImW#6vuTw7?r+J0=%ci{2Q2DmcYf@GUU$-nzp>K-6 zWy;$k?^uuTna;}W>jQ-!3O{PVDiN3ZMEp}Bou7$tY->b5H~kBdwZbW?`BekHR_N-i zH|IAZ8*C)sDda8I_YL^LI6K-X{!;@snfP-9er>=n4gdSYsLht5|99~%4fw+_ZcJi3`Dr2qE9F?Y9WJ@V+OPJ88XtOzT(-C>2}RjPL$C**OWX0?wd zgyZR(M?Wd#&VRDZr>L*~wvQauX;$|1JO+rLVG7%R#S}1X;5XBy-a43EAptx<4W#G9wYJ?mB&b% zD`vTkHs=`X#;N;_*X9w*qb`qtHRRZWmJJ(;ST>eNE{}K~Nu}!ZNQkf%%ck;3Taye| zm$h=)hCGUS^SC|l{ap;VDS50AxkCzVcgn`pT}CK!yC;w7dEA@Fj67zV znL3@btlE9nWRA%F!nwi+gl;4}q0Qq#&tpN}dk4oN#Dy}r@ZmfjQObpni7ztcaclLY zHCZg>Dbv~NnLM7&V~Hv3VyT&#eV(hA_y2h;H^U2-eJPLEI460$lK1Z3Uly`C`K!iP z%1nj&8+p8G`dcE@-gcD2tbspz01ZziO;iy7!?QNXUIGvwCFvbz`1 zR;fJ-Xf4u4DOPaKJqy@N`rgvpSwm-NUsbk)@%>$$ty??F+{yF| z6mY01%yO;{FW`tOrE9_afQj2t1#bfBIa&%ouA-SI&+Y~9D$}EYo@&)g$SV}H$BENJ z-dp?x;a&Xvw}2Ck_bq@5J*;z*s*$s=Qwr#>PRUO#;56erIs*zgtAI0X@6HqfhiAmi zBo%IhOdMRm&;rgY;GzP~FW`a#n5FYVtHW@JnJ+eSiO4YFaN(swHl+V@@hgO`+6eKH z!cjsxId4~Se+w8>fS>zlI-Ar~@j4q4bv6m=X#UCn|HYlv=Yx>~qQ+w)oB8lZGm{V| zZI-y^Id5r&8DUn{as@OfWPKXA6$&U?D~dd_6t6B|TmjdZK9=jm{Np8FYs!Rz_jv7k z;SEBDHx|%B54CQ#3KKYwvC$ zmjOkVny$(-3Yckq-K&{l>OLv6g>x*+9hqCeyn=U%c%Xm>wGO%D7|t(XfkN_y1w359 zLsi*FEJgEU1w2u}A{AlyxTT(yvRL6$!l#9<{<8%<3KhkPkRlp}AA8XRsf@ zo6xXJ(R+n97q$>G+_i|7;;l^Kk=niJ9i}~mB&~~RV|*}g{)^bRh`owvSH#{$@9(YX zY0mrqBH9*A`lQ^ELRDbbPtCZ7==)vxI3E-3(KeGs)1}UB`t*;3ROCE*2kZ$|XhbyYWnM8!quu;blc!F2cWt@GHyt8Bv6< zh>=B%(xkD;XnB~rO3E11{Y8X|s41eZh+6Z|A21#?C&jRdQ5~b04tHE)y^sfswxoDU zm=^NjQqPL#gbl*H(6!<&7cDHS^3}p?gky!{gyV(R3R#xLxmqR^aXptY@Bf7)H;UXO zWbuhbOex})A|@Act9d3_mj2s{xVz67gD{of#TM@q( z@plnh6#gOnQ}~zAwWa?bh5rh-3b!kHOP2ZOpL<4WjL!ts{vEpmco={&K7z8Xe98w^{WEW;@!3@D+038yJM)moii zB}7b*io}HRl6N~nL!yLq3CR*t(m9h9**s&dvL)n7C@5?Y=7p{cVyT2{N+_HEYK}@p z#+EQnBXKpymvF5-*V*tUSRL-v4JGeZ;YQ&Xx_`J?lR%M|NaC#}?`wzLCY3N*oO{ji z_7YCy!=DoFDPd{}(@MBQ4et~(#n~p_Rl?m;TsU2=$Y+@CUMY0W61h(}yM#HWa}39#iiABPBelCGnV$$|CJM3CljAy?#=-xP+%fT0ruh9&@fE_Cg|7&iqT#g?zA9m539CwYy@Yp4 zc%y{3N_f*eTpn+W^Dc$E`ECgxl<-~&?@Q!VunzSPOZZ6Rp~8)$`nZHOC45rCXC-`U z)!b-TYi+RM=OwIF>I=1X1O8G9onM#ma|!E8_`ZboC2WxXO{sG0_-zT_mAoGzXB}?* zzU2=k{8Yk^C2UlEcT>t6QD!&kFp>OH!fz$~TEb>k8=@sj&+jGtQSxrWx7gVJEa5NX z{M@`JPyQwBRmQ(1G%I6k2|JdtT^T52`?9xaIbaTEhcX(Ky*lo|ab_Bq(X@;vW$YxK zPPdyot5t*EnD0`??qxJDqh%Q_%GkB+T}0e85?htAo7#?$$O?Ou(WZ>ns^AK?Eo0Ae zWoFof&G#z- zk1~3f(X)(W-R=nKJg$u6Re`;5gk|3Um(jP3K4qM!J#|NxJ+ixgW$$dmL7rU3fHF=g zGR`aG ze6?a7H-HPvxJdiXaZ+J-7nd=tjG<**qRJdz4-Im78JB90Xyb~aet8*Jm2pKGBg?q5 zj1lUcd*SAAR2ieo;OmaFK{NF+W%%XssWSB%4o0hmHMtkG16ul=k}~e&bK3B78|IoJCw-+2uePvy@e`>?8ZTPtjzsT8LQS4-48-BALW-aIXgHLP^fAaC};V(Y$+weCZ{&pVS zS)g(WZ_zs_cpc-A;6 zPsBK<10u$p|h^Dec9hc(4eHd^G`9=7waj)&eJ*7eZS!+IVz@UXsQ ztl~<0c-T-K67w>k|3)4*@vyOnUYeIAuR8LZCfeA{!&V+P_pqghJ|4E<)Yb-l`g-W+ zEqdC!p11Zez{55k`g^U{XfDmIeV~VJZGT9zc94fXJPh_QjMI4-;$a7tc&+C-1#YoJ zJ?x}rNb(Ni6gzv^)x$0xhTB?5KFSggyW5_)PWJRL(!*XPJ?!magq*n*Tq9@a6#J^f z(Hwd>z{7qX_D^)^Ob#^9gFT$(;SdjFJsj%cC=Z8uINZZ152Mv#s|PLi2oFbUE?%YF zE6#PahcOBiRlRcd1;Us0b6)d6uDH>9F z8V?U=a25~ad1`EvxwY%JX73Zb{lBO2NBC74`~mv zhm`i5J@ z-tq93hqu)gcZudKc{i~w?|b-A^M0VnSt$5On3wb?9)9%jsfVvUeCFW`51)IOZ`Vef z_V7y&Uzy&Wj&D4C@8Mey-`SnZ6>$j*Jp5o&JLOLve)sURhlL(~@$jqkY|^#yn{3$+ z%m483H=qA}_}lEKiT_6$me79*AM5*A(#J|Z;A1%-OZn*HV`;zjNaw-xvW$;q{nqoJ zLv9!2@;+AZ(bY#c$;N6+>9(R((R^heYx?N!V>KVE_*m6nbgQ~8UERkT5>v^8ciCD# z*732nNLrCx*T;H3#tL(Gp0y2pZ0Vzik4=1R=wo9aJ$-DX658^hte1ua9B%4kb058Z zY-XCbv;%#7Y$1lTxE1yFG0;apAKUoY%E#7z>m3ChnB_U`?_+>=U>$pUZ|h@_kL~SL&noqg=&W0=X<;b?yN?_;=3Sj7dhd^aC^ zXs+GWAj4R*K}tnQZT_syN|PcO!jfMkBL6c z@o}E!I+r`F_au~^FNO=bz{kZtF7$DcW}zXcpkR`ZOWclWIGSI7@ZtNI;$y1jy3Akn zQ)HVDPqlPoA!Fbp_7VDsq-hh+{!>2E^5nLYq%z~9?xVv;(MQ%tUOqWHM+E_HGHXjd zDyl78S5+T1`7_ITDQj@(qv>Osk4_(#OF33qF6s&&SNg4YZoH%!$z1K@Iv>~gxYlp| zSx)+J`Al8!;|6s?Pc}*ZCLd4xxY@^jK5p?b-N&sy?(lINFMBCn4_p^Jxl;^phr4{- z!>iZF3|o=g+k1V?wDZL&SaQFQ$9z2C<6$2U`gllLx1aQU#K)sN?1JZSw;%WMq*nKY z`8=f|`={G1AFug%#>b03p7rs9kLP?mudbNoK~EmDbcO@Bu8;S9yeEd`&hP`x$l*u4 zfCGH&WAy-^`1sAor#`;%@tKeLD*0TIRbTk{((qS4zScF&pEPO0KEL(xlaKFw{NUqz z9}A>(7YqeFe$<^ZmVf-s$FIu%qWhP3_d*Tb`TgC;G6DYJgFV2XKK}9Xmyf?~UU!cE z^|3_IdVIMdJrQ8(p!K|6Dro(b< zc9e#b@}OpDfSn{G<`kTL=K#A0*d@TO;)g3z+*+oVL**U;_71RTfW4F*t(~NR58e?$ z>v=`Zz5)CIBLkcg;C}&*2(Vv(Ljvp{;Gh5p1UOLVg_G{Av%so@&HvBx8Qf|K+}WgTf_fu3JHUAX&Ixd?_3t$22bgHr zp6ma@0G9^1D8MBFE)FnBJ-ZX(c6hRS<5o-wFjcjenL}FuPuC2UtrN=Ue}HQOgaJwc zq5#m!}UP(a)8bNl>qes)c`fS zJ6vreK-1RF6G8Iw09OW>7T^kX=$6k_T*Vtr^HRosIK{OAZVPZ-fExl_uM|nncw>ND z0^AhfX6+#vo;x})d#mm0?E&rya7Tc<0^Av3x~?>Ld9#PR1I)0su$GVUd$|b#W(K%V zUD3+T^+13JH8rc;74k6e_YjW+_$k1n0bURASb!G-JRacb08a#XO8O_Y>cu{@0z4Ps znE=mr`Ks`10p@8H%yMZ|z7gQF z0B;8PAi!Gz-VN|}fOo7D%D7AK1$f`CcCLtpAM$}8;3Gc#ZS8I|KUD*6)t?9WCcyjv zUj_Igz?XJ)Ipx>thbMwld>ddvfbRl)Z#&G!xWFF*{3zL2O-knH0IP=hg-`4dzXtd_ zz(PLo1N;`?cUvqysr)m*UwRI6Iyd7#0hSE$Z-6Dj)X)Y?a32{P*{vq}Z zF(Aay5CcQ(5MtX9gF|c=Vvs4>KlN;Hd#%@XwPT1O+6vdhP9cVCI4s1@A$AG>@3%kH z?;2uvx|v~{4EG4(z+NE^3$b^I{X>ihF_PyZ#J=Xh*;|VWv7h|89M`}BAr204V2Fe4 z+_4k(c}R#ur5wxeN~!HpA&v<#I>eD74i9mJ?Uh^CQ6Y{NLuZyV9vkBL5Mx3dXAP5o zf4ILwF%h3UOYDlS7;t;uN0o5T}MXO{boPr%5?J#2M;pH_gJSCxkd# znzIyXcut6OrCGe;=ZCl?#KaI6g}5NZg_@o7w$25A{~KbG^c=c(Ba=g17UI$nQ{?I1 z8&ElwTP>wqBYW^e6hj0dG9khcsSr_!SXFd$O{PP%i(wVp<8!GaL_S0|L@vZrdbxMv zLSkv95RDM!5Va7M5LMndI%Pa-JVA9+a*fRp(?WEHxLmWaPaZV9LK#Xs{ch9I>L);PKwh*_AXEU_r&fFPd zx@z6!#0B0R;(-t|Ld*RbWZWvg3h_0!!cHh_zYXzI zi0?uy(5`+jJ;gtS_)(bWg`Ly(=MW3|{O7}8Jg*u49+oK{zu6l92+<|NpCOiv@E0HW zA^r~Wk9Le}cNh5*(V~|CdLqJ7QR`9ce3n*Agf$~<5@D?f8$?(;!nzUGk=QBM zi?F_i?i6#z9uYQ*uwjIr;@RO?UB(+n=wV6TniLh0Kt*u+PMt0KQn1K<7Mc9@@G22BL6k)J1JE4*{)D97b zh}qHjp%He9T2Fhoy^K3Y*dxL&5q6bkc(mvfw%sD^ZmV#Y@tzSzMA$3B-fUQ%vz$xb zC&Iqb|9t>O@&6*65MjRvM@HB`!l4lkh;Wen5427Wj&O+lX~k}7by$SantfEX=p(Gd zBOD>dbvv40{)sR~4o62gCc?3rmz(46o#P@LZ~c#rFplR`&oTOQ!%vKGc7&56oDt#V z2&Y9jCBmsu>vheYQ^wOHj8_#;9C^kwHQj^=XPL9RV$X?iL43DB z;bILhk|)p0Bn^4eX+AkZIl`q8(h;Ua2qIj@W+F_DT3;dFP}|}~@OkA3Z>7IX9!7{I zh!mMh39zKb&;KLjB4jj6M}%zD`j3jZd}bN*5sFF`R6?d?wZxSOS45~rs7q5*WML!1 z(a; zgApEy@KA(@rQ{Xmd>+-1m=ir7;iU*qM0hsBlM$X)>M2G3xtLiIo>32rxAeIPFDUzb zwCF!_njPUqF?6FRJD(HbwFq+~yb|GMrARXMsxSea=S6rk!s`*<;03SM4OQ)15#H8} z+$dHtz8m4!2=7JsGQ#^2K8^4JePs2a;&guhKf))rc9w98&mzo^@VNy1)fkyCgkAQl z2tP&mI>Leo-$eM`U;6 zdH!Yk8vp)7geBtErT(whNM=b5$?#5DD#mg#mX5JZj4tBcq|7d>A+LeuV{{Yl8e^E& zwL**)1bC~TpB`@+Fn9^&|kQl>b42`jKjGee$;wj*~6tHBMxb@S=j(qtBC6D^?L7C5HNAVjLIa z*cfBXfien?Hv!i*F2>n0PKa?@j1yy=!c>ft&68q!o@#nFaC(e0V~me+hLO&5LX5M- zQ199}C&ooF&W$lK#(6Q$H$AiL?SdE=sw=lBPIPgM$uTCyxJ1jR#x42M7*ni&%1BO) zaZQZ27|j@7jE)$7j8u$(mofkI#~6{$3vn!l;Cg=fUu3&tMv=>BDjTDuVJ=2qpb(>| zLJFLw%m$RI#Hhxo3A2{{Fg9#Rac7JxVq7kU!)XGP5nsvcC&twYF>BA{OF)e4V%!+x zdhV^58w6evzDf9IV{VP{XN=o;Q^&YH#tSj-i1BcYJ7e4%V|t9c<$ss$?Ti@r*nYa* zn;GMQ8281vKW_a)=52KFBt979Av;HoeTa1eGx!mnTgqX4R9tZRNl-=$KhC zo|VHhy24357vp)G-JR&!FclaIAUpTzhs#-}m9it$;D`7u6M371Blok4{~MKabv&5*KE^LG7Vxna;aNQdlL0RgI@JJy%a*4b8$yd5~Nyh5jk5ox&z5 ztdl~|6xK~)gA~?FVg1yiH)foO?*V$Guptk6$9oWgb~ z3^GsmD!F|MJ8&T?qzTK1q%bUnp(*U7p2_gw3+2u!?2=%(3A?7ScM7|uuxARpr?7|S zB~Lx$UK+ZV$c)f%AFfVr*&1g-cR6EQQlj z7?r{?DU43x$P^Bj`4Nc*IO9QAMRYN+n>hu)ONnyO0Gg6q4!kLz(@~jlj){q;^A@%2`Fj35TisxHb7o>1; z3Kynuk@Y}-?l$8j(@ahwpTean1Sw2Op-m2#DNa?KF1;u0+Z7(B(2+uvLOO*wg_N>2 zDfxHK+f&GxKj-4Avl0;J1lV>Vh0YX;DO6G@i7YF+-KeI}NTHTOo!5YDUFS{n;o2`x z;mQ=I8FPgIov%va+7zx%;Tm4R+FsVu_Bx$+$J~&@b1B@I!u=`Sl)~*w-JHTLDcqLA zts1&2782Z%!i*H|OyRB+rdyxndE9OD-jl+8DcqaFOff^1Wn@c~J&?kz6dp|Bi4-16 z;n5TxPT>)q7q?_;9!ueI^~@3;tbJ0QJe9)Jwx2xRRI=om6rNSqb@+S=ucz=r3a_Lv zTl|YD%t_&;#9HR2@N#14d|nmvn&LdmzLCN^!f&SVmcZMJoQv1PyN2IO;eBCe^%unHy6h6~#e5%OD!si0?;g3jPr0{hLU#9StW!*nO{w9TQ#niM|R(+qs zFDWcY;inXSNa4p+>%WqBj})i*+4R4r@OugiQ}|5`x6$p`A1VB4cY$O6=0iJ;fB1w? zv>BbM$WiQ8q0}UR*}r|0#4s8jaAZEA&r&Nt)Eg? zRAk}GX>>O|d0vF8rm;pEtEI8JW^}7ybUtgPv2Pk{r!hQ@b<*gc#=2?rN@Kk=Hb`TA zS#7VDdZe)t9n$D&opU;-HZ~3KlugpuB8^Sc*i2+^MQ-5cY4lMQF%K4QnZ{OW^i88* zy0yb(c+g?%G`3Nd+jBNKAdQ{U7?{TPX>6Oupft8)pX#4+u*6&r%Xdg)h=x1bZjc>}XSwJV+ZRzHosMDCu(9s+wR(t+8%r5T~Pk793mjuif%;(loyB(Q%P z2MDn6K%3~`G!7GaNE(L(-U_oSx1 zI!;4k?$y{dPE2E58YkF{oSjpgWW$g7{m(ScOykrv#;0*w8mHUNxUD`zN|ta}C!}$9 z8fS@d*9rM^G^F^vG%icy{4^$|F)@t`)3_j^yeN%}&6&Ni@RBqxO=Gh8v#}|LIoH%Q z!Zg~_@I`vs3U|r^^Px$kY^7C5=oP`7}Bt$fl7?FM4%$J5WfYltxim zo;A)`HcZ>9a4n5y8uc_98dAd)SK67z<#sK(eYhfxThh2PjqB66DvfK>xLPIDbFtT^ zah>$ep)0@tna0g&+?d8ql8s5c!=dI@E-;PT(zqjy+taPLNi?C=o#sjAt~6$7c(h2Sdw3OJ1yxO{&3NAX2Pe)dRaPP+9g6&`cbc-b(WUro0@oP14jp5p6@ zB;T-d;nm>1-ue`sSsn!Z{G?}l>vN%vWJ|!KS35Ql z$t5_Zw+%O!tdAnITNvNB9sPy-wPP!RtrfR1C4B~nAs8sY^6dl$wPSE%cJe#ekeJ61 z4Tl;zOkiglQZQV2S49qYYsc<}UH>HaGG=dq5w02QWF$$$`$@pU{S6#wfIj4JS67Rj z57Xw4QXFk(s)LOW(#A%`!SW==ci3csxQilTFVtsQT+V_tjfN3GWt-%#X` z4vcTL<85Pjr@Slto+1VBx3^wIDC6;=$d431R{TVfRi6n^!_Rx?x3_+INBl)Qz7+qJ zq9ZB(M)&Wx?f6cB{_YN4(2gI({HREh4KV)Pj$e%7{x8&7`%RGop1wcY@waZeKNbH{ zY}3j5ryc)l_>qQ7W?IYP0Rd{3Hl|Ak%NR+)`}_zf)B3mn%V*G4fVf)*D+u#NnZpL( zZOV4#OzZL9J+tWd#j9qpMh2^8u(~m9l7cleSj!j=N%B}n%(@w@C$PREw~?tH8EmZK zhKfBEH_Eg=q;<8u#B7qmrUHBqKz_3f`em@W7!LagY@xViru9~#uex;(TZ!LVahpu* z+py#ZWLj6tKt=8wG0)w0nbv6?q&S!k0$c@2o}(Qz7?NqdJPplYC%F;xpxe$F?3%$Y z%90tL$nKWG?&2w9YENPf_sU@J3`QhU6zrQEW^hmj`(IirooWUVV zxeMvA435fRR0fBO9IZ~c)kkD-WTJ|59i73k${u6gj!_9cnLVBxmBCo0I2@-G!HF51 zlEFzCoNQIpyUY7j)102cc^Qn);LHrpNO(>VK1=azm7ilK=UVOg8C)PdQ5P!BFVv7r zAig+*$r?^lyu`{c&ET>OrigU?Pfb*L#`_rrhPjp~gZ2#K3{vL9+O!0`Br*b&k>ruh zAeTWggM0=B(=X1JB<3loWN>)~)eIUL)H0|iOek(<&}p@<&uJN4mBAGmT=`$6%U+Yg zjTu~U$zj6)SB>rY|xK)4-w`FjNIM=5?w!?!bdM}Q9R zO7E;Fc;EOBGx(IdYT1u7_{1<}pJnj1l%H#t<_mw3!I#o}rAQfVzscZR^K`R(ui*k| zen=>P%HX#Qe$HTF2ESOzuO@JAziUXJKP31wgTGAR%o+dH=~$wp^@!%fiV+>Hcil@V z67ZWFU4)lOFv|%quh`Z2ZUWS=C^uTI)X_S>D|eu~m{kA-Fs7~X+h z|68@Y>8atdrwG$(m-2Tn2NsU0}I1E2!<9f*xw+(~-}@*T)@AlreC#EdyJbmfH(6jkf`bg?2$ zRk4<+ZAjTn=xK7fhSLpNP1A@Bx8zTf6?QwMIg;Vm7w z)i7nZ3*Vu5XM(@0qxB!t-`#;30#tIyc&~;t70KLZ*#|oCpkb$cm=6jukNlT^T*D_4 z121=Au9dLQS32;jWnJ_0I`C!(Uhlvg|K;E6 zz`J7JR(!`y+$!ET@dw6#)PawUq~;UhPZd8?{9JLq;ungpfv?Qr8oYT;g2-S znsPY-x^)%kW;~e{v*@njN{TCITUQ;;SIJ_vELIiinAMe9Ba5}NSTo_Uwv|w}ZWbG6 zv0fHEBv?O-4H6EnXXmz&_>Ik{m&rEGqPJn{H#6KPi@sTGq2ZQBQoy5M7F&rS-r7?A zvlu8mz?f}K!v+Qk4^A+w-64w|vly!73`s1?%`z;DolU<>7Q=s;>;{gmyFDKfio1H zW`gip#+;MI#aW!2#Y8dZDV}e(7if4PuU^x;Stez1X%?4=oUG{hDZ-a2vTZkGn}(hu znIMZei%`Qz(bY1hvPc`l@{HQxQ@ulER*??*EGk(PG%RLO%C_De?a0sn#Sl|dRc%eN zZp$IxG)F@hU~WXQTca;cFGIQ!UQ|Q#XjYQSm0ln-y_x3hRN z+xlVuE%ENB{&&O>zbn95-p}F#6MUG($KpRS##MbP@-r(TIX{c9v-l#5FB8hIOh8*| zT&=_3E44uJhb(@yDwlQfmn?qI;@2z|W?OILN&Y6_Fo%Drio?H5@OKvfWU)l9bqoJ% z*(GzWaww7~URt*^j4jY-9Q})VXQ!$$u&)VJzyt#0n z9Ja`zukel_B>uuTpFa_FDn={7KjZF3kTayzSa9d4h)&>VKiVTkx0rD4it z8FvyhEQg&f#kPm%uvZSd=CFsVc2nFvx9GPpduqtqtN8n0;Sq`)lH50k19KRe!+sJA%_zanv)awR0&Q~bRCY*VSIwvlGg5bGT5$^Kv*phYNC; zn9w`7i*mR)F&)WEa=1*g$%>ceFhv44%hVi#9NKd5MS2NC3Y;d&A(um(LneomWNFE0 z-k#8RD3vuPpF=5!f`&ySSyIlSDrLpUnucz!Mh;ix(9GfT96A&HG>P3BuM~fki)!+k z9In^!TE*+k`Gy>B%HhU@^5z7-HHW)$xGje}MBZ+xJ9C(B4z4TCd$+PPjK4RBhjN&i z!vi_om&5&5>+}zrjD-*9@MsQ?h;jWtmc!!-0ZX1#`BMp#SrR;x!wWe)EBssz&;PfI zZnJZE@xSC84d)t3^H*|sRnD*F@OlpOgk7I+Bxa=BTRFU~!gmy1x9{cfaSrc``5=dn za`-Tjb(&9dn4iO^IeexR?{4y+3v;3`669Ao{E)-fIeeGHH#vN38t3!9^|m0<*pI?L zN%^z!zvl2)4hwVmUHot6^M}Bniq7+I!+fvuZw^c6u|yuow_XdDRHSUFeCx5}^j-2; zR{S!ST~5I5Sl2vO$fH|AzoOxl@>tn0#j6Ofn#bw_tC<^9+@CcyTq{A6Unh@s6AtU= z(Ibxy#ISj`w_zR|Y1q>WH#U8*JT@_sR=xA+qv2+GY%V~O4qGHNeTDleZk5N@iIm%l z{$d6w4$Na)0s63+L52qlY@f#t0`Ap(i11L;>?ANOkDUeh$s0|ETXt80-4yvNi9PZ- zERQ|&*e{R0^4OQV%9nsVM&z-NFl%{`9BB^!v)cXhI4F+;@;FdRPDB~S2j_8U9*3B0 zu>--VJVuK@T+x*rDSVXT(TdLJSlNzIJWla=#j%Rx6i-le9lENM^BAAUDS4d6x%d@O z6P#|~BmVu*JkHke%seLKah6T$9O!mV9_NZAK2J)vIx&x_d0ddkWTh_5stm)I<{x-^f=@|a>iWSoCng7Kv%ALJ1VN5*jKR34pqr1L1|(Vj;xk4zpND(7@r z0q4n>S7AYswWU02d6e_0BxF^~*7InJZzQrbxtv#c9@DIcD+I1gXs*uV8q0DP9@ph@ zeIB<+b3-0C3fz>(&H2_Zv*^j+k}%#X{@@|Yv>GkH9l$MeF^ zS@s1DXDhy__>!XQoN;a*FH8K2_*WHQQ=FGjzLCeLdAym&`x3vE$J@%jqxi1kdkHkupe`m~sJbujM2Xmm{ zr#ybkwb{S}k$!qKymaRY30oHc{24ihPM- zhnp49w}8zH*rI?ws&XY;CLH=Du*+^EhyDd@D=?sdfdXzf7`H26PyvHQy1m_AnB_Yb zuyX-J3K(j()bCWlFmvFow@U%TP0#GErrcfR9+uiu{9cwFA+V1kC)&4wk(T1{>VN;; zuYmmvt$*x%fFi+x1so*IpY%E8T!+Z~&;st#aFm9l6%SXW<_MJ#93|#x9V~H3eK(z_qpn?!)y3+*rU3s^ySM&UKS* z1;4X#O98hkdz+$L%N@dZ7BHiL>AXlZbj{ygXnjaRd`|&03%FOQ>9Td^_ZRSxmi9oQ z^}*4Dik$ReDIZbf@KJ#UDtx?vCyalxfTs*|fwKyDMnlf{YymG8@LT~ehz`}**_Im;U7Vt*_e@XMFDgQ3uAH%L{i6T(MlEv1eo`)lsBB^1QB9>KZ z8AX!IDdn=%cNO2Qh!u)hxrh~uSjlRgTlXSXv0BHtTE^9jSVQ79t;D6)E@GV`)+=J& zL?LU}HyLpcOZ6;bvm!PsViPeNEA}$wrW#V;+nCLZ*ivL4#Vr&$Z{H%eDx#n1$!u*Y zmiI4WND%{y*uIE?MQo?kw&ppgh{1*_cB|N-h#eCSLyOo&!<~v4R>aQ#)ekRXH)VIV zlHCm~Hr%U-1B=+Zi2aHfQN+Fy>|;J7IW+7__LqS80JA!%h(m=BF5(c&vfIOo7+u7u z1jDMs&Fx4lCwX)cCl+x`5yusAtoSjB?D0j6wW@JNoM6~($Vo+uSj1yRJXFLZMLe9~ zA5D}zUc{3cK4IijHXXa2mB7yy@p2K*74bq5&zqPN%`W044PP|zoFe9$z-`4VO1)|V zM>4)H<_*O+E&G<$^0EI8FJ^xJU&MO?oQ^~OZuEm9J}kC=VS1K^9}9E%NfDnK{;Y`4 z4fECEi(>0N$(M>>DbkJ1H^Kzp7V(|%_lgUQcd{Rg_{o@`i}*#D?+sYEP@Vr~{c~MB z{wU(lBK|UxCVv<4j}4t>iBjv~-@+v6T}oKShKn?O2@tcqVpqj(rdhFs zl}lJjLzc6oyWv#?RyE~fH-a@wSj&1?+XSwhaXoWzB^zkiql67h*rbG>C2U;6MhQ)? zgagYrwc%z4NILT^#B5o@)+O{6?pMNA37MObv408Ml`uf5fr{HEWX^4H2}4WRzJwi1 z*g;vxGY(0JcM={}!p^4IC6VP^yBSZshwz??dzCPvguN5leS}?;oMj~UFp(v*zlH}W z9$3ObiR>Z5hbEX&hDVohcnL>pc!Zr7H_Oo_94qD+;FCiRQoZC+Wzb#yD?8VRm8*|oeBwYQAd3*S(} zEdn=|a8n64Cj>Nfp04Ef67Ev=juP$^AU{2!zgu{QG53~mpYTj$7Ek>^2@fVn$8)Yn zN_bSQx_KWjVU~tZl<;H;PuVJ{f7;5Q5&5j8SopkBFDTAdbp9`uFvnzM=9t@d3p@0IX@!28C3Si;98d}Mmp0HXuW^K)hAEAkH=d{Jus zb%ifW_^O1jg()M$_^oNaGoIuEkv}N%;(3oB0hPe`v*Is`zbYp1fA>SpQe`YHri19`kIgvySR>+2`cAGnO$GZ24(atqemIH ziQG_tTendeo0PF}8NDpU5^8vCszPcuE2FQb-n@)HBDW}mQ*5b7JtyMqWVTXvYsGC; z(!Y!W<<_1vOAW!cW$akSc18{=V{jSUo7E1gb%sOA*tv|MW$aYONGl&E0f*G=QpRu% zT@Skn?{3T<0(+YC-ev4x#)vZZ6~B)nmpQVG{j~P~8RK@~fW+`1;e!`{tGEAsL_R$xpSLhCc(SgRQxyNF ztK~G|(-rx>BVIXY=&B<)ldCpN@!7IEM@l-Mt0861hjC&V7f4ThVHp<*^HS$J|F;#(D8FgcvPqU0pF_$Y&OJuJsw?56-Szlb|o?NXx zxu%S31+G)%4ls3tFu{!iH!0p+Zv9Cpl00tZ^&|3jQ{ExK=LxgZ%ebqId&;=mvNN1m z*?Y^FX*_p^dj4|Z0Wl9MK4jU4%dJ;HH{+vaJZAjk0#9h$UG}Lmo)$UFG|!Y4XOu(-9=1Zl%QY86J8Q%$i zYs~j${2;tQaRU`{3YPyQ=4ZuU6zQ?O@6#?z{I1$`>mtb)yzqL}5b zpDm2(Tfx8z`c<$^1zU;ST9Gp9xf}f}7+?&~^|r#>DGsV&aHaL=aGu*+Cp%WKQw2k$ z8LH@(HcZ$#Gw!0{@CtTK@Vgt{qk=sRyYjs&7*WB<3idI6Ujb&FU_aycuiyZ~llkS( z3J$H{;0g{A$&=#r?BTEqMyc)5W<~Od3XZPeNHIqxcvp3-7|O=jdXG0|tiZSmPB6xm zoTTB&il->L%j`7a(-p@no}tLoG(q4jMb340rS*9-!MT;zqkzYG0_Q8z?Scv}=Faf> zuXvHp3-8KF6 zJF83u`3gEzn5`gZ8ux4|R8Xp*s4P8MQcmD%1)UYtDyUmkqk^UuPB9Oz?(zz*s9;*6 zu`4UMsoC;p4U~UC3i)8=qjK69= zG?`by+ZDWC!J8uANR+>2J-k!F`xU%f!F!hFiQv2+RPdo`Xhr7Z3O=vk6UjcU;4{-R zMZtUxzo_6#0j|RFUsv!$1>aQgo!q{)s_!dUAiSGhT|a8*s(!BEw+em{^J@hQtrM4J z{M~&16!@!xe{?PVZC4a;qJIr9S;f-T)?EX|r4-q77lCCImsO;O{VZR_3RQHiF8YmL zH>J2OJXWk?CGn4HNT$1nt5mV7>1nch6>CoFimj^XCk@54+B$*B^w)5J z)oxqG4pnSd#o#IiC6wDI@QzjNRK<`ghFX<#9+uGTQpFxs46kChDs~mm^FkSq-8Ez< zdkXB8s2U-|eH8btVn2bARs7FNSiZl=0~Fo72URh;ii4{-tcpXbIFzSAE9Ddfqijfg zxG=#HMjlngaa9~$#j#?Jku3#dOi7dDg~wJg&Z;ONe_|DlM{MoPu1`=(~pZ{rkKyv zDty(pDSGA;2yhQWV`71nV%kUwcx0;Rs3IpaD`&U)dBYqQt0+l8T(#Mjf!QY?;Xh@Trs<=g|o2{!`6Uy7G zn6BX+Rop4ys_v@dzAEmnVy4I$Ror9c_a_2Ls(4aLCwRKrdTHY^OW+yBXB8=UUX#9{I9riRd$EdJwMPEbGpD-f zdtY>TSyitny361-bvUnz*9G2CbgwvkcD+@_+tt=D-+8-Bhrb#Gv)UJ+(3H%P{ofL{$yDv{>6M2 zivLZ~rC9ZchJTvoZ-IYA{+m!bJ!*@77Fep*+IE&Rb`f4ik>_qXf#nsM?JCf%h7|-{ z3C{vkJXWruyZBWUS5+jxo3g8GxQ61IirnF~1=dlda@`u%t6}}xqHjUae*?oCnxk}=4{-z%wFwpqz zG#pgJjsk-j1$Iz$%N!y+Rz5ok({NY~I~(4mhT(=;vYX-EYuH2Bt%X&4X}GuI2*rIA zxo;x{{-;Rgel_gx7|nZNt@Yy0;~;^96?q38DsY%(M+uCswQfd=kEkvBJmkn4jxx+< zc#j-Y!?9wm+#l@X8 zYv>enxgve0*%e59B|XJoZCMsxTf_7kuB+j;8m!z|%vOgUEO&uRF)^+1Q&V)$7N4-V&;er^pf3%_EEeN{vDFt3IW zYk0kecWZb<4ZK;y+cmsp0{Xlo%;gimC;Yx5hac#EagT_PYWTQ@&z1V5hEHqwEYTY^ z^K1CBhA$*=C0_}PvX3p9tD)X}?+O>OAN&1~35Vn=Q%%n}a!32$Z0)+Xy;N1k8d z=AQtn<1m43joGe_L5BI1qh|X$cBr?Ww>v75As#Bclj1N%k~^!AfIBu^n?S&|GxFG- z-PWE<2)*eQA&P95iKc&_4kS{F4uCe~a38>6$ju#Sr);E>;(h-rYFJXdTFQ!WRST&J*A;n9(xfR&&{@ajbxhNcJ#b5T7Ot%0W}f#tuB+o} zrLL*tS^?g_tm4A2uj9r#ZZMzw`2OE8*LaKYt%|qRak~KhY0d@Sso`{rj8%$__mJk>-bKot5vc<_ydn5m69sf%FR~>%~{A0B=T%v)c8(6Xd@X#uj65uM_W2B3Q%QRY#aSC`W zCx+Rs4Rjao*1!r4tkl4Y8uHc6DOc8zJHz2B!mBp0nt;2u*Jv!-z%?6KOH-`fz&Z`R z67ioI>dsxSfejm2UsW3@_E4m!o2X}F(f{hTaRYrC=+!{)1~xIxrUL9?GXb8;%^R)P z2$pYQnk^gX+d#iY>oG{)t#s=Kc5Gmq2DWXWzmx+S7-%Mx(Q~^728$V_9$I7rJ2YAk ze`n>EIYdhv+Q3c?3~RJrtvH2ydhF7`o^lx8z^)DK&K|4{cZKiKXuVaY^Io)VVDAP- z$bk&^hkwa)Uz%&jMmAc{Uh@0N(5>Qt1`cW9Krsg?9<0dcBn5{yFsgxF_!3}yLUObO zhuaxHvVo(-u#KYyj!`_e(fUt(sOMsjYhYXh$BQ4U*xCwyRBQM|fs-1o|6Q6X9;`aG zfeGSIYvA+-&JZ52=pN%|3e)GT2F`Eb>;}$l;2e>3;1}1=OJFh+HM~HP{uecHNdp&~ zW|9EiCL80nXi5W@H853Vo1J~Hfk=$sKw$b%fK_n=DZ|dBUBirGhc1S!FuUSf@(olP zC^S%Nps0;y8%*&iH(LJ#ox{}zY7NvIt+zv?MY`*!*+6Flm+QK6(@ksO3Kd@2SoA{> zA758DT5r#;QM^|1Iz{(yf^HDLv4L9zZff9W0hUnUG{m>jR{R}`cPhHG;`pIw*LlfjO4taBc%Ho5L%{zt+GT4a{rcbz_|Ko4l&cYVnNkH1KW% z@BLRv{RhT;)WG}(K5pQ%20pR#{;BzVZVU~-NMJYP*Cyle+XjA?=XVW!-@p$IEJ$R3 zY~Uvwy54?i;Ex7=ZQ%C?7B=vkWu3E&e>U*9_`j@M*8XGIX~-LDI!Fq;x|vYgwVouG>UU zG3zz4eiIuuu|X3(5?0Qi;*FZvw26(I=w%L@B%CShZM>VSPZL}Ge?EQ1^!xw#ZHyVv z#Li6&Y-0N+wrygNJhwCF!IHVocW7d06FW9B#A@BVJ2f%P^p4r3iQSqQ-o&n^bPl^q z<}`aYv2PQ5H8Dcu-lk-BA9EYo#Qx-)*w3=ghnfTa%N*RqVND#;#G(J?N0}8%cpRP> z9%;&>n;0Yh7{y}~n&X-{J~14plEpoo*u+UqjBn!PCQg;?6!YXelJhm3sCYp_<_a%vVv><$E@@)2hL$(Kwp*O-^h^VKHi ziG0l%>R%W0hB0q7@m>>ei+sl%-nH!eVis>N%Rg%3^CmuS;!~wQNeDhOJYV1o8?x#v z!(W>-$;GzcD@$g9$%ub!;wKG%ZsOM_ez8JUEo|bqgwpx^(ZrwTL*{Sce-!_1Vu{X0 z&wM9_4LQ-$o#@iJ=siEP%Oq0E8BbYP@!b;4iegsk#L9^h=f7$vRu{RNrPk=gnu%J< z)>dkrPHZ5sZYS0=!TJVzD7B#?d+2HW#+}%-6TQT5qUh%B-HFXRv6<-|*~hBruw^Iu zTDD&&wo24)(}`_6(ciKI1O}R5JL8?_;7)Aci6NcXLHv#;;}k;^c$ih~oFIpHV%JXW zE@rm`zlZg?7eOcX?!-Qw7-0^acV82aH06F`_BWohAJ~aQG(4yi2TSG}X3BxXlpUqi z=uRA-sHNt}P8=oXXvJd`UG12Jl5e?>XM6l70E&Ez%O4p|=){Sgi$3i?iKkm6HK%mq zRLR%?ho@_5g7KX=!!T15I&pp{&g#Uuoj6lzdb7d#4{eM(l3A~i^`{fWRdm_m$qC%FkWC=z1 zsVFLvw8&ayi^x(TOSY1_v)$SEnR{pEmPk<)DT+!+6cQqPw*F_%x2ONx=ktEf=RD^* z&+}d0cix#hcjjKT3e}*t24T~kEn0)Pl$gyqQG=xMZQar}$kZS&XSN18k!{(6^`ufK zUN0;O%bsoxHJBlBrtp;-%<^P8B_6MBudwHw8qAgWhVV_{JmGxdTS7OV1vOZt<_m@I z2;UX5`FkRCE*4p0I+YJDsn)an|1 zE`^-Ud3>S5FNJGsu+HQEx&|9-@J$Ui)L?xLzV*zC<=@rd2Pxlgum4zsUu*DF4SrUu zO`e9onDe(9{8@wFYw(9B%gJo6!C&TaGyJCpTWavHL>m6H><+%_19nFrcJcwf>J5L} zigs4W>@Gg+CflyU#zN<8B2QCO_V8g}ANKTNFRR_#$Uf$2=EMHt`w5$yet-yvYhg-D zACB_jARi9*p_LDZNI%#b9_qtk##zPr9AO=fv<|I(IM#=weK^JxI@@^oan_-o4=4K2 z-iH%>INoD$ojdq&vJWSjnPZ*eLq{J@mD71TdHCr*obAIIK6F;enN~>WS=Rg^oayxyE_JH%{5jojeFjpD;iVNW`5_ThFP zZt-D+54ZYon`N1Da~^3kasE+0-0#DkKHTHOT|V4xS?9mkhta0oXRTbHF+M!tQO5f4 zgbxq-@QB2RE%m4mYqJnzFZK0GUNlJ%tdIpZ(* zFxiI}JylcG)6IXX4>dl#tn4%&rhA6t5I!IL*2npSKE!+o`4E;~YuSho(d}zl9`_+( zV$z&xA96lqq-TY$bKZxdJOwMM^P%3V+&-nR}*efUV( zWx@~5NzZa0R+x?9$4ag8;WHmT@!?Z*x;d|wlQxEHd|2zl7e0Ksy=R>d8+`c6hxI;u z?ZY?L+;t#+YyR(i_`!$o6}s$3AAU5y8-@BNAAXkS7axA};a88J+276orw{-5u-S*d zefVp84_p0f%75nH!H-6MJq7pyKX&$GCxvb%4q3R1U+@3;(b$u1V!Wxy?!rCfWZ_?^*v^nFZkCgRrB+>Zm5-CuZsA1y>&wxu7f{5Z&?94vl_N8vz+`Ej@(ttB4e$B}*< zWn;PdAHBW5jUUIF;W#7hbD8IgcM+avdiC8={{GjGuBLSJ z<3igv7Shn26IS*TKQ2{@dbOwV9)4UQLr-BZ;pLX4lWXkbM_=hz3a=7!R{i|A+K>Jg zZtcwX|D{|j9O#+PASu`TG1QO2RyD-NVncSgLE&&^tMk-xlOH$xaho5vNWax;X&B+h z9e#}T<8~8WAEriG=eztEUn zd4A0I<86s=nQei{LR&98zw5^bek}51i68GtU+l@g@8N8_RN*o`##zhbBR`h=vC5AX zeymiMBAp-Gh@bfJsc|>4)qZ^E$LD^0<;NO7*0P%)Uz*326W5vYwIA!%`5Wv1tsfhV zyPn_s@rxfn`0R>07nGSDu6?kIyitsEagT#EP%tUipr4zv<~1X zkLTzB+9*86#AD@mv*k?MDr_fgFFam&f{?Zj0h}7ZNh)V}asa0oXL(1nb)x9e&j{eG z0M0a}v)S0;Y>DRtaBcuy#M#H~$@#Pea6teU1<*Bs3zhA*y{CHsmj-Zg0GF8V*5dFo z4b&rmUdr~gaW4n*%XyN;H660I>kl0mK7Hs%OHo?342FjIvpqTRwnt0EGbRq!dlB51{0!;&7D! zW(3e+B9)mkyLrwEU`_z9N_kB<+giPDC3MaW;0>#K(+q4iU!J#wZwIg-fQ6QI{poo( zfJFhkAHaLEEe>Fbb!L_}=Uf`V@&J}8^`Y=1q4TUz+m!))62Qj+tg=yDmiVbDuG{AU ztX26M;THjXDY9)=>lA(!z}G5t`g-wig&Tz5d9ptQut`-Lg+B)HlgPF?{2ah9ru-`M zn~=@_F#S)F%>n#nDVG1EQMUE@FMut|?hvfr|9R{f1jOAucQ(C|iMs~TRJ^fpH(`_D zc6WaE*&~QOgVKpX#RslS_xUj4u@DF`C-Nn z58?>p)Q=KxEj(IyOb~6%;QAaF#PLD2Rp)lX_Cl7^a6%9r6rSj*Iw^>gCAto$k}K>e z>}1Z%Ta z5L1G9R{C>6yeRT~5HE?N>n!gsr>>%C>;`JcjRBBETbAx!p{LVQ~;r#7u-&VLlxKPLmyc@)OK`ipj zVX^oUoAdkTTpGkjK`c}Fp~t^Gh>wFkvdlNSX@k?aD&+Ei3*vVby40UR z{G-(7ApR2h+nhA~EB>Ewi$`al9Ya8=QyWdGiN#AsidR z5$bbf2uFu-l+B^Fr};4$OUHTrtm_`UL@kS<>C-73E{F3 zE_I@LT((CDJw0a5`2p`Z2XZ*#aNgn<$VgmA58 zS$LiJAhS^!EM$B*rcCpURU__Gimd`6 z#6t)w422L5q1IAt6$v5gsf}4G5kg9O(z0o#GG<^ck6Z|ODFu&S7eYCNdMWgjJSonn zA%xi>%m`tY^qIm}Y?N0Oz9wWX{jZD95zh7KZ;H156$_JDJw))TIiar3gMFwR)_GZ^v|r1%YLqKjg@>E!uk-_ zhVYH_bs>Be!q=8{B@VxpVM7Q%gz#Mm-Ysr@5_ zKNW5^aoeE$B*s6y*KMhOyy`z*DqHvwUhGi2^)vq*mpT-Ze9X`Ph&QU;`qKf$U2D;# z7L9AG&k?%`NkaOXa8sFguf-lB{Dd(5%de3Q;yQD}hnj)4JPxnL5%L@WjNWiK+lJBj!urc|d_i=GNEt3?kH*SwdF>t=X`QoU=@$7-)MbKhF@Gfs2= zT3oH#YdjsUt;G$s7+8zJwYaVp*K0!tdA5jy4ynbkS`4)+caEwv6Y5+=iYA>-X;&jk+rx}&fA4|2uBH-y{oqRSAgzT$vr}f>^9mA_toNl>23&SYx&~8 z7LQ0ATZ@N89`@9_4&!RUZ;g$w#p5CqYVnwQQe-QK{N2#R+Ui%NsXSGSXKV4aJkJOx z)m9&6JeVauSBvMRZ&RrAkutfq`l0+~X@CCCHiAR=-8X zltX^PDqLIroD~)R7Aaa={k};|W|BlL(zQs|A|>5T9dtizy20 zg!Gq0%0l;5mj-p1A#}Br*qpCMc#zEJ zHO4>wApLFO0wG0a-_hOaT_NvmyeIH@uNI4?EU|mn`Qo77GbR} zk{!dNeIOFZYI3bMo3XeCDh7-d$N#z|(OMH_OSZOi$VV&|?Neqk6FDeNAuJ}+M^eu?l> zkL|KBt_Y(?7`-I+3|F7`+3Irj=ZLKB9mbVm^zl?tzskaXVGI!OAI8;TTw@cXhkdRM zV^A0a!?@0LUT^GqeHepPMedwK!?-DoVPOmp;|8TzUY$8V|EZ9BaVcZeM zh%iP5W;I*jL}KNH5JFrKyjadUV+ zj2FXrK?Xh;SvWb2DGJ%2&52VLz8uDMk!hB#F~U}UUVh=~M-c+Tpi&HL!-z-;+x1B? zDuq??Fj8S86edliAst3GjEtJlMkQwr8S*HEQM7EG3i-I8UJ9cuy<%C`&Jdp|d__1* z=t{W8*TR^s?fpVarZOjtxl+iT_@=^nVayldUn60PM_>N`7jrHQ;~jBVvdHxJ!dUFl zS@pic4}?pF-1!f~SP{lYIzim_<>9Sgqg!dp$6>4r;}g?)zG(X_jL&6QEu^@{WB4+R zZ^Bp`#yS&O@>LjLD|8*!hw)t)-`Xe}JkIZ}C#yD^{!vF z?_vD0y|UTDzvTbh)A`>p{tIKrNc9f9Mfwhr|NlEGkiJs{JB!fchS){nt`RggeK)J( z6LHfBc2`JFKar<dlt2#P@W5hWY^#XCmODT33l(ow-cQ=@CIsZ8iJ%GQux%UJ=1n3VTP;CxR<2 zMH}~=*f)ZH68o!<)31qOkir4NYaAA{ZCJ!#sWb@P7o4Mz(%K*PuC`3@SQRuIa;ME995zJIc zIf6rd67Qu%Rtcc*F2$q}fY{ZqO@E)=%f=?p& zOzZko$c3ynLcwd92>y`sw+Mchfhn5*^z{78!~cokKZXCANdJ}yc8FrfX!SPB zS{@`jMbS8louk!TXrm~05n*aqBh+_`R`2aR$eTvNzb(9b6nmIqPZ6f}l8t1aC=L+c zSJ*6y{i4`Eisok6)~$t<13fyQ{m1a{|3|Aogz`981RX)iopd%~H|(Z$>$y7e!iofO5%(dtuYU)^a>mEJLmP9hZf zdV^CsUFB?khRB&wbQa+QpW@l-a84BGN@TY#QkWt?-^05`(LIW8QT(`N3y%wmT zLHL-EPS(Dq6U~cuqAt`Yb;=k%ZRD9KCMor-@Hrt3Jijl9zbIrl*-BoDV!FhsQM@cN z%{=bWQKQf&^jnHgh0KN&)(XQyHx{21qS5MWs#p|p5ni7RlNvN7Oh>DK4uvyun2jPA zMInm3vQ96G*9o1i6veD)^^?-&C@N9RjG`fm8EQq59^xx9I8J;uiq~Xt%Ii_gjbe_J zw^c&@4TWz;F)s=y65p~%=-W{&5ML%k}Qp4 znK(Cr;YX$~7g-U-N>gZ9CH{%<(G&{zDWSjsGa}lgIh9@n3Z=ev9JID1I03$d3R;FHF1@vkZWiEQ!scZ>nC>YdH`cNT9X+$Dy_BD)IR5X2@iG?l`?A;yD+dno+E=CGH- zy<^xXhJCHJnF!7M@%{f;^{&2uta^!(9H6j;kV;FDgM`esis9fG4pGSS&V%A%mOWhL z2;q@JzHsFztu-9Y$HdSkh8y(~_blOY8kYmLjiH_K_9Co3A-47X+Y@8xVEm+5^_u57 zJtbECBbm+hM{7HZQ|uJOY2qB0Sswg93une~UJL=g|F6_p>TtI39O1dbE<)PQkKw`? zE{LI93|(W@KM%z|9F)lHMKN?&A96OoI0mBgT*{Sdpv#0b9L<}5tomXW4Kx(H_a&nVi+33wJ}^5!$8$KeNYU8W7x!}025g< zB!=VoJ`Zo0G29Zv4cvTn8y>>~z7N0`|1sPg!)!iX^5=T~!A8FRkKs0Mmqs5E!$@^w z2OgZy9SUcOb6hU)t{Cp-MJVN-819qd-WW!Uu!O1m#mB_(fH|G+Iy@8uFNTM;V^lcM zqq<1O3C9a5P7tAiXZi6Mp0MkITl%E&r$n9>QlAv7zJhvI_?(d8^CEnr=NfrJC+k9; zB78~cUeCPD3u()iX+kRGH7fK8{X*(&$Ro&Il~OCD!c;_;JtxeW5M$c;cnk>J_ z>hBzv2|pC_6j0%-h~=^B>xvZ|TH(jq`Bg%0{uli4Cm%$ng8n;zTpE$eb$S78^Z==DSjt~-uujbX<){)=IUc=bNEg%3>WOpzd7z5kQ!WTa6XyT-AL zLi%}KaZq}=?YqU%BwoFHHx)W@5Ai+a-z$#2Md;x{1Izb~qglNAqJ6(Onk!4r)c(d@ zc%VEj<7gGfL2pCG~#dOC=o~`^mrm6UT!hV}(@y;Qc?2@d_UiJ}Mk1WOhOvL^>an^0?_#CW=34 z%F}T?AICEaCkdYw()pZuUNGfFwVfQt6id-IRs3c1OtYbRx@+{9CE=rqTOH8Sg2L)6 z(l~03hef{7E7hoYERMKHLdcsQPxMTF{y&biHYy{e!oAAHQHmoUM=_3qPA&)Kh{U=$ z>OD$1ju~-O;%M-QwDFi}%B(o%#_?(#v*UP8SB2~LdK_~Uva@UcMjZ3vc+(1C)U&6m_tbfhM@-5;!B>w+3KN8p_QGJZ>l)%o? z8!6nj>Rlx^HnEAqro!EYZl!z5u$M<+hkX**S4uOX>)AYk7BcUjzya2lO%6=ppafca zoUIZ#B!PoHiW}>&1ddSQ;Z}ZR0DUMghCWeHp^-b2_^*vqn4i1be2ss#EZaHZ*PR>Z!h^iN<= z0#_$+jm>930s|Ac)(kXXr<9xL_0lO0Hp9>aZj@nI0ykK8xOKb92+MCt;En`tO<;s< zw^;{v8!3LfDWgR0OyKSW?lO@!9`{(o(Fr`L)O`uupTHQiJzxfoI94L79!lV0Gq^sF zCNNIU@zN)FvX3Y5l)@(xm?-k3C(H7u6L`im%Cp9wOW=8PzF=gsvQvbd(o3eloIp(i z(-ck@vNH`nIsFL)B?hc{$m4O&NCLAGh$fIrAeKNXfp`MR1bXlzKtkT<$@$coP9Up3 z8D7S``Afff%a(isr34BI)Fn`~{(N!B{`Cs^g1MZ)j07qPG^mzUJlJ7o0EX0_Y*xq} z<3aHs`Tyk|K8gPlKoVOL*fEJ6lGP6q@D&AT;&7)V8YQb+y>qhq)Zkva6L(FbNfM1E z?j{30ZtI##++9d>$zTwQ7 zA0%5V;laW~gog^bQkEPpzbiRXoIlhvY%R~x!efMOgvScqaJ02eR$nEOa5C*RljD=s z#{xr&CnnLs`k$1<$;O#IRlK9HlhBo%E`Ema%p}ed>1>9xjj%b7bCc+zLCT3wUQXi0Bwk8lvKgjW$yASXn)vi2f+96SpU^K1 z2sztO61CRKjY5nh5j6ut9`Pg++bb!BX<zvO_ zDX$1;CGncbt3qaHi?}{>l6WhLxk z-R;-D*!nCn{evV{Cb2Y$kCIrH#D}K4IV?|Ng(+^VkCXUBO;!mherm*(tWM%{m8=nd zA^cM4I;>0L+a$h9;u{ry?I~X`n_JO_B)&`H2W7wa=o`)dQxbnBu_=jPrTm=4FP3s0 zeoNx_B>phbjlP*T`6T{I;veaMTlQZgtlg5tj;ZQxb_XE~k-|=?t#1LjK8;e?ErnfV z*j3or%x?513Y!Xdx7s~ZXr97eDeNnK?-ceCVF}wdGrpe)mHn;ofD~GoNOQ{+j!fa8 z6b_NtN_eo4_xwXsI6Q^J6uQnwc=%D`ty5@|!qF)lV?(%g(SNKdZBsZYg?1?%uafqr z({qCOiPAd=S$=W~r;49qN=K1SLN}As#m`9L>=e#Sp|kZo%j2Q*9EIl!+4(%#&QGCh z3Kw{s-BP&FI=KGbQ@GfaOH#Ph`2VcxGV9qhg)36%rSNhS*`&94AK{hT%Jo3&n?gV7 z{XPC`QW%uN04dj|Fwjca>N?}sD@$dt6%JKum>F(JVR#BRTIkktbE^7OdyDYaRQ1Qt z+r%k;p%(xnQ@C9UpQ9=A^#k9g;C9`qK10Rl3-6I~ZwjMD?i2D-p?L=1|4HG26i6Nv zjuo;Sm4{Q+cQQHjBSyw)CgW3hTx3EDkBK;&!-*+8mBN!&LhpC)L9-#A!vT5)TR)X z5*9|(zpeZ+@px+MTm8ut(kY}o<*q|kwwy;V*d&W4@}1=R6iTV;_an-}im*Y*=~3tW zXQuFqoyS=zyeiJgFg08Jb>ST0T;Ur+8n`;*JcaXxZwXnxAhq?katl*<$2dpi?`0OH z@SZ7)Q&^J1`wF?+JZNCgrRuXRg%3rj@S<8SP7lMC;vWlF2|p1s)sCP4)CpZJ*I+%c~A`xJgiRo|WF^~~ka`J>MDPr^+? zI)4`7T7FGc|MJ*x!ex3y{Gm~J9{<#tVh3{K-_l9`F~fgm*kTH^JEnnj_2$2mkc8!p z($&Y~F2Y@fPN%q=g-u0v7w(b9o+_t-2hDp+-^Y6HYgNqdmqv5x`&)@?PCU?~aBmMv zqgA@P$vh5DSN|0k$)TnkCUUrtsUy?Xi=0h}t;I=>PUDy~j!mPD8&QVi(rD`mX=|Ux zDQO&^Mh6w1AUx62@Fek*J<6%-&@qipo>r%epOHpqInVU?&r0KLh1({1t`(k_M%OgX zPvZhp+$y@6|H3pb67Oyb4VQ>tnnq7niC<>f9@eLqDVK||s&^V!rO`*>m6oO6H;t>) z=x0iQ^Iwz3wc-Oz;rs_0AC$(8X5@@id-R_(U2L(|A(c4fK?!>KW;i(s-7at9hL5g*0l?crlG>X-rPz zC1t0WXQ~Ltec97(x@D>R((o$`m^0|f)}|3oBQ7N(j0$6(ZV4$#Q_^YFr;$mckVaN1 zj*=6}3pwqgNS$S=l+viAQT8aTYEU@CI=_;}8)?i+W482H(|Aq9?ZfNhbA)q+?7-BU zX}qm)o^XB|Z;8071!*i&xG;@((s}cq_HuL?<9UN z{6Xll#2?f6DUF}iWRsBMFPlEI%x$>2)sf0YXRX3)plI4WH8hWuFnk_+?v7g3~tKcMvwDm@moBd-Cm8z;NA>IW^iW)w`XvNbsHt( zJa>uToxwepb^7QG9?amr4DPqKV={QaJZ?T?Gk7?Ihs;2c$0Oz$m%(^TvFC&g9#iV^ z44yEL8|z8go)SK7C2Tb*gJ;d@MtnYlsZw6Z;KdB4$UNCfUNS=S%d)Zmv<#+ubf0v; zFd#i>PFB@skj@~SK|F&<1~D0;o^m!!WRS`rxxL8ROa}Q3vKizooebX3;N1)sXRs)P_blto#3eSL4>I^LgQXcPGsSs6QiUphZN$O>fAZI^}Ahcb+)ohZQJTDnxxwYCtjeXbrn+SW-Gc#6YDPIkBt{|f%^IJ z(kyyvp#NoYSr$DUx1Yj#dBQ8QxJqq%XVE8%D=o!QIJdq^^^@3N{AwXnH1HUp)U^@^ zW^r8>gSPMR1~()N;t=7`EQX0t8N@&SVEo1`ZW5=+)Ggw-3UA9|q{s*}+%Doe&_61R zJ2@^t|0BG6`|Q10jFx_%@P45ih4?@g4`wk|B7c>}o)4+~N8bFi)$dt6YT>vn#v7;Y zu`Hfc_;?mi$T?BS6sw-fVv@qA<$1ku}7#Ppah*SL_^YCoBLwm=`4V zf(&2q!#@&9>a*2P4>DEGq9KclbcXyW@(l5rLOxj7lQ=7jSJmV-J_@qc_nc?zp~S3v z4{)v;vM0kgWguZVUsZ1@%d4IK1z9Y#kOqqH%CpEONzY>OC0V>LClxx0OS4#+#WIN> zX0berk2DQ8PkyaqMYj5;3Y}cb$62hB^AmM*p3jW0w)wBg;!E1>@#qFxo5ecSekGj^ zInQrYyI$yQ8^php(McCq)!*|5c>m7xuX==z1_3ecs`)RK_&*^FIbx3-uE?Qh4wp;pB`2#mC=I=H=qtUC^ec1N$iM#} zWNkmCIDhi1a~Q)v{+Yw|ISj~QAh(Wx0wM?Yp?+NsgVf<5nfZ|hZsuSqLxg?#`Trd5 z%Hf6_Zq8wN4mYYfoos#+Ly=o@xFd&KbGS_ktEi9QKFfT&r({$PcPixQuJ&%uFo%0` zxG#r$a~Q1-oFubuEAE#<{{uNZ$c1af9(?~tGo+^2^#J( z&m5jmL-uEu$CD~~O8B&pOPiDfpI@F8k~}B!yzm9#i$Xf5h`c16szEs}OL$C^I9*sH z^yT2!Oaj87kWTigbvnP+pF<>vSPoGsTsSY4cn%4LZqq2Ha%jjQokKB)Ob+=RvN`1V z=+@Sa*X|W^)z8eklDZtqIn?J+vVH5Qcf~7e%L(w*&&c7`9A-*+C5KtsD4(XsCa>i% zCx_WNyq*Iu7%J`|FgJ%cRN~GTb&`3iou9*7IV{ZKZ9atM;mmos;oiyNAv?>9lzlIU z#Ue|D?wf;5!v>H3y{C}18!h}vWRtKt-~Z2n zNCS^wxj^Z^3wh6>_@}O)&BDKge+%d6N$_9Z+w=G@haL0P4cU^z4*BXu&gTvy59F~^ z9y{l8twO#4pty@Xy9yf%Sxdc19{c6dG>^UW*gcOumD+=$vNY_KhZ}bvrS{FESsv?^ zWd~k7&86?3M~gfT5O*^rd0dl6?>w%O(nolu zkfZd?qrZ4RAzuhxEyC%!lRkjghLnLqCo(%IkL%6JNe;;GETxR}{M7DKap>U<${iv^!!Yv~Il&i>NwG?+N;KbH&OR41XrB$t! zfy-H^(ZBM{;T!Art;hx;JG)0HOSY|aV;(=|@skWL>n7sV!aaq1 z3HKK6Bc#7s0nNqtD{Ot1VbA>wSgIjfC`IK!k(O3PrImP$Fa8TSqJXLV6>tHENjzLg zg*F~X7I2gl^40~kmUv77Clt`8fVQeVR(PBhwo}-?fa6VJEgPOFouoqnClzqALN^LU zF6Yz&I%)^VJBgfT8$#s_@iT>;3ph)JIy;=BfzB0n5mG;|fb)&h(^b5iaHgs*67Mdg z;o<@=DWHeKOAGiP58nTU%#!z1s+W-A<(6W$cL9A0xVnHV3mC!||H8gPX8RS;-#D|^ zsKbB)uIE`(6N&>1xUPUfW^*GBmUD=3sEy0i4F%j*z;G!HZ!F*@@tX^{MT8A`+-luM z6fjEqNa5|mJA_=wog#M$?>3Qb?=4_V0i&fbysv=!Ejx^_{|k7yfCr_FE#RR7687SU z+xtiX;|qASfN_QD`v5HGK*S01yNA!?*7=D7CW=2Pbmx@jrxiXUoK(QGBGla-<21d= z_Clfhy#JzbvT%y-BbP+!1|0!q@$x}Gb-1|bXCd1e8# zWq3v7&Jw;_z-yjv+jeYD0du8qQ{F6Ko)mWDqwK8$7ASn%hFEA>o~CyT_@IDAQr;_I ziO6DezHd%0VX64C0zN9>L-E(OW6RCMKVq;_{Nn;X6Vm zC{$nTep$d;h2-m`d?ox^$ny0CY$)JcSHeG-z|a2|@V&w@`UV6&8x{U&o}WaxIX@Th zdjY>F{ME9*S(b%=*s94l7x0&P{x0Ai&HrCh{wrXMxO;t0|Bl7#-5y2kRK%|0I|~~L zcM5X%Uau{_G)T&m#76PGKu$_Z4SVvm*90-nWe*WKv{?NS+s))~DMtu7Pl`v0w-z4lP>7LS}m!;S>Gk=Deba-p2b_&#Q{Ku86)x zT%%OKBKj9`wPo3g;|@^j+9C#uIMLxCDV+1*B5n{LA{<)8FcFs1IlPFQ72a6HO(L$G z*;^FeYT}3@MinvA!rL{IJ8V987IBYKcS*V1^n1}q6Y!MGhA%B?H z@b=kp3daj42p_Xio>0iDiA6jq{*)ba+W?v9t?TbZBE@F!5+xB6q zl$VQ`CNjNXR55QV$+yW#2ZD-EMj&MuN3jBva_t@H6tv1y@X=TJ}hE+5g&PU zI@x?>5vwGAY^hI-(C`_Tsc>}>pNp&!y4o*`_^ODtQq~FGioQ0_H?~XPifjcRE>g&Mt*bsqFiYI64owvDr&oqNc2~GZ-PWHMXxpm} zd)I-6eLRJ9Hmk#aQko0*7amZDmUU>M@&m02S9FlFB&|$jheOy_`eDMug-6t(bsdhZ z+jh3b}-{jGV2toMS8MBAs(MuMX!Mzn~6X>u^yWx^Wx% zVYF0Dg|1| z%y6~HHNpYHYlQ=auEU@@jI6`;br>#juyBZQsBl;vZt%?i#yZ?qhntkTS;$q~QiofO zyIGA;$Zfn`+pIV=1QOAknjJ9Y`Y)MQ#ij4F>TA+b$F)^3nVTSx}VYB z73V06MBLlUi^Z4NCHH}OShCFchazsc<>D)Z^Y}Wv4xfpys>3IB_*6WkUr%$O)e1is zt`Sn?87H2`FaOq6f0`!mEc~ht8If)!~Oad~aD-yU|w7K6Gxf?9X-h zMVuc>;qR1xtHba1uyrH;sqALqUslCExkYoJ=ij=m?*VS%t-c;R)K_omI|?CW$hGWj zyphN*Lh6l0cB@CzdNeVQTl?Eg@>BwaLXQ1zxCPYC@HN?Ke`^r)T51MU7zFX(N0QR>(gGLTh0mMC)VTSdUUAA zN#=3cQ>+!kj!JbBo+doK9%q=}jn%mx=hfq^dYn^_vpu7nTaPZ=JI}92w|ZPqkFMM6 z7ka9?*W+T#y7>?;ub7-r)-Wq3Vql5(TzH`n79h};!j-Nd=3ys>@N{CX^|$6NJyw;pfTW1+GOtcufk$Nc1r>hYc@wWJ;& z*5mzpEUm`})}NE%vCM2A)njEnme*s2DQ>nO*JG6_>`d`fg`WwjthVf$dVI|})MKrb zFKs^S>hYC%T+eS5t~ZfQHi*0a&htY(eyYbt(|TT0ycPdq%5gcz+LX#49DWS0py9$}z%?NExOW3o7 z-AmZRL|5)Q>|H{O680&fc?tWLuwMzyWOLbVxPJ);c*Z@@JS|OZCFNk#4-w%&hm~-+ zdA5yvWC=%^bE{|`j@YJzW38NF+Y*j1p`H2Ldz>efaH8qE*q)p$`|6zxYC3Nys zxe-q<;S71sv<}qI5_bmTIVGHHN*7Ou^G)n3(yfGxL@qQ>cZD39O)e?nvJx&e<$oe> zh#ulSO}Sj*}0#1f8o`_YlH)Y*9r#;*=JA*HcQ&hTXmxrFH@)Rf>?mCy8mLbo%a62j7Jt+N|3T0*>pm{Lw5 zCagoMglq|Eg&84VYSO?XXP!a{MdPkReF;ZE5uaPa8{0eQmGG97`5rUN7f2*oXgc}3B`h-CZOCHl_P*&Kl(4jfWme^EAC<7W zgykiCEZYjK}!l&Y&Sk-5i;-EY}FJX;Sw%6B|ux@+hYwNJSgiR%UTf%oGZ18x# zFJYs?A58qQgrBU+&GzRKek zxq7SLLFiV*aHsPBKNnDJWZ7NI*rSZb%I;Q1(=wWD@7&#-tlG1Ty~@}}hP{RC%wu2k z>{rHtWi&72fHL+sgPTJO3tN`aO8g*GXgJuz4;4SmdLB{6F=ZTCMr-LunSQiF)^Y;G zHf0>^Y0|cgcH5lt9AC!CGMpehv5XF7oFvZQq`N++C_GizQRteVChk0Ecz9RG{VkzmvLVi_ei<7 zjL{E2F!wv6Y>ctNe67c%>z2!DiU=P70Q z%Xq1bX=O~6{<4q*G0S6m88v12%HYd3{vLNvIscacJt&u}Gg``lf{x-ZQe_eU&C(ud?%R+i8Wi%LX z&)@%+@n#vXl<|5Qv&xuV#;aw#CWBiPf79w#F-PLuGTz|Y?Y-qUl%1#4{4(CM>zuU< z%2-^+LZ#j*RsG`&9dIlv1n9)o&7UK5LjNSO2aooACHj9o7oh3BR(Q-<0uv8SB;R z+cLf@V}m$vDF^DW%d-53GJYy!qja9EAGv|{NuEvW^RxE<7vZnM-|US1p{hU2__vJB zW&Ex1uX6Rzba1L{{*M&?!uLOsEka(3Ozl`f;|fqgqe}G|VJG3vLK=3dU{`ToIn3_D z*Z&plA*D$LO)J=4oTrc38NB&duvca4`!LQ=+(({$D`-|hbMgHu)vGki5C15nhaFl} zaA*YwR&a0yEh{*v^8de4ZDl%Xo?$&x#rMi1;dvpbDRC0{a zt>RdXew?tau$_>8wGt*zk&;7aQ?2=`9e;wf{QBXt}JVB<$Gv+ z{VxLvmH#PqnXtNW{{C0Imq(#~g~Hwy^r@g<1y|bAuBxD~an|;ijpXVIt}#Bq3mfLx6*qmxL^9c!qLL}?D`o~!NV0iP{G&=9#qQR3|ae-!aaEZuV9?`qgKW2cqzQ1 z9;@JK@y9E8qJk&ICsuH|=Ju3A_fGFKn$;vJ&srC9)^OX%+Y@m@cJ8=o4~FIZ&X2T3$I)Xby>RlyC*n3L>UcVK%0D^1F(O3erj? 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 diff --git a/configs/sql-init-scripts/sqlite/clientprefs-sqlite.sq3 b/configs/sql-init-scripts/sqlite/clientprefs-sqlite.sq3 deleted file mode 100644 index 04d300534859077e362f288c7179dfe951a0acf3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6144 zcmeH}&rZTH7{J?YKqT3jYq@QK14z(#FcHl{h%g1lfrDA_+F4si=ADJiNxxrb=D+0b47q-!H5+N`1~1kmj%_v? zI**B5kI)EvOCG}&_oLpRGn%4XV~Vt0!8(dF>uOoQEEFrl8U(ICBQJEdV1sDmbrk%{ z_Q8kS%>za8UM_Mb(;bpsI3=q!@g4G)Z7(WmBxzsG#~!IOSN;7QmMYaM{J2PCrg3R1 zr8Dg}g6_C7Vm;F`y2c14+wV-QyPnA+2Zm{JHoRg?u$AD8CT4FqF}Tl+P$zVkksJ82 z>uJ0F3mZGEMY^xWP`0FErCa?MB~4JIGMhL>. - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "ADTFactory.h" -#include "sm_globals.h" -#include "ShareSys.h" - -ADTFactory g_AdtFactory; - -const char *ADTFactory::GetInterfaceName() -{ - return SMINTERFACE_ADTFACTORY_NAME; -} - -unsigned int ADTFactory::GetInterfaceVersion() -{ - return SMINTERFACE_ADTFACTORY_VERSION; -} - -void ADTFactory::OnSourceModAllInitialized() -{ - g_ShareSys.AddInterface(NULL, this); -} - -IBasicTrie *ADTFactory::CreateBasicTrie() -{ - return new BaseTrie(); -} - -BaseTrie::BaseTrie() -{ - m_pTrie = sm_trie_create(); -} - -BaseTrie::~BaseTrie() -{ - sm_trie_destroy(m_pTrie); -} - -bool BaseTrie::Insert(const char *key, void *value) -{ - return sm_trie_insert(m_pTrie, key, value); -} - -bool BaseTrie::Retrieve(const char *key, void **value) -{ - return sm_trie_retrieve(m_pTrie, key, value); -} - -bool BaseTrie::Delete(const char *key) -{ - return sm_trie_delete(m_pTrie, key); -} - -void BaseTrie::Clear() -{ - sm_trie_clear(m_pTrie); -} - -void BaseTrie::Destroy() -{ - delete this; -} - -bool BaseTrie::Replace(const char *key, void *value) -{ - return sm_trie_replace(m_pTrie, key, value); -} diff --git a/core/ADTFactory.h b/core/ADTFactory.h deleted file mode 100644 index 31bff041..00000000 --- a/core/ADTFactory.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_ADTFACTORY_H_ -#define _INCLUDE_SOURCEMOD_ADTFACTORY_H_ - -#include -#include "sm_globals.h" -#include "sm_trie.h" - -using namespace SourceMod; - -class BaseTrie : public IBasicTrie -{ -public: - BaseTrie(); - virtual ~BaseTrie(); - virtual bool Insert(const char *key, void *value); - virtual bool Replace(const char *key, void *value); - virtual bool Retrieve(const char *key, void **value); - virtual bool Delete(const char *key); - virtual void Clear(); - virtual void Destroy(); -private: - Trie *m_pTrie; -}; - -class ADTFactory : - public SMGlobalClass, - public IADTFactory -{ -public: //SMInterface - const char *GetInterfaceName(); - unsigned int GetInterfaceVersion(); -public: //SMGlobalClass - void OnSourceModAllInitialized(); -public: //IADTFactory - IBasicTrie *CreateBasicTrie(); -}; - -#endif //_INCLUDE_SOURCEMOD_ADTFACTORY_H_ - diff --git a/core/AdminCache.cpp b/core/AdminCache.cpp deleted file mode 100644 index a03c1899..00000000 --- a/core/AdminCache.cpp +++ /dev/null @@ -1,2081 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include -#include -#include "AdminCache.h" -#include "ShareSys.h" -#include "ForwardSys.h" -#include "PlayerManager.h" -#include "ConCmdManager.h" -#include "Logger.h" -#include "sourcemod.h" -#include "sm_stringutil.h" -#include "sourcemm_api.h" -#include "sm_srvcmds.h" - -#define LEVEL_STATE_NONE 0 -#define LEVEL_STATE_LEVELS 1 -#define LEVEL_STATE_FLAGS 2 - -AdminCache g_Admins; -char g_ReverseFlags[26]; -AdminFlag g_FlagLetters[26]; -bool g_FlagSet[26]; - -ConVar sm_immunity_mode("sm_immunity_mode", "1", FCVAR_SPONLY, "Mode for deciding immunity protection"); - -/* Default flags */ -AdminFlag g_DefaultFlags[26] = -{ - Admin_Reservation, Admin_Generic, Admin_Kick, Admin_Ban, Admin_Unban, - Admin_Slay, Admin_Changemap, Admin_Convars, Admin_Config, Admin_Chat, - Admin_Vote, Admin_Password, Admin_RCON, Admin_Cheats, Admin_Custom1, - Admin_Custom2, Admin_Custom3, Admin_Custom4, Admin_Custom5, Admin_Custom6, - Admin_Generic, Admin_Generic, Admin_Generic, Admin_Generic, Admin_Generic, - Admin_Root -}; - - -class FlagReader : public ITextListener_SMC -{ -public: - void LoadLevels() - { - if (!Parse()) - { - memcpy(g_FlagLetters, g_DefaultFlags, sizeof(AdminFlag) * 26); - for (unsigned int i=0; i<20; i++) - { - g_FlagSet[i] = true; - } - g_FlagSet[25] = true; - } - } -private: - bool Parse() - { - SMCStates states; - SMCError error; - - m_bFileNameLogged = false; - g_SourceMod.BuildPath(Path_SM, m_File, sizeof(m_File), "configs/admin_levels.cfg"); - - if ((error = textparsers->ParseFile_SMC(m_File, this, &states)) - != SMCError_Okay) - { - const char *err_string = textparsers->GetSMCErrorString(error); - if (!err_string) - { - err_string = "Unknown error"; - } - ParseError(NULL, "Error %d (%s)", error, err_string); - return false; - } - - return true; - } - void ReadSMC_ParseStart() - { - m_LevelState = LEVEL_STATE_NONE; - m_IgnoreLevel = 0; - memset(g_FlagSet, 0, sizeof(g_FlagSet)); - } - SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name) - { - if (m_IgnoreLevel) - { - m_IgnoreLevel++; - return SMCResult_Continue; - } - - if (m_LevelState == LEVEL_STATE_NONE) - { - if (strcmp(name, "Levels") == 0) - { - m_LevelState = LEVEL_STATE_LEVELS; - } - else - { - m_IgnoreLevel++; - } - } else if (m_LevelState == LEVEL_STATE_LEVELS) { - if (strcmp(name, "Flags") == 0) - { - m_LevelState = LEVEL_STATE_FLAGS; - } - else - { - m_IgnoreLevel++; - } - } - else - { - m_IgnoreLevel++; - } - - return SMCResult_Continue; - } - SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value) - { - if (m_LevelState != LEVEL_STATE_FLAGS || m_IgnoreLevel) - { - return SMCResult_Continue; - } - - unsigned char c = (unsigned)value[0]; - - if (c < (unsigned)'a' || c > (unsigned)'z') - { - ParseError(states, "Flag \"%c\" is not a lower-case ASCII letter", c); - return SMCResult_Continue; - } - - c -= (unsigned)'a'; - - if (!g_Admins.FindFlag(key, &g_FlagLetters[c])) - { - ParseError(states, "Unrecognized admin level \"%s\"", key); - return SMCResult_Continue; - } - - g_FlagSet[c] = true; - - return SMCResult_Continue; - } - SMCResult ReadSMC_LeavingSection(const SMCStates *states) - { - if (m_IgnoreLevel) - { - m_IgnoreLevel--; - return SMCResult_Continue; - } - - if (m_LevelState == LEVEL_STATE_FLAGS) - { - m_LevelState = LEVEL_STATE_LEVELS; - return SMCResult_Halt; - } - else if (m_LevelState == LEVEL_STATE_LEVELS) - { - m_LevelState = LEVEL_STATE_NONE; - } - - return SMCResult_Continue; - } - void ParseError(const SMCStates *states, const char *message, ...) - { - va_list ap; - char buffer[256]; - - va_start(ap, message); - UTIL_FormatArgs(buffer, sizeof(buffer), message, ap); - va_end(ap); - - if (!m_bFileNameLogged) - { - g_Logger.LogError("[SM] Parse error(s) detected in file \"%s\":", m_File); - m_bFileNameLogged = true; - } - - g_Logger.LogError("[SM] (Line %d): %s", states ? states->line : 0, buffer); - } -private: - bool m_bFileNameLogged; - char m_File[PLATFORM_MAX_PATH]; - int m_LevelState; - int m_IgnoreLevel; -} s_FlagReader; - -AdminCache::AdminCache() -{ - m_pCmdOverrides = sm_trie_create(); - m_pCmdGrpOverrides = sm_trie_create(); - m_pStrings = new BaseStringTable(1024); - m_pMemory = m_pStrings->GetMemTable(); - m_FreeGroupList = m_FirstGroup = m_LastGroup = INVALID_GROUP_ID; - m_FreeUserList = m_FirstUser = m_LastUser = INVALID_ADMIN_ID; - m_pGroups = sm_trie_create(); - m_pCacheFwd = NULL; - m_FirstGroup = -1; - m_pAuthTables = sm_trie_create(); - m_InvalidatingAdmins = false; - m_destroying = false; - m_pLevelNames = sm_trie_create(); -} - -AdminCache::~AdminCache() -{ - m_destroying = true; - DumpAdminCache(AdminCache_Overrides, false); - DumpAdminCache(AdminCache_Groups, false); - - sm_trie_destroy(m_pCmdGrpOverrides); - sm_trie_destroy(m_pCmdOverrides); - - if (m_pGroups) - { - sm_trie_destroy(m_pGroups); - } - - List::iterator iter; - for (iter=m_AuthMethods.begin(); - iter!=m_AuthMethods.end(); - iter++) - { - sm_trie_destroy((*iter).table); - } - - sm_trie_destroy(m_pAuthTables); - - delete m_pStrings; - - sm_trie_destroy(m_pLevelNames); -} - -void AdminCache::OnSourceModStartup(bool late) -{ - RegisterAuthIdentType("steam"); - RegisterAuthIdentType("name"); - RegisterAuthIdentType("ip"); - - NameFlag("reservation", Admin_Reservation); - NameFlag("kick", Admin_Kick); - NameFlag("generic", Admin_Generic); - NameFlag("ban", Admin_Ban); - NameFlag("unban", Admin_Unban); - NameFlag("slay", Admin_Slay); - NameFlag("changemap", Admin_Changemap); - NameFlag("cvars", Admin_Convars); - NameFlag("config", Admin_Config); - NameFlag("chat", Admin_Chat); - NameFlag("vote", Admin_Vote); - NameFlag("password", Admin_Password); - NameFlag("rcon", Admin_RCON); - NameFlag("cheats", Admin_Cheats); - NameFlag("root", Admin_Root); - NameFlag("custom1", Admin_Custom1); - NameFlag("custom2", Admin_Custom2); - NameFlag("custom3", Admin_Custom3); - NameFlag("custom4", Admin_Custom4); - NameFlag("custom5", Admin_Custom5); - NameFlag("custom6", Admin_Custom6); -} - -void AdminCache::OnSourceModAllInitialized() -{ - m_pCacheFwd = g_Forwards.CreateForward("OnRebuildAdminCache", ET_Ignore, 1, NULL, Param_Cell); - g_ShareSys.AddInterface(NULL, this); -} - -void AdminCache::OnSourceModLevelChange(const char *mapName) -{ - int i; - AdminFlag flag; - - /* For now, we only read these once per level. */ - s_FlagReader.LoadLevels(); - - for (i = 0; i < 26; i++) - { - if (FindFlag('a' + i, &flag)) - { - g_ReverseFlags[flag] = 'a' + i; - } - else - { - g_ReverseFlags[flag] = '?'; - } - } -} - -void AdminCache::OnSourceModShutdown() -{ - g_Forwards.ReleaseForward(m_pCacheFwd); - m_pCacheFwd = NULL; -} - -void AdminCache::OnSourceModPluginsLoaded() -{ - DumpAdminCache(AdminCache_Overrides, true); - DumpAdminCache(AdminCache_Groups, true); -} - -void AdminCache::NameFlag(const char *str, AdminFlag flag) -{ - sm_trie_insert(m_pLevelNames, str, (void *)flag); -} - -bool AdminCache::FindFlag(const char *str, AdminFlag *pFlag) -{ - void *obj; - if (!sm_trie_retrieve(m_pLevelNames, str, &obj)) - { - return false; - } - - if (pFlag) - { - *pFlag = (AdminFlag)(int)obj; - } - - return true; -} - -void AdminCache::AddCommandOverride(const char *cmd, OverrideType type, FlagBits flags) -{ - Trie *pTrie = NULL; - if (type == Override_Command) - { - pTrie = m_pCmdOverrides; - } else if (type == Override_CommandGroup) { - pTrie = m_pCmdGrpOverrides; - } else { - return; - } - - sm_trie_insert(pTrie, cmd, (void *)(unsigned int)flags); - - g_ConCmds.UpdateAdminCmdFlags(cmd, type, flags, false); -} - -bool AdminCache::GetCommandOverride(const char *cmd, OverrideType type, FlagBits *pFlags) -{ - Trie *pTrie = NULL; - - if (type == Override_Command) - { - pTrie = m_pCmdOverrides; - } else if (type == Override_CommandGroup) { - pTrie = m_pCmdGrpOverrides; - } else { - return false; - } - - void *object; - if (sm_trie_retrieve(pTrie, cmd, &object)) - { - if (pFlags) - { - *pFlags = (FlagBits)object; - } - return true; - } - - return false; -} - -void AdminCache::UnsetCommandOverride(const char *cmd, OverrideType type) -{ - if (type == Override_Command) - { - return _UnsetCommandOverride(cmd); - } else if (type == Override_CommandGroup) { - return _UnsetCommandGroupOverride(cmd); - } -} - -void AdminCache::_UnsetCommandGroupOverride(const char *group) -{ - if (!m_pCmdGrpOverrides) - { - return; - } - - sm_trie_delete(m_pCmdGrpOverrides, group); - - g_ConCmds.UpdateAdminCmdFlags(group, Override_CommandGroup, 0, true); -} - -void AdminCache::_UnsetCommandOverride(const char *cmd) -{ - if (!m_pCmdOverrides) - { - return; - } - - sm_trie_delete(m_pCmdOverrides, cmd); - - g_ConCmds.UpdateAdminCmdFlags(cmd, Override_Command, 0, true); -} - -void AdminCache::DumpCommandOverrideCache(OverrideType type) -{ - if (type == Override_Command && m_pCmdOverrides) - { - sm_trie_clear(m_pCmdOverrides); - } else if (type == Override_CommandGroup && m_pCmdGrpOverrides) { - sm_trie_clear(m_pCmdGrpOverrides); - } -} - -AdminId AdminCache::CreateAdmin(const char *name) -{ - AdminId id; - AdminUser *pUser; - - if (m_FreeUserList != INVALID_ADMIN_ID) - { - pUser = (AdminUser *)m_pMemory->GetAddress(m_FreeUserList); - assert(pUser->magic == USR_MAGIC_UNSET); - id = m_FreeUserList; - m_FreeUserList = pUser->next_user; - } - else - { - id = m_pMemory->CreateMem(sizeof(AdminUser), (void **)&pUser); - pUser->grp_size = 0; - pUser->grp_table = -1; - } - - pUser->flags = 0; - pUser->eflags = 0; - pUser->grp_count = 0; - pUser->password = -1; - pUser->magic = USR_MAGIC_SET; - pUser->auth.identidx = -1; - pUser->auth.index = 0; - pUser->immunity_level = 0; - pUser->serialchange = 1; - - if (m_FirstUser == INVALID_ADMIN_ID) - { - m_FirstUser = id; - m_LastUser = id; - } - else - { - AdminUser *pPrev = (AdminUser *)m_pMemory->GetAddress(m_LastUser); - pPrev->next_user = id; - pUser->prev_user = m_LastUser; - m_LastUser = id; - } - - /* Since we always append to the tail, we should invalidate their next */ - pUser->next_user = -1; - - if (name && name[0] != '\0') - { - int nameidx = m_pStrings->AddString(name); - pUser = (AdminUser *)m_pMemory->GetAddress(id); - pUser->nameidx = nameidx; - } - else - { - pUser->nameidx = -1; - } - - return id; -} - -GroupId AdminCache::AddGroup(const char *group_name) -{ - if (sm_trie_retrieve(m_pGroups, group_name, NULL)) - { - return INVALID_GROUP_ID; - } - - GroupId id; - AdminGroup *pGroup; - if (m_FreeGroupList != INVALID_GROUP_ID) - { - pGroup = (AdminGroup *)m_pMemory->GetAddress(m_FreeGroupList); - assert(pGroup->magic == GRP_MAGIC_UNSET); - id = m_FreeGroupList; - m_FreeGroupList = pGroup->next_grp; - } else { - id = m_pMemory->CreateMem(sizeof(AdminGroup), (void **)&pGroup); - } - - pGroup->immunity_level = 0; - pGroup->immune_table = -1; - pGroup->magic = GRP_MAGIC_SET; - pGroup->next_grp = INVALID_GROUP_ID; - pGroup->pCmdGrpTable = NULL; - pGroup->pCmdTable = NULL; - pGroup->addflags = 0; - - if (m_FirstGroup == INVALID_GROUP_ID) - { - m_FirstGroup = id; - m_LastGroup = id; - pGroup->prev_grp = INVALID_GROUP_ID; - } else { - AdminGroup *pPrev = (AdminGroup *)m_pMemory->GetAddress(m_LastGroup); - assert(pPrev->magic == GRP_MAGIC_SET); - pPrev->next_grp = id; - pGroup->prev_grp = m_LastGroup; - m_LastGroup = id; - } - - int nameidx = m_pStrings->AddString(group_name); - pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - pGroup->nameidx = nameidx; - - sm_trie_insert(m_pGroups, group_name, (void *)id); - - return id; -} - -GroupId AdminCache::FindGroupByName(const char *group_name) -{ - void *object; - - if (!sm_trie_retrieve(m_pGroups, group_name, &object)) - { - return INVALID_GROUP_ID; - } - - GroupId id = (GroupId)object; - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return INVALID_GROUP_ID; - } - - return id; -} - -void AdminCache::SetGroupAddFlag(GroupId id, AdminFlag flag, bool enabled) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return; - } - - if (flag < Admin_Reservation || flag >= AdminFlags_TOTAL) - { - return; - } - - FlagBits bits = (1<<(FlagBits)flag); - - if (enabled) - { - pGroup->addflags |= bits; - } else { - pGroup->addflags &= ~bits; - } -} - -bool AdminCache::GetGroupAddFlag(GroupId id, AdminFlag flag) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return false; - } - - if (flag < Admin_Reservation || flag >= AdminFlags_TOTAL) - { - return false; - } - - FlagBits bit = 1<<(FlagBits)flag; - return ((pGroup->addflags & bit) == bit); -} - -FlagBits AdminCache::GetGroupAddFlags(GroupId id) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return 0; - } - - return pGroup->addflags; -} - -const char *AdminCache::GetGroupName(GroupId gid) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(gid); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return NULL; - } - - return m_pStrings->GetString(pGroup->nameidx); -} - -void AdminCache::SetGroupGenericImmunity(GroupId id, ImmunityType type, bool enabled) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return; - } - - unsigned int level = 0; - - if (enabled) - { - if (type == Immunity_Default) - { - level = 1; - } else if (type == Immunity_Global) { - level = 2; - } - if (level > pGroup->immunity_level) - { - pGroup->immunity_level = level; - } - } else { - pGroup->immunity_level = 0; - } -} - -bool AdminCache::GetGroupGenericImmunity(GroupId id, ImmunityType type) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return false; - } - - if (type == Immunity_Default && pGroup->immunity_level >= 1) - { - return true; - } else if (type == Immunity_Global && pGroup->immunity_level >= 2) { - return true; - } - - return false; -} - -void AdminCache::AddGroupImmunity(GroupId id, GroupId other_id) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(other_id); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return; - } - - pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return; - } - - /* We always need to resize the immunity table */ - int *table, tblidx; - if (pGroup->immune_table == -1) - { - tblidx = m_pMemory->CreateMem(sizeof(int) * 2, (void **)&table); - pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - table[0] = 0; - } else { - int *old_table = (int *)m_pMemory->GetAddress(pGroup->immune_table); - /* Break out if this group is already in the list */ - for (int i=0; iCreateMem(sizeof(int) * (old_table[0] + 2), (void **)&table); - /* Get the old address again in case of resize */ - pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - old_table = (int *)m_pMemory->GetAddress(pGroup->immune_table); - table[0] = old_table[0]; - for (unsigned int i=1; i<=(unsigned int)old_table[0]; i++) - { - table[i] = old_table[i]; - } - } - - /* Assign */ - pGroup->immune_table = tblidx; - - /* Add to the array */ - table[0]++; - table[table[0]] = other_id; -} - -unsigned int AdminCache::GetGroupImmunityCount(GroupId id) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return 0; - } - - if (pGroup->immune_table == -1) - { - return 0; - } - - int *table = (int *)m_pMemory->GetAddress(pGroup->immune_table); - - return table[0]; -} - -GroupId AdminCache::GetGroupImmunity(GroupId id, unsigned int number) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return INVALID_GROUP_ID; - } - - if (pGroup->immune_table == -1) - { - return INVALID_GROUP_ID; - } - - int *table = (int *)m_pMemory->GetAddress(pGroup->immune_table); - if (number >= (unsigned int)table[0]) - { - return INVALID_GROUP_ID; - } - - return table[1 + number]; -} - -void AdminCache::AddGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule rule) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return; - } - - Trie *pTrie = NULL; - if (type == Override_Command) - { - if (pGroup->pCmdTable == NULL) - { - pGroup->pCmdTable = sm_trie_create(); - } - pTrie = pGroup->pCmdTable; - } else if (type == Override_CommandGroup) { - if (pGroup->pCmdGrpTable == NULL) - { - pGroup->pCmdGrpTable = sm_trie_create(); - } - pTrie = pGroup->pCmdGrpTable; - } else { - return; - } - - sm_trie_insert(pTrie, name, (void *)(int)rule); -} - -bool AdminCache::GetGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule *pRule) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return false; - } - - Trie *pTrie = NULL; - if (type == Override_Command) - { - if (pGroup->pCmdTable == NULL) - { - return false; - } - pTrie = pGroup->pCmdTable; - } else if (type == Override_CommandGroup) { - if (pGroup->pCmdGrpTable == NULL) - { - return false; - } - pTrie = pGroup->pCmdGrpTable; - } else { - return false; - } - - void *object; - if (!sm_trie_retrieve(pTrie, name, &object)) - { - return false; - } - - if (pRule) - { - *pRule = (OverrideRule)(int)object; - } - - return true; -} - -Trie *AdminCache::GetMethodByIndex(unsigned int index) -{ - List::iterator iter; - for (iter=m_AuthMethods.begin(); - iter!=m_AuthMethods.end(); - iter++) - { - if (index-- == 0) - { - return (*iter).table; - } - } - - return NULL; -} - -bool AdminCache::InvalidateAdmin(AdminId id) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - AdminUser *pOther; - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return false; - } - - if (!m_InvalidatingAdmins && !m_destroying) - { - g_Players.ClearAdminId(id); - } - - /* Unlink from the dbl link list */ - if (id == m_FirstUser && id == m_LastUser) - { - m_FirstUser = INVALID_ADMIN_ID; - m_LastUser = INVALID_ADMIN_ID; - } else if (id == m_FirstUser) { - m_FirstUser = pUser->next_user; - pOther = (AdminUser *)m_pMemory->GetAddress(m_FirstUser); - pOther->prev_user = INVALID_ADMIN_ID; - } else if (id == m_LastUser) { - m_LastUser = pUser->prev_user; - pOther = (AdminUser *)m_pMemory->GetAddress(m_LastUser); - pOther->next_user = INVALID_ADMIN_ID; - } else { - pOther = (AdminUser *)m_pMemory->GetAddress(pUser->prev_user); - pOther->next_user = pUser->next_user; - pOther = (AdminUser *)m_pMemory->GetAddress(pUser->next_user); - pOther->prev_user = pUser->prev_user; - } - - /* Unlink from auth tables */ - if (pUser->auth.identidx != -1) - { - Trie *pTrie = GetMethodByIndex(pUser->auth.index); - if (pTrie) - { - sm_trie_delete(pTrie, m_pStrings->GetString(pUser->auth.identidx)); - } - } - - /* Clear table counts */ - pUser->grp_count = 0; - - /* Link into free list */ - pUser->magic = USR_MAGIC_UNSET; - pUser->next_user = m_FreeUserList; - m_FreeUserList = id; - - /* Unset serial change */ - pUser->serialchange = 0; - - return true; -} - - -void AdminCache::InvalidateGroup(GroupId id) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); - AdminGroup *pOther; - - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return; - } - - const char *str = m_pStrings->GetString(pGroup->nameidx); - sm_trie_delete(m_pGroups, str); - - /* Unlink from the live dbllink list */ - if (id == m_FirstGroup && id == m_LastGroup) - { - m_LastGroup = INVALID_GROUP_ID; - m_FirstGroup = INVALID_GROUP_ID; - } else if (id == m_FirstGroup) { - m_FirstGroup = pGroup->next_grp; - pOther = (AdminGroup *)m_pMemory->GetAddress(m_FirstGroup); - pOther->prev_grp = INVALID_GROUP_ID; - } else if (id == m_LastGroup) { - m_LastGroup = pGroup->prev_grp; - pOther = (AdminGroup *)m_pMemory->GetAddress(m_LastGroup); - pOther->next_grp = INVALID_GROUP_ID; - } else { - pOther = (AdminGroup *)m_pMemory->GetAddress(pGroup->prev_grp); - pOther->next_grp = pGroup->next_grp; - pOther = (AdminGroup *)m_pMemory->GetAddress(pGroup->next_grp); - pOther->prev_grp = pGroup->prev_grp; - } - - /* Free any used memory to be safe */ - if (pGroup->pCmdGrpTable) - { - sm_trie_destroy(pGroup->pCmdGrpTable); - pGroup->pCmdGrpTable = NULL; - } - if (pGroup->pCmdTable) - { - sm_trie_destroy(pGroup->pCmdTable); - pGroup->pCmdTable = NULL; - } - - /* Link into the free list */ - pGroup->magic = GRP_MAGIC_UNSET; - pGroup->next_grp = m_FreeGroupList; - m_FreeGroupList = id; - - int idx = m_FirstUser; - AdminUser *pUser; - int *table; - while (idx != INVALID_ADMIN_ID) - { - pUser = (AdminUser *)m_pMemory->GetAddress(idx); - if (pUser->grp_count > 0) - { - table = (int *)m_pMemory->GetAddress(pUser->grp_table); - for (unsigned int i=0; igrp_count; i++) - { - if (table[i] == id) - { - /* We have to remove this entry */ - for (unsigned int j=i+1; jgrp_count; j++) - { - /* Move everything down by one */ - table[j-1] = table[j]; - } - /* Decrease count */ - pUser->grp_count--; - /* Recalculate effective flags */ - pUser->eflags = pUser->flags; - for (unsigned int j=0; jgrp_count; j++) - { - pOther = (AdminGroup *)m_pMemory->GetAddress(table[j]); - pUser->eflags |= pOther->addflags; - } - /* Mark as changed */ - pUser->serialchange++; - /* Break now, duplicates aren't allowed */ - break; - } - } - } - idx = pUser->next_user; - } -} - -void AdminCache::InvalidateGroupCache() -{ - /* Nuke the free list */ - m_FreeGroupList = -1; - - /* Nuke reverse lookups */ - sm_trie_clear(m_pGroups); - - /* Free memory on groups */ - GroupId cur = m_FirstGroup; - AdminGroup *pGroup; - while (cur != INVALID_GROUP_ID) - { - pGroup = (AdminGroup *)m_pMemory->GetAddress(cur); - assert(pGroup->magic == GRP_MAGIC_SET); - if (pGroup->pCmdGrpTable) - { - sm_trie_destroy(pGroup->pCmdGrpTable); - } - if (pGroup->pCmdTable) - { - sm_trie_destroy(pGroup->pCmdTable); - } - cur = pGroup->next_grp; - } - - m_FirstGroup = INVALID_GROUP_ID; - m_LastGroup = INVALID_GROUP_ID; - - InvalidateAdminCache(false); - - /* Reset the memory table */ - m_pMemory->Reset(); -} - -void AdminCache::AddAdminListener(IAdminListener *pListener) -{ - m_hooks.push_back(pListener); -} - -void AdminCache::RemoveAdminListener(IAdminListener *pListener) -{ - m_hooks.remove(pListener); -} - -void AdminCache::RegisterAuthIdentType(const char *name) -{ - if (sm_trie_retrieve(m_pAuthTables, name, NULL)) - { - return; - } - - Trie *pAuth = sm_trie_create(); - - AuthMethod method; - method.name.assign(name); - method.table = pAuth; - - m_AuthMethods.push_back(method); - - sm_trie_insert(m_pAuthTables, name, pAuth); -} - -void AdminCache::InvalidateAdminCache(bool unlink_admins) -{ - m_InvalidatingAdmins = true; - if (!m_destroying) - { - g_Players.ClearAllAdmins(); - } - /* Wipe the identity cache first */ - List::iterator iter; - for (iter=m_AuthMethods.begin(); - iter!=m_AuthMethods.end(); - iter++) - { - sm_trie_clear((*iter).table); - } - - if (unlink_admins) - { - while (m_FirstUser != INVALID_ADMIN_ID) - { - InvalidateAdmin(m_FirstUser); - } - } else { - m_FirstUser = -1; - m_LastUser = -1; - m_FreeUserList = -1; - } - m_InvalidatingAdmins = false; -} - -void AdminCache::DumpAdminCache(AdminCachePart part, bool rebuild) -{ - List::iterator iter; - IAdminListener *pListener; - cell_t result; - - if (part == AdminCache_Overrides) - { - DumpCommandOverrideCache(Override_Command); - DumpCommandOverrideCache(Override_CommandGroup); - if (rebuild && !m_destroying) - { - for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++) - { - pListener = (*iter); - pListener->OnRebuildOverrideCache(); - } - m_pCacheFwd->PushCell(part); - m_pCacheFwd->Execute(&result); - } - } else if (part == AdminCache_Groups || part == AdminCache_Admins) { - if (part == AdminCache_Groups) - { - InvalidateGroupCache(); - if (rebuild && !m_destroying) - { - for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++) - { - pListener = (*iter); - pListener->OnRebuildGroupCache(); - } - m_pCacheFwd->PushCell(part); - m_pCacheFwd->Execute(&result); - } - } - InvalidateAdminCache(true); - if (rebuild && !m_destroying) - { - for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++) - { - pListener = (*iter); - pListener->OnRebuildAdminCache((part == AdminCache_Groups)); - } - m_pCacheFwd->PushCell(AdminCache_Admins); - m_pCacheFwd->Execute(&result); - g_Players.RecheckAnyAdmins(); - } - } -} - -const char *AdminCache::GetAdminName(AdminId id) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return NULL; - } - - return m_pStrings->GetString(pUser->nameidx); -} - -bool AdminCache::GetMethodIndex(const char *name, unsigned int *_index) -{ - List::iterator iter; - unsigned int index = 0; - for (iter=m_AuthMethods.begin(); - iter!=m_AuthMethods.end(); - iter++,index++) - { - if ((*iter).name.compare(name) == 0) - { - *_index = index; - return true; - } - } - - return false; -} - -bool AdminCache::BindAdminIdentity(AdminId id, const char *auth, const char *ident) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return false; - } - - Trie *pTable; - if (!sm_trie_retrieve(m_pAuthTables, auth, (void **)&pTable)) - { - return false; - } - - if (sm_trie_retrieve(pTable, ident, NULL)) - { - return false; - } - - int i_ident = m_pStrings->AddString(ident); - - pUser = (AdminUser *)m_pMemory->GetAddress(id); - pUser->auth.identidx = i_ident; - GetMethodIndex(auth, &pUser->auth.index); - - return sm_trie_insert(pTable, ident, (void **)id); -} - -AdminId AdminCache::FindAdminByIdentity(const char *auth, const char *identity) -{ - Trie *pTable; - if (!sm_trie_retrieve(m_pAuthTables, auth, (void **)&pTable)) - { - return INVALID_ADMIN_ID; - } - - void *object; - if (!sm_trie_retrieve(pTable, identity, &object)) - { - return INVALID_ADMIN_ID; - } - - return (AdminId)object; -} - -void AdminCache::SetAdminFlag(AdminId id, AdminFlag flag, bool enabled) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return; - } - - if (flag < Admin_Reservation - || flag >= AdminFlags_TOTAL) - { - return; - } - - FlagBits bits = (1<<(FlagBits)flag); - - if (enabled) - { - pUser->flags |= bits; - pUser->eflags |= bits; - } else { - pUser->flags &= ~bits; - pUser->eflags &= ~bits; - } - - pUser->serialchange++; -} - -bool AdminCache::GetAdminFlag(AdminId id, AdminFlag flag, AccessMode mode) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return false; - } - - if (flag < Admin_Reservation - || flag >= AdminFlags_TOTAL) - { - return false; - } - - FlagBits bit = (1<<(FlagBits)flag); - - if (mode == Access_Real) - { - return ((pUser->flags & bit) == bit); - } else if (mode == Access_Effective) { - bool has_bit = ((pUser->eflags & bit) == bit); - if (!has_bit && flag != Admin_Root && ((pUser->eflags & ADMFLAG_ROOT) == ADMFLAG_ROOT)) - { - has_bit = true; - } - return has_bit; - } - - return false; -} - -FlagBits AdminCache::GetAdminFlags(AdminId id, AccessMode mode) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return 0; - } - - if (mode == Access_Real) - { - return pUser->flags; - } else if (mode == Access_Effective) { - return pUser->eflags; - } - - return 0; -} - -void AdminCache::SetAdminFlags(AdminId id, AccessMode mode, FlagBits bits) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return; - } - - if (mode == Access_Real) - { - pUser->flags = bits; - pUser->eflags = bits; - } else if (mode == Access_Effective) { - pUser->eflags = bits; - } - - pUser->serialchange++; -} - -bool AdminCache::AdminInheritGroup(AdminId id, GroupId gid) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return false; - } - - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(gid); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return false; - } - - /* First check for duplicates */ - if (pUser->grp_count != 0) - { - int *temp_table = (int *)m_pMemory->GetAddress(pUser->grp_table); - for (unsigned int i=0; igrp_count; i++) - { - if (temp_table[i] == gid) - { - return false; - } - } - } - - int *table; - if (pUser->grp_count + 1 > pUser->grp_size) - { - int new_size = 0; - int tblidx; - - if (pUser->grp_size == 0) - { - new_size = 2; - } else { - new_size = pUser->grp_size * 2; - } - - /* Create and refresh pointers */ - tblidx = m_pMemory->CreateMem(new_size * sizeof(int), (void **)&table); - pUser = (AdminUser *)m_pMemory->GetAddress(id); - pGroup = (AdminGroup *)m_pMemory->GetAddress(gid); - - /* Copy old data if necessary */ - if (pUser->grp_table != -1) - { - int *old_table = (int *)m_pMemory->GetAddress(pUser->grp_table); - memcpy(table, old_table, sizeof(int) * pUser->grp_count); - } - pUser->grp_table = tblidx; - pUser->grp_size = new_size; - } else { - table = (int *)m_pMemory->GetAddress(pUser->grp_table); - } - - table[pUser->grp_count] = gid; - pUser->grp_count++; - - /* Compute new effective permissions */ - pUser->eflags |= pGroup->addflags; - - if (pGroup->immunity_level > pUser->immunity_level) - { - pUser->immunity_level = pGroup->immunity_level; - } - - pUser->serialchange++; - - return true; -} - -bool AdminCache::IsValidAdmin(AdminId id) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - return (pUser != NULL && pUser->magic == USR_MAGIC_SET); -} - -unsigned int AdminCache::GetAdminGroupCount(AdminId id) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return 0; - } - - return pUser->grp_count; -} - -GroupId AdminCache::GetAdminGroup(AdminId id, unsigned int index, const char **name) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET || index >= pUser->grp_count) - { - return INVALID_GROUP_ID; - } - - int *table = (int *)m_pMemory->GetAddress(pUser->grp_table); - - GroupId gid = table[index]; - - if (name) - { - *name = GetGroupName(gid); - } - - return gid; -} - -const char *AdminCache::GetAdminPassword(AdminId id) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return NULL; - } - - return m_pStrings->GetString(pUser->password); -} - -void AdminCache::SetAdminPassword(AdminId id, const char *password) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return; - } - - if (password[0] == '\0') - { - pUser->password = -1; - return; - } - - int i_password = m_pStrings->AddString(password); - pUser = (AdminUser *)m_pMemory->GetAddress(id); - pUser->password = i_password; -} - -unsigned int AdminCache::FlagBitsToBitArray(FlagBits bits, bool array[], unsigned int maxSize) -{ - unsigned int i; - for (i=0; iGetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return false; - } - - return ((pUser->eflags & bits) == bits); -} - -bool AdminCache::CanAdminTarget(AdminId id, AdminId target) -{ - /** - * Zeroth, if the targeting AdminId is INVALID_ADMIN_ID, targeting fails. - * First, if the targeted AdminId is INVALID_ADMIN_ID, targeting succeeds. - */ - - if (id == INVALID_ADMIN_ID) - { - return false; - } - - if (target == INVALID_ADMIN_ID) - { - return true; - } - - if (id == target) - { - return true; - } - - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return false; - } - - AdminUser *pTarget = (AdminUser *)m_pMemory->GetAddress(target); - if (!pTarget || pTarget->magic != USR_MAGIC_SET) - { - return false; - } - - /** - * Second, if the targeting admin is root, targeting succeeds. - */ - if (pUser->eflags & ADMFLAG_ROOT) - { - return true; - } - - /** Fourth, if the targeted admin is immune from targeting admin. */ - int mode = sm_immunity_mode.GetInt(); - switch (mode) - { - case 1: - { - if (pTarget->immunity_level > pUser->immunity_level) - { - return false; - } - break; - } - case 3: - { - /* If neither has any immunity, let this pass. */ - if (!pUser->immunity_level && !pTarget->immunity_level) - { - return true; - } - /* Don't break, go to the next case. */ - } - case 2: - { - if (pTarget->immunity_level >= pUser->immunity_level) - { - return false; - } - break; - } - } - - /** - * Fifth, if the targeted admin has specific immunity from the - * targeting admin via group immunities, targeting fails. - */ - //:TODO: speed this up... maybe with trie hacks. - //idea is to insert %d.%d in the trie after computing this and use it as a cache lookup. - //problem is the trie cannot delete prefixes, so we'd have a problem with invalidations. - if (pTarget->grp_count > 0 && pUser->grp_count > 0) - { - int *grp_table = (int *)m_pMemory->GetAddress(pTarget->grp_table); - int *src_table = (int *)m_pMemory->GetAddress(pUser->grp_table); - GroupId id, other; - unsigned int num; - for (unsigned int i=0; igrp_count; i++) - { - id = grp_table[i]; - num = GetGroupImmunityCount(id); - for (unsigned int j=0; jgrp_count; k++) - { - if (other == src_table[k]) - { - return false; - } - } - } - } - } - - return true; -} - -bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag) -{ - if (c < 'a' - || c > 'z' - || !g_FlagSet[(unsigned)c - (unsigned)'a']) - { - return false; - } - - if (pAdmFlag) - { - *pAdmFlag = g_FlagLetters[(unsigned)c - (unsigned)'a']; - } - - return true; -} - -bool AdminCache::FindFlagChar(AdminFlag flag, char *c) -{ - if (!g_FlagSet[flag]) - { - return false; - } - - if (c) - { - *c = g_ReverseFlags[flag]; - } - - return true; -} - -FlagBits AdminCache::ReadFlagString(const char *flags, const char **end) -{ - FlagBits bits = 0; - - while (flags && (*flags != '\0')) - { - AdminFlag flag; - if (!FindFlag(*flags, &flag)) - { - break; - } - bits |= FlagArrayToBits(&flag, 1); - flags++; - } - - if (end) - { - *end = flags; - } - - return bits; -} - -unsigned int AdminCache::GetAdminSerialChange(AdminId id) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return 0; - } - - return pUser->serialchange; -} - -bool AdminCache::CanAdminUseCommand(int client, const char *cmd) -{ - FlagBits bits; - OverrideType otype = Override_Command; - - if (cmd[0] == '@') - { - otype = Override_CommandGroup; - cmd++; - } - - if (!g_ConCmds.LookForCommandAdminFlags(cmd, &bits)) - { - if (!GetCommandOverride(cmd, otype, &bits)) - { - bits = 0; - } - } - - return g_ConCmds.CheckCommandAccess(client, cmd, bits); -} - -unsigned int AdminCache::SetGroupImmunityLevel(GroupId gid, unsigned int level) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(gid); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return 0; - } - - unsigned int old_level = pGroup->immunity_level; - - pGroup->immunity_level = level; - - return old_level; -} - -unsigned int AdminCache::GetGroupImmunityLevel(GroupId gid) -{ - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(gid); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return 0; - } - - return pGroup->immunity_level; -} - -unsigned int AdminCache::SetAdminImmunityLevel(AdminId id, unsigned int level) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return 0; - } - - unsigned int old_level = pUser->immunity_level; - - pUser->immunity_level = level; - - return old_level; -} - -unsigned int AdminCache::GetAdminImmunityLevel(AdminId id) -{ - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); - if (!pUser || pUser->magic != USR_MAGIC_SET) - { - return 0; - } - - return pUser->immunity_level; -} - -bool AdminCache::CheckAccess(int client, const char *cmd, FlagBits flags, bool override_only) -{ - if (client == 0) - { - return true; - } - - /* Auto-detect a command if we can */ - FlagBits bits = flags; - bool found_command = false; - if (!override_only) - { - found_command = g_ConCmds.LookForCommandAdminFlags(cmd, &bits); - } - - if (!found_command) - { - GetCommandOverride(cmd, Override_Command, &bits); - } - - return g_ConCmds.CheckCommandAccess(client, cmd, bits) ? 1 : 0; -} - -void iterator_glob_basic_override(Trie *pTrie, const char *key, void **value, void *data) -{ - FILE *fp; - int flags; - char flagstr[64]; - - fp = (FILE *)data; - flags = (int)*value; - g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr)); - - fprintf(fp, "\t\"%s\"\t\t\"%s\"\n", key, flagstr); -} - -void iterator_glob_grp_override(Trie *pTrie, const char *key, void **value, void *data) -{ - FILE *fp; - int flags; - char flagstr[64]; - - fp = (FILE *)data; - flags = (int)*value; - g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr)); - - fprintf(fp, "\t\"@%s\"\t\t\"%s\"\n", key, flagstr); -} - -void iterator_group_basic_override(Trie *pTrie, const char *key, void **value, void *data) -{ - FILE *fp; - int flags; - char flagstr[64]; - - fp = (FILE *)data; - flags = (int)*value; - g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr)); - - fprintf(fp, "\t\t\t\"%s\"\t\t\"%s\"\n", key, flagstr); -} - -void iterator_group_grp_override(Trie *pTrie, const char *key, void **value, void *data) -{ - FILE *fp; - int flags; - char flagstr[64]; - - fp = (FILE *)data; - flags = (int)*value; - g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr)); - - fprintf(fp, "\t\t\t\"@%s\"\t\t\"%s\"\n", key, flagstr); -} - -void AdminCache::DumpCache(FILE *fp) -{ - int *itable; - AdminId aid; - GroupId gid; - char flagstr[64]; - unsigned int num; - AdminUser *pAdmin; - AdminGroup *pGroup; - char name_buffer[512]; - - fprintf(fp, "\"Groups\"\n{\n"); - - num = 0; - gid = m_FirstGroup; - while (gid != INVALID_GROUP_ID - && (pGroup = GetGroup(gid)) != NULL) - { - num++; - FillFlagString(pGroup->addflags, flagstr, sizeof(flagstr)); - - fprintf(fp, "\t/* num = %d, gid = 0x%X */\n", num, gid); - fprintf(fp, "\t\"%s\"\n\t{\n", GetString(pGroup->nameidx)); - fprintf(fp, "\t\t\"flags\"\t\t\t\"%s\"\n", flagstr); - fprintf(fp, "\t\t\"immunity\"\t\t\"%d\"\n", pGroup->immunity_level); - - if (pGroup->immune_table != -1 - && (itable = (int *)m_pMemory->GetAddress(pGroup->immune_table)) != NULL) - { - AdminGroup *pAltGroup; - const char *gname, *mod; - - for (int i = 1; i <= itable[0]; i++) - { - if ((pAltGroup = GetGroup(itable[i])) == NULL) - { - /* Assume the rest of the table is corrupt */ - break; - } - gname = GetString(pAltGroup->nameidx); - if (atoi(gname) != 0) - { - mod = "@"; - } - else - { - mod = ""; - } - fprintf(fp, "\t\t\"immunity\"\t\t\"%s%s\"\n", mod, gname); - } - } - - fprintf(fp, "\n\t\t\"Overrides\"\n\t\t{\n"); - if (pGroup->pCmdGrpTable != NULL) - { - sm_trie_bad_iterator(pGroup->pCmdGrpTable, - name_buffer, - sizeof(name_buffer), - iterator_group_grp_override, - fp); - } - if (pGroup->pCmdTable != NULL) - { - sm_trie_bad_iterator(pGroup->pCmdTable, - name_buffer, - sizeof(name_buffer), - iterator_group_basic_override, - fp); - } - fprintf(fp, "\t\t}\n"); - - fprintf(fp, "\t}\n"); - - if ((gid = pGroup->next_grp) != INVALID_GROUP_ID) - { - fprintf(fp, "\n"); - } - } - - fprintf(fp, "}\n\n"); - fprintf(fp, "\"Admins\"\n{\n"); - - num = 0; - aid = m_FirstUser; - while (aid != INVALID_ADMIN_ID - && (pAdmin = GetUser(aid)) != NULL) - { - num++; - FillFlagString(pAdmin->flags, flagstr, sizeof(flagstr)); - - fprintf(fp, "\t/* num = %d, aid = 0x%X, serialno = 0x%X*/\n", num, aid, pAdmin->serialchange); - - if (pAdmin->nameidx != -1) - { - fprintf(fp, "\t\"%s\"\n\t{\n", GetString(pAdmin->nameidx)); - } - else - { - fprintf(fp, "\t\"\"\n\t{\n"); - } - - if (pAdmin->auth.identidx != -1) - { - fprintf(fp, "\t\t\"auth\"\t\t\t\"%s\"\n", GetMethodName(pAdmin->auth.index)); - fprintf(fp, "\t\t\"identity\"\t\t\"%s\"\n", GetString(pAdmin->auth.identidx)); - } - if (pAdmin->password != -1) - { - fprintf(fp, "\t\t\"password\"\t\t\"%s\"\n", GetString(pAdmin->password)); - } - fprintf(fp, "\t\t\"flags\"\t\t\t\"%s\"\n", flagstr); - fprintf(fp, "\t\t\"immunity\"\t\t\"%d\"\n", pAdmin->immunity_level); - - if (pAdmin->grp_count != 0 - && pAdmin->grp_table != -1 - && (itable = (int *)m_pMemory->GetAddress(pAdmin->grp_table)) != NULL) - { - unsigned int i; - - for (i = 0; i < pAdmin->grp_count; i++) - { - if ((pGroup = GetGroup(itable[i])) == NULL) - { - /* Assume the rest of the table is corrupt */ - break; - } - fprintf(fp, "\t\t\"group\"\t\t\t\"%s\"\n", GetString(pGroup->nameidx)); - } - } - - fprintf(fp, "\t}\n"); - - if ((aid = pAdmin->next_user) != INVALID_ADMIN_ID) - { - fprintf(fp, "\n"); - } - } - - fprintf(fp, "}\n\n"); - - fprintf(fp, "\"Overrides\"\n{\n"); - if (m_pCmdGrpOverrides != NULL) - { - sm_trie_bad_iterator(m_pCmdGrpOverrides, - name_buffer, - sizeof(name_buffer), - iterator_glob_grp_override, - fp); - } - if (m_pCmdOverrides != NULL) - { - sm_trie_bad_iterator(m_pCmdOverrides, - name_buffer, - sizeof(name_buffer), - iterator_glob_basic_override, - fp); - } - fprintf(fp, "}\n"); -} - -AdminGroup *AdminCache::GetGroup(GroupId gid) -{ - AdminGroup *pGroup; - - pGroup = (AdminGroup *)m_pMemory->GetAddress(gid); - if (!pGroup || pGroup->magic != GRP_MAGIC_SET) - { - return NULL; - } - - return pGroup; -} - -AdminUser *AdminCache::GetUser(AdminId aid) -{ - AdminUser *pAdmin; - - pAdmin = (AdminUser *)m_pMemory->GetAddress(aid); - if (!pAdmin || pAdmin->magic != USR_MAGIC_SET) - { - return NULL; - } - - return pAdmin; -} - -const char *AdminCache::GetMethodName(unsigned int index) -{ - List::iterator iter; - for (iter=m_AuthMethods.begin(); - iter!=m_AuthMethods.end(); - iter++) - { - if (index-- == 0) - { - return (*iter).name.c_str(); - } - } - - return NULL; -} - -const char *AdminCache::GetString(int idx) -{ - return m_pStrings->GetString(idx); -} - -size_t AdminCache::FillFlagString(FlagBits bits, char *buffer, size_t maxlen) -{ - size_t pos; - unsigned int i, num_flags; - AdminFlag flags[AdminFlags_TOTAL]; - - num_flags = FlagBitsToArray(bits, flags, AdminFlags_TOTAL); - - pos = 0; - for (i = 0; pos < maxlen && i < num_flags; i++) - { - if (FindFlagChar(flags[i], &buffer[pos])) - { - pos++; - } - } - buffer[pos] = '\0'; - - return pos; -} - -CON_COMMAND(sm_dump_admcache, "Dumps the admin cache for debugging") -{ - FILE *fp; - char buffer[PLATFORM_MAX_PATH]; - - g_SourceMod.BuildPath(Path_SM, buffer, sizeof(buffer), "data/admin_cache_dump.txt"); - - if ((fp = fopen(buffer, "wt")) == NULL) - { - g_RootMenu.ConsolePrint("Could not open file for writing: %s", buffer); - return; - } - - g_Admins.DumpCache(fp); - - g_RootMenu.ConsolePrint("Admin cache dumped to: %s", buffer); - - fclose(fp); -} diff --git a/core/AdminCache.h b/core/AdminCache.h deleted file mode 100644 index c7d21da1..00000000 --- a/core/AdminCache.h +++ /dev/null @@ -1,208 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_ADMINCACHE_H_ -#define _INCLUDE_SOURCEMOD_ADMINCACHE_H_ - -#include "sm_memtable.h" -#include -#include -#include -#include -#include "sm_globals.h" -#include - -using namespace SourceHook; - -#define GRP_MAGIC_SET 0xDEADFADE -#define GRP_MAGIC_UNSET 0xFACEFACE -#define USR_MAGIC_SET 0xDEADFACE -#define USR_MAGIC_UNSET 0xFADEDEAD - -struct AdminGroup -{ - uint32_t magic; /* Magic flag, for memory validation (ugh) */ - unsigned int immunity_level; /* Immunity level */ - /* Immune from target table (-1 = nonexistent) - * [0] = number of entries - * [1...N] = immune targets - */ - int immune_table; - Trie *pCmdTable; /* Command override table (can be NULL) */ - Trie *pCmdGrpTable; /* Command group override table (can be NULL) */ - int next_grp; /* Next group in the chain */ - int prev_grp; /* Previous group in the chain */ - int nameidx; /* Name */ - FlagBits addflags; /* Additive flags */ -}; - -struct AuthMethod -{ - String name; - Trie *table; -}; - -struct UserAuth -{ - unsigned int index; /* Index into auth table */ - int identidx; /* Index into the string table */ -}; - -struct AdminUser -{ - uint32_t magic; /* Magic flag, for memory validation */ - FlagBits flags; /* Flags */ - FlagBits eflags; /* Effective flags */ - int nameidx; /* Name index */ - int password; /* Password index */ - unsigned int grp_count; /* Number of groups */ - unsigned int grp_size; /* Size of groups table */ - int grp_table; /* Group table itself */ - int next_user; /* Next user in the list */ - int prev_user; /* Previous user in the list */ - UserAuth auth; /* Auth method for this user */ - unsigned int immunity_level; /* Immunity level */ - unsigned int serialchange; /* Serial # for changes */ -}; - -class AdminCache : - public IAdminSystem, - public SMGlobalClass -{ -public: - AdminCache(); - ~AdminCache(); -public: //SMGlobalClass - void OnSourceModStartup(bool late); - void OnSourceModAllInitialized(); - void OnSourceModLevelChange(const char *mapName); - void OnSourceModShutdown(); - void OnSourceModPluginsLoaded(); -public: //IAdminSystem - /** Command cache stuff */ - void AddCommandOverride(const char *cmd, OverrideType type, FlagBits flags); - bool GetCommandOverride(const char *cmd, OverrideType type, FlagBits *flags); - void UnsetCommandOverride(const char *cmd, OverrideType type); - /** Group cache stuff */ - GroupId AddGroup(const char *group_name); - GroupId FindGroupByName(const char *group_name); - void SetGroupAddFlag(GroupId id, AdminFlag flag, bool enabled); - bool GetGroupAddFlag(GroupId id, AdminFlag flag); - FlagBits GetGroupAddFlags(GroupId id); - void SetGroupGenericImmunity(GroupId id, ImmunityType type, bool enabled); - bool GetGroupGenericImmunity(GroupId id, ImmunityType type); - void InvalidateGroup(GroupId id); - void AddGroupImmunity(GroupId id, GroupId other_id); - unsigned int GetGroupImmunityCount(GroupId id); - GroupId GetGroupImmunity(GroupId id, unsigned int number); - void AddGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule rule); - bool GetGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule *pRule); - void DumpAdminCache(AdminCachePart part, bool rebuild); - void AddAdminListener(IAdminListener *pListener); - void RemoveAdminListener(IAdminListener *pListener); - /** User stuff */ - void RegisterAuthIdentType(const char *name); - AdminId CreateAdmin(const char *name); - const char *GetAdminName(AdminId id); - bool BindAdminIdentity(AdminId id, const char *auth, const char *ident); - virtual void SetAdminFlag(AdminId id, AdminFlag flag, bool enabled); - bool GetAdminFlag(AdminId id, AdminFlag flag, AccessMode mode); - FlagBits GetAdminFlags(AdminId id, AccessMode mode); - bool AdminInheritGroup(AdminId id, GroupId gid); - unsigned int GetAdminGroupCount(AdminId id); - GroupId GetAdminGroup(AdminId id, unsigned int index, const char **name); - void SetAdminPassword(AdminId id, const char *password); - const char *GetAdminPassword(AdminId id); - AdminId FindAdminByIdentity(const char *auth, const char *identity); - bool InvalidateAdmin(AdminId id); - unsigned int FlagBitsToBitArray(FlagBits bits, bool array[], unsigned int maxSize); - FlagBits FlagBitArrayToBits(const bool array[], unsigned int maxSize); - FlagBits FlagArrayToBits(const AdminFlag array[], unsigned int numFlags); - unsigned int FlagBitsToArray(FlagBits bits, AdminFlag array[], unsigned int maxSize); - bool CheckAdminFlags(AdminId id, FlagBits bits); - bool CanAdminTarget(AdminId id, AdminId target); - void SetAdminFlags(AdminId id, AccessMode mode, FlagBits bits); - bool FindFlag(const char *str, AdminFlag *pFlag); - bool FindFlag(char c, AdminFlag *pAdmFlag); - FlagBits ReadFlagString(const char *flags, const char **end); - size_t FillFlagString(FlagBits bits, char *buffer, size_t maxlen); - unsigned int GetAdminSerialChange(AdminId id); - bool CanAdminUseCommand(int client, const char *cmd); - const char *GetGroupName(GroupId gid); - unsigned int SetGroupImmunityLevel(GroupId gid, unsigned int level); - unsigned int GetGroupImmunityLevel(GroupId gid); - unsigned int SetAdminImmunityLevel(AdminId id, unsigned int level); - unsigned int GetAdminImmunityLevel(AdminId id); - bool CheckAccess(int client, - const char *cmd, - FlagBits flags, - bool override_only); - bool FindFlagChar(AdminFlag flag, char *c); -public: - bool IsValidAdmin(AdminId id); - void DumpCache(FILE *fp); - AdminGroup *GetGroup(GroupId gid); - AdminUser *GetUser(AdminId id); - const char *GetString(int idx); -private: - void _UnsetCommandOverride(const char *cmd); - void _UnsetCommandGroupOverride(const char *group); - void InvalidateGroupCache(); - void InvalidateAdminCache(bool unlink_admins); - void DumpCommandOverrideCache(OverrideType type); - Trie *GetMethodByIndex(unsigned int index); - bool GetMethodIndex(const char *name, unsigned int *_index); - const char *GetMethodName(unsigned int index); - void NameFlag(const char *str, AdminFlag flag); -public: - BaseStringTable *m_pStrings; - BaseMemTable *m_pMemory; - Trie *m_pCmdOverrides; - Trie *m_pCmdGrpOverrides; - int m_FirstGroup; - int m_LastGroup; - int m_FreeGroupList; - Trie *m_pGroups; - List m_hooks; - List m_AuthMethods; - Trie *m_pAuthTables; - IForward *m_pCacheFwd; - int m_FirstUser; - int m_LastUser; - int m_FreeUserList; - bool m_InvalidatingAdmins; - bool m_destroying; - Trie *m_pLevelNames; -}; - -extern AdminCache g_Admins; - -#endif //_INCLUDE_SOURCEMOD_ADMINCACHE_H_ diff --git a/core/CDataPack.cpp b/core/CDataPack.cpp deleted file mode 100644 index 99d15694..00000000 --- a/core/CDataPack.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include -#include "CDataPack.h" - -#define DATAPACK_INITIAL_SIZE 512 - -CDataPack::CDataPack() -{ - m_pBase = (char *)malloc(DATAPACK_INITIAL_SIZE); - m_capacity = DATAPACK_INITIAL_SIZE; - Initialize(); -} - -CDataPack::~CDataPack() -{ - free(m_pBase); -} - -void CDataPack::Initialize() -{ - m_curptr = m_pBase; - m_size = 0; -} - -void CDataPack::CheckSize(size_t typesize) -{ - if (m_curptr - m_pBase + typesize <= m_capacity) - { - return; - } - - size_t pos = m_curptr - m_pBase; - do - { - m_capacity *= 2; - m_pBase = (char *)realloc(m_pBase, m_capacity); - m_curptr = m_pBase + pos; - } while (m_curptr - m_pBase + typesize > m_capacity); -} - -void CDataPack::ResetSize() -{ - m_size = 0; -} - -size_t CDataPack::CreateMemory(size_t size, void **addr) -{ - CheckSize(sizeof(size_t) + size); - size_t pos = m_curptr - m_pBase; - - *(size_t *)m_curptr = size; - m_curptr += sizeof(size_t); - - if (addr) - { - *addr = m_curptr; - } - - m_curptr += size; - m_size += sizeof(size_t) + size; - - return pos; -} - -void CDataPack::PackCell(cell_t cell) -{ - CheckSize(sizeof(size_t) + sizeof(cell_t)); - - *(size_t *)m_curptr = sizeof(cell_t); - m_curptr += sizeof(size_t); - - *(cell_t *)m_curptr = cell; - m_curptr += sizeof(cell_t); - - m_size += sizeof(size_t) + sizeof(cell_t); -} - -void CDataPack::PackFloat(float val) -{ - CheckSize(sizeof(size_t) + sizeof(float)); - - *(size_t *)m_curptr = sizeof(float); - m_curptr += sizeof(size_t); - - *(float *)m_curptr = val; - m_curptr += sizeof(float); - - m_size += sizeof(size_t) + sizeof(float); -} - -void CDataPack::PackString(const char *string) -{ - size_t len = strlen(string); - size_t maxsize = sizeof(size_t) + len + 1; - CheckSize(maxsize); - - // Pack the string length first for buffer overrun checking. - *(size_t *)m_curptr = len; - m_curptr += sizeof(size_t); - - // Now pack the string. - memcpy(m_curptr, string, len); - m_curptr[len] = '\0'; - m_curptr += len + 1; - - m_size += maxsize; -} - -void CDataPack::Reset() const -{ - m_curptr = m_pBase; -} - -size_t CDataPack::GetPosition() const -{ - return static_cast(m_curptr - m_pBase); -} - -bool CDataPack::SetPosition(size_t pos) const -{ - if (pos > m_size-1) - { - return false; - } - m_curptr = m_pBase + pos; - - return true; -} - -cell_t CDataPack::ReadCell() const -{ - if (!IsReadable(sizeof(size_t) + sizeof(cell_t))) - { - return 0; - } - if (*reinterpret_cast(m_curptr) != sizeof(cell_t)) - { - return 0; - } - - m_curptr += sizeof(size_t); - - cell_t val = *reinterpret_cast(m_curptr); - m_curptr += sizeof(cell_t); - return val; -} - -float CDataPack::ReadFloat() const -{ - if (!IsReadable(sizeof(size_t) + sizeof(float))) - { - return 0; - } - if (*reinterpret_cast(m_curptr) != sizeof(float)) - { - return 0; - } - - m_curptr += sizeof(size_t); - - float val = *reinterpret_cast(m_curptr); - m_curptr += sizeof(float); - return val; -} - -bool CDataPack::IsReadable(size_t bytes) const -{ - return (bytes + (m_curptr - m_pBase) > m_size) ? false : true; -} - -const char *CDataPack::ReadString(size_t *len) const -{ - if (!IsReadable(sizeof(size_t))) - { - return NULL; - } - - size_t real_len = *(size_t *)m_curptr; - - m_curptr += sizeof(size_t); - char *str = (char *)m_curptr; - - if ((strlen(str) != real_len) || !(IsReadable(real_len+1))) - { - return NULL; - } - - if (len) - { - *len = real_len; - } - - m_curptr += real_len + 1; - - return str; -} - -void *CDataPack::GetMemory() const -{ - return m_curptr; -} - -void *CDataPack::ReadMemory(size_t *size) const -{ - if (!IsReadable(sizeof(size_t))) - { - return NULL; - } - - size_t bytecount = *(size_t *)m_curptr; - m_curptr += sizeof(size_t); - - if (!IsReadable(bytecount)) - { - return NULL; - } - - void *ptr = m_curptr; - - if (size) - { - *size = bytecount; - } - - m_curptr += bytecount; - - return ptr; -} diff --git a/core/CDataPack.h b/core/CDataPack.h deleted file mode 100644 index 83a53539..00000000 --- a/core/CDataPack.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_CDATAPACK_H_ -#define _INCLUDE_SOURCEMOD_CDATAPACK_H_ - -#include - -using namespace SourceMod; - -class CDataPack : public IDataPack -{ -public: - CDataPack(); - ~CDataPack(); -public: //IDataReader - void Reset() const; - size_t GetPosition() const; - bool SetPosition(size_t pos) const; - cell_t ReadCell() const; - float ReadFloat() const; - bool IsReadable(size_t bytes) const; - const char *ReadString(size_t *len) const; - void *GetMemory() const; - void *ReadMemory(size_t *size) const; -public: //IDataPack - void ResetSize(); - void PackCell(cell_t cell); - void PackFloat(float val); - void PackString(const char *string); - size_t CreateMemory(size_t size, void **addr); -public: - void Initialize(); -private: - void CheckSize(size_t sizetype); -private: - char *m_pBase; - mutable char *m_curptr; - size_t m_capacity; - size_t m_size; -}; - -#endif //_INCLUDE_SOURCEMOD_CDATAPACK_H_ diff --git a/core/CellArray.h b/core/CellArray.h deleted file mode 100644 index c5ec78b0..00000000 --- a/core/CellArray.h +++ /dev/null @@ -1,206 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include - -extern HandleType_t htCellArray; - -class CellArray -{ -public: - CellArray(size_t blocksize) : m_Data(NULL), m_BlockSize(blocksize), m_AllocSize(0), m_Size(0) - { - } - - ~CellArray() - { - free(m_Data); - } - - size_t size() const - { - return m_Size; - } - - cell_t *push() - { - if (!GrowIfNeeded(1)) - { - return NULL; - } - cell_t *arr = &m_Data[m_Size * m_BlockSize]; - m_Size++; - return arr; - } - - cell_t *at(size_t b) const - { - return &m_Data[b * m_BlockSize]; - } - - size_t blocksize() const - { - return m_BlockSize; - } - - void clear() - { - m_Size = 0; - } - - bool swap(size_t item1, size_t item2) - { - /* Make sure there is extra space available */ - if (!GrowIfNeeded(1)) - { - return false; - } - - cell_t *pri = at(item1); - cell_t *alt = at(item2); - - /* Get our temporary array 1 after the limit */ - cell_t *temp = &m_Data[m_Size * m_BlockSize]; - - memcpy(temp, pri, sizeof(cell_t) * m_BlockSize); - memcpy(pri, alt, sizeof(cell_t) * m_BlockSize); - memcpy(alt, temp, sizeof(cell_t) * m_BlockSize); - - return true; - } - - void remove(size_t index) - { - /* If we're at the end, take the easy way out */ - if (index == m_Size - 1) - { - m_Size--; - return; - } - - /* Otherwise, it's time to move stuff! */ - size_t remaining_indexes = (m_Size - 1) - index; - cell_t *src = at(index + 1); - cell_t *dest = at(index); - memmove(dest, src, sizeof(cell_t) * m_BlockSize * remaining_indexes); - - m_Size--; - } - - cell_t *insert_at(size_t index) - { - /* Make sure it'll fit */ - if (!GrowIfNeeded(1)) - { - return NULL; - } - - /* move everything up */ - cell_t *src = at(index); - cell_t *dst = at(index + 1); - memmove(dst, src, sizeof(cell_t) * m_BlockSize * (m_Size-index)); - - m_Size++; - - return src; - } - - bool resize(size_t count) - { - if (count <= m_Size) - { - m_Size = count; - return true; - } - - if (!GrowIfNeeded(count - m_Size)) - { - return false; - } - - m_Size = count; - return true; - } - - CellArray *clone() - { - CellArray *array = new CellArray(m_BlockSize); - array->m_AllocSize = m_AllocSize; - array->m_Size = m_Size; - array->m_Data = (cell_t *)malloc(sizeof(cell_t) * m_BlockSize * m_AllocSize); - memcpy(array->m_Data, m_Data, sizeof(cell_t) * m_BlockSize * m_Size); - return array; - } - - cell_t *base() - { - return m_Data; - } - - size_t mem_usage() - { - return m_AllocSize * m_BlockSize * sizeof(cell_t); - } - -private: - bool GrowIfNeeded(size_t count) - { - /* Shortcut out if we can store this */ - if (m_Size + count <= m_AllocSize) - { - return true; - } - /* Set a base allocation size of 8 items */ - if (!m_AllocSize) - { - m_AllocSize = 8; - } - /* If it's not enough, keep doubling */ - while (m_Size + count > m_AllocSize) - { - m_AllocSize *= 2; - } - /* finally, allocate the new block */ - if (m_Data) - { - m_Data = (cell_t *)realloc(m_Data, sizeof(cell_t) * m_BlockSize * m_AllocSize); - } else { - m_Data = (cell_t *)malloc(sizeof(cell_t) * m_BlockSize * m_AllocSize); - } - return (m_Data != NULL); - } -private: - cell_t *m_Data; - size_t m_BlockSize; - size_t m_AllocSize; - size_t m_Size; -}; diff --git a/core/CellRecipientFilter.h b/core/CellRecipientFilter.h deleted file mode 100644 index e7dcddee..00000000 --- a/core/CellRecipientFilter.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_CELLRECIPIENTFILTER_H_ -#define _INCLUDE_SOURCEMOD_CELLRECIPIENTFILTER_H_ - -#include -#include - -class CellRecipientFilter : public IRecipientFilter -{ -public: - CellRecipientFilter() : m_IsReliable(false), m_IsInitMessage(false), m_Size(0) {} - ~CellRecipientFilter() {} -public: //IRecipientFilter - bool IsReliable() const; - bool IsInitMessage() const; - int GetRecipientCount() const; - int GetRecipientIndex(int slot) const; -public: - void Initialize(const cell_t *ptr, size_t count); - void SetToReliable(bool isreliable); - void SetToInit(bool isinitmsg); - void Reset(); -private: - cell_t m_Players[255]; - bool m_IsReliable; - bool m_IsInitMessage; - size_t m_Size; -}; - -inline void CellRecipientFilter::Reset() -{ - m_IsReliable = false; - m_IsInitMessage = false; - m_Size = 0; -} - -inline bool CellRecipientFilter::IsReliable() const -{ - return m_IsReliable; -} - -inline bool CellRecipientFilter::IsInitMessage() const -{ - return m_IsInitMessage; -} - -inline int CellRecipientFilter::GetRecipientCount() const -{ - return m_Size; -} - -inline int CellRecipientFilter::GetRecipientIndex(int slot) const -{ - if ((slot < 0) || (slot >= GetRecipientCount())) - { - return -1; - } - return static_cast(m_Players[slot]); -} - -inline void CellRecipientFilter::SetToInit(bool isinitmsg) -{ - m_IsInitMessage = isinitmsg; -} - -inline void CellRecipientFilter::SetToReliable(bool isreliable) -{ - m_IsReliable = isreliable; -} - -inline void CellRecipientFilter::Initialize(const cell_t *ptr, size_t count) -{ - memcpy(m_Players, ptr, count * sizeof(cell_t)); - m_Size = count; -} - -#endif //_INCLUDE_SOURCEMOD_CELLRECIPIENTFILTER_H_ diff --git a/core/ChatTriggers.cpp b/core/ChatTriggers.cpp deleted file mode 100644 index d2491cc2..00000000 --- a/core/ChatTriggers.cpp +++ /dev/null @@ -1,450 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include "ChatTriggers.h" -#include "sm_stringutil.h" -#include "ConCmdManager.h" -#include "PlayerManager.h" -#include "Translator.h" -#include "HalfLife2.h" - -/* :HACKHACK: We can't SH_DECL here because ConCmdManager.cpp does. - * While the OB build only runs on MM:S 1.6.0+ (SH 5+), the older one - * can technically be compiled against any MM:S version after 1.4.2. - */ -#if defined ORANGEBOX_BUILD -extern bool __SourceHook_FHRemoveConCommandDispatch(void *, bool, class fastdelegate::FastDelegate1); -extern int __SourceHook_FHAddConCommandDispatch(void *, ISourceHook::AddHookMode, bool, class fastdelegate::FastDelegate1); -#else -extern bool __SourceHook_FHRemoveConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0); -#if SH_IMPL_VERSION >= 5 -extern int __SourceHook_FHAddConCommandDispatch(void *, ISourceHook::AddHookMode, bool, class fastdelegate::FastDelegate0); -#elif SH_IMPL_VERSION == 4 -extern int __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0); -#elif SH_IMPL_VERSION == 3 -extern bool __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0); -#endif //SH_IMPL_VERSION -#endif //ORANGEBOX_BUILD - -ChatTriggers g_ChatTriggers; -bool g_bSupressSilentFails = false; -CPhraseFile *g_pFloodPhrases = NULL; - -ChatTriggers::ChatTriggers() : m_pSayCmd(NULL), m_bWillProcessInPost(false), - m_bTriggerWasSilent(false), m_ReplyTo(SM_REPLY_CONSOLE) -{ - m_PubTrigger = sm_strdup("!"); - m_PrivTrigger = sm_strdup("/"); - m_PubTriggerSize = 1; - m_PrivTriggerSize = 1; - m_bIsChatTrigger = false; -} - -ChatTriggers::~ChatTriggers() -{ - delete [] m_PubTrigger; - m_PubTrigger = NULL; - delete [] m_PrivTrigger; - m_PrivTrigger = NULL; -} - -ConfigResult ChatTriggers::OnSourceModConfigChanged(const char *key, - const char *value, - ConfigSource source, - char *error, - size_t maxlength) -{ - if (strcmp(key, "PublicChatTrigger") == 0) - { - delete [] m_PubTrigger; - m_PubTrigger = sm_strdup(value); - m_PubTriggerSize = strlen(m_PubTrigger); - return ConfigResult_Accept; - } - else if (strcmp(key, "SilentChatTrigger") == 0) - { - delete [] m_PrivTrigger; - m_PrivTrigger = sm_strdup(value); - m_PrivTriggerSize = strlen(m_PrivTrigger); - return ConfigResult_Accept; - } - else if (strcmp(key, "SilentFailSuppress") == 0) - { - g_bSupressSilentFails = strcmp(value, "yes") == 0; - return ConfigResult_Accept; - } - - return ConfigResult_Ignore; -} - -void ChatTriggers::OnSourceModAllInitialized() -{ - m_pShouldFloodBlock = g_Forwards.CreateForward("OnClientFloodCheck", ET_Event, 1, NULL, Param_Cell); - m_pDidFloodBlock = g_Forwards.CreateForward("OnClientFloodResult", ET_Event, 2, NULL, Param_Cell, Param_Cell); -} - -void ChatTriggers::OnSourceModAllInitialized_Post() -{ - unsigned int file_id; - - file_id = g_Translator.FindOrAddPhraseFile("antiflood.phrases.txt"); - g_pFloodPhrases = g_Translator.GetFileByIndex(file_id); -} - -void ChatTriggers::OnSourceModGameInitialized() -{ - unsigned int total = 2; - ConCommandBase *pCmd = icvar->GetCommands(); - const char *name; - while (pCmd) - { - if (pCmd->IsCommand()) - { - name = pCmd->GetName(); - if (!m_pSayCmd && strcmp(name, "say") == 0) - { - m_pSayCmd = (ConCommand *)pCmd; - if (--total == 0) - { - break; - } - } else if (!m_pSayTeamCmd && strcmp(name, "say_team") == 0) { - m_pSayTeamCmd = (ConCommand *)pCmd; - if (--total == 0) - { - break; - } - } - } - pCmd = const_cast(pCmd->GetNext()); - } - - if (m_pSayCmd) - { - SH_ADD_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayCmd, this, &ChatTriggers::OnSayCommand_Pre, false); - SH_ADD_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayCmd, this, &ChatTriggers::OnSayCommand_Post, true); - } - if (m_pSayTeamCmd) - { - SH_ADD_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayTeamCmd, this, &ChatTriggers::OnSayCommand_Pre, false); - SH_ADD_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayTeamCmd, this, &ChatTriggers::OnSayCommand_Post, true); - } -} - -void ChatTriggers::OnSourceModShutdown() -{ - if (m_pSayTeamCmd) - { - SH_REMOVE_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayTeamCmd, this, &ChatTriggers::OnSayCommand_Post, true); - SH_REMOVE_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayTeamCmd, this, &ChatTriggers::OnSayCommand_Pre, false); - } - if (m_pSayCmd) - { - SH_REMOVE_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayCmd, this, &ChatTriggers::OnSayCommand_Post, true); - SH_REMOVE_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayCmd, this, &ChatTriggers::OnSayCommand_Pre, false); - } - - g_Forwards.ReleaseForward(m_pShouldFloodBlock); - g_Forwards.ReleaseForward(m_pDidFloodBlock); -} - -#if defined ORANGEBOX_BUILD -void ChatTriggers::OnSayCommand_Pre(const CCommand &command) -{ -#else -void ChatTriggers::OnSayCommand_Pre() -{ - CCommand command; -#endif - int client; - CPlayer *pPlayer; - - client = g_ConCmds.GetCommandClient(); - m_bIsChatTrigger = false; - m_bWasFloodedMessage = false; - - /* The server console cannot do this */ - if (client == 0 || (pPlayer = g_Players.GetPlayerByIndex(client)) == NULL) - { - RETURN_META(MRES_IGNORED); - } - - /* We guarantee the client is connected */ - if (!pPlayer->IsConnected()) - { - RETURN_META(MRES_IGNORED); - } - - const char *args = command.ArgS(); - - if (!args) - { - RETURN_META(MRES_IGNORED); - } - - /* Check if we need to block this message from being sent */ - if (ClientIsFlooding(client)) - { - char buffer[128]; - - if (!CoreTranslate( - buffer, - sizeof(buffer), - "%T", - 2, - NULL, - "Flooding the server", - &client)) - { - UTIL_Format(buffer, sizeof(buffer), "You are flooding the server!"); - } - - /* :TODO: we should probably kick people who spam too much. */ - - char fullbuffer[192]; - UTIL_Format(fullbuffer, sizeof(fullbuffer), "[SM] %s", buffer); - g_HL2.TextMsg(client, HUD_PRINTTALK, fullbuffer); - - m_bWasFloodedMessage = true; - - RETURN_META(MRES_SUPERCEDE); - } - - /* Handle quoted string sets */ - bool is_quoted = false; - if (args[0] == '"') - { - args++; - is_quoted = true; - } - - bool is_trigger = false; - bool is_silent = false; - - /* Check for either trigger */ - if (m_PubTriggerSize && strncmp(args, m_PubTrigger, m_PubTriggerSize) == 0) - { - is_trigger = true; - args = &args[m_PubTriggerSize]; - } - else if (m_PrivTriggerSize && strncmp(args, m_PrivTrigger, m_PrivTriggerSize) == 0) - { - is_trigger = true; - is_silent = true; - args = &args[m_PrivTriggerSize]; - } - - if (!is_trigger) - { - RETURN_META(MRES_IGNORED); - } - - /** - * Test if this is actually a command! - */ - if (!PreProcessTrigger(engine->PEntityOfEntIndex(client), args, is_quoted)) - { - CPlayer *pPlayer; - if (is_silent - && g_bSupressSilentFails - && client != 0 - && (pPlayer = g_Players.GetPlayerByIndex(client)) != NULL - && pPlayer->GetAdminId() != INVALID_ADMIN_ID) - { - RETURN_META(MRES_SUPERCEDE); - } - RETURN_META(MRES_IGNORED); - } - - m_bIsChatTrigger = true; - - /** - * We'll execute it in post. - */ - m_bWillProcessInPost = true; - m_bTriggerWasSilent = is_silent; - - /* If we're silent, block */ - if (is_silent) - { - RETURN_META(MRES_SUPERCEDE); - } - - /* Otherwise, let the command continue */ - RETURN_META(MRES_IGNORED); -} - -#if defined ORANGEBOX_BUILD -void ChatTriggers::OnSayCommand_Post(const CCommand &command) -#else -void ChatTriggers::OnSayCommand_Post() -#endif -{ - m_bIsChatTrigger = false; - m_bWasFloodedMessage = false; - if (m_bWillProcessInPost) - { - /* Reset this for re-entrancy */ - m_bWillProcessInPost = false; - - /* Execute the cached command */ - int client = g_ConCmds.GetCommandClient(); - unsigned int old = SetReplyTo(SM_REPLY_CHAT); - serverpluginhelpers->ClientCommand(engine->PEntityOfEntIndex(client), m_ToExecute); - SetReplyTo(old); - } -} - -bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args, bool is_quoted) -{ - /* Extract a command. This is kind of sloppy. */ - char cmd_buf[64]; - size_t cmd_len = 0; - const char *inptr = args; - while (*inptr != '\0' - && !textparsers->IsWhitespace(inptr) - && *inptr != '"' - && cmd_len < sizeof(cmd_buf) - 1) - { - cmd_buf[cmd_len++] = *inptr++; - } - cmd_buf[cmd_len] = '\0'; - - if (cmd_len == 0) - { - return false; - } - - /* See if we have this registered */ - bool prepended = false; - if (!g_ConCmds.LookForSourceModCommand(cmd_buf)) - { - /* Check if we had an "sm_" prefix */ - if (strncmp(cmd_buf, "sm_", 3) == 0) - { - return false; - } - - /* Now, prepend. Don't worry about the buffers. This will - * work because the sizes are limited from earlier. - */ - char new_buf[80]; - strcpy(new_buf, "sm_"); - strncopy(&new_buf[3], cmd_buf, sizeof(new_buf)-3); - - /* Recheck */ - if (!g_ConCmds.LookForSourceModCommand(new_buf)) - { - return false; - } - - prepended = true; - } - - /* See if we need to do extra string manipulation */ - if (is_quoted || prepended) - { - size_t len; - - /* Check if we need to prepend sm_ */ - if (prepended) - { - len = UTIL_Format(m_ToExecute, sizeof(m_ToExecute), "sm_%s", args); - } else { - len = strncopy(m_ToExecute, args, sizeof(m_ToExecute)); - } - - /* Check if we need to strip a quote */ - if (is_quoted) - { - if (m_ToExecute[len-1] == '"') - { - m_ToExecute[--len] = '\0'; - } - } - } else { - strncopy(m_ToExecute, args, sizeof(m_ToExecute)); - } - - return true; -} - -unsigned int ChatTriggers::SetReplyTo(unsigned int reply) -{ - unsigned int old = m_ReplyTo; - - m_ReplyTo = reply; - - return old; -} - -unsigned int ChatTriggers::GetReplyTo() -{ - return m_ReplyTo; -} - -bool ChatTriggers::IsChatTrigger() -{ - return m_bIsChatTrigger; -} - -bool ChatTriggers::ClientIsFlooding(int client) -{ - bool is_flooding = false; - - if (m_pShouldFloodBlock->GetFunctionCount() != 0) - { - cell_t res = 0; - - m_pShouldFloodBlock->PushCell(client); - m_pShouldFloodBlock->Execute(&res); - - if (res != 0) - { - is_flooding = true; - } - } - - if (m_pDidFloodBlock->GetFunctionCount() != 0) - { - m_pDidFloodBlock->PushCell(client); - m_pDidFloodBlock->PushCell(is_flooding ? 1 : 0); - m_pDidFloodBlock->Execute(NULL); - } - - return is_flooding; -} - -bool ChatTriggers::WasFloodedMessage() -{ - return m_bWasFloodedMessage; -} diff --git a/core/ChatTriggers.h b/core/ChatTriggers.h deleted file mode 100644 index c003f997..00000000 --- a/core/ChatTriggers.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_CHAT_TRIGGERS_H_ -#define _INCLUDE_SOURCEMOD_CHAT_TRIGGERS_H_ - -#include "sm_globals.h" -#include "sourcemm_api.h" -#include -#include -#include - -class ChatTriggers : public SMGlobalClass -{ -public: - ChatTriggers(); - ~ChatTriggers(); -public: //SMGlobalClass - void OnSourceModAllInitialized(); - void OnSourceModAllInitialized_Post(); - void OnSourceModGameInitialized(); - void OnSourceModShutdown(); - ConfigResult OnSourceModConfigChanged(const char *key, - const char *value, - ConfigSource source, - char *error, - size_t maxlength); -private: //ConCommand -#if defined ORANGEBOX_BUILD - void OnSayCommand_Pre(const CCommand &command); - void OnSayCommand_Post(const CCommand &command); -#else - void OnSayCommand_Pre(); - void OnSayCommand_Post(); -#endif -public: - unsigned int GetReplyTo(); - unsigned int SetReplyTo(unsigned int reply); - bool IsChatTrigger(); - bool WasFloodedMessage(); -private: - bool PreProcessTrigger(edict_t *pEdict, const char *args, bool is_quoted); - bool ClientIsFlooding(int client); -private: - ConCommand *m_pSayCmd; - ConCommand *m_pSayTeamCmd; - char *m_PubTrigger; - size_t m_PubTriggerSize; - char *m_PrivTrigger; - size_t m_PrivTriggerSize; - bool m_bWillProcessInPost; - bool m_bTriggerWasSilent; - bool m_bIsChatTrigger; - bool m_bWasFloodedMessage; - unsigned int m_ReplyTo; - char m_ToExecute[300]; - IForward *m_pShouldFloodBlock; - IForward *m_pDidFloodBlock; -}; - -extern ChatTriggers g_ChatTriggers; - -#endif //_INCLUDE_SOURCEMOD_CHAT_TRIGGERS_H_ diff --git a/core/ConCmdManager.cpp b/core/ConCmdManager.cpp deleted file mode 100644 index 562936a7..00000000 --- a/core/ConCmdManager.cpp +++ /dev/null @@ -1,991 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "ConCmdManager.h" -#include "sm_srvcmds.h" -#include "AdminCache.h" -#include "sm_stringutil.h" -#include "PlayerManager.h" -#include "Translator.h" -#include "HalfLife2.h" -#include "ChatTriggers.h" - -ConCmdManager g_ConCmds; - -#if defined ORANGEBOX_BUILD - SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &); -#else - SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false); -#endif - -SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, false, int); - -struct PlCmdInfo -{ - ConCmdInfo *pInfo; - CmdHook *pHook; - CmdType type; -}; -typedef List CmdList; - -void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info); - -ConCmdManager::ConCmdManager() : m_Strings(1024) -{ - m_pCmds = sm_trie_create(); - m_pCmdGrps = sm_trie_create(); - m_CmdClient = 0; -} - -ConCmdManager::~ConCmdManager() -{ - sm_trie_destroy(m_pCmds); - sm_trie_destroy(m_pCmdGrps); -} - -void ConCmdManager::OnSourceModAllInitialized() -{ - g_PluginSys.AddPluginsListener(this); - g_RootMenu.AddRootConsoleCommand("cmds", "List console commands", this); - SH_ADD_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, serverClients, this, &ConCmdManager::SetCommandClient, false); -} - -void ConCmdManager::OnSourceModShutdown() -{ - /* All commands should already be removed by the time we're done */ - SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, serverClients, this, &ConCmdManager::SetCommandClient, false); - g_RootMenu.RemoveRootConsoleCommand("cmds", this); -} - -void ConCmdManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe) -{ - /* Whoa, first get its information struct */ - ConCmdInfo *pInfo; - - if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo)) - { - return; - } - - RemoveConCmds(pInfo->srvhooks); - RemoveConCmds(pInfo->conhooks); - - RemoveConCmd(pInfo, name, is_read_safe, false); -} - -void ConCmdManager::RemoveConCmds(List &cmdlist) -{ - List::iterator iter = cmdlist.begin(); - - while (iter != cmdlist.end()) - { - CmdHook *pHook = (*iter); - IPluginContext *pContext = pHook->pf->GetParentContext(); - IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext()); - CmdList *pList = NULL; - - //gaben - if (!pPlugin->GetProperty("CommandList", (void **)&pList, false) || !pList) - { - continue; - } - - CmdList::iterator p_iter = pList->begin(); - while (p_iter != pList->end()) - { - PlCmdInfo &cmd = (*p_iter); - if (cmd.pHook == pHook) - { - p_iter = pList->erase(p_iter); - } - else - { - p_iter++; - } - } - - delete pHook->pAdmin; - delete pHook; - - iter = cmdlist.erase(iter); - } -} - -void ConCmdManager::RemoveConCmds(List &cmdlist, IPluginContext *pContext) -{ - List::iterator iter = cmdlist.begin(); - CmdHook *pHook; - - while (iter != cmdlist.end()) - { - pHook = (*iter); - if (pHook->pf->GetParentContext() == pContext) - { - delete pHook->pAdmin; - delete pHook; - iter = cmdlist.erase(iter); - } - else - { - iter++; - } - } -} - -void ConCmdManager::OnPluginDestroyed(IPlugin *plugin) -{ - CmdList *pList; - List removed; - if (plugin->GetProperty("CommandList", (void **)&pList, true)) - { - IPluginContext *pContext = plugin->GetBaseContext(); - CmdList::iterator iter; - /* First pass! - * Only bother if there's an actual command list on this plugin... - */ - for (iter=pList->begin(); - iter!=pList->end(); - iter++) - { - PlCmdInfo &cmd = (*iter); - ConCmdInfo *pInfo = cmd.pInfo; - - /* Has this chain already been fully cleaned/removed? */ - if (removed.find(pInfo) != removed.end()) - { - continue; - } - - /* Remove any hooks from us on this command */ - RemoveConCmds(pInfo->conhooks, pContext); - RemoveConCmds(pInfo->srvhooks, pContext); - - /* See if there are still hooks */ - if (pInfo->srvhooks.size()) - { - continue; - } - if (pInfo->conhooks.size()) - { - continue; - } - - /* Remove the command, it should be safe now */ - RemoveConCmd(pInfo, pInfo->pCmd->GetName(), true, true); - removed.push_back(pInfo); - } - delete pList; - } -} -#if defined ORANGEBOX_BUILD -void CommandCallback(const CCommand &command) -{ -#else -void CommandCallback() -{ - CCommand command; -#endif - - g_HL2.PushCommandStack(&command); - - g_ConCmds.InternalDispatch(command); - - g_HL2.PopCommandStack(); -} - -void ConCmdManager::SetCommandClient(int client) -{ - m_CmdClient = client + 1; -} - -ResultType ConCmdManager::DispatchClientCommand(int client, const char *cmd, int args, ResultType type) -{ - ConCmdInfo *pInfo; - if (sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo)) - { - cell_t result = type; - cell_t tempres = result; - List::iterator iter; - CmdHook *pHook; - for (iter=pInfo->conhooks.begin(); - iter!=pInfo->conhooks.end(); - iter++) - { - pHook = (*iter); - if (!pHook->pf->IsRunnable()) - { - continue; - } - if (pHook->pAdmin && !CheckAccess(client, cmd, pHook->pAdmin)) - { - if (result < Pl_Handled) - { - result = Pl_Handled; - } - continue; - } - pHook->pf->PushCell(client); - pHook->pf->PushCell(args); - if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE) - { - if (tempres > result) - { - result = tempres; - } - if (result == Pl_Stop) - { - break; - } - } - } - type = (ResultType)result; - } - - return type; -} - -void ConCmdManager::InternalDispatch(const CCommand &command) -{ - int client = m_CmdClient; - - if (client) - { - CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); - if (!pPlayer || !pPlayer->IsConnected()) - { - return; - } - } - - /** - * Note: Console commands will EITHER go through IServerGameDLL::ClientCommand, - * OR this dispatch. They will NEVER go through both. - * -- - * Whether or not it goes through the callback is determined by FCVAR_GAMEDLL - */ - const char *cmd = g_HL2.CurrentCommandName(); - - ConCmdInfo *pInfo; - if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo)) - { - return; - } - - /* This is a hack to prevent say triggers from firing on messages that were - * blocked because of flooding. We won't remove this, but the hack will get - * "nicer" when we expose explicit say hooks. - */ - if (g_ChatTriggers.WasFloodedMessage()) - { - return; - } - - cell_t result = Pl_Continue; - int args = command.ArgC() - 1; - - List::iterator iter; - CmdHook *pHook; - - /* Execute server-only commands if viable */ - if (client == 0 && pInfo->srvhooks.size()) - { - cell_t tempres = result; - for (iter=pInfo->srvhooks.begin(); - iter!=pInfo->srvhooks.end(); - iter++) - { - pHook = (*iter); - if (!pHook->pf->IsRunnable()) - { - continue; - } - pHook->pf->PushCell(args); - if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE) - { - if (tempres > result) - { - result = tempres; - } - if (result == Pl_Stop) - { - break; - } - } - } - - /* Check if there's an early stop */ - if (result >= Pl_Stop) - { - if (!pInfo->sourceMod) - { - RETURN_META(MRES_SUPERCEDE); - } - return; - } - } - - /* Execute console commands */ - if (pInfo->conhooks.size()) - { - cell_t tempres = result; - for (iter=pInfo->conhooks.begin(); - iter!=pInfo->conhooks.end(); - iter++) - { - pHook = (*iter); - if (!pHook->pf->IsRunnable()) - { - continue; - } - if (client - && pHook->pAdmin - && !CheckAccess(client, cmd, pHook->pAdmin)) - { - if (result < Pl_Handled) - { - result = Pl_Handled; - } - continue; - } - - /* On a listen server, sometimes the server host's client index can be set as 0. - * So index 1 is passed to the command callback to correct this potential problem. - */ - if (!engine->IsDedicatedServer()) - { - client = g_Players.ListenClient(); - } - - pHook->pf->PushCell(client); - pHook->pf->PushCell(args); - - if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE) - { - if (tempres > result) - { - result = tempres; - } - if (result == Pl_Stop) - { - break; - } - } - } - } - - if (result >= Pl_Handled) - { - if (!pInfo->sourceMod) - { - RETURN_META(MRES_SUPERCEDE); - } - return; - } -} - -bool ConCmdManager::CheckCommandAccess(int client, const char *cmd, FlagBits cmdflags) -{ - if (cmdflags == 0 || client == 0) - { - return true; - } - - /* If running listen server, then client 1 is the server host and should have 'root' access */ - if (client == 1 && !engine->IsDedicatedServer()) - { - return true; - } - - CPlayer *player = g_Players.GetPlayerByIndex(client); - if (!player - || player->GetEdict() == NULL - || player->IsFakeClient()) - { - return false; - } - - AdminId adm = player->GetAdminId(); - if (adm != INVALID_ADMIN_ID) - { - FlagBits bits = g_Admins.GetAdminFlags(adm, Access_Effective); - - /* root knows all, WHOA */ - if ((bits & ADMFLAG_ROOT) == ADMFLAG_ROOT) - { - return true; - } - - /* Check for overrides - * :TODO: is it worth optimizing this? - */ - unsigned int groups = g_Admins.GetAdminGroupCount(adm); - GroupId gid; - OverrideRule rule; - bool override = false; - for (unsigned int i=0; ieflags)) - { - return true; - } - - edict_t *pEdict = engine->PEntityOfEntIndex(client); - - /* If we got here, the command failed... */ - char buffer[128]; - if (!CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "No Access", &client)) - { - UTIL_Format(buffer, sizeof(buffer), "You do not have access to this command"); - } - - unsigned int replyto = g_ChatTriggers.GetReplyTo(); - if (replyto == SM_REPLY_CONSOLE) - { - char fullbuffer[192]; - UTIL_Format(fullbuffer, sizeof(fullbuffer), "[SM] %s.\n", buffer); - engine->ClientPrintf(pEdict, fullbuffer); - } - else if (replyto == SM_REPLY_CHAT) - { - char fullbuffer[192]; - UTIL_Format(fullbuffer, sizeof(fullbuffer), "[SM] %s.", buffer); - g_HL2.TextMsg(client, HUD_PRINTTALK, fullbuffer); - } - - return false; -} - -bool ConCmdManager::AddConsoleCommand(IPluginFunction *pFunction, - const char *name, - const char *description, - int flags) -{ - ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags); - - if (!pInfo) - { - return false; - } - - CmdHook *pHook = new CmdHook(); - - pHook->pf = pFunction; - if (description && description[0]) - { - pHook->helptext.assign(description); - } - pInfo->conhooks.push_back(pHook); - - /* Add to the plugin */ - CmdList *pList; - IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext()); - if (!pPlugin->GetProperty("CommandList", (void **)&pList)) - { - pList = new CmdList(); - pPlugin->SetProperty("CommandList", pList); - } - PlCmdInfo info; - info.pInfo = pInfo; - info.type = Cmd_Console; - info.pHook = pHook; - AddToPlCmdList(pList, info); - - return true; -} - -bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction, - const char *name, - const char *group, - int adminflags, - const char *description, - int flags) -{ - ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags); - - if (!pInfo) - { - return false; - } - - CmdHook *pHook = new CmdHook(); - AdminCmdInfo *pAdmin = new AdminCmdInfo(); - - pHook->pf = pFunction; - if (description && description[0]) - { - pHook->helptext.assign(description); - } - pHook->pAdmin = pAdmin; - - void *object; - int grpid; - if (!sm_trie_retrieve(m_pCmdGrps, group, (void **)&object)) - { - grpid = m_Strings.AddString(group); - sm_trie_insert(m_pCmdGrps, group, (void *)grpid); - } - else - { - grpid = (int)object; - } - - pAdmin->cmdGrpId = grpid; - pAdmin->flags = adminflags; - - /* First get the command group override, if any */ - bool override = g_Admins.GetCommandOverride(group, - Override_CommandGroup, - &(pAdmin->eflags)); - - /* Next get the command override, if any */ - if (g_Admins.GetCommandOverride(name, - Override_Command, - &(pAdmin->eflags))) - { - override = true; - } - - /* Assign normal flags if there were no overrides */ - if (!override) - { - pAdmin->eflags = pAdmin->flags; - } - - /* Finally, add the hook */ - pInfo->conhooks.push_back(pHook); - pInfo->admin = *(pHook->pAdmin); - pInfo->is_admin_set = true; - - /* Now add to the plugin */ - CmdList *pList; - IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext()); - if (!pPlugin->GetProperty("CommandList", (void **)&pList)) - { - pList = new CmdList(); - pPlugin->SetProperty("CommandList", pList); - } - PlCmdInfo info; - info.pInfo = pInfo; - info.type = Cmd_Admin; - info.pHook = pHook; - AddToPlCmdList(pList, info); - - return true; -} - -bool ConCmdManager::AddServerCommand(IPluginFunction *pFunction, - const char *name, - const char *description, - int flags) - -{ - ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags); - - if (!pInfo) - { - return false; - } - - CmdHook *pHook = new CmdHook(); - - pHook->pf = pFunction; - if (description && description[0]) - { - pHook->helptext.assign(description); - } - - pInfo->srvhooks.push_back(pHook); - - /* Add to the plugin */ - CmdList *pList; - IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext()); - if (!pPlugin->GetProperty("CommandList", (void **)&pList)) - { - pList = new CmdList(); - pPlugin->SetProperty("CommandList", pList); - } - PlCmdInfo info; - info.pInfo = pInfo; - info.type = Cmd_Server; - info.pHook = pHook; - AddToPlCmdList(pList, info); - - return true; -} - -void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info) -{ - CmdList::iterator iter = pList->begin(); - bool inserted = false; - const char *orig = NULL; - - orig = info.pInfo->pCmd->GetName(); - - /* Insert this into the help list, SORTED alphabetically. */ - while (iter != pList->end()) - { - PlCmdInfo &obj = (*iter); - const char *cmd = obj.pInfo->pCmd->GetName(); - if (strcmp(orig, cmd) < 0) - { - pList->insert(iter, info); - inserted = true; - break; - } - iter++; - } - - if (!inserted) - { - pList->push_back(info); - } -} - -void ConCmdManager::AddToCmdList(ConCmdInfo *info) -{ - List::iterator iter = m_CmdList.begin(); - ConCmdInfo *pInfo; - bool inserted = false; - const char *orig = NULL; - - orig = info->pCmd->GetName(); - - /* Insert this into the help list, SORTED alphabetically. */ - while (iter != m_CmdList.end()) - { - const char *cmd = NULL; - pInfo = (*iter); - cmd = pInfo->pCmd->GetName(); - if (strcmp(orig, cmd) < 0) - { - m_CmdList.insert(iter, info); - inserted = true; - break; - } - iter++; - } - - if (!inserted) - { - m_CmdList.push_back(info); - } -} - -void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove) -{ - ConCmdInfo *pInfo; - - if (type == Override_Command) - { - if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo)) - { - return; - } - - List::iterator iter; - CmdHook *pHook; - - for (iter=pInfo->conhooks.begin(); iter!=pInfo->conhooks.end(); iter++) - { - pHook = (*iter); - if (pHook->pAdmin) - { - if (!remove) - { - pHook->pAdmin->eflags = bits; - } else { - pHook->pAdmin->eflags = pHook->pAdmin->flags; - } - pInfo->admin = *(pHook->pAdmin); - } - } - pInfo->is_admin_set = true; - } - else if (type == Override_CommandGroup) - { - void *object; - if (!sm_trie_retrieve(m_pCmdGrps, cmd, &object)) - { - return; - } - int grpid = (int)object; - - /* This is bad :( loop through all commands */ - List::iterator iter; - CmdHook *pHook; - for (iter=m_CmdList.begin(); iter!=m_CmdList.end(); iter++) - { - pInfo = (*iter); - for (List::iterator citer=pInfo->conhooks.begin(); - citer!=pInfo->conhooks.end(); - citer++) - { - pHook = (*citer); - if (pHook->pAdmin && pHook->pAdmin->cmdGrpId == grpid) - { - if (remove) - { - pHook->pAdmin->eflags = bits; - } else { - pHook->pAdmin->eflags = pHook->pAdmin->flags; - } - pInfo->admin = *(pHook->pAdmin); - } - } - } - pInfo->is_admin_set = true; - } -} - -void ConCmdManager::RemoveConCmd(ConCmdInfo *info, const char *name, bool is_read_safe, bool untrack) -{ - /* Remove from the trie */ - sm_trie_delete(m_pCmds, name); - - /* Remove console-specific information - * This should always be true as of right now - */ - if (info->pCmd) - { - if (info->sourceMod) - { - /* Unlink from SourceMM */ - g_SMAPI->UnregisterConCommandBase(g_PLAPI, info->pCmd); - /* Delete the command's memory */ - char *new_help = const_cast(info->pCmd->GetHelpText()); - char *new_name = const_cast(info->pCmd->GetName()); - delete [] new_help; - delete [] new_name; - delete info->pCmd; - } - else - { - if (is_read_safe) - { - /* Remove the external hook */ - SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, info->pCmd, CommandCallback, false); - } - if (untrack) - { - UntrackConCommandBase(info->pCmd, this); - } - } - } - - /* Remove from list */ - m_CmdList.remove(info); - - delete info; -} - -bool ConCmdManager::LookForSourceModCommand(const char *cmd) -{ - ConCmdInfo *pInfo; - - if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo)) - { - return false; - } - - return pInfo->sourceMod && (pInfo->conhooks.size() > 0); -} - -bool ConCmdManager::LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags) -{ - ConCmdInfo *pInfo; - - if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo)) - { - return false; - } - - *pFlags = pInfo->admin.eflags; - - return pInfo->is_admin_set; -} - -ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *description, int flags) -{ - ConCmdInfo *pInfo; - if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo)) - { - pInfo = new ConCmdInfo(); - /* Find the commandopan */ - ConCommandBase *pBase = icvar->GetCommands(); - ConCommand *pCmd = NULL; - while (pBase) - { - if (strcmp(pBase->GetName(), name) == 0) - { - /* Don't want to return convar with same name */ - if (!pBase->IsCommand()) - { - return NULL; - } - - pCmd = (ConCommand *)pBase; - break; - } - pBase = const_cast(pBase->GetNext()); - } - - if (!pCmd) - { - /* Note that we have to duplicate because the source might not be - * a static string, and these expect static memory. - */ - if (!description) - { - description = ""; - } - char *new_name = sm_strdup(name); - char *new_help = sm_strdup(description); - pCmd = new ConCommand(new_name, CommandCallback, new_help, flags); - pInfo->sourceMod = true; - } - else - { - TrackConCommandBase(pCmd, this); - SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pCmd, CommandCallback, false); - } - - pInfo->pCmd = pCmd; - pInfo->is_admin_set = false; - - sm_trie_insert(m_pCmds, name, pInfo); - AddToCmdList(pInfo); - } - - return pInfo; -} - -void ConCmdManager::OnRootConsoleCommand(const char *cmdname, const CCommand &command) -{ - if (command.ArgC() >= 3) - { - const char *text = command.Arg(2); - - CPlugin *pPlugin = g_PluginSys.FindPluginByConsoleArg(text); - - if (!pPlugin) - { - g_RootMenu.ConsolePrint("[SM] Plugin \"%s\" was not found.", text); - return; - } - - const sm_plugininfo_t *plinfo = pPlugin->GetPublicInfo(); - const char *plname = IS_STR_FILLED(plinfo->name) ? plinfo->name : pPlugin->GetFilename(); - - CmdList *pList; - if (!pPlugin->GetProperty("CommandList", (void **)&pList)) - { - g_RootMenu.ConsolePrint("[SM] No commands found for: %s", plname); - return; - } - if (!pList->size()) - { - g_RootMenu.ConsolePrint("[SM] No commands found for: %s", plname); - return; - } - - CmdList::iterator iter; - const char *type = NULL; - const char *name; - const char *help; - g_RootMenu.ConsolePrint("[SM] Listing %d commands for: %s", pList->size(), plname); - g_RootMenu.ConsolePrint(" %-17.16s %-8.7s %s", "[Name]", "[Type]", "[Help]"); - for (iter=pList->begin(); - iter!=pList->end(); - iter++) - { - PlCmdInfo &cmd = (*iter); - if (cmd.type == Cmd_Server) - { - type = "server"; - } - else if (cmd.type == Cmd_Console) - { - type = "console"; - } - else if (cmd.type == Cmd_Admin) - { - type = "admin"; - } - name = cmd.pInfo->pCmd->GetName(); - if (cmd.pHook->helptext.size()) - { - help = cmd.pHook->helptext.c_str(); - } - else - { - help = cmd.pInfo->pCmd->GetHelpText(); - } - g_RootMenu.ConsolePrint(" %-17.16s %-12.11s %s", name, type, help); - } - - return; - } - - g_RootMenu.ConsolePrint("[SM] Usage: sm cmds "); -} diff --git a/core/ConCmdManager.h b/core/ConCmdManager.h deleted file mode 100644 index 8c25bb73..00000000 --- a/core/ConCmdManager.h +++ /dev/null @@ -1,161 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_CONCMDMANAGER_H_ -#define _INCLUDE_SOURCEMOD_CONCMDMANAGER_H_ - -#include "sm_globals.h" -#include "sourcemm_api.h" -#include "ForwardSys.h" -#include "sm_trie.h" -#include "sm_memtable.h" -#include -#include -#include -#include -#include "concmd_cleaner.h" - -using namespace SourceHook; - -enum CmdType -{ - Cmd_Server, - Cmd_Console, - Cmd_Admin, -}; - -struct AdminCmdInfo -{ - AdminCmdInfo() - { - cmdGrpId = -1; - flags = 0; - eflags = 0; - } - int cmdGrpId; /* index into cmdgroup string table */ - FlagBits flags; /* default flags */ - FlagBits eflags; /* effective flags */ -}; - -struct CmdHook -{ - CmdHook() - { - pf = NULL; - pAdmin = NULL; - } - IPluginFunction *pf; /* function hook */ - String helptext; /* help text */ - AdminCmdInfo *pAdmin; /* admin requirements, if any */ -}; - -struct ConCmdInfo -{ - ConCmdInfo() - { - sourceMod = false; - pCmd = NULL; - } - bool sourceMod; /**< Determines whether or not concmd was created by a SourceMod plugin */ - ConCommand *pCmd; /**< Pointer to the command itself */ - List srvhooks; /**< Hooks as a server command */ - List conhooks; /**< Hooks as a console command */ - AdminCmdInfo admin; /**< Admin info, if any */ - bool is_admin_set; /**< Whether or not admin info is set */ -}; - -class ConCmdManager : - public SMGlobalClass, - public IRootConsoleCommand, - public IPluginsListener, - public IConCommandTracker -{ -#if defined ORANGEBOX_BUILD - friend void CommandCallback(const CCommand &command); -#else - friend void CommandCallback(); -#endif -public: - ConCmdManager(); - ~ConCmdManager(); -public: //SMGlobalClass - void OnSourceModAllInitialized(); - void OnSourceModShutdown(); -public: //IPluginsListener - void OnPluginDestroyed(IPlugin *plugin); -public: //IRootConsoleCommand - void OnRootConsoleCommand(const char *cmdname, const CCommand &command); -public: //IConCommandTracker - void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe); -public: - bool AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags); - bool AddConsoleCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags); - bool AddAdminCommand(IPluginFunction *pFunction, - const char *name, - const char *group, - int adminflags, - const char *description, - int flags); - ResultType DispatchClientCommand(int client, const char *cmd, int args, ResultType type); - void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove); - bool LookForSourceModCommand(const char *cmd); - bool LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags); - bool CheckCommandAccess(int client, const char *cmd, FlagBits flags); -private: - void InternalDispatch(const CCommand &command); - ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args); - ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags); - void SetCommandClient(int client); - void AddToCmdList(ConCmdInfo *info); - void RemoveConCmd(ConCmdInfo *info, const char *cmd, bool is_read_safe, bool untrack); - void RemoveConCmds(List &cmdlist); - void RemoveConCmds(List &cmdlist, IPluginContext *pContext); - bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin); -public: - inline int GetCommandClient() - { - return m_CmdClient; - } - inline const List & GetCommandList() - { - return m_CmdList; - } -private: - Trie *m_pCmds; /* command lookup */ - Trie *m_pCmdGrps; /* command group lookup */ - List m_CmdList; /* command list */ - int m_CmdClient; /* current client */ - BaseStringTable m_Strings; /* string table */ -}; - -extern ConCmdManager g_ConCmds; - -#endif // _INCLUDE_SOURCEMOD_CONCMDMANAGER_H_ diff --git a/core/ConVarManager.cpp b/core/ConVarManager.cpp deleted file mode 100644 index f8e27cee..00000000 --- a/core/ConVarManager.cpp +++ /dev/null @@ -1,707 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "ConVarManager.h" -#include "HalfLife2.h" -#include "PluginSys.h" -#include "ForwardSys.h" -#include "HandleSys.h" -#include "sm_srvcmds.h" -#include "sm_stringutil.h" -#include -#include - -ConVarManager g_ConVarManager; - -#if !defined ORANGEBOX_BUILD -#define CallGlobalChangeCallbacks CallGlobalChangeCallback -#endif - -#if defined ORANGEBOX_BUILD -SH_DECL_HOOK3_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *, float); -#else -SH_DECL_HOOK2_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *); -#endif - -SH_DECL_HOOK5_void(IServerGameDLL, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *); -SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *); - -const ParamType CONVARCHANGE_PARAMS[] = {Param_Cell, Param_String, Param_String}; -typedef List ConVarList; -KTrie convar_cache; - -ConVarManager::ConVarManager() : m_ConVarType(0), m_bIsDLLQueryHooked(false), m_bIsVSPQueryHooked(false) -{ -} - -ConVarManager::~ConVarManager() -{ -} - -void ConVarManager::OnSourceModStartup(bool late) -{ - HandleAccess sec; - - /* Set up access rights for the 'ConVar' handle type */ - sec.access[HandleAccess_Read] = 0; - sec.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER; - sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER; - - /* Create the 'ConVar' handle type */ - m_ConVarType = g_HandleSys.CreateType("ConVar", this, 0, NULL, &sec, g_pCoreIdent, NULL); -} - -void ConVarManager::OnSourceModAllInitialized() -{ - /** - * Episode 2 has this function by default, but the older versions do not. - */ -#if !defined ORANGEBOX_BUILD - if (g_SMAPI->GetGameDLLVersion() >= 6) - { - SH_ADD_HOOK_MEMFUNC(IServerGameDLL, OnQueryCvarValueFinished, gamedll, this, &ConVarManager::OnQueryCvarValueFinished, false); - m_bIsDLLQueryHooked = true; - } -#endif - - SH_ADD_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false); - - /* Add the 'convars' option to the 'sm' console command */ - g_RootMenu.AddRootConsoleCommand("cvars", "View convars created by a plugin", this); -} - -void ConVarManager::OnSourceModShutdown() -{ - List::iterator iter = m_ConVars.begin(); - HandleSecurity sec(NULL, g_pCoreIdent); - - /* Iterate list of ConVarInfo structures, remove every one of them */ - while (iter != m_ConVars.end()) - { - ConVarInfo *pInfo = (*iter); - - iter = m_ConVars.erase(iter); - - g_HandleSys.FreeHandle(pInfo->handle, &sec); - if (pInfo->pChangeForward != NULL) - { - g_Forwards.ReleaseForward(pInfo->pChangeForward); - } - if (pInfo->sourceMod) - { - /* If we created it, we won't be tracking it, therefore it is - * safe to remove everything in one go. - */ - META_UNREGCVAR(pInfo->pVar); - delete [] pInfo->pVar->GetName(); - delete [] pInfo->pVar->GetHelpText(); - delete [] pInfo->pVar->GetDefault(); - delete pInfo->pVar; - } - else - { - /* If we didn't create it, we might be tracking it. Also, - * it could be unreadable. - */ - UntrackConCommandBase(pInfo->pVar, this); - } - - /* It's not safe to read the name here, so we simply delete the - * the info struct and clear the lookup cache at the end. - */ - delete pInfo; - } - convar_cache.clear(); - - /* Unhook things */ - if (m_bIsDLLQueryHooked) - { - SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, OnQueryCvarValueFinished, gamedll, this, &ConVarManager::OnQueryCvarValueFinished, false); - m_bIsDLLQueryHooked = false; - } - else if (m_bIsVSPQueryHooked) - { - SH_REMOVE_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, this, &ConVarManager::OnQueryCvarValueFinished, false); - m_bIsVSPQueryHooked = false; - } - - SH_REMOVE_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false); - - /* Remove the 'convars' option from the 'sm' console command */ - g_RootMenu.RemoveRootConsoleCommand("cvars", this); - - /* Remove the 'ConVar' handle type */ - g_HandleSys.RemoveType(m_ConVarType, g_pCoreIdent); -} - -/** - * Orange Box will never use this. - */ -void ConVarManager::OnSourceModVSPReceived() -{ - /** - * Don't bother if the DLL is already hooked. - */ - if (m_bIsDLLQueryHooked) - { - return; - } - - /* For later MM:S versions, use the updated API, since it's cleaner. */ -#if defined METAMOD_PLAPI_VERSION - int engine = g_SMAPI->GetSourceEngineBuild(); - if (engine == SOURCE_ENGINE_ORIGINAL || vsp_version < 2) - { - return; - } -#else - if (g_HL2.IsOriginalEngine() || vsp_version < 2) - { - return; - } -#endif - - SH_ADD_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, this, &ConVarManager::OnQueryCvarValueFinished, false); - m_bIsVSPQueryHooked = true; -} - -bool convar_cache_lookup(const char *name, ConVarInfo **pVar) -{ - ConVarInfo **pLookup = convar_cache.retrieve(name); - if (pLookup != NULL) - { - *pVar = *pLookup; - return true; - } - else - { - return false; - } -} - -void ConVarManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe) -{ - /* Only check convars that have not been created by SourceMod's core */ - ConVarInfo *pInfo; - if (!convar_cache_lookup(name, &pInfo)) - { - return; - } - - HandleSecurity sec(NULL, g_pCoreIdent); - - /* Remove it from our cache */ - m_ConVars.remove(pInfo); - convar_cache.remove(name); - - /* Now make sure no plugins are referring to this pointer */ - IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator(); - while (pl_iter->MorePlugins()) - { - IPlugin *pl = pl_iter->GetPlugin(); - - ConVarList *pConVarList; - if (pl->GetProperty("ConVarList", (void **)&pConVarList, true) - && pConVarList != NULL) - { - pConVarList->remove(pInfo->pVar); - } - - pl_iter->NextPlugin(); - } - - /* Free resources */ - g_HandleSys.FreeHandle(pInfo->handle, &sec); - delete pInfo; -} - -void ConVarManager::OnPluginUnloaded(IPlugin *plugin) -{ - ConVarList *pConVarList; - - /* If plugin has a convar list, free its memory */ - if (plugin->GetProperty("ConVarList", (void **)&pConVarList, true)) - { - delete pConVarList; - } -} - -void ConVarManager::OnHandleDestroy(HandleType_t type, void *object) -{ -} - -bool ConVarManager::GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize) -{ - *pSize = sizeof(ConVar) + sizeof(ConVarInfo); - return true; -} - -void ConVarManager::OnRootConsoleCommand(const char *cmdname, const CCommand &command) -{ - int argcount = command.ArgC(); - if (argcount >= 3) - { - /* Get plugin index that was passed */ - const char *arg = command.Arg(2); - - /* Get plugin object */ - CPlugin *plugin = g_PluginSys.FindPluginByConsoleArg(arg); - - if (!plugin) - { - g_RootMenu.ConsolePrint("[SM] Plugin \"%s\" was not found.", arg); - return; - } - - /* Get plugin name */ - const sm_plugininfo_t *plinfo = plugin->GetPublicInfo(); - const char *plname = IS_STR_FILLED(plinfo->name) ? plinfo->name : plugin->GetFilename(); - - ConVarList *pConVarList; - ConVarList::iterator iter; - - /* If no convar list... */ - if (!plugin->GetProperty("ConVarList", (void **)&pConVarList)) - { - g_RootMenu.ConsolePrint("[SM] No convars found for: %s", plname); - return; - } - - g_RootMenu.ConsolePrint("[SM] Listing %d convars for: %s", pConVarList->size(), plname); - g_RootMenu.ConsolePrint(" %-32.31s %s", "[Name]", "[Value]"); - - /* Iterate convar list and display each one */ - for (iter = pConVarList->begin(); iter != pConVarList->end(); iter++) - { - const ConVar *pConVar = (*iter); - g_RootMenu.ConsolePrint(" %-32.31s %s", pConVar->GetName(), pConVar->GetString()); - } - - return; - } - - /* Display usage of subcommand */ - g_RootMenu.ConsolePrint("[SM] Usage: sm convars "); -} - -Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, const char *description, int flags, bool hasMin, float min, bool hasMax, float max) -{ - ConVar *pConVar = NULL; - ConVarInfo *pInfo = NULL; - Handle_t hndl = 0; - - /* Find out if the convar exists already */ - pConVar = icvar->FindVar(name); - - /* If the convar already exists... */ - if (pConVar) - { - /* Add convar to plugin's list */ - AddConVarToPluginList(pContext, pConVar); - - /* First find out if we already have a handle to it */ - if (convar_cache_lookup(name, &pInfo)) - { - return pInfo->handle; - } - else - { - /* Create and initialize ConVarInfo structure */ - pInfo = new ConVarInfo(); - pInfo->sourceMod = false; - pInfo->pChangeForward = NULL; - pInfo->pVar = pConVar; - - /* If we don't, then create a new handle from the convar */ - hndl = g_HandleSys.CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL); - if (hndl == BAD_HANDLE) - { - delete pInfo; - return BAD_HANDLE; - } - - pInfo->handle = hndl; - - /* Insert struct into caches */ - m_ConVars.push_back(pInfo); - convar_cache.insert(name, pInfo); - TrackConCommandBase(pConVar, this); - - return hndl; - } - } - - /* To prevent creating a convar that has the same name as a console command... ugh */ - ConCommandBase *pBase = icvar->GetCommands(); - - while (pBase) - { - if (pBase->IsCommand() && strcmp(pBase->GetName(), name) == 0) - { - return BAD_HANDLE; - } - - pBase = const_cast(pBase->GetNext()); - } - - /* Create and initialize ConVarInfo structure */ - pInfo = new ConVarInfo(); - pInfo->handle = hndl; - pInfo->sourceMod = true; - pInfo->pChangeForward = NULL; - - /* Create a handle from the new convar */ - hndl = g_HandleSys.CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL); - if (hndl == BAD_HANDLE) - { - delete pInfo; - return BAD_HANDLE; - } - - pInfo->handle = hndl; - - /* Since an existing convar (or concmd with the same name) was not found , now we can finally create it */ - pConVar = new ConVar(sm_strdup(name), sm_strdup(defaultVal), flags, sm_strdup(description), hasMin, min, hasMax, max); - pInfo->pVar = pConVar; - - /* Add convar to plugin's list */ - AddConVarToPluginList(pContext, pConVar); - - /* Insert struct into caches */ - m_ConVars.push_back(pInfo); - convar_cache.insert(name, pInfo); - - return hndl; -} - -Handle_t ConVarManager::FindConVar(const char *name) -{ - ConVar *pConVar = NULL; - ConVarInfo *pInfo; - Handle_t hndl; - - /* Search for convar */ - pConVar = icvar->FindVar(name); - - /* If it doesn't exist, then return an invalid handle */ - if (!pConVar) - { - return BAD_HANDLE; - } - - /* At this point, the convar exists. So, find out if we already have a handle */ - if (convar_cache_lookup(name, &pInfo)) - { - return pInfo->handle; - } - - /* Create and initialize ConVarInfo structure */ - pInfo = new ConVarInfo(); - pInfo->sourceMod = false; - pInfo->pChangeForward = NULL; - pInfo->pVar = pConVar; - - /* If we don't have a handle, then create a new one */ - hndl = g_HandleSys.CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL); - if (hndl == BAD_HANDLE) - { - delete pInfo; - return BAD_HANDLE; - } - - pInfo->handle = hndl; - - /* Insert struct into our caches */ - m_ConVars.push_back(pInfo); - convar_cache.insert(name, pInfo); - TrackConCommandBase(pConVar, this); - - return hndl; -} - -void ConVarManager::AddConVarChangeListener(const char *name, IConVarChangeListener *pListener) -{ - ConVarInfo *pInfo; - - if (FindConVar(name) == BAD_HANDLE) - { - return; - } - - /* Find the convar in the lookup trie */ - if (convar_cache_lookup(name, &pInfo)) - { - pInfo->changeListeners.push_back(pListener); - } -} - -void ConVarManager::RemoveConVarChangeListener(const char *name, IConVarChangeListener *pListener) -{ - ConVarInfo *pInfo; - - /* Find the convar in the lookup trie */ - if (convar_cache_lookup(name, &pInfo)) - { - pInfo->changeListeners.remove(pListener); - } -} - -void ConVarManager::HookConVarChange(ConVar *pConVar, IPluginFunction *pFunction) -{ - ConVarInfo *pInfo; - IChangeableForward *pForward; - - /* Find the convar in the lookup trie */ - if (convar_cache_lookup(pConVar->GetName(), &pInfo)) - { - /* Get the forward */ - pForward = pInfo->pChangeForward; - - /* If forward does not exist, create it */ - if (!pForward) - { - pForward = g_Forwards.CreateForwardEx(NULL, ET_Ignore, 3, CONVARCHANGE_PARAMS); - pInfo->pChangeForward = pForward; - } - - /* Add function to forward's list */ - pForward->AddFunction(pFunction); - } -} - -void ConVarManager::UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFunction) -{ - ConVarInfo *pInfo; - IChangeableForward *pForward; - IPluginContext *pContext = pFunction->GetParentContext(); - - /* Find the convar in the lookup trie */ - if (convar_cache_lookup(pConVar->GetName(), &pInfo)) - { - /* Get the forward */ - pForward = pInfo->pChangeForward; - - /* If the forward doesn't exist, we can't unhook anything */ - if (!pForward) - { - pContext->ThrowNativeError("Convar \"%s\" has no active hook", pConVar->GetName()); - return; - } - - /* Remove the function from the forward's list */ - if (!pForward->RemoveFunction(pFunction)) - { - pContext->ThrowNativeError("Invalid hook callback specified for convar \"%s\"", pConVar->GetName()); - return; - } - - /* If the forward now has 0 functions in it... */ - if (pForward->GetFunctionCount() == 0) - { - /* Free this forward */ - g_Forwards.ReleaseForward(pForward); - pInfo->pChangeForward = NULL; - } - } -} - -QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char *name, IPluginFunction *pCallback, Handle_t hndl) -{ - QueryCvarCookie_t cookie; - - /* Call StartQueryCvarValue() in either the IVEngineServer or IServerPluginHelpers depending on situation */ - if (m_bIsDLLQueryHooked) - { - cookie = engine->StartQueryCvarValue(pPlayer, name); - } - else if (m_bIsVSPQueryHooked) - { - cookie = serverpluginhelpers->StartQueryCvarValue(pPlayer, name); - } - else - { - return InvalidQueryCvarCookie; - } - - ConVarQuery query = {cookie, pCallback, hndl}; - m_ConVarQueries.push_back(query); - - return cookie; -} - -void ConVarManager::AddConVarToPluginList(IPluginContext *pContext, const ConVar *pConVar) -{ - ConVarList *pConVarList; - ConVarList::iterator iter; - bool inserted = false; - const char *orig = pConVar->GetName(); - - IPlugin *plugin = g_PluginSys.FindPluginByContext(pContext->GetContext()); - - /* Check plugin for an existing convar list */ - if (!plugin->GetProperty("ConVarList", (void **)&pConVarList)) - { - pConVarList = new ConVarList(); - plugin->SetProperty("ConVarList", pConVarList); - } - else if (pConVarList->find(pConVar) != pConVarList->end()) - { - /* If convar is already in list, then don't add it */ - return; - } - - /* Insert convar into list which is sorted alphabetically */ - for (iter = pConVarList->begin(); iter != pConVarList->end(); iter++) - { - if (strcmp(orig, (*iter)->GetName()) < 0) - { - pConVarList->insert(iter, pConVar); - inserted = true; - break; - } - } - - if (!inserted) - { - pConVarList->push_back(pConVar); - } -} - -#if defined ORANGEBOX_BUILD -void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue) -#else -void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue) -#endif -{ - /* If the values are the same, exit early in order to not trigger callbacks */ - if (strcmp(pConVar->GetString(), oldValue) == 0) - { - return; - } - - ConVarInfo *pInfo; - - /* Find the convar in the lookup trie */ - if (!convar_cache_lookup(pConVar->GetName(), &pInfo)) - { - return; - } - - IChangeableForward *pForward = pInfo->pChangeForward; - - if (pInfo->changeListeners.size() != 0) - { - for (List::iterator i = pInfo->changeListeners.begin(); - i != pInfo->changeListeners.end(); - i++) - { -#if defined ORANGEBOX_BUILD - (*i)->OnConVarChanged(pConVar, oldValue, flOldValue); -#else - (*i)->OnConVarChanged(pConVar, oldValue, atof(oldValue)); -#endif - } - } - - if (pForward != NULL) - { - /* Now call forwards in plugins that have hooked this */ - pForward->PushCell(pInfo->handle); - pForward->PushString(oldValue); - pForward->PushString(pConVar->GetString()); - pForward->Execute(NULL); - } -} - -bool ConVarManager::IsQueryingSupported() -{ - return (m_bIsDLLQueryHooked || m_bIsVSPQueryHooked); -} - -void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue) -{ - IPluginFunction *pCallback = NULL; - cell_t value = 0; - List::iterator iter; - - for (iter = m_ConVarQueries.begin(); iter != m_ConVarQueries.end(); iter++) - { - ConVarQuery &query = (*iter); - if (query.cookie == cookie) - { - pCallback = query.pCallback; - value = query.value; - break; - } - } - - if (pCallback) - { - cell_t ret; - - pCallback->PushCell(cookie); - pCallback->PushCell(engine->IndexOfEdict(pPlayer)); - pCallback->PushCell(result); - pCallback->PushString(cvarName); - - if (result == eQueryCvarValueStatus_ValueIntact) - { - pCallback->PushString(cvarValue); - } - else - { - pCallback->PushString("\0"); - } - - pCallback->PushCell(value); - pCallback->Execute(&ret); - - m_ConVarQueries.erase(iter); - } -} - -HandleError ConVarManager::ReadConVarHandle(Handle_t hndl, ConVar **pVar) -{ - ConVarInfo *pInfo; - HandleError error; - - if ((error = g_HandleSys.ReadHandle(hndl, m_ConVarType, NULL, (void **)&pInfo)) != HandleError_None) - { - return error; - } - - if (pVar) - { - *pVar = pInfo->pVar; - } - - return error; -} diff --git a/core/ConVarManager.h b/core/ConVarManager.h deleted file mode 100644 index 148f7c40..00000000 --- a/core/ConVarManager.h +++ /dev/null @@ -1,165 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_CONVARMANAGER_H_ -#define _INCLUDE_SOURCEMOD_CONVARMANAGER_H_ - -#include "sm_globals.h" -#include "sourcemm_api.h" -#include -#include -#include -#include -#include -#include -#include "concmd_cleaner.h" - -using namespace SourceHook; - -class IConVarChangeListener -{ -public: - virtual void OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue) =0; -}; - -/** - * Holds SourceMod-specific information about a convar - */ -struct ConVarInfo -{ - Handle_t handle; /**< Handle to self */ - bool sourceMod; /**< Determines whether or not convar was created by a SourceMod plugin */ - IChangeableForward *pChangeForward; /**< Forward associated with convar */ - ConVar *pVar; /**< The actual convar */ - List changeListeners; -}; - -/** - * Holds information about a client convar query - */ -struct ConVarQuery -{ - QueryCvarCookie_t cookie; /**< Cookie that identifies query */ - IPluginFunction *pCallback; /**< Function that will be called when query is finished */ - cell_t value; /**< Optional value passed to query function */ -}; - -class ConVarManager : - public SMGlobalClass, - public IHandleTypeDispatch, - public IPluginsListener, - public IRootConsoleCommand, - public IConCommandTracker -{ -public: - ConVarManager(); - ~ConVarManager(); -public: // SMGlobalClass - void OnSourceModStartup(bool late); - void OnSourceModAllInitialized(); - void OnSourceModShutdown(); - void OnSourceModVSPReceived(); -public: // IHandleTypeDispatch - void OnHandleDestroy(HandleType_t type, void *object); - bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize); -public: // IPluginsListener - void OnPluginUnloaded(IPlugin *plugin); -public: //IRootConsoleCommand - void OnRootConsoleCommand(const char *cmdname, const CCommand &command); -public: //IConCommandTracker - void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe); -public: - /** - * Create a convar and return a handle to it. - */ - Handle_t CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, - const char *description, int flags, bool hasMin, float min, bool hasMax, float max); - - /** - * Searches for a convar and returns a handle to it - */ - Handle_t FindConVar(const char* name); - - /** - * Add a function to call when the specified convar changes. - */ - void HookConVarChange(ConVar *pConVar, IPluginFunction *pFunction); - - /** - * Remove a function from the forward that will be called when the specified convar changes. - */ - void UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFunction); - - void AddConVarChangeListener(const char *name, IConVarChangeListener *pListener); - void RemoveConVarChangeListener(const char *name, IConVarChangeListener *pListener); - - /** - * Starts a query to find the value of a client convar. - */ - QueryCvarCookie_t QueryClientConVar(edict_t *pPlayer, const char *name, IPluginFunction *pCallback, - Handle_t hndl); - - bool IsQueryingSupported(); - - HandleError ReadConVarHandle(Handle_t hndl, ConVar **pVar); - -private: - /** - * Adds a convar to a plugin's list. - */ - static void AddConVarToPluginList(IPluginContext *pContext, const ConVar *pConVar); - - /** - * Static callback that Valve's ConVar object executes when the convar's value changes. - */ -#if defined ORANGEBOX_BUILD - static void OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue); -#else - static void OnConVarChanged(ConVar *pConVar, const char *oldValue); -#endif - - /** - * Callback for when StartQueryCvarValue() has finished. - */ - void OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, - const char *cvarName, const char *cvarValue); -private: - HandleType_t m_ConVarType; - List m_ConVars; - List m_ConVarQueries; - bool m_bIsDLLQueryHooked; - bool m_bIsVSPQueryHooked; -}; - -extern ConVarManager g_ConVarManager; - -#endif // _INCLUDE_SOURCEMOD_CONVARMANAGER_H_ - diff --git a/core/CoreConfig.cpp b/core/CoreConfig.cpp deleted file mode 100644 index 2b0fc95c..00000000 --- a/core/CoreConfig.cpp +++ /dev/null @@ -1,524 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include "CoreConfig.h" -#include "sourcemod.h" -#include "sourcemm_api.h" -#include "sm_srvcmds.h" -#include "sm_version.h" -#include "sm_stringutil.h" -#include "LibrarySys.h" -#include "Logger.h" -#include "PluginSys.h" -#include "ForwardSys.h" - -#ifdef PLATFORM_WINDOWS -ConVar sm_corecfgfile("sm_corecfgfile", "addons\\sourcemod\\configs\\core.cfg", 0, "SourceMod core configuration file"); -#elif defined PLATFORM_LINUX -ConVar sm_corecfgfile("sm_corecfgfile", "addons/sourcemod/configs/core.cfg", 0, "SourceMod core configuration file"); -#endif - -IForward *g_pOnServerCfg = NULL; -IForward *g_pOnConfigsExecuted = NULL; -IForward *g_pOnAutoConfigsBuffered = NULL; -CoreConfig g_CoreConfig; -bool g_bConfigsExecd = false; -bool g_bServerExecd = false; -bool g_bGotServerStart = false; -bool g_bGotTrigger = false; -ConCommand *g_pExecPtr = NULL; -ConVar *g_ServerCfgFile = NULL; - -void CheckAndFinalizeConfigs(); - -#if defined ORANGEBOX_BUILD -SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &); -void Hook_ExecDispatchPre(const CCommand &cmd) -#else -extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0); -extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0); -void Hook_ExecDispatchPre() -#endif -{ -#if !defined ORANGEBOX_BUILD - CCommand cmd; -#endif - - const char *arg = cmd.Arg(1); - - if (!g_bServerExecd - && arg != NULL - && strcmp(arg, g_ServerCfgFile->GetString()) == 0) - { - g_bGotTrigger = true; - } -} - -#if defined ORANGEBOX_BUILD -void Hook_ExecDispatchPost(const CCommand &cmd) -#else -void Hook_ExecDispatchPost() -#endif -{ - if (g_bGotTrigger) - { - g_bGotTrigger = false; - g_bServerExecd = true; - CheckAndFinalizeConfigs(); - } -} - -void CheckAndFinalizeConfigs() -{ - if ((g_bServerExecd || g_ServerCfgFile == NULL) - && g_bGotServerStart) - { - /* Order is important here. We need to buffer things before we send the command out. */ - g_pOnAutoConfigsBuffered->Execute(NULL); - engine->ServerCommand("sm internal 1\n"); - } -} - -void CoreConfig::OnSourceModAllInitialized() -{ - g_RootMenu.AddRootConsoleCommand("config", "Set core configuration options", this); - g_pOnServerCfg = g_Forwards.CreateForward("OnServerCfg", ET_Ignore, 0, NULL); - g_pOnConfigsExecuted = g_Forwards.CreateForward("OnConfigsExecuted", ET_Ignore, 0, NULL); - g_pOnAutoConfigsBuffered = g_Forwards.CreateForward("OnAutoConfigsBuffered", ET_Ignore, 0, NULL); -} - -void CoreConfig::OnSourceModShutdown() -{ - g_RootMenu.RemoveRootConsoleCommand("config", this); - g_Forwards.ReleaseForward(g_pOnServerCfg); - g_Forwards.ReleaseForward(g_pOnConfigsExecuted); - g_Forwards.ReleaseForward(g_pOnAutoConfigsBuffered); - - if (g_pExecPtr != NULL) - { - SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPre, false); - SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPost, true); - g_pExecPtr = NULL; - } -} - -void CoreConfig::OnSourceModLevelChange(const char *mapName) -{ - static bool already_checked = false; - - if (!already_checked) - { - g_ServerCfgFile = icvar->FindVar("servercfgfile"); - if (g_ServerCfgFile != NULL) - { - ConCommandBase *pBase = icvar->GetCommands(); - while (pBase != NULL) - { - if (pBase->IsCommand() && strcmp(pBase->GetName(), "exec") == 0) - { - break; - } - pBase = const_cast(pBase->GetNext()); - } - - g_pExecPtr = (ConCommand *)pBase; - if (g_pExecPtr != NULL) - { - SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPre, false); - SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPost, true); - } - else - { - g_ServerCfgFile = NULL; - } - } - already_checked = true; - } - - g_bConfigsExecd = false; - g_bServerExecd = false; - g_bGotServerStart = false; - g_bGotTrigger = false; -} - -void CoreConfig::OnRootConsoleCommand(const char *cmdname, const CCommand &command) -{ - int argcount = command.ArgC(); - if (argcount >= 4) - { - const char *option = command.Arg(2); - const char *value = command.Arg(3); - - char error[255]; - - ConfigResult res = SetConfigOption(option, value, ConfigSource_Console, error, sizeof(error)); - - if (res == ConfigResult_Reject) - { - g_RootMenu.ConsolePrint("[SM] Could not set config option \"%s\" to \"%s\" (%s)", option, value, error); - } else if (res == ConfigResult_Ignore) { - g_RootMenu.ConsolePrint("[SM] No such config option \"%s\" exists.", option); - } else { - g_RootMenu.ConsolePrint("Config option \"%s\" successfully set to \"%s.\"", option, value); - } - - return; - } - - g_RootMenu.ConsolePrint("[SM] Usage: sm config

IiOr1R3bq6 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

b)ifPgMt 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 diff --git a/extensions/regex/msvc8/regex.sln b/extensions/regex/msvc8/regex.sln deleted file mode 100644 index 1126def0..00000000 --- a/extensions/regex/msvc8/regex.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "regex", "regex.vcproj", "{B3E797CF-4E77-4C9D-B8A8-7589B6902206}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.ActiveCfg = Debug|Win32 - {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.Build.0 = Debug|Win32 - {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.ActiveCfg = Release|Win32 - {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/extensions/regex/msvc8/regex.vcproj b/extensions/regex/msvc8/regex.vcproj deleted file mode 100644 index bfee2772..00000000 --- a/extensions/regex/msvc8/regex.vcproj +++ /dev/null @@ -1,247 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/extensions/regex/pcre.h b/extensions/regex/pcre.h deleted file mode 100644 index 77720e1c..00000000 --- a/extensions/regex/pcre.h +++ /dev/null @@ -1,305 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* This is the public header file for the PCRE library, to be #included by -applications that call the PCRE functions. - - Copyright (c) 1997-2007 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -#ifndef _PCRE_H -#define _PCRE_H - -/* The current PCRE version information. */ - -#define PCRE_MAJOR 7 -#define PCRE_MINOR 4 -#define PCRE_PRERELEASE -#define PCRE_DATE 2007-09-21 - -/* When an application links to a PCRE DLL in Windows, the symbols that are -imported have to be identified as such. When building PCRE, the appropriate -export setting is defined in pcre_internal.h, which includes this file. So we -don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */ - -#define PCRE_STATIC - -#if defined(_WIN32) && !defined(PCRE_STATIC) -# ifndef PCRE_EXP_DECL -# define PCRE_EXP_DECL extern __declspec(dllimport) -# endif -# ifdef __cplusplus -# ifndef PCRECPP_EXP_DECL -# define PCRECPP_EXP_DECL extern __declspec(dllimport) -# endif -# ifndef PCRECPP_EXP_DEFN -# define PCRECPP_EXP_DEFN __declspec(dllimport) -# endif -# endif -#endif - -/* By default, we use the standard "extern" declarations. */ - -#ifndef PCRE_EXP_DECL -# ifdef __cplusplus -# define PCRE_EXP_DECL extern "C" -# else -# define PCRE_EXP_DECL extern -# endif -#endif - -#ifdef __cplusplus -# ifndef PCRECPP_EXP_DECL -# define PCRECPP_EXP_DECL extern -# endif -# ifndef PCRECPP_EXP_DEFN -# define PCRECPP_EXP_DEFN -# endif -#endif - -/* Have to include stdlib.h in order to ensure that size_t is defined; -it is needed here for malloc. */ - -#include - -/* Allow for C++ users */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Options */ - -#define PCRE_CASELESS 0x00000001 -#define PCRE_MULTILINE 0x00000002 -#define PCRE_DOTALL 0x00000004 -#define PCRE_EXTENDED 0x00000008 -#define PCRE_ANCHORED 0x00000010 -#define PCRE_DOLLAR_ENDONLY 0x00000020 -#define PCRE_EXTRA 0x00000040 -#define PCRE_NOTBOL 0x00000080 -#define PCRE_NOTEOL 0x00000100 -#define PCRE_UNGREEDY 0x00000200 -#define PCRE_NOTEMPTY 0x00000400 -#define PCRE_UTF8 0x00000800 -#define PCRE_NO_AUTO_CAPTURE 0x00001000 -#define PCRE_NO_UTF8_CHECK 0x00002000 -#define PCRE_AUTO_CALLOUT 0x00004000 -#define PCRE_PARTIAL 0x00008000 -#define PCRE_DFA_SHORTEST 0x00010000 -#define PCRE_DFA_RESTART 0x00020000 -#define PCRE_FIRSTLINE 0x00040000 -#define PCRE_DUPNAMES 0x00080000 -#define PCRE_NEWLINE_CR 0x00100000 -#define PCRE_NEWLINE_LF 0x00200000 -#define PCRE_NEWLINE_CRLF 0x00300000 -#define PCRE_NEWLINE_ANY 0x00400000 -#define PCRE_NEWLINE_ANYCRLF 0x00500000 -#define PCRE_BSR_ANYCRLF 0x00800000 -#define PCRE_BSR_UNICODE 0x01000000 - -/* Exec-time and get/set-time error codes */ - -#define PCRE_ERROR_NOMATCH (-1) -#define PCRE_ERROR_NULL (-2) -#define PCRE_ERROR_BADOPTION (-3) -#define PCRE_ERROR_BADMAGIC (-4) -#define PCRE_ERROR_UNKNOWN_OPCODE (-5) -#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ -#define PCRE_ERROR_NOMEMORY (-6) -#define PCRE_ERROR_NOSUBSTRING (-7) -#define PCRE_ERROR_MATCHLIMIT (-8) -#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ -#define PCRE_ERROR_BADUTF8 (-10) -#define PCRE_ERROR_BADUTF8_OFFSET (-11) -#define PCRE_ERROR_PARTIAL (-12) -#define PCRE_ERROR_BADPARTIAL (-13) -#define PCRE_ERROR_INTERNAL (-14) -#define PCRE_ERROR_BADCOUNT (-15) -#define PCRE_ERROR_DFA_UITEM (-16) -#define PCRE_ERROR_DFA_UCOND (-17) -#define PCRE_ERROR_DFA_UMLIMIT (-18) -#define PCRE_ERROR_DFA_WSSIZE (-19) -#define PCRE_ERROR_DFA_RECURSE (-20) -#define PCRE_ERROR_RECURSIONLIMIT (-21) -#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */ -#define PCRE_ERROR_BADNEWLINE (-23) - -/* Request types for pcre_fullinfo() */ - -#define PCRE_INFO_OPTIONS 0 -#define PCRE_INFO_SIZE 1 -#define PCRE_INFO_CAPTURECOUNT 2 -#define PCRE_INFO_BACKREFMAX 3 -#define PCRE_INFO_FIRSTBYTE 4 -#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ -#define PCRE_INFO_FIRSTTABLE 5 -#define PCRE_INFO_LASTLITERAL 6 -#define PCRE_INFO_NAMEENTRYSIZE 7 -#define PCRE_INFO_NAMECOUNT 8 -#define PCRE_INFO_NAMETABLE 9 -#define PCRE_INFO_STUDYSIZE 10 -#define PCRE_INFO_DEFAULT_TABLES 11 -#define PCRE_INFO_OKPARTIAL 12 -#define PCRE_INFO_JCHANGED 13 -#define PCRE_INFO_HASCRORLF 14 - -/* Request types for pcre_config(). Do not re-arrange, in order to remain -compatible. */ - -#define PCRE_CONFIG_UTF8 0 -#define PCRE_CONFIG_NEWLINE 1 -#define PCRE_CONFIG_LINK_SIZE 2 -#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 -#define PCRE_CONFIG_MATCH_LIMIT 4 -#define PCRE_CONFIG_STACKRECURSE 5 -#define PCRE_CONFIG_UNICODE_PROPERTIES 6 -#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 -#define PCRE_CONFIG_BSR 8 - -/* Bit flags for the pcre_extra structure. Do not re-arrange or redefine -these bits, just add new ones on the end, in order to remain compatible. */ - -#define PCRE_EXTRA_STUDY_DATA 0x0001 -#define PCRE_EXTRA_MATCH_LIMIT 0x0002 -#define PCRE_EXTRA_CALLOUT_DATA 0x0004 -#define PCRE_EXTRA_TABLES 0x0008 -#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 - -/* Types */ - -struct real_pcre; /* declaration; the definition is private */ -typedef struct real_pcre pcre; - -/* When PCRE is compiled as a C++ library, the subject pointer type can be -replaced with a custom type. For conventional use, the public interface is a -const char *. */ - -#ifndef PCRE_SPTR -#define PCRE_SPTR const char * -#endif - -/* The structure for passing additional data to pcre_exec(). This is defined in -such as way as to be extensible. Always add new fields at the end, in order to -remain compatible. */ - -typedef struct pcre_extra { - unsigned long int flags; /* Bits for which fields are set */ - void *study_data; /* Opaque data from pcre_study() */ - unsigned long int match_limit; /* Maximum number of calls to match() */ - void *callout_data; /* Data passed back in callouts */ - const unsigned char *tables; /* Pointer to character tables */ - unsigned long int match_limit_recursion; /* Max recursive calls to match() */ -} pcre_extra; - -/* The structure for passing out data via the pcre_callout_function. We use a -structure so that new fields can be added on the end in future versions, -without changing the API of the function, thereby allowing old clients to work -without modification. */ - -typedef struct pcre_callout_block { - int version; /* Identifies version of block */ - /* ------------------------ Version 0 ------------------------------- */ - int callout_number; /* Number compiled into pattern */ - int *offset_vector; /* The offset vector */ - PCRE_SPTR subject; /* The subject being matched */ - int subject_length; /* The length of the subject */ - int start_match; /* Offset to start of this match attempt */ - int current_position; /* Where we currently are in the subject */ - int capture_top; /* Max current capture */ - int capture_last; /* Most recently closed capture */ - void *callout_data; /* Data passed in with the call */ - /* ------------------- Added for Version 1 -------------------------- */ - int pattern_position; /* Offset to next item in the pattern */ - int next_item_length; /* Length of next item in the pattern */ - /* ------------------------------------------------------------------ */ -} pcre_callout_block; - -/* Indirection for store get and free functions. These can be set to -alternative malloc/free functions if required. Special ones are used in the -non-recursive case for "frames". There is also an optional callout function -that is triggered by the (?) regex item. For Virtual Pascal, these definitions -have to take another form. */ - -#ifndef VPCOMPAT -PCRE_EXP_DECL void *(*pcre_malloc)(size_t); -PCRE_EXP_DECL void (*pcre_free)(void *); -PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t); -PCRE_EXP_DECL void (*pcre_stack_free)(void *); -PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *); -#else /* VPCOMPAT */ -PCRE_EXP_DECL void *pcre_malloc(size_t); -PCRE_EXP_DECL void pcre_free(void *); -PCRE_EXP_DECL void *pcre_stack_malloc(size_t); -PCRE_EXP_DECL void pcre_stack_free(void *); -PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); -#endif /* VPCOMPAT */ - -/* Exported PCRE functions */ - -PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, - const unsigned char *); -PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, - int *, const unsigned char *); -PCRE_EXP_DECL int pcre_config(int, void *); -PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, - int *, int, const char *, char *, int); -PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *, - int); -PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, - const char *, int, int, int, int *, int , int *, int); -PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, - int, int, int, int *, int); -PCRE_EXP_DECL void pcre_free_substring(const char *); -PCRE_EXP_DECL void pcre_free_substring_list(const char **); -PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, - void *); -PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, - int *, int, const char *, const char **); -PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); -PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, - char **, char **); -PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, - const char **); -PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, - const char ***); -PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *); -PCRE_EXP_DECL const unsigned char *pcre_maketables(void); -PCRE_EXP_DECL int pcre_refcount(pcre *, int); -PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); -PCRE_EXP_DECL const char *pcre_version(void); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* End of pcre.h */ diff --git a/extensions/regex/sdk/smsdk_config.h b/extensions/regex/sdk/smsdk_config.h deleted file mode 100644 index 719ed0c7..00000000 --- a/extensions/regex/sdk/smsdk_config.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Regular Expressions Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ -#define _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ - -#include "svn_version.h" - -/** - * @file smsdk_config.h - * @brief Contains macros for configuring basic extension information. - */ - -/* Basic information exposed publicly */ -#define SMEXT_CONF_NAME "Regex" -#define SMEXT_CONF_DESCRIPTION "Provides regex natives for plugins" -#define SMEXT_CONF_VERSION SVN_FULL_VERSION -#define SMEXT_CONF_AUTHOR "AlliedModders LLC" -#define SMEXT_CONF_URL "http://www.sourcemod.net/" -#define SMEXT_CONF_LOGTAG "REGEX" -#define SMEXT_CONF_LICENSE "GPL" -#define SMEXT_CONF_DATESTRING __DATE__ " " __TIME__ - -/** - * @brief Exposes plugin's main interface. - */ -#define SMEXT_LINK(name) SDKExtension *g_pExtensionIface = name; - -/** - * @brief Sets whether or not this plugin required Metamod. - * NOTE: Uncomment to enable, comment to disable. - */ -//#define SMEXT_CONF_METAMOD - -/** Enable interfaces you want to use here by uncommenting lines */ -//#define SMEXT_ENABLE_FORWARDSYS -#define SMEXT_ENABLE_HANDLESYS -//#define SMEXT_ENABLE_PLAYERHELPERS -//#define SMEXT_ENABLE_DBMANAGER -//#define SMEXT_ENABLE_GAMECONF -//#define SMEXT_ENABLE_MEMUTILS -//#define SMEXT_ENABLE_GAMEHELPERS -//#define SMEXT_ENABLE_TIMERSYS -//#define SMEXT_ENABLE_THREADER -//#define SMEXT_ENABLE_LIBSYS -//#define SMEXT_ENABLE_MENUS -//#define SMEXT_ENABLE_ADTFACTORY -//#define SMEXT_ENABLE_PLUGINSYS -//#define SMEXT_ENABLE_ADMINSYS -//#define SMEXT_ENABLE_TEXTPARSERS -//#define SMEXT_ENABLE_USERMSGS - -#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ diff --git a/extensions/regex/sdk/smsdk_ext.cpp b/extensions/regex/sdk/smsdk_ext.cpp deleted file mode 100644 index bf027ac5..00000000 --- a/extensions/regex/sdk/smsdk_ext.cpp +++ /dev/null @@ -1,455 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Base Extension Code - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include -#include "smsdk_ext.h" - -/** - * @file smsdk_ext.cpp - * @brief Contains wrappers for making Extensions easier to write. - */ - -IExtension *myself = NULL; /**< Ourself */ -IShareSys *g_pShareSys = NULL; /**< Share system */ -IShareSys *sharesys = NULL; /**< Share system */ -ISourceMod *g_pSM = NULL; /**< SourceMod helpers */ -ISourceMod *smutils = NULL; /**< SourceMod helpers */ - -#if defined SMEXT_ENABLE_FORWARDSYS -IForwardManager *g_pForwards = NULL; /**< Forward system */ -IForwardManager *forwards = NULL; /**< Forward system */ -#endif -#if defined SMEXT_ENABLE_HANDLESYS -IHandleSys *g_pHandleSys = NULL; /**< Handle system */ -IHandleSys *handlesys = NULL; /**< Handle system */ -#endif -#if defined SMEXT_ENABLE_PLAYERHELPERS -IPlayerManager *playerhelpers = NULL; /**< Player helpers */ -#endif //SMEXT_ENABLE_PLAYERHELPERS -#if defined SMEXT_ENABLE_DBMANAGER -IDBManager *dbi = NULL; /**< DB Manager */ -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMECONF -IGameConfigManager *gameconfs = NULL; /**< Game config manager */ -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_MEMUTILS -IMemoryUtils *memutils = NULL; -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMEHELPERS -IGameHelpers *gamehelpers = NULL; -#endif -#if defined SMEXT_ENABLE_TIMERSYS -ITimerSystem *timersys = NULL; -#endif -#if defined SMEXT_ENABLE_ADTFACTORY -IADTFactory *adtfactory = NULL; -#endif -#if defined SMEXT_ENABLE_THREADER -IThreader *threader = NULL; -#endif -#if defined SMEXT_ENABLE_LIBSYS -ILibrarySys *libsys = NULL; -#endif -#if defined SMEXT_ENABLE_PLUGINSYS -SourceMod::IPluginManager *plsys; -#endif -#if defined SMEXT_ENABLE_MENUS -IMenuManager *menus = NULL; -#endif -#if defined SMEXT_ENABLE_ADMINSYS -IAdminSystem *adminsys = NULL; -#endif -#if defined SMEXT_ENABLE_TEXTPARSERS -ITextParsers *textparsers = NULL; -#endif -#if defined SMEXT_ENABLE_USERMSGS -IUserMessages *usermsgs = NULL; -#endif - -/** Exports the main interface */ -PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI() -{ - return g_pExtensionIface; -} - -SDKExtension::SDKExtension() -{ -#if defined SMEXT_CONF_METAMOD - m_SourceMMLoaded = false; - m_WeAreUnloaded = false; - m_WeGotPauseChange = false; -#endif -} - -bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late) -{ - g_pShareSys = sharesys = sys; - myself = me; - -#if defined SMEXT_CONF_METAMOD - m_WeAreUnloaded = true; - - if (!m_SourceMMLoaded) - { - if (error) - { - snprintf(error, maxlength, "Metamod attach failed"); - } - return false; - } -#endif - SM_GET_IFACE(SOURCEMOD, g_pSM); - smutils = g_pSM; -#if defined SMEXT_ENABLE_HANDLESYS - SM_GET_IFACE(HANDLESYSTEM, g_pHandleSys); - handlesys = g_pHandleSys; -#endif -#if defined SMEXT_ENABLE_FORWARDSYS - SM_GET_IFACE(FORWARDMANAGER, g_pForwards); - forwards = g_pForwards; -#endif -#if defined SMEXT_ENABLE_PLAYERHELPERS - SM_GET_IFACE(PLAYERMANAGER, playerhelpers); -#endif -#if defined SMEXT_ENABLE_DBMANAGER - SM_GET_IFACE(DBI, dbi); -#endif -#if defined SMEXT_ENABLE_GAMECONF - SM_GET_IFACE(GAMECONFIG, gameconfs); -#endif -#if defined SMEXT_ENABLE_MEMUTILS - SM_GET_IFACE(MEMORYUTILS, memutils); -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS - SM_GET_IFACE(GAMEHELPERS, gamehelpers); -#endif -#if defined SMEXT_ENABLE_TIMERSYS - SM_GET_IFACE(TIMERSYS, timersys); -#endif -#if defined SMEXT_ENABLE_ADTFACTORY - SM_GET_IFACE(ADTFACTORY, adtfactory); -#endif -#if defined SMEXT_ENABLE_THREADER - SM_GET_IFACE(THREADER, threader); -#endif -#if defined SMEXT_ENABLE_LIBSYS - SM_GET_IFACE(LIBRARYSYS, libsys); -#endif -#if defined SMEXT_ENABLE_PLUGINSYS - SM_GET_IFACE(PLUGINSYSTEM, plsys); -#endif -#if defined SMEXT_ENABLE_MENUS - SM_GET_IFACE(MENUMANAGER, menus); -#endif -#if defined SMEXT_ENABLE_ADMINSYS - SM_GET_IFACE(ADMINSYS, adminsys); -#endif -#if defined SMEXT_ENABLE_TEXTPARSERS - SM_GET_IFACE(TEXTPARSERS, textparsers); -#endif -#if defined SMEXT_ENABLE_USERMSGS - SM_GET_IFACE(USERMSGS, usermsgs); -#endif - - if (SDK_OnLoad(error, maxlength, late)) - { -#if defined SMEXT_CONF_METAMOD - m_WeAreUnloaded = true; -#endif - return true; - } - - return false; -} - -bool SDKExtension::IsMetamodExtension() -{ -#if defined SMEXT_CONF_METAMOD - return true; -#else - return false; -#endif -} - -void SDKExtension::OnExtensionPauseChange(bool state) -{ -#if defined SMEXT_CONF_METAMOD - m_WeGotPauseChange = true; -#endif - SDK_OnPauseChange(state); -} - -void SDKExtension::OnExtensionsAllLoaded() -{ - SDK_OnAllLoaded(); -} - -void SDKExtension::OnExtensionUnload() -{ -#if defined SMEXT_CONF_METAMOD - m_WeAreUnloaded = true; -#endif - SDK_OnUnload(); -} - -const char *SDKExtension::GetExtensionAuthor() -{ - return SMEXT_CONF_AUTHOR; -} - -const char *SDKExtension::GetExtensionDateString() -{ - return SMEXT_CONF_DATESTRING; -} - -const char *SDKExtension::GetExtensionDescription() -{ - return SMEXT_CONF_DESCRIPTION; -} - -const char *SDKExtension::GetExtensionVerString() -{ - return SMEXT_CONF_VERSION; -} - -const char *SDKExtension::GetExtensionName() -{ - return SMEXT_CONF_NAME; -} - -const char *SDKExtension::GetExtensionTag() -{ - return SMEXT_CONF_LOGTAG; -} - -const char *SDKExtension::GetExtensionURL() -{ - return SMEXT_CONF_URL; -} - -bool SDKExtension::SDK_OnLoad(char *error, size_t maxlength, bool late) -{ - return true; -} - -void SDKExtension::SDK_OnUnload() -{ -} - -void SDKExtension::SDK_OnPauseChange(bool paused) -{ -} - -void SDKExtension::SDK_OnAllLoaded() -{ -} - -#if defined SMEXT_CONF_METAMOD - -PluginId g_PLID = 0; /**< Metamod plugin ID */ -ISmmPlugin *g_PLAPI = NULL; /**< Metamod plugin API */ -SourceHook::ISourceHook *g_SHPtr = NULL; /**< SourceHook pointer */ -ISmmAPI *g_SMAPI = NULL; /**< SourceMM API pointer */ - -IVEngineServer *engine = NULL; /**< IVEngineServer pointer */ -IServerGameDLL *gamedll = NULL; /**< IServerGameDLL pointer */ - -/** Exposes the extension to Metamod */ -SMM_API void *PL_EXPOSURE(const char *name, int *code) -{ -#if defined METAMOD_PLAPI_VERSION - if (name && !strcmp(name, METAMOD_PLAPI_NAME)) -#else - if (name && !strcmp(name, PLAPI_NAME)) -#endif - { - if (code) - { - *code = IFACE_OK; - } - return static_cast(g_pExtensionIface); - } - - if (code) - { - *code = IFACE_FAILED; - } - - return NULL; -} - -bool SDKExtension::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) -{ - PLUGIN_SAVEVARS(); - -#if defined METAMOD_PLAPI_VERSION - GET_V_IFACE_ANY(serverFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); - GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); -#else - GET_V_IFACE_ANY(GetServerFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); - GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); -#endif - - m_SourceMMLoaded = true; - - return SDK_OnMetamodLoad(ismm, error, maxlen, late); -} - -bool SDKExtension::Unload(char *error, size_t maxlen) -{ - if (!m_WeAreUnloaded) - { - if (error) - { - snprintf(error, maxlen, "This extension must be unloaded by SourceMod."); - } - return false; - } - - return SDK_OnMetamodUnload(error, maxlen); -} - -bool SDKExtension::Pause(char *error, size_t maxlen) -{ - if (!m_WeGotPauseChange) - { - if (error) - { - snprintf(error, maxlen, "This extension must be paused by SourceMod."); - } - return false; - } - - m_WeGotPauseChange = false; - - return SDK_OnMetamodPauseChange(true, error, maxlen); -} - -bool SDKExtension::Unpause(char *error, size_t maxlen) -{ - if (!m_WeGotPauseChange) - { - if (error) - { - snprintf(error, maxlen, "This extension must be unpaused by SourceMod."); - } - return false; - } - - m_WeGotPauseChange = false; - - return SDK_OnMetamodPauseChange(false, error, maxlen); -} - -const char *SDKExtension::GetAuthor() -{ - return GetExtensionAuthor(); -} - -const char *SDKExtension::GetDate() -{ - return GetExtensionDateString(); -} - -const char *SDKExtension::GetDescription() -{ - return GetExtensionDescription(); -} - -const char *SDKExtension::GetLicense() -{ - return SMEXT_CONF_LICENSE; -} - -const char *SDKExtension::GetLogTag() -{ - return GetExtensionTag(); -} - -const char *SDKExtension::GetName() -{ - return GetExtensionName(); -} - -const char *SDKExtension::GetURL() -{ - return GetExtensionURL(); -} - -const char *SDKExtension::GetVersion() -{ - return GetExtensionVerString(); -} - -bool SDKExtension::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late) -{ - return true; -} - -bool SDKExtension::SDK_OnMetamodUnload(char *error, size_t maxlength) -{ - return true; -} - -bool SDKExtension::SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength) -{ - return true; -} - -#endif - -/* Overload a few things to prevent libstdc++ linking */ -#if defined __linux__ -extern "C" void __cxa_pure_virtual(void) -{ -} - -void *operator new(size_t size) -{ - return malloc(size); -} - -void *operator new[](size_t size) -{ - return malloc(size); -} - -void operator delete(void *ptr) -{ - free(ptr); -} - -void operator delete[](void * ptr) -{ - free(ptr); -} -#endif diff --git a/extensions/regex/sdk/smsdk_ext.h b/extensions/regex/sdk/smsdk_ext.h deleted file mode 100644 index 0ee0dfa2..00000000 --- a/extensions/regex/sdk/smsdk_ext.h +++ /dev/null @@ -1,327 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Base Extension Code - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ -#define _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ - -/** - * @file smsdk_ext.h - * @brief Contains wrappers for making Extensions easier to write. - */ - -#include "smsdk_config.h" -#include -#include -#include -#include -#include -#if defined SMEXT_ENABLE_FORWARDSYS -#include -#endif //SMEXT_ENABLE_FORWARDSYS -#if defined SMEXT_ENABLE_PLAYERHELPERS -#include -#endif //SMEXT_ENABLE_PlAYERHELPERS -#if defined SMEXT_ENABLE_DBMANAGER -#include -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMECONF -#include -#endif -#if defined SMEXT_ENABLE_MEMUTILS -#include -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS -#include -#endif -#if defined SMEXT_ENABLE_TIMERSYS -#include -#endif -#if defined SMEXT_ENABLE_ADTFACTORY -#include -#endif -#if defined SMEXT_ENABLE_THREADER -#include -#endif -#if defined SMEXT_ENABLE_LIBSYS -#include -#endif -#if defined SMEXT_ENABLE_PLUGINSYS -#include -#endif -#if defined SMEXT_ENABLE_MENUS -#include -#endif -#if defined SMEXT_ENABLE_ADMINSYS -#include -#endif -#if defined SMEXT_ENABLE_TEXTPARSERS -#include -#endif -#if defined SMEXT_ENABLE_USERMSGS -#include -#endif - -#if defined SMEXT_CONF_METAMOD -#include -#include -#endif - -using namespace SourceMod; -using namespace SourcePawn; - -class SDKExtension : -#if defined SMEXT_CONF_METAMOD - public ISmmPlugin, -#endif - public IExtensionInterface -{ -public: - /** Constructor */ - SDKExtension(); -public: - /** - * @brief This is called after the initial loading sequence has been processed. - * - * @param error Error message buffer. - * @param maxlength Size of error message buffer. - * @param late Whether or not the module was loaded after map load. - * @return True to succeed loading, false to fail. - */ - virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late); - - /** - * @brief This is called right before the extension is unloaded. - */ - virtual void SDK_OnUnload(); - - /** - * @brief This is called once all known extensions have been loaded. - */ - virtual void SDK_OnAllLoaded(); - - /** - * @brief Called when the pause state is changed. - */ - virtual void SDK_OnPauseChange(bool paused); - -#if defined SMEXT_CONF_METAMOD - /** - * @brief Called when Metamod is attached, before the extension version is called. - * - * @param error Error buffer. - * @param maxlength Maximum size of error buffer. - * @param late Whether or not Metamod considers this a late load. - * @return True to succeed, false to fail. - */ - virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late); - - /** - * @brief Called when Metamod is detaching, after the extension version is called. - * NOTE: By default this is blocked unless sent from SourceMod. - * - * @param error Error buffer. - * @param maxlength Maximum size of error buffer. - * @return True to succeed, false to fail. - */ - virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength); - - /** - * @brief Called when Metamod's pause state is changing. - * NOTE: By default this is blocked unless sent from SourceMod. - * - * @param paused Pause state being set. - * @param error Error buffer. - * @param maxlength Maximum size of error buffer. - * @return True to succeed, false to fail. - */ - virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength); -#endif - -public: //IExtensionInterface - virtual bool OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late); - virtual void OnExtensionUnload(); - virtual void OnExtensionsAllLoaded(); - - /** Returns whether or not this is a Metamod-based extension */ - virtual bool IsMetamodExtension(); - - /** - * @brief Called when the pause state changes. - * - * @param state True if being paused, false if being unpaused. - */ - virtual void OnExtensionPauseChange(bool state); - - /** Returns name */ - virtual const char *GetExtensionName(); - /** Returns URL */ - virtual const char *GetExtensionURL(); - /** Returns log tag */ - virtual const char *GetExtensionTag(); - /** Returns author */ - virtual const char *GetExtensionAuthor(); - /** Returns version string */ - virtual const char *GetExtensionVerString(); - /** Returns description string */ - virtual const char *GetExtensionDescription(); - /** Returns date string */ - virtual const char *GetExtensionDateString(); -#if defined SMEXT_CONF_METAMOD -public: //ISmmPlugin - /** Called when the extension is attached to Metamod. */ - virtual bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlength, bool late); - /** Returns the author to MM */ - virtual const char *GetAuthor(); - /** Returns the name to MM */ - virtual const char *GetName(); - /** Returns the description to MM */ - virtual const char *GetDescription(); - /** Returns the URL to MM */ - virtual const char *GetURL(); - /** Returns the license to MM */ - virtual const char *GetLicense(); - /** Returns the version string to MM */ - virtual const char *GetVersion(); - /** Returns the date string to MM */ - virtual const char *GetDate(); - /** Returns the logtag to MM */ - virtual const char *GetLogTag(); - /** Called on unload */ - virtual bool Unload(char *error, size_t maxlength); - /** Called on pause */ - virtual bool Pause(char *error, size_t maxlength); - /** Called on unpause */ - virtual bool Unpause(char *error, size_t maxlength); -private: - bool m_SourceMMLoaded; - bool m_WeAreUnloaded; - bool m_WeGotPauseChange; -#endif -}; - -extern SDKExtension *g_pExtensionIface; -extern IExtension *myself; - -extern IShareSys *g_pShareSys; -extern IShareSys *sharesys; /* Note: Newer name */ -extern ISourceMod *g_pSM; -extern ISourceMod *smutils; /* Note: Newer name */ - -/* Optional interfaces are below */ -#if defined SMEXT_ENABLE_FORWARDSYS -extern IForwardManager *g_pForwards; -extern IForwardManager *forwards; /* Note: Newer name */ -#endif //SMEXT_ENABLE_FORWARDSYS -#if defined SMEXT_ENABLE_HANDLESYS -extern IHandleSys *g_pHandleSys; -extern IHandleSys *handlesys; /* Note: Newer name */ -#endif //SMEXT_ENABLE_HANDLESYS -#if defined SMEXT_ENABLE_PLAYERHELPERS -extern IPlayerManager *playerhelpers; -#endif //SMEXT_ENABLE_PLAYERHELPERS -#if defined SMEXT_ENABLE_DBMANAGER -extern IDBManager *dbi; -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMECONF -extern IGameConfigManager *gameconfs; -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_MEMUTILS -extern IMemoryUtils *memutils; -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS -extern IGameHelpers *gamehelpers; -#endif -#if defined SMEXT_ENABLE_TIMERSYS -extern ITimerSystem *timersys; -#endif -#if defined SMEXT_ENABLE_ADTFACTORY -extern IADTFactory *adtfactory; -#endif -#if defined SMEXT_ENABLE_THREADER -extern IThreader *threader; -#endif -#if defined SMEXT_ENABLE_LIBSYS -extern ILibrarySys *libsys; -#endif -#if defined SMEXT_ENABLE_PLUGINSYS -extern SourceMod::IPluginManager *plsys; -#endif -#if defined SMEXT_ENABLE_MENUS -extern IMenuManager *menus; -#endif -#if defined SMEXT_ENABLE_ADMINSYS -extern IAdminSystem *adminsys; -#endif -#if defined SMEXT_ENABLE_USERMSGS -extern IUserMessages *usermsgs; -#endif - -#if defined SMEXT_CONF_METAMOD -PLUGIN_GLOBALVARS(); -extern IVEngineServer *engine; -extern IServerGameDLL *gamedll; -#endif - -/** Creates a SourceMod interface macro pair */ -#define SM_MKIFACE(name) SMINTERFACE_##name##_NAME, SMINTERFACE_##name##_VERSION -/** Automates retrieving SourceMod interfaces */ -#define SM_GET_IFACE(prefix, addr) \ - if (!g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr)) \ - { \ - if (error != NULL && maxlength) \ - { \ - size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \ - if (len >= maxlength) \ - { \ - error[maxlength - 1] = '\0'; \ - } \ - } \ - return false; \ - } -/** Automates retrieving SourceMod interfaces when needed outside of SDK_OnLoad() */ -#define SM_GET_LATE_IFACE(prefix, addr) \ - g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr) -/** Validates a SourceMod interface pointer */ -#define SM_CHECK_IFACE(prefix, addr) \ - if (!addr) \ - { \ - if (error != NULL && maxlength) \ - { \ - size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \ - if (len >= maxlength) \ - { \ - error[maxlength - 1] = '\0'; \ - } \ - } \ - return false; \ - } - -#endif // _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ diff --git a/extensions/regex/svn_version.h b/extensions/regex/svn_version.h deleted file mode 100644 index 7bd120c9..00000000 --- a/extensions/regex/svn_version.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Regular Expressions Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -/** - * Autogenerated by build scripts - */ - -#ifndef _INCLUDE_REGEXEXT_VERSION_H_ -#define _INCLUDE_REGEXEXT_VERSION_H_ - -#define SVN_FULL_VERSION "1.1.0-svn" -#define SVN_FILE_VERSION 1,1,0,2230 - -#endif //_INCLUDE_REGEXEXT_VERSION_H_ diff --git a/extensions/regex/svn_version.tpl b/extensions/regex/svn_version.tpl deleted file mode 100644 index 3cbf9f19..00000000 --- a/extensions/regex/svn_version.tpl +++ /dev/null @@ -1,42 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Regular Expressions Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -/** - * Autogenerated by build scripts - */ - -#ifndef _INCLUDE_REGEXEXT_VERSION_H_ -#define _INCLUDE_REGEXEXT_VERSION_H_ - -#define SVN_FULL_VERSION "$PMAJOR$.$PMINOR$.$PREVISION$-svn" -#define SVN_FILE_VERSION $PMAJOR$,$PMINOR$,$PREVISION$,$GLOBAL_BUILD$ - -#endif //_INCLUDE_REGEXEXT_VERSION_H_ diff --git a/extensions/regex/version.rc b/extensions/regex/version.rc deleted file mode 100644 index f09d4127..00000000 --- a/extensions/regex/version.rc +++ /dev/null @@ -1,104 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -//#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -#include "svn_version.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION SVN_FILE_VERSION - PRODUCTVERSION SVN_FILE_VERSION - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "Comments", "SourceMod Regular Expression Extension" - VALUE "FileDescription", "SourceMod Regular Expression Extension" - VALUE "FileVersion", SVN_FULL_VERSION - VALUE "InternalName", "SourceMod Regular Expression Extension" - VALUE "LegalCopyright", "Copyright (c) 2004-2008, AlliedModders LLC" - VALUE "OriginalFilename", "regex.ext.dll" - VALUE "ProductName", "SourceMod Regular Expression Extension" - VALUE "ProductVersion", SVN_FULL_VERSION - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0, 1200 - END -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/extensions/sdktools/CellRecipientFilter.h b/extensions/sdktools/CellRecipientFilter.h deleted file mode 100644 index e48ed7d1..00000000 --- a/extensions/sdktools/CellRecipientFilter.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_CELLRECIPIENTFILTER_H_ -#define _INCLUDE_SOURCEMOD_CELLRECIPIENTFILTER_H_ - -#include -#include - -class CellRecipientFilter : public IRecipientFilter -{ -public: - CellRecipientFilter() : m_IsReliable(false), m_IsInitMessage(false), m_Size(0) {} - ~CellRecipientFilter() {} -public: //IRecipientFilter - bool IsReliable() const; - bool IsInitMessage() const; - int GetRecipientCount() const; - int GetRecipientIndex(int slot) const; -public: - void Initialize(cell_t *ptr, size_t count); - void SetToReliable(bool isreliable); - void SetToInit(bool isinitmsg); - void Reset(); -private: - cell_t m_Players[255]; - bool m_IsReliable; - bool m_IsInitMessage; - size_t m_Size; -}; - -inline void CellRecipientFilter::Reset() -{ - m_IsReliable = false; - m_IsInitMessage = false; - m_Size = 0; -} - -inline bool CellRecipientFilter::IsReliable() const -{ - return m_IsReliable; -} - -inline bool CellRecipientFilter::IsInitMessage() const -{ - return m_IsInitMessage; -} - -inline int CellRecipientFilter::GetRecipientCount() const -{ - return m_Size; -} - -inline int CellRecipientFilter::GetRecipientIndex(int slot) const -{ - if ((slot < 0) || (slot >= GetRecipientCount())) - { - return -1; - } - return static_cast(m_Players[slot]); -} - -inline void CellRecipientFilter::SetToInit(bool isinitmsg) -{ - m_IsInitMessage = isinitmsg; -} - -inline void CellRecipientFilter::SetToReliable(bool isreliable) -{ - m_IsReliable = isreliable; -} - -inline void CellRecipientFilter::Initialize(cell_t *ptr, size_t count) -{ - memcpy(m_Players, ptr, count * sizeof(cell_t)); - m_Size = count; -} - -#endif //_INCLUDE_SOURCEMOD_CELLRECIPIENTFILTER_H_ diff --git a/extensions/sdktools/Makefile b/extensions/sdktools/Makefile deleted file mode 100644 index cdc676cc..00000000 --- a/extensions/sdktools/Makefile +++ /dev/null @@ -1,129 +0,0 @@ -# (C)2004-2008 SourceMod Development Team -# Makefile written by David "BAILOPAN" Anderson - -SMSDK = ../.. -SRCDS_BASE = ~/srcds -HL2SDK_ORIG = ../../../hl2sdk -HL2SDK_OB = ../../../hl2sdk-ob -SOURCEMM14 = ../../../sourcemm-1.4 -SOURCEMM16 = ../../../sourcemm-1.6 - -##################################### -### EDIT BELOW FOR OTHER PROJECTS ### -##################################### - -PROJECT = sdktools - -#Uncomment for Metamod: Source enabled extension -USEMETA = true - -OBJECTS = sdk/smsdk_ext.cpp extension.cpp vdecoder.cpp vcallbuilder.cpp vcaller.cpp \ - vnatives.cpp vsound.cpp tenatives.cpp trnatives.cpp tempents.cpp vstringtable.cpp \ - vhelpers.cpp vglobals.cpp voice.cpp inputnatives.cpp teamnatives.cpp output.cpp \ - outputnatives.cpp - -############################################## -### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ### -############################################## - -C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing -C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3 -C_GCC4_FLAGS = -fvisibility=hidden -CPP_GCC4_FLAGS = -fvisibility-inlines-hidden -CPP = gcc-4.1 - -override ENGSET = false -ifeq "$(ENGINE)" "original" - HL2SDK = $(HL2SDK_ORIG) - HL2PUB = $(HL2SDK_ORIG)/public - HL2LIB = $(HL2SDK_ORIG)/linux_sdk - METAMOD = $(SOURCEMM14) - INCLUDE += -I$(HL2SDK)/public/dlls - SRCDS = $(SRCDS_BASE) - override ENGSET = true -endif -ifeq "$(ENGINE)" "orangebox" - HL2SDK = $(HL2SDK_OB) - HL2PUB = $(HL2SDK_OB)/public - HL2LIB = $(HL2SDK_OB)/linux_sdk - CFLAGS += -DORANGEBOX_BUILD - METAMOD = $(SOURCEMM16) - INCLUDE += -I$(HL2SDK)/public/game/server -I$(HL2SDK)/common - SRCDS = $(SRCDS_BASE)/orangebox - override ENGSET = true -endif - -ifeq "$(USEMETA)" "true" - LINK_HL2 = $(HL2LIB)/tier1_i486.a $(HL2LIB)/mathlib_i486.a vstdlib_i486.so tier0_i486.so - - LINK += $(LINK_HL2) - - INCLUDE += -I. -I.. -Isdk -I$(HL2PUB) -I$(HL2PUB)/engine -I$(HL2PUB)/mathlib -I$(HL2PUB)/tier0 \ - -I$(HL2PUB)/tier1 -I$(METAMOD) -I$(METAMOD)/sourcehook -I$(METAMOD)/sourcemm -I$(SMSDK)/public \ - -I$(SMSDK)/public/extensions -I$(SMSDK)/public/sourcepawn -else - INCLUDE += -I. -I.. -Isdk -I$(SMSDK)/public -I$(SMSDK)/public/sourcepawn -endif - -LINK += -static-libgcc - -CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \ - -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror -Wno-switch \ - -Wno-unused -mfpmath=sse -msse -DSOURCEMOD_BUILD -DHAVE_STDINT_H -m32 -CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti -fno-threadsafe-statics - -################################################ -### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ### -################################################ - -ifeq "$(DEBUG)" "true" - BIN_DIR = Debug - CFLAGS += $(C_DEBUG_FLAGS) -else - BIN_DIR = Release - CFLAGS += $(C_OPT_FLAGS) -endif - -ifeq "$(USEMETA)" "true" - BIN_DIR := $(BIN_DIR).$(ENGINE) -endif - -GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1) -ifeq "$(GCC_VERSION)" "4" - CFLAGS += $(C_GCC4_FLAGS) - CPPFLAGS += $(CPP_GCC4_FLAGS) -endif - -BINARY = $(PROJECT).ext.so - -OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) - -$(BIN_DIR)/%.o: %.cpp - $(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< - -all: check - mkdir -p $(BIN_DIR)/sdk - if [ "$(USEMETA)" == "true" ]; then \ - ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so; \ - ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so; \ - fi - $(MAKE) -f Makefile extension - -check: - if [ "$(USEMETA)" == "true" ] && [ "$(ENGSET)" == "false" ]; then \ - echo "You must supply ENGINE=orangebox or ENGINE=original"; \ - exit 1; \ - fi - -extension: check $(OBJ_LINUX) - $(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -shared -ldl -lm -o$(BIN_DIR)/$(BINARY) - -debug: - $(MAKE) -f Makefile all DEBUG=true - -default: all - -clean: check - rm -rf $(BIN_DIR)/*.o - rm -rf $(BIN_DIR)/sdk/*.o - rm -rf $(BIN_DIR)/$(BINARY) diff --git a/extensions/sdktools/detours.h b/extensions/sdktools/detours.h deleted file mode 100644 index ab7a30c6..00000000 --- a/extensions/sdktools/detours.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_DETOURS_H_ -#define _INCLUDE_SOURCEMOD_DETOURS_H_ - -#if defined PLATFORM_LINUX -#include -#define PAGE_SIZE 4096 -#define ALIGN(ar) ((long)ar & ~(PAGE_SIZE-1)) -#define PAGE_EXECUTE_READWRITE PROT_READ|PROT_WRITE|PROT_EXEC -#endif - -struct patch_t -{ - patch_t() - { - patch[0] = 0; - bytes = 0; - } - unsigned char patch[20]; - size_t bytes; -}; - -inline void ProtectMemory(void *addr, int length, int prot) -{ -#if defined PLATFORM_LINUX - void *addr2 = (void *)ALIGN(addr); - mprotect(addr2, sysconf(_SC_PAGESIZE), prot); -#elif defined PLATFORM_WINDOWS - DWORD old_prot; - VirtualProtect(addr, length, prot, &old_prot); -#endif -} - -inline void SetMemPatchable(void *address, size_t size) -{ - ProtectMemory(address, (int)size, PAGE_EXECUTE_READWRITE); -} - -inline void DoGatePatch(unsigned char *target, void *callback) -{ - SetMemPatchable(target, 20); - - target[0] = 0xFF; /* JMP */ - target[1] = 0x25; /* MEM32 */ - *(void **)(&target[2]) = callback; -} - -inline void ApplyPatch(void *address, int offset, const patch_t *patch, patch_t *restore) -{ - ProtectMemory(address, 20, PAGE_EXECUTE_READWRITE); - - unsigned char *addr = (unsigned char *)address + offset; - if (restore) - { - for (size_t i=0; ibytes; i++) - { - restore->patch[i] = addr[i]; - } - restore->bytes = patch->bytes; - } - - for (size_t i=0; ibytes; i++) - { - addr[i] = patch->patch[i]; - } -} - -#endif //_INCLUDE_SOURCEMOD_DETOURS_H_ diff --git a/extensions/sdktools/extension.cpp b/extensions/sdktools/extension.cpp deleted file mode 100644 index befdbe67..00000000 --- a/extensions/sdktools/extension.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "extension.h" -#include "vcallbuilder.h" -#include "vnatives.h" -#include "vhelpers.h" -#include "vglobals.h" -#include "tempents.h" -#include "vsound.h" -#include "output.h" - -#if defined ORANGEBOX_BUILD - #define SDKTOOLS_GAME_FILE "sdktools.games.ep2" -#else - #define SDKTOOLS_GAME_FILE "sdktools.games" -#endif - -/** - * @file extension.cpp - * @brief Implements SDK Tools extension code. - */ - -SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool); - -SDKTools g_SdkTools; /**< Global singleton for extension's main interface */ -IServerGameEnts *gameents = NULL; -IEngineTrace *enginetrace = NULL; -IEngineSound *engsound = NULL; -INetworkStringTableContainer *netstringtables = NULL; -IServerPluginHelpers *pluginhelpers = NULL; -IBinTools *g_pBinTools = NULL; -IGameConfig *g_pGameConf = NULL; -IGameHelpers *g_pGameHelpers = NULL; -IServerGameClients *serverClients = NULL; -IVoiceServer *voiceserver = NULL; -IPlayerInfoManager *playerinfomngr = NULL; -ICvar *icvar = NULL; -IServer *iserver = NULL; -SourceHook::CallClass *enginePatch = NULL; -SourceHook::CallClass *enginesoundPatch = NULL; -HandleType_t g_CallHandle = 0; -HandleType_t g_TraceHandle = 0; - -SMEXT_LINK(&g_SdkTools); - -extern sp_nativeinfo_t g_CallNatives[]; -extern sp_nativeinfo_t g_TENatives[]; -extern sp_nativeinfo_t g_TRNatives[]; -extern sp_nativeinfo_t g_StringTableNatives[]; -extern sp_nativeinfo_t g_VoiceNatives[]; -extern sp_nativeinfo_t g_EntInputNatives[]; -extern sp_nativeinfo_t g_TeamNatives[]; - -bool SDKTools::SDK_OnLoad(char *error, size_t maxlength, bool late) -{ - if (!gameconfs->LoadGameConfigFile(SDKTOOLS_GAME_FILE, &g_pGameConf, error, maxlength)) - { - return false; - } - - sharesys->AddDependency(myself, "bintools.ext", true, true); - sharesys->AddNatives(myself, g_CallNatives); - sharesys->AddNatives(myself, g_Natives); - sharesys->AddNatives(myself, g_TENatives); - sharesys->AddNatives(myself, g_SoundNatives); - sharesys->AddNatives(myself, g_TRNatives); - sharesys->AddNatives(myself, g_StringTableNatives); - sharesys->AddNatives(myself, g_VoiceNatives); - sharesys->AddNatives(myself, g_EntInputNatives); - sharesys->AddNatives(myself, g_TeamNatives); - sharesys->AddNatives(myself, g_EntOutputNatives); - - SM_GET_IFACE(GAMEHELPERS, g_pGameHelpers); - - playerhelpers->AddClientListener(&g_SdkTools); - g_CallHandle = handlesys->CreateType("ValveCall", this, 0, NULL, NULL, myself->GetIdentity(), NULL); - - TypeAccess TraceAccess; - handlesys->InitAccessDefaults(&TraceAccess, NULL); - TraceAccess.ident = myself->GetIdentity(); - TraceAccess.access[HTypeAccess_Create] = true; - TraceAccess.access[HTypeAccess_Inherit] = true; - g_TraceHandle = handlesys->CreateType("TraceRay", this, 0, &TraceAccess, NULL, myself->GetIdentity(), NULL); - -#if defined ORANGEBOX_BUILD - g_pCVar = icvar; -#endif - CONVAR_REGISTER(this); - - SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SDKTools::LevelInit, true); - - playerhelpers->RegisterCommandTargetProcessor(this); - - MathLib_Init(2.2f, 2.2f, 0.0f, 2); - - spengine = g_pSM->GetScriptingEngine(); - - plsys->AddPluginsListener(&g_OutputManager); - - g_OutputManager.Init(); - - VoiceInit(); - - return true; -} - -void SDKTools::OnHandleDestroy(HandleType_t type, void *object) -{ - if (type == g_CallHandle) - { - ValveCall *v = (ValveCall *)object; - delete v; - } - else if (type == g_TraceHandle) - { - trace_t *tr = (trace_t *)object; - delete tr; - } -} - -void SDKTools::SDK_OnUnload() -{ - SourceHook::List::iterator iter; - for (iter = g_RegCalls.begin(); - iter != g_RegCalls.end(); - iter++) - { - delete (*iter); - } - g_RegCalls.clear(); - ShutdownHelpers(); - - if (g_pAcceptInput) - { - g_pAcceptInput->Destroy(); - g_pAcceptInput = NULL; - } - - g_TEManager.Shutdown(); - s_TempEntHooks.Shutdown(); - s_SoundHooks.Shutdown(); - - gameconfs->CloseGameConfigFile(g_pGameConf); - playerhelpers->RemoveClientListener(&g_SdkTools); - playerhelpers->UnregisterCommandTargetProcessor(this); - plsys->RemovePluginsListener(&g_OutputManager); - - SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SDKTools::LevelInit, true); - - if (enginePatch) - { - SH_RELEASE_CALLCLASS(enginePatch); - enginePatch = NULL; - } - if (enginesoundPatch) - { - SH_RELEASE_CALLCLASS(enginesoundPatch); - enginesoundPatch = NULL; - } -} - -bool SDKTools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late) -{ - GET_V_IFACE_ANY(GetServerFactory, gameents, IServerGameEnts, INTERFACEVERSION_SERVERGAMEENTS); - GET_V_IFACE_ANY(GetEngineFactory, engsound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION); - GET_V_IFACE_ANY(GetEngineFactory, enginetrace, IEngineTrace, INTERFACEVERSION_ENGINETRACE_SERVER); - GET_V_IFACE_ANY(GetEngineFactory, netstringtables, INetworkStringTableContainer, INTERFACENAME_NETWORKSTRINGTABLESERVER); - GET_V_IFACE_ANY(GetEngineFactory, pluginhelpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS); - GET_V_IFACE_ANY(GetServerFactory, serverClients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS); - GET_V_IFACE_ANY(GetEngineFactory, voiceserver, IVoiceServer, INTERFACEVERSION_VOICESERVER); - GET_V_IFACE_ANY(GetServerFactory, playerinfomngr, IPlayerInfoManager, INTERFACEVERSION_PLAYERINFOMANAGER); - GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION); - - enginePatch = SH_GET_CALLCLASS(engine); - enginesoundPatch = SH_GET_CALLCLASS(engsound); - - return true; -} - -void SDKTools::SDK_OnAllLoaded() -{ - SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools); - - if (!g_pBinTools) - { - return; - } - - g_TEManager.Initialize(); - s_TempEntHooks.Initialize(); - s_SoundHooks.Initialize(); - InitializeValveGlobals(); - GetIServer(); -} - -bool SDKTools::QueryRunning(char *error, size_t maxlength) -{ - SM_CHECK_IFACE(BINTOOLS, g_pBinTools); - - return true; -} - -bool SDKTools::QueryInterfaceDrop(SMInterface *pInterface) -{ - if (pInterface == g_pBinTools) - { - return false; - } - - return IExtensionInterface::QueryInterfaceDrop(pInterface); -} - -void SDKTools::NotifyInterfaceDrop(SMInterface *pInterface) -{ - SourceHook::List::iterator iter; - for (iter = g_RegCalls.begin(); - iter != g_RegCalls.end(); - iter++) - { - delete (*iter); - } - g_RegCalls.clear(); - ShutdownHelpers(); - - g_TEManager.Shutdown(); - s_TempEntHooks.Shutdown(); - - if (g_pAcceptInput) - { - g_pAcceptInput->Destroy(); - g_pAcceptInput = NULL; - } -} - -bool SDKTools::RegisterConCommandBase(ConCommandBase *pVar) -{ -#if defined METAMOD_PLAPI_VERSION - return g_SMAPI->RegisterConCommandBase(g_PLAPI, pVar); -#else - return g_SMAPI->RegisterConCmdBase(g_PLAPI, pVar); -#endif -} - -bool SDKTools::LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background) -{ - const char *name; - char key[32]; - int count, n = 1; - - if (!(name=g_pGameConf->GetKeyValue("SlapSoundCount"))) - { - RETURN_META_VALUE(MRES_IGNORED, true); - } - - count = atoi(name); - - while (n <= count) - { - snprintf(key, sizeof(key), "SlapSound%d", n); - if ((name=g_pGameConf->GetKeyValue(key))) - { - engsound->PrecacheSound(name, true); - } - n++; - } - - RETURN_META_VALUE(MRES_IGNORED, true); -} - -bool SDKTools::ProcessCommandTarget(cmd_target_info_t *info) -{ - if (strcmp(info->pattern, "@aim") != 0) - { - return false; - } - - IGamePlayer *pAdmin = info->admin ? playerhelpers->GetGamePlayer(info->admin) : NULL; - - /* The server can't aim, of course. */ - if (pAdmin == NULL) - { - return false; - } - - int player_index; - if ((player_index = GetClientAimTarget(pAdmin->GetEdict(), true)) < 1) - { - info->reason = COMMAND_TARGET_NONE; - info->num_targets = 0; - return true; - } - - IGamePlayer *pTarget = playerhelpers->GetGamePlayer(player_index); - - if (pTarget == NULL) - { - info->reason = COMMAND_TARGET_NONE; - info->num_targets = 0; - return true; - } - - info->reason = playerhelpers->FilterCommandTarget(pAdmin, pTarget, info->flags); - if (info->reason != COMMAND_TARGET_VALID) - { - info->num_targets = 0; - return true; - } - - info->targets[0] = player_index; - info->num_targets = 1; - info->reason = COMMAND_TARGET_VALID; - info->target_name_style = COMMAND_TARGETNAME_RAW; - snprintf(info->target_name, info->target_name_maxlength, "%s", pTarget->GetName()); - - return true; -} diff --git a/extensions/sdktools/extension.h b/extensions/sdktools/extension.h deleted file mode 100644 index 54eec222..00000000 --- a/extensions/sdktools/extension.h +++ /dev/null @@ -1,124 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ -#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ - -/** - * @file extension.h - * @brief SDK Tools extension code header. - */ - -#include "smsdk_ext.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * @brief Implementation of the SDK Tools extension. - * Note: Uncomment one of the pre-defined virtual functions in order to use it. - */ -class SDKTools : - public SDKExtension, - public IHandleTypeDispatch, - public IConCommandBaseAccessor, - public IClientListener, - public ICommandTargetProcessor -{ -public: //public IHandleTypeDispatch - void OnHandleDestroy(HandleType_t type, void *object); -public: //public SDKExtension - virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late); - virtual void SDK_OnUnload(); - virtual void SDK_OnAllLoaded(); - //virtual void SDK_OnPauseChange(bool paused); - virtual bool QueryRunning(char *error, size_t maxlength); - virtual bool QueryInterfaceDrop(SMInterface *pInterface); - virtual void NotifyInterfaceDrop(SMInterface *pInterface); - virtual void OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax); -public: -#if defined SMEXT_CONF_METAMOD - virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late); - //virtual bool SDK_OnMetamodUnload(char *error, size_t maxlen); - //virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlen); -#endif -public: //IConCommandBaseAccessor - bool RegisterConCommandBase(ConCommandBase *pVar); -public: //IClientListner - void OnClientDisconnecting(int client); -public: // IVoiceServer - bool OnSetClientListening(int iReceiver, int iSender, bool bListen); - void VoiceInit(); -public: //ICommandTargetProcessor - bool ProcessCommandTarget(cmd_target_info_t *info); -public: - bool LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background); - void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax); -}; - -extern SDKTools g_SdkTools; -/* Interfaces from engine or gamedll */ -extern IServerGameEnts *gameents; -extern IEngineTrace *enginetrace; -extern IEngineSound *engsound; -extern INetworkStringTableContainer *netstringtables; -extern IServerPluginHelpers *pluginhelpers; -extern IServerGameClients *serverClients; -extern IVoiceServer *voiceserver; -extern IPlayerInfoManager *playerinfomngr; -extern ICvar *icvar; -extern IServer *iserver; -/* Interfaces from SourceMod */ -extern IBinTools *g_pBinTools; -extern IGameConfig *g_pGameConf; -extern IGameHelpers *g_pGameHelpers; -/* Handle types */ -extern HandleType_t g_CallHandle; -extern HandleType_t g_TraceHandle; -/* Call Wrappers */ -extern ICallWrapper *g_pAcceptInput; -/* Call classes */ -extern SourceHook::CallClass *enginePatch; -extern SourceHook::CallClass *enginesoundPatch; - -#define ENGINE_CALL(func) SH_CALL(enginePatch, &IVEngineServer::func) - -#endif //_INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ diff --git a/extensions/sdktools/inputnatives.cpp b/extensions/sdktools/inputnatives.cpp deleted file mode 100644 index b8b56620..00000000 --- a/extensions/sdktools/inputnatives.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "extension.h" -#include - -#define SIZEOF_VARIANT_T 20 - -ICallWrapper *g_pAcceptInput = NULL; -unsigned char g_Variant_t[SIZEOF_VARIANT_T] = {0}; - -#define ENTINDEX_TO_CBASEENTITY(index, buffer) \ - pEdict = engine->PEntityOfEntIndex(index); \ - if (!pEdict || pEdict->IsFree()) \ - { \ - return pContext->ThrowNativeError("Entity %d is not valid or is freed", index); \ - } \ - pUnk = pEdict->GetUnknown(); \ - if (!pUnk) \ - { \ - return pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", index); \ - } \ - buffer = pUnk->GetBaseEntity(); \ - if (!buffer) \ - { \ - return pContext->ThrowNativeError("Entity %d is not a CBaseEntity", index); \ - } - -/* Hack to init the variant_t object for the first time */ -class VariantFirstTimeInit -{ -public: - VariantFirstTimeInit() - { - *(unsigned int *)(&g_Variant_t[12]) = INVALID_EHANDLE_INDEX; - } -} g_VariantFirstTimeInit; - -inline void _init_variant_t() -{ - unsigned char *vptr = g_Variant_t; - - *(int *)vptr = 0; - vptr += sizeof(int)*3; - *(unsigned long *)vptr = INVALID_EHANDLE_INDEX; - vptr += sizeof(unsigned long); - *(fieldtype_t *)vptr = FIELD_VOID; -} - -static cell_t AcceptEntityInput(IPluginContext *pContext, const cell_t *params) -{ - if (!g_pAcceptInput) - { - int offset; - if (!g_pGameConf->GetOffset("AcceptInput", &offset)) - { - return pContext->ThrowNativeError("\"AcceptEntityInput\" not supported by this mod"); - } - - PassInfo pass[6]; - pass[0].type = PassType_Basic; - pass[0].flags = PASSFLAG_BYVAL; - pass[0].size = sizeof(const char *); - pass[1].type = pass[2].type = PassType_Basic; - pass[1].flags = pass[2].flags = PASSFLAG_BYVAL; - pass[1].size = pass[2].size = sizeof(CBaseEntity *); - pass[3].type = PassType_Object; - pass[3].flags = PASSFLAG_BYVAL|PASSFLAG_OCTOR|PASSFLAG_ODTOR|PASSFLAG_OASSIGNOP; - pass[3].size = SIZEOF_VARIANT_T; - pass[4].type = PassType_Basic; - pass[4].flags = PASSFLAG_BYVAL; - pass[4].size = sizeof(int); - pass[5].type = PassType_Basic; - pass[5].flags = PASSFLAG_BYVAL; - pass[5].size = sizeof(bool); - - if (!(g_pAcceptInput=g_pBinTools->CreateVCall(offset, 0, 0, &pass[5], pass, 5))) - { - pContext->ThrowNativeError("\"AcceptEntityInput\" wrapper failed to initialized"); - } - } - - CBaseEntity *pActivator, *pCaller, *pDest; - edict_t *pEdict; - IServerUnknown *pUnk; - - char *inputname; - unsigned char vstk[sizeof(void *) + sizeof(const char *) + sizeof(CBaseEntity *)*2 + SIZEOF_VARIANT_T + sizeof(int)]; - unsigned char *vptr = vstk; - - ENTINDEX_TO_CBASEENTITY(params[1], pDest); - pContext->LocalToString(params[2], &inputname); - if (params[3] == -1) - { - pActivator = NULL; - } else { - ENTINDEX_TO_CBASEENTITY(params[3], pActivator); - } - if (params[4] == -1) - { - pCaller = NULL; - } else { - ENTINDEX_TO_CBASEENTITY(params[4], pCaller); - } - - *(void **)vptr = pDest; - vptr += sizeof(void *); - *(const char **)vptr = inputname; - vptr += sizeof(const char *); - *(CBaseEntity **)vptr = pActivator; - vptr += sizeof(CBaseEntity *); - *(CBaseEntity **)vptr = pCaller; - vptr += sizeof(CBaseEntity *); - memcpy(vptr, g_Variant_t, SIZEOF_VARIANT_T); - vptr += SIZEOF_VARIANT_T; - *(int *)vptr = params[5]; - - bool ret; - g_pAcceptInput->Execute(vstk, &ret); - - _init_variant_t(); - - return (ret) ? 1 : 0; -} - -static cell_t SetVariantBool(IPluginContext *pContext, const cell_t *params) -{ - unsigned char *vptr = g_Variant_t; - - *(bool *)vptr = (params[1]) ? true : false; - vptr += sizeof(int)*3 + sizeof(unsigned long); - *(fieldtype_t *)vptr = FIELD_BOOLEAN; - - return 1; -} - -static cell_t SetVariantString(IPluginContext *pContext, const cell_t *params) -{ - char *str; - unsigned char *vptr = g_Variant_t; - - pContext->LocalToString(params[1], &str); - - *(string_t *)vptr = MAKE_STRING(str); - vptr += sizeof(int)*3 + sizeof(unsigned long); - *(fieldtype_t *)vptr = FIELD_STRING; - - return 1; -} - -static cell_t SetVariantInt(IPluginContext *pContext, const cell_t *params) -{ - unsigned char *vptr = g_Variant_t; - - *(int *)vptr = params[1]; - vptr += sizeof(int)*3 + sizeof(unsigned long); - *(fieldtype_t *)vptr = FIELD_INTEGER; - - return 1; -} - -static cell_t SetVariantFloat(IPluginContext *pContext, const cell_t *params) -{ - unsigned char *vptr = g_Variant_t; - - *(float *)vptr = sp_ctof(params[1]); - vptr += sizeof(int)*3 + sizeof(unsigned long); - *(fieldtype_t *)vptr = FIELD_FLOAT; - - return 1; -} - -static cell_t SetVariantVector3D(IPluginContext *pContext, const cell_t *params) -{ - cell_t *val; - unsigned char *vptr = g_Variant_t; - - pContext->LocalToPhysAddr(params[1], &val); - - *(float *)vptr = sp_ctof(val[0]); - vptr += sizeof(float); - *(float *)vptr = sp_ctof(val[1]); - vptr += sizeof(float); - *(float *)vptr = sp_ctof(val[2]); - vptr += sizeof(float) + sizeof(unsigned long); - *(fieldtype_t *)vptr = FIELD_VECTOR; - - return 1; -} - -static cell_t SetVariantPosVector3D(IPluginContext *pContext, const cell_t *params) -{ - cell_t *val; - unsigned char *vptr = g_Variant_t; - - pContext->LocalToPhysAddr(params[1], &val); - - *(float *)vptr = sp_ctof(val[0]); - vptr += sizeof(float); - *(float *)vptr = sp_ctof(val[1]); - vptr += sizeof(float); - *(float *)vptr = sp_ctof(val[2]); - vptr += sizeof(float) + sizeof(unsigned long); - *(fieldtype_t *)vptr = FIELD_POSITION_VECTOR; - - return 1; -} - -static cell_t SetVariantColor(IPluginContext *pContext, const cell_t *params) -{ - cell_t *val; - unsigned char *vptr = g_Variant_t; - - pContext->LocalToPhysAddr(params[1], &val); - - *(unsigned char *)vptr = val[0]; - vptr += sizeof(unsigned char); - *(unsigned char *)vptr = val[1]; - vptr += sizeof(unsigned char); - *(unsigned char *)vptr = val[2]; - vptr += sizeof(unsigned char); - *(unsigned char *)vptr = val[3]; - vptr += sizeof(unsigned char) + sizeof(int)*2 + sizeof(unsigned long); - *(fieldtype_t *)vptr = FIELD_COLOR32; - - return 1; -} - -static cell_t SetVariantEntity(IPluginContext *pContext, const cell_t *params) -{ - CBaseEntity *pEntity; - edict_t *pEdict; - IServerUnknown *pUnk; - unsigned char *vptr = g_Variant_t; - CBaseHandle bHandle; - - ENTINDEX_TO_CBASEENTITY(params[1], pEntity); - bHandle = reinterpret_cast(pEntity)->GetRefEHandle(); - - vptr += sizeof(int)*3; - *(unsigned long *)vptr = (unsigned long)(bHandle.ToInt()); - vptr += sizeof(unsigned long); - *(fieldtype_t *)vptr = FIELD_EHANDLE; - - return 1; -} - -sp_nativeinfo_t g_EntInputNatives[] = -{ - {"AcceptEntityInput", AcceptEntityInput}, - {"SetVariantBool", SetVariantBool}, - {"SetVariantString", SetVariantString}, - {"SetVariantInt", SetVariantInt}, - {"SetVariantFloat", SetVariantFloat}, - {"SetVariantVector3D", SetVariantVector3D}, - {"SetVariantPosVector3D", SetVariantPosVector3D}, - {"SetVariantColor", SetVariantColor}, - {"SetVariantEntity", SetVariantEntity}, - {NULL, NULL}, -}; diff --git a/extensions/sdktools/msvc8/sdktools.sln b/extensions/sdktools/msvc8/sdktools.sln deleted file mode 100644 index dbc95add..00000000 --- a/extensions/sdktools/msvc8/sdktools.sln +++ /dev/null @@ -1,32 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdktools", "sdktools.vcproj", "{7A740927-C751-4312-BF9D-6367F8C508F8}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug - Episode 1|Win32 = Debug - Episode 1|Win32 - Debug - Old Metamod|Win32 = Debug - Old Metamod|Win32 - Debug - Orange Box|Win32 = Debug - Orange Box|Win32 - Release - Episode 1|Win32 = Release - Episode 1|Win32 - Release - Old Metamod|Win32 = Release - Old Metamod|Win32 - Release - Orange Box|Win32 = Release - Orange Box|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7A740927-C751-4312-BF9D-6367F8C508F8}.Debug - Episode 1|Win32.ActiveCfg = Debug - Episode 1|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Debug - Episode 1|Win32.Build.0 = Debug - Episode 1|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Debug - Old Metamod|Win32.ActiveCfg = Debug - Old Metamod|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Debug - Old Metamod|Win32.Build.0 = Debug - Old Metamod|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Debug - Orange Box|Win32.ActiveCfg = Debug - Orange Box|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Debug - Orange Box|Win32.Build.0 = Debug - Orange Box|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Release - Episode 1|Win32.ActiveCfg = Release - Episode 1|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Release - Episode 1|Win32.Build.0 = Release - Episode 1|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Release - Old Metamod|Win32.ActiveCfg = Release - Old Metamod|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Release - Old Metamod|Win32.Build.0 = Release - Old Metamod|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Release - Orange Box|Win32.ActiveCfg = Release - Orange Box|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Release - Orange Box|Win32.Build.0 = Release - Orange Box|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/extensions/sdktools/msvc8/sdktools.vcproj b/extensions/sdktools/msvc8/sdktools.vcproj deleted file mode 100644 index bbdb742a..00000000 --- a/extensions/sdktools/msvc8/sdktools.vcproj +++ /dev/null @@ -1,665 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/extensions/sdktools/msvc9/sdktools.sln b/extensions/sdktools/msvc9/sdktools.sln deleted file mode 100644 index b314d769..00000000 --- a/extensions/sdktools/msvc9/sdktools.sln +++ /dev/null @@ -1,32 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdktools", "sdktools.vcproj", "{7A740927-C751-4312-BF9D-6367F8C508F8}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug - Episode 1|Win32 = Debug - Episode 1|Win32 - Debug - Old Metamod|Win32 = Debug - Old Metamod|Win32 - Debug - Orange Box|Win32 = Debug - Orange Box|Win32 - Release - Episode 1|Win32 = Release - Episode 1|Win32 - Release - Old Metamod|Win32 = Release - Old Metamod|Win32 - Release - Orange Box|Win32 = Release - Orange Box|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7A740927-C751-4312-BF9D-6367F8C508F8}.Debug - Episode 1|Win32.ActiveCfg = Debug - Episode 1|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Debug - Episode 1|Win32.Build.0 = Debug - Episode 1|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Debug - Old Metamod|Win32.ActiveCfg = Debug - Old Metamod|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Debug - Old Metamod|Win32.Build.0 = Debug - Old Metamod|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Debug - Orange Box|Win32.ActiveCfg = Debug - Orange Box|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Debug - Orange Box|Win32.Build.0 = Debug - Orange Box|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Release - Episode 1|Win32.ActiveCfg = Release - Episode 1|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Release - Episode 1|Win32.Build.0 = Release - Episode 1|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Release - Old Metamod|Win32.ActiveCfg = Release - Old Metamod|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Release - Old Metamod|Win32.Build.0 = Release - Old Metamod|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Release - Orange Box|Win32.ActiveCfg = Release - Orange Box|Win32 - {7A740927-C751-4312-BF9D-6367F8C508F8}.Release - Orange Box|Win32.Build.0 = Release - Orange Box|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/extensions/sdktools/msvc9/sdktools.vcproj b/extensions/sdktools/msvc9/sdktools.vcproj deleted file mode 100644 index 33674010..00000000 --- a/extensions/sdktools/msvc9/sdktools.vcproj +++ /dev/null @@ -1,660 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/extensions/sdktools/output.cpp b/extensions/sdktools/output.cpp deleted file mode 100644 index bc925f4c..00000000 --- a/extensions/sdktools/output.cpp +++ /dev/null @@ -1,489 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "extension.h" -#include "output.h" - -ISourcePawnEngine *spengine = NULL; -EntityOutputManager g_OutputManager; - -EntityOutputManager::EntityOutputManager() -{ - info_address = NULL; - info_callback = NULL; - HookCount = 0; - is_detoured = false; - enabled = false; -} - -EntityOutputManager::~EntityOutputManager() -{ - if (!enabled) - { - return; - } - - EntityOutputs->Destroy(); - ClassNames->Destroy(); - ShutdownFireEventDetour(); -} - -void EntityOutputManager::Init() -{ - enabled = CreateFireEventDetour(); - - if (!enabled) - { - return; - } - - EntityOutputs = adtfactory->CreateBasicTrie(); - ClassNames = adtfactory->CreateBasicTrie(); -} - -bool EntityOutputManager::IsEnabled() -{ - return enabled; -} - -bool EntityOutputManager::CreateFireEventDetour() -{ - if (!g_pGameConf->GetMemSig("FireOutput", &info_address)) - { - return false; - } - - if (!info_address) - { - g_pSM->LogError(myself, "Could not locate FireOutput - Disabling Entity Outputs"); - return false; - } - - if (!g_pGameConf->GetOffset("FireOutputBackup", (int *)&(info_restore.bytes))) - { - return false; - } - - /* First, save restore bits */ - for (size_t i=0; iExecAlloc(100); - JitWriter wr; - JitWriter *jit = ≀ - wr.outbase = (jitcode_t)info_callback; - wr.outptr = wr.outbase; - - /* Function we are detouring into is - * - * void FireEventDetour(CBaseEntityOutput(void *) *pOutput, CBaseEntity *pActivator, CBaseEntity *pCaller, float fDelay = 0 ) - */ - - /* push fDelay [esp+20h] - * push pCaller [esp+1Ch] - * push pActivator [esp+18h] - * push pOutput [ecx] - */ - - -#if defined PLATFORM_WINDOWS - - IA32_Push_Rm_Disp8_ESP(jit, 32); - IA32_Push_Rm_Disp8_ESP(jit, 32); - IA32_Push_Rm_Disp8_ESP(jit, 32); - - IA32_Push_Reg(jit, REG_ECX); - -#elif defined PLATFORM_LINUX - IA32_Push_Rm_Disp8_ESP(jit, 20); - IA32_Push_Rm_Disp8_ESP(jit, 20); - IA32_Push_Rm_Disp8_ESP(jit, 20); - - IA32_Push_Rm_Disp8_ESP(jit, 16); -#endif - - jitoffs_t call = IA32_Call_Imm32(jit, 0); - IA32_Write_Jump32_Abs(jit, call, (void *)TempDetour); - - -#if defined PLATFORM_LINUX - IA32_Add_Rm_Imm8(jit, REG_ESP, 4, MOD_REG); //add esp, 4 -#elif defined PLATFORM_WINDOWS - IA32_Pop_Reg(jit, REG_ECX); -#endif - - IA32_Add_Rm_Imm8(jit, REG_ESP, 12, MOD_REG); //add esp, 12 (0Ch) - - - /* Patch old bytes in */ - for (size_t i=0; iwrite_ubyte(info_restore.patch[i]); - } - - /* Return to the original function */ - call = IA32_Jump_Imm32(jit, 0); - IA32_Write_Jump32_Abs(jit, call, (unsigned char *)info_address + info_restore.bytes); - - return true; -} - -void EntityOutputManager::InitFireEventDetour() -{ - if (!is_detoured) - { - DoGatePatch((unsigned char *)info_address, &info_callback); - is_detoured = true; - } -} - -void EntityOutputManager::DeleteFireEventDetour() -{ - if (is_detoured) - { - ShutdownFireEventDetour(); - } - - if (info_callback) - { - /* Free the gate */ - spengine->ExecFree(info_callback); - info_callback = NULL; - } -} - -void TempDetour(void *pOutput, CBaseEntity *pActivator, CBaseEntity *pCaller, float fDelay) -{ - g_OutputManager.FireEventDetour(pOutput, pActivator, pCaller, fDelay); -} - -void EntityOutputManager::ShutdownFireEventDetour() -{ - if (info_callback) - { - /* Remove the patch */ - ApplyPatch(info_address, 0, &info_restore, NULL); - is_detoured = false; - } -} - -void EntityOutputManager::FireEventDetour(void *pOutput, CBaseEntity *pActivator, CBaseEntity *pCaller, float fDelay) -{ - char sOutput[20]; - Q_snprintf(sOutput, sizeof(sOutput), "%x", pOutput); - - // attempt to directly lookup a hook using the pOutput pointer - OutputNameStruct *pOutputName = NULL; - - edict_t *pEdict = gameents->BaseEntityToEdict(pCaller); - - /* TODO: Add support for entities without an edict */ - if (pEdict == NULL) - { - return; - } - - bool fastLookup = false; - - // Fast lookup failed - check the slow way for hooks that havn't fired yet - if ((fastLookup = EntityOutputs->Retrieve(sOutput, (void **)&pOutputName)) == false) - { - const char *classname = pEdict->GetClassName(); - const char *outputname = FindOutputName(pOutput, pCaller); - - pOutputName = FindOutputPointer(classname, outputname, false); - - if (!pOutputName) - { - return; - } - } - - if (!pOutputName->hooks.empty()) - { - if (!fastLookup) - { - // hook exists on this classname and output - map it into our quick find trie - EntityOutputs->Insert(sOutput, pOutputName); - } - - SourceHook::List::iterator _iter; - - omg_hooks *hook; - - _iter = pOutputName->hooks.begin(); - - while (_iter != pOutputName->hooks.end()) - { - hook = (omg_hooks *)*_iter; - - hook->in_use = true; - - int serial = pEdict->m_NetworkSerialNumber; - - if (serial != hook->entity_filter && hook->entity_index == engine->IndexOfEdict(pEdict)) - { - // same entity index but different serial number. Entity has changed, kill the hook. - _iter = pOutputName->hooks.erase(_iter); - CleanUpHook(hook); - - continue; - } - - if (hook->entity_filter == -1 || hook->entity_filter == serial) // Global classname hook - { - //fire the forward to hook->pf - hook->pf->PushString(pOutputName->Name); - hook->pf->PushCell(engine->IndexOfEdict(pEdict)); - - edict_t *pEdictActivator = gameents->BaseEntityToEdict(pActivator); - if (!pEdictActivator) - { - hook->pf->PushCell(-1); - } - else - { - hook->pf->PushCell(engine->IndexOfEdict(pEdictActivator)); - } - //hook->pf->PushCell(handle); - hook->pf->PushFloat(fDelay); - hook->pf->Execute(NULL); - - if ((hook->entity_filter != -1) && hook->only_once) - { - _iter = pOutputName->hooks.erase(_iter); - CleanUpHook(hook); - - continue; - } - - if (hook->delete_me) - { - _iter = pOutputName->hooks.erase(_iter); - CleanUpHook(hook); - continue; - } - } - - hook->in_use = false; - _iter++; - } - } -} - -omg_hooks *EntityOutputManager::NewHook() -{ - omg_hooks *hook; - - if (FreeHooks.empty()) - { - hook = new omg_hooks; - } - else - { - hook = g_OutputManager.FreeHooks.front(); - g_OutputManager.FreeHooks.pop(); - } - - return hook; -} - -void EntityOutputManager::OnHookAdded() -{ - HookCount++; - - if (HookCount == 1) - { - // This is the first hook created - InitFireEventDetour(); - } -} - -void EntityOutputManager::OnHookRemoved() -{ - HookCount--; - - if (HookCount == 0) - { - ShutdownFireEventDetour(); - } -} - -void EntityOutputManager::CleanUpHook(omg_hooks *hook) -{ - FreeHooks.push(hook); - - OnHookRemoved(); - - IPlugin *pPlugin = plsys->FindPluginByContext(hook->pf->GetParentContext()->GetContext()); - SourceHook::List *pList = NULL; - - if (!pPlugin->GetProperty("OutputHookList", (void **)&pList, false) || !pList) - { - return; - } - - SourceHook::List::iterator p_iter = pList->begin(); - - omg_hooks *pluginHook; - - while (p_iter != pList->end()) - { - pluginHook = (omg_hooks *)*p_iter; - if (pluginHook == hook) - { - p_iter = pList->erase(p_iter); - } - else - { - p_iter++; - } - } -} - -void EntityOutputManager::OnPluginDestroyed(IPlugin *plugin) -{ - SourceHook::List *pList = NULL; - - if (plugin->GetProperty("OutputHookList", (void **)&pList, true)) - { - SourceHook::List::iterator p_iter = pList->begin(); - omg_hooks *hook; - - while (p_iter != pList->end()) - { - hook = (omg_hooks *)*p_iter; - - p_iter = pList->erase(p_iter); //remove from this plugins list - hook->m_parent->hooks.remove(hook); // remove from the y's list - - FreeHooks.push(hook); //save the omg_hook - - OnHookRemoved(); - } - } -} - -OutputNameStruct *EntityOutputManager::FindOutputPointer(const char *classname, const char *outputname, bool create) -{ - ClassNameStruct *pClassname; - - if (!ClassNames->Retrieve(classname, (void **)&pClassname)) - { - if (create) - { - pClassname = new ClassNameStruct; - ClassNames->Insert(classname, pClassname); - } - else - { - return NULL; - } - } - - OutputNameStruct *pOutputName; - - if (!pClassname->OutputList->Retrieve(outputname, (void **)&pOutputName)) - { - if (create) - { - pOutputName = new OutputNameStruct; - pClassname->OutputList->Insert(outputname, pOutputName); - strncpy(pOutputName->Name, outputname, sizeof(pOutputName->Name)); - pOutputName->Name[49] = 0; - } - else - { - return NULL; - } - } - - return pOutputName; -} - -// Iterate the datamap of pCaller and look for output pointers with the same address as pOutput -const char *EntityOutputManager::FindOutputName(void *pOutput, CBaseEntity *pCaller) -{ - datamap_t *pMap = gamehelpers->GetDataMap(pCaller); - - while (pMap) - { - for (int i=0; idataNumFields; i++) - { - if (pMap->dataDesc[i].flags & FTYPEDESC_OUTPUT) - { - if ((char *)pCaller + pMap->dataDesc[i].fieldOffset[0] == pOutput) - { - return pMap->dataDesc[i].externalName; - } - } - } - pMap = pMap->baseMap; - } - - return NULL; -} - -// Thanks SM core -edict_t *EntityOutputManager::BaseHandleToEdict(CBaseHandle &hndl) -{ - if (!hndl.IsValid()) - { - return NULL; - } - - int index = hndl.GetEntryIndex(); - - edict_t *pStoredEdict; - - pStoredEdict = engine->PEntityOfEntIndex(index); - - if (pStoredEdict == NULL) - { - return NULL; - } - - IServerEntity *pSE = pStoredEdict->GetIServerEntity(); - - if (pSE == NULL) - { - return NULL; - } - - if (pSE->GetRefEHandle() != hndl) - { - return NULL; - } - - return pStoredEdict; -} diff --git a/extensions/sdktools/output.h b/extensions/sdktools/output.h deleted file mode 100644 index c696feeb..00000000 --- a/extensions/sdktools/output.h +++ /dev/null @@ -1,148 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_OUTPUT_H_ -#define _INCLUDE_SOURCEMOD_OUTPUT_H_ - -#include -#include -#include "sh_list.h" -#include "sh_stack.h" -#include "sm_trie_tpl.h" -#include "detours.h" - -extern ISourcePawnEngine *spengine; - -struct OutputNameStruct; - -/** - * This is a function specific hook that corresponds to an entity classname - * and outputname. There can be many of these for each classname/output combo - */ -struct omg_hooks -{ - int entity_filter; // if not -1 is an entity signature - int entity_index; - bool only_once; - IPluginFunction *pf; - OutputNameStruct *m_parent; - bool in_use; - bool delete_me; -}; - -/** - * This represents an output belonging to a specific classname - */ -struct OutputNameStruct -{ - SourceHook::List hooks; - char Name[50]; -}; - -/** - * This represents an entity classname - */ -struct ClassNameStruct -{ - //Trie mapping outputname to a OutputNameStruct - //KTrie OutputList; - IBasicTrie *OutputList; - - ClassNameStruct() - { - OutputList = adtfactory->CreateBasicTrie(); - } - - ~ClassNameStruct() - { - OutputList->Destroy(); - } -}; - -class EntityOutputManager : public IPluginsListener -{ -public: - EntityOutputManager(); - ~EntityOutputManager(); -public: - void Init(); - - bool IsEnabled(); - - void FireEventDetour(void *pOutput, CBaseEntity *pActivator, CBaseEntity *pCaller, float fDelay); - - void OnPluginDestroyed(IPlugin *plugin); - - OutputNameStruct *FindOutputPointer(const char *classname, const char *outputname, bool create); - - void CleanUpHook(omg_hooks *hook); - - omg_hooks *NewHook(); - - void OnHookAdded(); - void OnHookRemoved(); - -private: - bool enabled; - - // Patch/unpatch the server dll - void InitFireEventDetour(); - void ShutdownFireEventDetour(); - bool is_detoured; - - //These create/delete the allocated memory and write into it - bool CreateFireEventDetour(); - void DeleteFireEventDetour(); - - const char *FindOutputName(void *pOutput, CBaseEntity *pCaller); - edict_t *BaseHandleToEdict(CBaseHandle &hndl); - - //Maps CEntityOutput * to a OutputNameStruct - IBasicTrie *EntityOutputs; - // Maps classname to a ClassNameStruct - IBasicTrie *ClassNames; - - SourceHook::CStack FreeHooks; //Stores hook pointers to avoid calls to new - - int HookCount; - - patch_t info_restore; - void *info_address; - void *info_callback; -}; - -void TempDetour(void *pOutput, CBaseEntity *pActivator, CBaseEntity *pCaller, float fDelay); - -extern EntityOutputManager g_OutputManager; - -extern sp_nativeinfo_t g_EntOutputNatives[]; - -#endif //_INCLUDE_SOURCEMOD_OUTPUT_H_ diff --git a/extensions/sdktools/outputnatives.cpp b/extensions/sdktools/outputnatives.cpp deleted file mode 100644 index dc3350e2..00000000 --- a/extensions/sdktools/outputnatives.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "extension.h" -#include "output.h" - -// HookSingleEntityOutput(ent, const String:output[], function, bool:once); -cell_t HookSingleEntityOutput(IPluginContext *pContext, const cell_t *params) -{ - if (!g_OutputManager.IsEnabled()) - { - return pContext->ThrowNativeError("Entity Outputs are disabled - See error logs for details"); - } - - edict_t *pEdict = engine->PEntityOfEntIndex(params[1]); - if (!pEdict) - { - return pContext->ThrowNativeError("Invalid Entity index %i", params[1]); - } - const char *classname = pEdict->GetClassName(); - - char *outputname; - pContext->LocalToString(params[2], &outputname); - - OutputNameStruct *pOutputName = g_OutputManager.FindOutputPointer((const char *)classname, outputname, true); - - //Check for an existing identical hook - SourceHook::List::iterator _iter; - - omg_hooks *hook; - - IPluginFunction *pFunction; - pFunction = pContext->GetFunctionById(params[3]); - - for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++) - { - hook = (omg_hooks *)*_iter; - if (hook->pf == pFunction && hook->entity_filter == pEdict->m_NetworkSerialNumber) - { - return 0; - } - } - - hook = g_OutputManager.NewHook(); - - hook->entity_filter = pEdict->m_NetworkSerialNumber; - hook->entity_index = engine->IndexOfEdict(pEdict); - hook->only_once= !!params[4]; - hook->pf = pFunction; - hook->m_parent = pOutputName; - hook->in_use = false; - hook->delete_me = false; - - pOutputName->hooks.push_back(hook); - - g_OutputManager.OnHookAdded(); - - IPlugin *pPlugin = plsys->FindPluginByContext(pContext->GetContext()); - SourceHook::List *pList = NULL; - - if (!pPlugin->GetProperty("OutputHookList", (void **)&pList, false) || !pList) - { - pList = new SourceHook::List; - pPlugin->SetProperty("OutputHookList", pList); - } - - pList->push_back(hook); - - return 1; -} - -// HookEntityOutput(const String:classname[], const String:output[], function); -cell_t HookEntityOutput(IPluginContext *pContext, const cell_t *params) -{ - if (!g_OutputManager.IsEnabled()) - { - return pContext->ThrowNativeError("Entity Outputs are disabled - See error logs for details"); - } - - //Find or create the base structures for this classname and the output - char *classname; - pContext->LocalToString(params[1], &classname); - - char *outputname; - pContext->LocalToString(params[2], &outputname); - - OutputNameStruct *pOutputName = g_OutputManager.FindOutputPointer((const char *)classname, outputname, true); - - //Check for an existing identical hook - SourceHook::List::iterator _iter; - - omg_hooks *hook; - - IPluginFunction *pFunction; - pFunction = pContext->GetFunctionById(params[3]); - - for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++) - { - hook = (omg_hooks *)*_iter; - if (hook->pf == pFunction && hook->entity_filter == -1) - { - //already hooked to this function... - //throw an error or just let them get away with stupidity? - // seems like poor coding if they dont know if something is hooked or not - return 0; - } - } - - hook = g_OutputManager.NewHook(); - - hook->entity_filter = -1; - hook->pf = pFunction; - hook->m_parent = pOutputName; - hook->in_use = false; - hook->delete_me = false; - - pOutputName->hooks.push_back(hook); - - g_OutputManager.OnHookAdded(); - - IPlugin *pPlugin = plsys->FindPluginByContext(pContext->GetContext()); - SourceHook::List *pList = NULL; - - if (!pPlugin->GetProperty("OutputHookList", (void **)&pList, false) || !pList) - { - pList = new SourceHook::List; - pPlugin->SetProperty("OutputHookList", pList); - } - - pList->push_back(hook); - - return 1; -} - -// UnHookEntityOutput(const String:classname[], const String:output[], EntityOutput:callback); -cell_t UnHookEntityOutput(IPluginContext *pContext, const cell_t *params) -{ - if (!g_OutputManager.IsEnabled()) - { - return pContext->ThrowNativeError("Entity Outputs are disabled - See error logs for details"); - } - - char *classname; - pContext->LocalToString(params[1], &classname); - - char *outputname; - pContext->LocalToString(params[2], &outputname); - - OutputNameStruct *pOutputName = g_OutputManager.FindOutputPointer((const char *)classname, outputname, false); - - if (!pOutputName) - { - return 0; - } - - //Check for an existing identical hook - SourceHook::List::iterator _iter; - - omg_hooks *hook; - - IPluginFunction *pFunction; - pFunction = pContext->GetFunctionById(params[3]); - - for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++) - { - hook = (omg_hooks *)*_iter; - if (hook->pf == pFunction && hook->entity_filter == -1) - { - // remove this hook. - if (hook->in_use) - { - hook->delete_me = true; - return 1; - } - - pOutputName->hooks.erase(_iter); - g_OutputManager.CleanUpHook(hook); - - return 1; - } - } - - return 0; -} - -// UnHookSingleEntityOutput(entity, const String:output[], EntityOutput:callback); -cell_t UnHookSingleEntityOutput(IPluginContext *pContext, const cell_t *params) -{ - if (!g_OutputManager.IsEnabled()) - { - return pContext->ThrowNativeError("Entity Outputs are disabled - See error logs for details"); - } - - // Find the classname of the entity and lookup the classname and output structures - edict_t *pEdict = engine->PEntityOfEntIndex(params[1]); - if (!pEdict) - { - return pContext->ThrowNativeError("Invalid Entity index %i", params[1]); - } - - const char *classname = pEdict->GetClassName(); - - char *outputname; - pContext->LocalToString(params[2], &outputname); - - OutputNameStruct *pOutputName = g_OutputManager.FindOutputPointer((const char *)classname, outputname, false); - - if (!pOutputName) - { - return 0; - } - - //Check for an existing identical hook - SourceHook::List::iterator _iter; - - omg_hooks *hook; - - IPluginFunction *pFunction; - pFunction = pContext->GetFunctionById(params[3]); - - for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++) - { - hook = (omg_hooks *)*_iter; - if (hook->pf == pFunction && hook->entity_index == engine->IndexOfEdict(pEdict)) - { - // remove this hook. - if (hook->in_use) - { - hook->delete_me = true; - return 1; - } - - pOutputName->hooks.erase(_iter); - g_OutputManager.CleanUpHook(hook); - - return 1; - } - } - - return 0; -} - -sp_nativeinfo_t g_EntOutputNatives[] = -{ - {"HookEntityOutput", HookEntityOutput}, - {"UnhookEntityOutput", UnHookEntityOutput}, - {"HookSingleEntityOutput", HookSingleEntityOutput}, - {"UnhookSingleEntityOutput", UnHookSingleEntityOutput}, - {NULL, NULL}, -}; diff --git a/extensions/sdktools/sdk/smsdk_config.h b/extensions/sdktools/sdk/smsdk_config.h deleted file mode 100644 index c4b14539..00000000 --- a/extensions/sdktools/sdk/smsdk_config.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ -#define _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ - -/** - * @file smsdk_config.h - * @brief Contains macros for configuring basic extension information. - */ - -#include "svn_version.h" - -/* Basic information exposed publicly */ -#define SMEXT_CONF_NAME "SDK Tools" -#define SMEXT_CONF_DESCRIPTION "Source SDK Tools" -#define SMEXT_CONF_VERSION SVN_FULL_VERSION -#define SMEXT_CONF_AUTHOR "AlliedModders LLC" -#define SMEXT_CONF_URL "http://www.sourcemod.net/" -#define SMEXT_CONF_LOGTAG "SDKTOOLS" -#define SMEXT_CONF_LICENSE "GPL" -#define SMEXT_CONF_DATESTRING __DATE__ " " __TIME__ - -/** - * @brief Exposes plugin's main interface. - */ -#define SMEXT_LINK(name) SDKExtension *g_pExtensionIface = name; - -/** - * @brief Sets whether or not this plugin required Metamod. - * NOTE: Uncomment to enable, comment to disable. - */ -#define SMEXT_CONF_METAMOD - -/** Enable interfaces you want to use here by uncommenting lines */ -//#define SMEXT_ENABLE_FORWARDSYS -#define SMEXT_ENABLE_HANDLESYS -#define SMEXT_ENABLE_PLAYERHELPERS -//#define SMEXT_ENABLE_DBMANAGER -#define SMEXT_ENABLE_GAMECONF -#define SMEXT_ENABLE_MEMUTILS -#define SMEXT_ENABLE_GAMEHELPERS -//#define SMEXT_ENABLE_TIMERSYS -#define SMEXT_ENABLE_ADTFACTORY -#define SMEXT_ENABLE_PLUGINSYS - -#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ diff --git a/extensions/sdktools/sdk/smsdk_ext.cpp b/extensions/sdktools/sdk/smsdk_ext.cpp deleted file mode 100644 index a823d1b2..00000000 --- a/extensions/sdktools/sdk/smsdk_ext.cpp +++ /dev/null @@ -1,422 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Base Extension Code - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include -#include "smsdk_ext.h" - -/** - * @file smsdk_ext.cpp - * @brief Contains wrappers for making Extensions easier to write. - */ - -IExtension *myself = NULL; /**< Ourself */ -IShareSys *g_pShareSys = NULL; /**< Share system */ -IShareSys *sharesys = NULL; /**< Share system */ -ISourceMod *g_pSM = NULL; /**< SourceMod helpers */ -ISourceMod *smutils = NULL; /**< SourceMod helpers */ - -#if defined SMEXT_ENABLE_FORWARDSYS -IForwardManager *g_pForwards = NULL; /**< Forward system */ -IForwardManager *forwards = NULL; /**< Forward system */ -#endif -#if defined SMEXT_ENABLE_HANDLESYS -IHandleSys *g_pHandleSys = NULL; /**< Handle system */ -IHandleSys *handlesys = NULL; /**< Handle system */ -#endif -#if defined SMEXT_ENABLE_PLAYERHELPERS -IPlayerManager *playerhelpers = NULL; /**< Player helpers */ -#endif //SMEXT_ENABLE_PLAYERHELPERS -#if defined SMEXT_ENABLE_DBMANAGER -IDBManager *dbi = NULL; /**< DB Manager */ -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMECONF -IGameConfigManager *gameconfs = NULL; /**< Game config manager */ -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_MEMUTILS -IMemoryUtils *memutils = NULL; -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMEHELPERS -IGameHelpers *gamehelpers = NULL; -#endif -#if defined SMEXT_ENABLE_TIMERSYS -ITimerSystem *timersys = NULL; -#endif -#if defined SMEXT_ENABLE_ADTFACTORY -IADTFactory *adtfactory = NULL; -#endif -#if defined SMEXT_ENABLE_THREADER -IThreader *threader = NULL; -#endif -#if defined SMEXT_ENABLE_LIBSYS -ILibrarySys *libsys = NULL; -#endif -#if defined SMEXT_ENABLE_PLUGINSYS -SourceMod::IPluginManager *plsys; -#endif - -/** Exports the main interface */ -PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI() -{ - return g_pExtensionIface; -} - -SDKExtension::SDKExtension() -{ -#if defined SMEXT_CONF_METAMOD - m_SourceMMLoaded = false; - m_WeAreUnloaded = false; - m_WeGotPauseChange = false; -#endif -} - -bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late) -{ - g_pShareSys = sharesys = sys; - myself = me; - -#if defined SMEXT_CONF_METAMOD - m_WeAreUnloaded = true; - - if (!m_SourceMMLoaded) - { - if (error) - { - snprintf(error, maxlength, "Metamod attach failed"); - } - return false; - } -#endif - SM_GET_IFACE(SOURCEMOD, g_pSM); - smutils = g_pSM; -#if defined SMEXT_ENABLE_HANDLESYS - SM_GET_IFACE(HANDLESYSTEM, g_pHandleSys); - handlesys = g_pHandleSys; -#endif -#if defined SMEXT_ENABLE_FORWARDSYS - SM_GET_IFACE(FORWARDMANAGER, g_pForwards); - forwards = g_pForwards; -#endif -#if defined SMEXT_ENABLE_PLAYERHELPERS - SM_GET_IFACE(PLAYERMANAGER, playerhelpers); -#endif -#if defined SMEXT_ENABLE_DBMANAGER - SM_GET_IFACE(DBI, dbi); -#endif -#if defined SMEXT_ENABLE_GAMECONF - SM_GET_IFACE(GAMECONFIG, gameconfs); -#endif -#if defined SMEXT_ENABLE_MEMUTILS - SM_GET_IFACE(MEMORYUTILS, memutils); -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS - SM_GET_IFACE(GAMEHELPERS, gamehelpers); -#endif -#if defined SMEXT_ENABLE_TIMERSYS - SM_GET_IFACE(TIMERSYS, timersys); -#endif -#if defined SMEXT_ENABLE_ADTFACTORY - SM_GET_IFACE(ADTFACTORY, adtfactory); -#endif -#if defined SMEXT_ENABLE_THREADER - SM_GET_IFACE(THREADER, threader); -#endif -#if defined SMEXT_ENABLE_LIBSYS - SM_GET_IFACE(LIBRARYSYS, libsys); -#endif -#if defined SMEXT_ENABLE_PLUGINSYS - SM_GET_IFACE(PLUGINSYSTEM, plsys); -#endif - - if (SDK_OnLoad(error, maxlength, late)) - { -#if defined SMEXT_CONF_METAMOD - m_WeAreUnloaded = true; -#endif - return true; - } - - return false; -} - -bool SDKExtension::IsMetamodExtension() -{ -#if defined SMEXT_CONF_METAMOD - return true; -#else - return false; -#endif -} - -void SDKExtension::OnExtensionPauseChange(bool state) -{ -#if defined SMEXT_CONF_METAMOD - m_WeGotPauseChange = true; -#endif - SDK_OnPauseChange(state); -} - -void SDKExtension::OnExtensionsAllLoaded() -{ - SDK_OnAllLoaded(); -} - -void SDKExtension::OnExtensionUnload() -{ -#if defined SMEXT_CONF_METAMOD - m_WeAreUnloaded = true; -#endif - SDK_OnUnload(); -} - -const char *SDKExtension::GetExtensionAuthor() -{ - return SMEXT_CONF_AUTHOR; -} - -const char *SDKExtension::GetExtensionDateString() -{ - return SMEXT_CONF_DATESTRING; -} - -const char *SDKExtension::GetExtensionDescription() -{ - return SMEXT_CONF_DESCRIPTION; -} - -const char *SDKExtension::GetExtensionVerString() -{ - return SMEXT_CONF_VERSION; -} - -const char *SDKExtension::GetExtensionName() -{ - return SMEXT_CONF_NAME; -} - -const char *SDKExtension::GetExtensionTag() -{ - return SMEXT_CONF_LOGTAG; -} - -const char *SDKExtension::GetExtensionURL() -{ - return SMEXT_CONF_URL; -} - -bool SDKExtension::SDK_OnLoad(char *error, size_t maxlength, bool late) -{ - return true; -} - -void SDKExtension::SDK_OnUnload() -{ -} - -void SDKExtension::SDK_OnPauseChange(bool paused) -{ -} - -void SDKExtension::SDK_OnAllLoaded() -{ -} - -#if defined SMEXT_CONF_METAMOD - -PluginId g_PLID = 0; /**< Metamod plugin ID */ -ISmmPlugin *g_PLAPI = NULL; /**< Metamod plugin API */ -SourceHook::ISourceHook *g_SHPtr = NULL; /**< SourceHook pointer */ -ISmmAPI *g_SMAPI = NULL; /**< SourceMM API pointer */ - -IVEngineServer *engine = NULL; /**< IVEngineServer pointer */ -IServerGameDLL *gamedll = NULL; /**< IServerGameDLL pointer */ - -/** Exposes the extension to Metamod */ -SMM_API void *PL_EXPOSURE(const char *name, int *code) -{ - if (name && !strcmp(name, METAMOD_PLAPI_NAME)) - { - if (code) - { - *code = IFACE_OK; - } - return static_cast(g_pExtensionIface); - } - - if (code) - { - *code = IFACE_FAILED; - } - - return NULL; -} - -bool SDKExtension::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) -{ - PLUGIN_SAVEVARS(); - - GET_V_IFACE_ANY(GetServerFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); - GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); - - m_SourceMMLoaded = true; - - return SDK_OnMetamodLoad(ismm, error, maxlen, late); -} - -bool SDKExtension::Unload(char *error, size_t maxlen) -{ - if (!m_WeAreUnloaded) - { - if (error) - { - snprintf(error, maxlen, "This extension must be unloaded by SourceMod."); - } - return false; - } - - return SDK_OnMetamodUnload(error, maxlen); -} - -bool SDKExtension::Pause(char *error, size_t maxlen) -{ - if (!m_WeGotPauseChange) - { - if (error) - { - snprintf(error, maxlen, "This extension must be paused by SourceMod."); - } - return false; - } - - m_WeGotPauseChange = false; - - return SDK_OnMetamodPauseChange(true, error, maxlen); -} - -bool SDKExtension::Unpause(char *error, size_t maxlen) -{ - if (!m_WeGotPauseChange) - { - if (error) - { - snprintf(error, maxlen, "This extension must be unpaused by SourceMod."); - } - return false; - } - - m_WeGotPauseChange = false; - - return SDK_OnMetamodPauseChange(false, error, maxlen); -} - -const char *SDKExtension::GetAuthor() -{ - return GetExtensionAuthor(); -} - -const char *SDKExtension::GetDate() -{ - return GetExtensionDateString(); -} - -const char *SDKExtension::GetDescription() -{ - return GetExtensionDescription(); -} - -const char *SDKExtension::GetLicense() -{ - return SMEXT_CONF_LICENSE; -} - -const char *SDKExtension::GetLogTag() -{ - return GetExtensionTag(); -} - -const char *SDKExtension::GetName() -{ - return GetExtensionName(); -} - -const char *SDKExtension::GetURL() -{ - return GetExtensionURL(); -} - -const char *SDKExtension::GetVersion() -{ - return GetExtensionVerString(); -} - -bool SDKExtension::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late) -{ - return true; -} - -bool SDKExtension::SDK_OnMetamodUnload(char *error, size_t maxlength) -{ - return true; -} - -bool SDKExtension::SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength) -{ - return true; -} - -#endif - -/* Overload a few things to prevent libstdc++ linking */ -#if defined __linux__ -extern "C" void __cxa_pure_virtual(void) -{ -} - -void *operator new(size_t size) -{ - return malloc(size); -} - -void *operator new[](size_t size) -{ - return malloc(size); -} - -void operator delete(void *ptr) -{ - free(ptr); -} - -void operator delete[](void * ptr) -{ - free(ptr); -} -#endif diff --git a/extensions/sdktools/sdk/smsdk_ext.h b/extensions/sdktools/sdk/smsdk_ext.h deleted file mode 100644 index aec87f98..00000000 --- a/extensions/sdktools/sdk/smsdk_ext.h +++ /dev/null @@ -1,310 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Base Extension Code - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ -#define _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ - -/** - * @file smsdk_ext.h - * @brief Contains wrappers for making Extensions easier to write. - */ - -#include "smsdk_config.h" -#include -#include -#include -#include -#include -#if defined SMEXT_ENABLE_FORWARDSYS -#include -#endif //SMEXT_ENABLE_FORWARDSYS -#if defined SMEXT_ENABLE_PLAYERHELPERS -#include -#endif //SMEXT_ENABLE_PlAYERHELPERS -#if defined SMEXT_ENABLE_DBMANAGER -#include -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMECONF -#include -#endif -#if defined SMEXT_ENABLE_MEMUTILS -#include -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS -#include -#endif -#if defined SMEXT_ENABLE_TIMERSYS -#include -#endif -#if defined SMEXT_ENABLE_ADTFACTORY -#include -#endif -#if defined SMEXT_ENABLE_THREADER -#include -#endif -#if defined SMEXT_ENABLE_LIBSYS -#include -#endif -#if defined SMEXT_ENABLE_PLUGINSYS -#include -#endif - -#if defined SMEXT_CONF_METAMOD -#include -#include -#endif - -#if !defined METAMOD_PLAPI_VERSION -#include -#endif - -using namespace SourceMod; -using namespace SourcePawn; - -class SDKExtension : -#if defined SMEXT_CONF_METAMOD - public ISmmPlugin, -#endif - public IExtensionInterface -{ -public: - /** Constructor */ - SDKExtension(); -public: - /** - * @brief This is called after the initial loading sequence has been processed. - * - * @param error Error message buffer. - * @param maxlength Size of error message buffer. - * @param late Whether or not the module was loaded after map load. - * @return True to succeed loading, false to fail. - */ - virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late); - - /** - * @brief This is called right before the extension is unloaded. - */ - virtual void SDK_OnUnload(); - - /** - * @brief This is called once all known extensions have been loaded. - */ - virtual void SDK_OnAllLoaded(); - - /** - * @brief Called when the pause state is changed. - */ - virtual void SDK_OnPauseChange(bool paused); - -#if defined SMEXT_CONF_METAMOD - /** - * @brief Called when Metamod is attached, before the extension version is called. - * - * @param error Error buffer. - * @param maxlength Maximum size of error buffer. - * @param late Whether or not Metamod considers this a late load. - * @return True to succeed, false to fail. - */ - virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late); - - /** - * @brief Called when Metamod is detaching, after the extension version is called. - * NOTE: By default this is blocked unless sent from SourceMod. - * - * @param error Error buffer. - * @param maxlength Maximum size of error buffer. - * @return True to succeed, false to fail. - */ - virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength); - - /** - * @brief Called when Metamod's pause state is changing. - * NOTE: By default this is blocked unless sent from SourceMod. - * - * @param paused Pause state being set. - * @param error Error buffer. - * @param maxlength Maximum size of error buffer. - * @return True to succeed, false to fail. - */ - virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength); -#endif - -public: //IExtensionInterface - virtual bool OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late); - virtual void OnExtensionUnload(); - virtual void OnExtensionsAllLoaded(); - - /** Returns whether or not this is a Metamod-based extension */ - virtual bool IsMetamodExtension(); - - /** - * @brief Called when the pause state changes. - * - * @param state True if being paused, false if being unpaused. - */ - virtual void OnExtensionPauseChange(bool state); - - /** Returns name */ - virtual const char *GetExtensionName(); - /** Returns URL */ - virtual const char *GetExtensionURL(); - /** Returns log tag */ - virtual const char *GetExtensionTag(); - /** Returns author */ - virtual const char *GetExtensionAuthor(); - /** Returns version string */ - virtual const char *GetExtensionVerString(); - /** Returns description string */ - virtual const char *GetExtensionDescription(); - /** Returns date string */ - virtual const char *GetExtensionDateString(); -#if defined SMEXT_CONF_METAMOD -public: //ISmmPlugin - /** Called when the extension is attached to Metamod. */ - virtual bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlength, bool late); - /** Returns the author to MM */ - virtual const char *GetAuthor(); - /** Returns the name to MM */ - virtual const char *GetName(); - /** Returns the description to MM */ - virtual const char *GetDescription(); - /** Returns the URL to MM */ - virtual const char *GetURL(); - /** Returns the license to MM */ - virtual const char *GetLicense(); - /** Returns the version string to MM */ - virtual const char *GetVersion(); - /** Returns the date string to MM */ - virtual const char *GetDate(); - /** Returns the logtag to MM */ - virtual const char *GetLogTag(); - /** Called on unload */ - virtual bool Unload(char *error, size_t maxlength); - /** Called on pause */ - virtual bool Pause(char *error, size_t maxlength); - /** Called on unpause */ - virtual bool Unpause(char *error, size_t maxlength); -private: - bool m_SourceMMLoaded; - bool m_WeAreUnloaded; - bool m_WeGotPauseChange; -#endif -}; - -extern SDKExtension *g_pExtensionIface; -extern IExtension *myself; - -extern IShareSys *g_pShareSys; -extern IShareSys *sharesys; /* Note: Newer name */ -extern ISourceMod *g_pSM; -extern ISourceMod *smutils; /* Note: Newer name */ - -/* Optional interfaces are below */ -#if defined SMEXT_ENABLE_FORWARDSYS -extern IForwardManager *g_pForwards; -extern IForwardManager *forwards; /* Note: Newer name */ -#endif //SMEXT_ENABLE_FORWARDSYS -#if defined SMEXT_ENABLE_HANDLESYS -extern IHandleSys *g_pHandleSys; -extern IHandleSys *handlesys; /* Note: Newer name */ -#endif //SMEXT_ENABLE_HANDLESYS -#if defined SMEXT_ENABLE_PLAYERHELPERS -extern IPlayerManager *playerhelpers; -#endif //SMEXT_ENABLE_PLAYERHELPERS -#if defined SMEXT_ENABLE_DBMANAGER -extern IDBManager *dbi; -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMECONF -extern IGameConfigManager *gameconfs; -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_MEMUTILS -extern IMemoryUtils *memutils; -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS -extern IGameHelpers *gamehelpers; -#endif -#if defined SMEXT_ENABLE_TIMERSYS -extern ITimerSystem *timersys; -#endif -#if defined SMEXT_ENABLE_ADTFACTORY -extern IADTFactory *adtfactory; -#endif -#if defined SMEXT_ENABLE_THREADER -extern IThreader *threader; -#endif -#if defined SMEXT_ENABLE_LIBSYS -extern ILibrarySys *libsys; -#endif -#if defined SMEXT_ENABLE_PLUGINSYS -extern SourceMod::IPluginManager *plsys; -#endif - -#if defined SMEXT_CONF_METAMOD -PLUGIN_GLOBALVARS(); -extern IVEngineServer *engine; -extern IServerGameDLL *gamedll; -#endif - -/** Creates a SourceMod interface macro pair */ -#define SM_MKIFACE(name) SMINTERFACE_##name##_NAME, SMINTERFACE_##name##_VERSION -/** Automates retrieving SourceMod interfaces */ -#define SM_GET_IFACE(prefix, addr) \ - if (!g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr)) \ - { \ - if (error != NULL && maxlength) \ - { \ - size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \ - if (len >= maxlength) \ - { \ - error[maxlength - 1] = '\0'; \ - } \ - } \ - return false; \ - } -/** Automates retrieving SourceMod interfaces when needed outside of SDK_OnLoad() */ -#define SM_GET_LATE_IFACE(prefix, addr) \ - g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr) -/** Validates a SourceMod interface pointer */ -#define SM_CHECK_IFACE(prefix, addr) \ - if (!addr) \ - { \ - if (error != NULL && maxlength) \ - { \ - size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \ - if (len >= maxlength) \ - { \ - error[maxlength - 1] = '\0'; \ - } \ - } \ - return false; \ - } - -#endif // _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ diff --git a/extensions/sdktools/svn_version.h b/extensions/sdktools/svn_version.h deleted file mode 100644 index 42146034..00000000 --- a/extensions/sdktools/svn_version.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -/** - * Autogenerated by build scripts - */ - -#ifndef _INCLUDE_SDKTOOLS_VERSION_H_ -#define _INCLUDE_SDKTOOLS_VERSION_H_ - -#define SVN_FULL_VERSION "1.1.0-svn" -#define SVN_FILE_VERSION 1,1,0,2230 - -#endif //_INCLUDE_SDKTOOLS_VERSION_H_ diff --git a/extensions/sdktools/svn_version.tpl b/extensions/sdktools/svn_version.tpl deleted file mode 100644 index 2b1e90f2..00000000 --- a/extensions/sdktools/svn_version.tpl +++ /dev/null @@ -1,42 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -/** - * Autogenerated by build scripts - */ - -#ifndef _INCLUDE_SDKTOOLS_VERSION_H_ -#define _INCLUDE_SDKTOOLS_VERSION_H_ - -#define SVN_FULL_VERSION "$PMAJOR$.$PMINOR$.$PREVISION$-svn" -#define SVN_FILE_VERSION $PMAJOR$,$PMINOR$,$PREVISION$,$GLOBAL_BUILD$ - -#endif //_INCLUDE_SDKTOOLS_VERSION_H_ diff --git a/extensions/sdktools/teamnatives.cpp b/extensions/sdktools/teamnatives.cpp deleted file mode 100644 index 33cc0134..00000000 --- a/extensions/sdktools/teamnatives.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "extension.h" -#include - -struct TeamInfo -{ - const char *ClassName; - CBaseEntity *pEnt; -}; - -SourceHook::CVector g_Teams; - -bool FindTeamEntities(SendTable *pTable, const char *name) -{ - if (strcmp(pTable->GetName(), name) == 0) - { - return true; - } - - int props = pTable->GetNumProps(); - SendProp *prop; - - for (int i=0; iGetProp(i); - if (prop->GetDataTable()) - { - if (FindTeamEntities(prop->GetDataTable(), name)) - { - return true; - } - } - } - - return false; -} - -void SDKTools::OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax) -{ - g_Teams.clear(); - g_Teams.resize(1); - - for (int i=0; iPEntityOfEntIndex(i); - if (!pEdict || pEdict->IsFree()) - { - continue; - } - if (!pEdict->GetNetworkable()) - { - continue; - } - - ServerClass *pClass = pEdict->GetNetworkable()->GetServerClass(); - if (FindTeamEntities(pClass->m_pTable, "DT_Team")) - { - SendProp *pTeamNumProp = g_pGameHelpers->FindInSendTable(pClass->GetName(), "m_iTeamNum"); - - if (pTeamNumProp != NULL) - { - int offset = pTeamNumProp->GetOffset(); - CBaseEntity *pEnt = pEdict->GetUnknown()->GetBaseEntity(); - int TeamIndex = *(int *)((unsigned char *)pEnt + offset); - - if (TeamIndex >= (int)g_Teams.size()) - { - g_Teams.resize(TeamIndex+1); - } - g_Teams[TeamIndex].ClassName = pClass->GetName(); - g_Teams[TeamIndex].pEnt = pEnt; - } - } - } -} - -static cell_t GetTeamCount(IPluginContext *pContext, const cell_t *params) -{ - return g_Teams.size(); -} - -static cell_t GetTeamName(IPluginContext *pContext, const cell_t *params) -{ - int teamindex = params[1]; - if (!g_Teams[teamindex].ClassName || (teamindex > (int)g_Teams.size())) - { - pContext->ThrowNativeError("Team index %d is invalid", teamindex); - } - - static int offset = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "m_szTeamname")->GetOffset(); - char *name = (char *)((unsigned char *)g_Teams[teamindex].pEnt + offset); - - pContext->StringToLocalUTF8(params[2], params[3], name, NULL); - - return 1; -} - -static cell_t GetTeamScore(IPluginContext *pContext, const cell_t *params) -{ - int teamindex = params[1]; - if (!g_Teams[teamindex].ClassName || (teamindex > (int)g_Teams.size())) - { - pContext->ThrowNativeError("Team index %d is invalid", teamindex); - } - - static int offset = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "m_iScore")->GetOffset(); - - return *(int *)((unsigned char *)g_Teams[teamindex].pEnt + offset); -} - -static cell_t SetTeamScore(IPluginContext *pContext, const cell_t *params) -{ - int teamindex = params[1]; - if (!g_Teams[teamindex].ClassName || (teamindex > (int)g_Teams.size())) - { - pContext->ThrowNativeError("Team index %d is invalid", teamindex); - } - - static int offset = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "m_iScore")->GetOffset(); - *(int *)((unsigned char *)g_Teams[teamindex].pEnt + offset) = params[2]; - - return 1; -} - -static cell_t GetTeamClientCount(IPluginContext *pContext, const cell_t *params) -{ - int teamindex = params[1]; - if (!g_Teams[teamindex].ClassName || (teamindex > (int)g_Teams.size())) - { - pContext->ThrowNativeError("Team index %d is invalid", teamindex); - } - - SendProp *pProp = g_pGameHelpers->FindInSendTable(g_Teams[teamindex].ClassName, "\"player_array\""); - ArrayLengthSendProxyFn fn = pProp->GetArrayLengthProxy(); - - return fn(g_Teams[teamindex].pEnt, 0); -} - -sp_nativeinfo_t g_TeamNatives[] = -{ - {"GetTeamCount", GetTeamCount}, - {"GetTeamName", GetTeamName}, - {"GetTeamScore", GetTeamScore}, - {"SetTeamScore", SetTeamScore}, - {"GetTeamClientCount", GetTeamClientCount}, - {NULL, NULL} -}; diff --git a/extensions/sdktools/tempents.cpp b/extensions/sdktools/tempents.cpp deleted file mode 100644 index 407f709a..00000000 --- a/extensions/sdktools/tempents.cpp +++ /dev/null @@ -1,493 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "tempents.h" - -TempEntityManager g_TEManager; -ICallWrapper *g_GetServerClass = NULL; - -CON_COMMAND(sm_print_telist, "Prints the temp entity list") -{ - if (!g_TEManager.IsAvailable()) - { - META_CONPRINT("The tempent portion of SDKTools failed to load.\n"); - META_CONPRINT("Check that you have the latest sdktools.games.txt file!\n"); - return; - } - g_TEManager.DumpList(); -} - -CON_COMMAND(sm_dump_teprops, "Dumps tempentity props to a file") -{ -#if !defined ORANGEBOX_BUILD - CCommand args; -#endif - if (!g_TEManager.IsAvailable()) - { - META_CONPRINT("The tempent portion of SDKTools failed to load.\n"); - META_CONPRINT("Check that you have the latest sdktools.games.txt file!\n"); - return; - } - int argc = args.ArgC(); - if (argc < 2) - { - META_CONPRINT("Usage: sm_dump_teprops \n"); - return; - } - - const char *arg = args.Arg(1); - - if (!arg || arg[0] == '\0') - { - META_CONPRINTF("Usage: sm_dump_teprops \n"); - return; - } - - char path[PLATFORM_MAX_PATH]; - g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", arg); - - FILE *fp = NULL; - if ((fp = fopen(path, "wt")) == NULL) - { - META_CONPRINTF("Could not open file \"%s\"\n", path); - return; - } - - g_TEManager.DumpProps(fp); - - fclose(fp); -} - -/************************* -* * -* Temp Entities Wrappers * -* * -**************************/ - -TempEntityInfo::TempEntityInfo(const char *name, void *me) -{ - m_Name.assign(name); - m_Me = me; - g_GetServerClass->Execute(&m_Me, &m_Sc); -} - -const char *TempEntityInfo::GetName() -{ - return m_Name.c_str(); -} - -ServerClass *TempEntityInfo::GetServerClass() -{ - return m_Sc; -} - -bool TempEntityInfo::IsValidProp(const char *name) -{ - return (g_pGameHelpers->FindInSendTable(m_Sc->GetName(), name)) ? true : false; -} - -int TempEntityInfo::_FindOffset(const char *name, int *size) -{ - int offset; - - SendProp *prop = g_pGameHelpers->FindInSendTable(m_Sc->GetName(), name); - if (!prop) - { - return -1; - } - - offset = prop->GetOffset(); - if (size) - { - *size = prop->m_nBits; - } - - return offset; -} - -bool TempEntityInfo::TE_SetEntData(const char *name, int value) -{ - /* Search for our offset */ - int size; - int offset = _FindOffset(name, &size); - - if (offset < 0) - { - return false; - } - - if (size <= 8) - { - *((uint8_t *)m_Me + offset) = value; - } else if (size <= 16) { - *(short *)((uint8_t *)m_Me + offset) = value; - } else if (size <= 32) { - *(int *)((uint8_t *)m_Me + offset) = value; - } else { - return false; - } - - return true; -} - -bool TempEntityInfo::TE_GetEntData(const char *name, int *value) -{ - /* Search for our offset */ - int size; - int offset = _FindOffset(name, &size); - - if (offset < 0) - { - return false; - } - - if (size <= 8) - { - *value = *((uint8_t *)m_Me + offset); - } else if (size <= 16) { - *value = *(short *)((uint8_t *)m_Me + offset); - } else if (size <= 32) { - *value = *(int *)((uint8_t *)m_Me + offset); - } else { - return false; - } - - return true; -} - -bool TempEntityInfo::TE_SetEntDataFloat(const char *name, float value) -{ - /* Search for our offset */ - int offset = _FindOffset(name); - - if (offset < 0) - { - return false; - } - - *(float *)((uint8_t *)m_Me + offset) = value; - - return true; -} - -bool TempEntityInfo::TE_GetEntDataFloat(const char *name, float *value) -{ - /* Search for our offset */ - int offset = _FindOffset(name); - - if (offset < 0) - { - return false; - } - - *value = *(float *)((uint8_t *)m_Me + offset); - - return true; -} - -bool TempEntityInfo::TE_SetEntDataVector(const char *name, float vector[3]) -{ - /* Search for our offset */ - int offset = _FindOffset(name); - - if (offset < 0) - { - return false; - } - - Vector *v = (Vector *)((uint8_t *)m_Me + offset); - v->x = vector[0]; - v->y = vector[1]; - v->z = vector[2]; - - return true; -} - -bool TempEntityInfo::TE_GetEntDataVector(const char *name, float vector[3]) -{ - /* Search for our offset */ - int offset = _FindOffset(name); - - if (offset < 0) - { - return false; - } - - Vector *v = (Vector *)((uint8_t *)m_Me + offset); - vector[0] = v->x; - vector[1] = v->y; - vector[2] = v->z; - - return true; -} - -bool TempEntityInfo::TE_SetEntDataFloatArray(const char *name, cell_t *array, int size) -{ - /* Search for our offset */ - int offset = _FindOffset(name); - - if (offset < 0) - { - return false; - } - - float *base = (float *)((uint8_t *)m_Me + offset); - for (int i=0; iPlaybackTempEntity(filter, delay, m_Me, m_Sc->m_pTable, m_Sc->m_ClassID); -} - -/********************** -* * -* Temp Entity Manager * -* * -***********************/ - -void TempEntityManager::Initialize() -{ - void *addr; - int offset; - m_Loaded = false; - - /* Read our sigs and offsets from the config file */ -#if defined PLATFORM_WINDOWS - if (!g_pGameConf->GetMemSig("CBaseTempEntity", &addr) || !addr) - { - return; - } - if (!g_pGameConf->GetOffset("s_pTempEntities", &offset)) - { - return; - } - /* Store the head of the TE linked list */ - m_ListHead = **(void ***)((unsigned char *)addr + offset); -#else - if (!g_pGameConf->GetMemSig("s_pTempEntities", &addr) || !addr) - { - return; - } - /* Store the head of the TE linked list */ - m_ListHead = *(void **)addr; -#endif - if (!g_pGameConf->GetOffset("GetTEName", &m_NameOffs)) - { - return; - } - if (!g_pGameConf->GetOffset("GetTENext", &m_NextOffs)) - { - return; - } - if (!g_pGameConf->GetOffset("TE_GetServerClass", &m_GetClassNameOffs)) - { - return; - } - - /* Create our trie */ - m_TempEntInfo = adtfactory->CreateBasicTrie(); - - /* Create the GetServerClass call */ - PassInfo retinfo; - retinfo.flags = PASSFLAG_BYVAL; - retinfo.type = PassType_Basic; - retinfo.size = sizeof(ServerClass *); - g_GetServerClass = g_pBinTools->CreateVCall(m_GetClassNameOffs, 0, 0, &retinfo, NULL, 0); - - /* We're done */ - m_Loaded = true; -} - -bool TempEntityManager::IsAvailable() -{ - return m_Loaded; -} - -void TempEntityManager::Shutdown() -{ - if (!IsAvailable()) - { - return; - } - - SourceHook::List::iterator iter; - for (iter=m_TEList.begin(); iter!=m_TEList.end(); iter++) - { - delete (*iter); - } - m_TEList.clear(); - - m_TempEntInfo->Destroy(); - g_GetServerClass->Destroy(); - g_GetServerClass = NULL; - m_ListHead = NULL; - m_NextOffs = m_NameOffs = m_GetClassNameOffs = 0; - m_Loaded = false; -} - -TempEntityInfo *TempEntityManager::GetTempEntityInfo(const char *name) -{ - /* If the system is unloaded skip the search */ - if (!IsAvailable()) - { - return NULL; - } - - TempEntityInfo *te = NULL; - - /* Start searching for the TE inside the engine */ - if (!m_TempEntInfo->Retrieve(name, reinterpret_cast(&te))) - { - void *iter = m_ListHead; - while (iter) - { - const char *realname = *(const char **)((unsigned char *)iter + m_NameOffs); - if (!realname) - { - continue; - } - if (strcmp(name, realname) == 0) - { - te = new TempEntityInfo(name, iter); - m_TempEntInfo->Insert(name, (void *)te); - m_TEList.push_back(te); - return te; - } - iter = *(void **)((unsigned char *)iter + m_NextOffs); - } - return NULL; - } - - return te; -} - -const char *TempEntityManager::GetNameFromThisPtr(void *me) -{ - return *(const char **)((unsigned char *)me + m_NameOffs); -} - -void TempEntityManager::DumpList() -{ - unsigned int index = 0; - META_CONPRINT("Listing temp entities:\n"); - void *iter = m_ListHead; - while (iter) - { - const char *realname = *(const char **)((unsigned char *)iter + m_NameOffs); - if (!realname) - { - break; - } - TempEntityInfo *info = GetTempEntityInfo(realname); - if (!info) - { - continue; - } - ServerClass *sc = info->GetServerClass(); - META_CONPRINTF("[%02d] %s (%s)\n", index++, realname, sc->GetName()); - iter = *(void **)((unsigned char *)iter + m_NextOffs); - } - META_CONPRINTF("%d tempent%s found.\n", index, (index == 1) ? " was" : "s were"); -} - -const char *SendPropTypeToString(SendPropType type) -{ - if (type == DPT_Int) - { - return "int"; - } else if (type == DPT_Float) { - return "float"; - } else if (type == DPT_Vector) { - return "vector"; - } else if (type == DPT_String) { - return "string"; - } else if (type == DPT_Array) { - return "array"; - } else if (type == DPT_DataTable) { - return "datatable"; - } else { - return "unknown"; - } -} - -void _DumpProps(FILE *fp, SendTable *pTable) -{ - SendTable *pOther; - for (int i=0; iGetNumProps(); i++) - { - SendProp *prop = pTable->GetProp(i); - if ((pOther = prop->GetDataTable()) != NULL) - { - _DumpProps(fp, pOther); - } else { - fprintf(fp, "\t\t\t\"%s\"\t\t\"%s\"\n", - prop->GetName() ? prop->GetName() : "unknown", - SendPropTypeToString(prop->GetType())); - } - } -} - -void TempEntityManager::DumpProps(FILE *fp) -{ - unsigned int index = 0; - void *iter = m_ListHead; - fprintf(fp, "\"TempEnts\"\n{\n"); - while (iter) - { - const char *realname = *(const char **)((unsigned char *)iter + m_NameOffs); - if (!realname) - { - break; - } - TempEntityInfo *info = GetTempEntityInfo(realname); - if (!info) - { - continue; - } - ServerClass *sc = info->GetServerClass(); - fprintf(fp, "\t\"%s\"\n", sc->GetName()); - fprintf(fp, "\t{\n"); - fprintf(fp, "\t\t\"name\"\t\t\"%s\"\n", realname); - fprintf(fp, "\t\t\"index\"\t\t\"%d\"\n", index++); - fprintf(fp, "\t\t\"SendTable\"\n\t\t{\n"); - _DumpProps(fp, sc->m_pTable); - fprintf(fp, "\t\t}\n\t}\n"); - iter = *(void **)((unsigned char *)iter + m_NextOffs); - } - fprintf(fp, "}\n"); - META_CONPRINTF("%d tempent%s written to file.\n", index, (index == 1) ? " was" : "s were"); -} diff --git a/extensions/sdktools/tempents.h b/extensions/sdktools/tempents.h deleted file mode 100644 index 366ccc6a..00000000 --- a/extensions/sdktools/tempents.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_TEMPENTS_H_ -#define _INCLUDE_SOURCEMOD_TEMPENTS_H_ - -#include "extension.h" -#include -#include -#include -#include - -class TempEntityInfo -{ -public: - TempEntityInfo(const char *name, void *me); -public: - const char *GetName(); - ServerClass *GetServerClass(); - bool IsValidProp(const char *name); - bool TE_SetEntData(const char *name, int value); - bool TE_SetEntDataFloat(const char *name, float value); - bool TE_SetEntDataVector(const char *name, float vector[3]); - bool TE_SetEntDataFloatArray(const char *name, cell_t *array, int size); - bool TE_GetEntData(const char *name, int *value); - bool TE_GetEntDataFloat(const char *name, float *value); - bool TE_GetEntDataVector(const char *name, float vector[3]); - void Send(IRecipientFilter &filter, float delay); -private: - int _FindOffset(const char *name, int *size=NULL); -private: - void *m_Me; - ServerClass *m_Sc; - SourceHook::String m_Name; -}; - -class TempEntityManager -{ -public: - TempEntityManager() : m_NameOffs(0), m_NextOffs(0), m_GetClassNameOffs(0), m_Loaded(false) {} -public: - void Initialize(); - bool IsAvailable(); - void Shutdown(); -public: - TempEntityInfo *GetTempEntityInfo(const char *name); - const char *GetNameFromThisPtr(void *me); -public: - void DumpList(); - void DumpProps(FILE *fp); -private: - SourceHook::List m_TEList; - IBasicTrie *m_TempEntInfo; - void *m_ListHead; - int m_NameOffs; - int m_NextOffs; - int m_GetClassNameOffs; - bool m_Loaded; -}; - -struct TEHookInfo -{ - TempEntityInfo *te; - SourceHook::List lst; -}; - -class TempEntHooks : public IPluginsListener -{ -public: //IPluginsListener - void OnPluginUnloaded(IPlugin *plugin); -public: - void Initialize(); - void Shutdown(); - bool AddHook(const char *name, IPluginFunction *pFunc); - bool RemoveHook(const char *name, IPluginFunction *pFunc); - void OnPlaybackTempEntity(IRecipientFilter &filter, float delay, const void *pSender, const SendTable *pST, int classID); -private: - void _IncRefCounter(); - void _DecRefCounter(); - size_t _FillInPlayers(int *pl_array, IRecipientFilter *pFilter); -private: - IBasicTrie *m_TEHooks; - SourceHook::List m_HookInfo; - size_t m_HookCount; -}; - -extern TempEntityManager g_TEManager; -extern TempEntHooks s_TempEntHooks; - -#endif //_INCLUDE_SOURCEMOD_TEMPENTS_H_ diff --git a/extensions/sdktools/tenatives.cpp b/extensions/sdktools/tenatives.cpp deleted file mode 100644 index 0f4e20ed..00000000 --- a/extensions/sdktools/tenatives.cpp +++ /dev/null @@ -1,561 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "tempents.h" -#include "CellRecipientFilter.h" -#include - -SH_DECL_HOOK5_void(IVEngineServer, PlaybackTempEntity, SH_NOATTRIB, 0, IRecipientFilter &, float, const void *, const SendTable *, int); - -CellRecipientFilter g_TERecFilter; -TempEntityInfo *g_CurrentTE = NULL; -int g_TEPlayers[256]; -bool tenatives_initialized = false; - -/************************* -* * -* Temp Entity Hook Class * -* * -**************************/ - -void TempEntHooks::Initialize() -{ - m_TEHooks = adtfactory->CreateBasicTrie(); - plsys->AddPluginsListener(this); - tenatives_initialized = true; -} - -void TempEntHooks::Shutdown() -{ - if (!tenatives_initialized) - { - return; - } - - plsys->RemovePluginsListener(this); - SourceHook::List::iterator iter; - for (iter=m_HookInfo.begin(); iter!=m_HookInfo.end(); iter++) - { - delete (*iter); - } - if (m_HookCount) - { - m_HookCount = 1; - _DecRefCounter(); - } - m_TEHooks->Destroy(); - tenatives_initialized = false; -} - -void TempEntHooks::OnPluginUnloaded(IPlugin *plugin) -{ - SourceHook::List::iterator iter = m_HookInfo.begin(); - IPluginContext *pContext = plugin->GetBaseContext(); - - /* For each hook list... */ - while (iter != m_HookInfo.end()) - { - SourceHook::List::iterator f_iter = (*iter)->lst.begin(); - - /* Find the hooks on the given temp entity */ - while (f_iter != (*iter)->lst.end()) - { - /* If it matches, remove it and dec the ref count */ - if ((*f_iter)->GetParentContext() == pContext) - { - f_iter = (*iter)->lst.erase(f_iter); - _DecRefCounter(); - } - else - { - f_iter++; - } - } - - /* If there are no more hooks left, we can safely - * remove it from the cache and remove its list. - */ - if ((*iter)->lst.size() == 0) - { - m_TEHooks->Delete((*iter)->te->GetName()); - delete (*iter); - iter = m_HookInfo.erase(iter); - } - else - { - iter++; - } - } -} - -void TempEntHooks::_IncRefCounter() -{ - if (m_HookCount++ == 0) - { - SH_ADD_HOOK_MEMFUNC(IVEngineServer, PlaybackTempEntity, engine, this, &TempEntHooks::OnPlaybackTempEntity, false); - } -} - -void TempEntHooks::_DecRefCounter() -{ - if (--m_HookCount == 0) - { - SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, PlaybackTempEntity, engine, this, &TempEntHooks::OnPlaybackTempEntity, false); - } -} - -size_t TempEntHooks::_FillInPlayers(int *pl_array, IRecipientFilter *pFilter) -{ - size_t size = static_cast(pFilter->GetRecipientCount()); - - for (size_t i=0; iGetRecipientIndex(i); - } - - return size; -} - -bool TempEntHooks::AddHook(const char *name, IPluginFunction *pFunc) -{ - TEHookInfo *pInfo; - - if (m_TEHooks->Retrieve(name, reinterpret_cast(&pInfo))) - { - pInfo->lst.push_back(pFunc); - } else { - TempEntityInfo *te; - if (!(te=g_TEManager.GetTempEntityInfo(name))) - { - return false; - } - - pInfo = new TEHookInfo; - pInfo->te = te; - pInfo->lst.push_back(pFunc); - - m_TEHooks->Insert(name, reinterpret_cast(pInfo)); - m_HookInfo.push_back(pInfo); - } - - _IncRefCounter(); - - return true; -} - -bool TempEntHooks::RemoveHook(const char *name, IPluginFunction *pFunc) -{ - TEHookInfo *pInfo; - - if (m_TEHooks->Retrieve(name, reinterpret_cast(&pInfo))) - { - SourceHook::List::iterator iter; - if ((iter=pInfo->lst.find(pFunc)) != pInfo->lst.end()) - { - pInfo->lst.erase(iter); - if (pInfo->lst.empty()) - { - m_HookInfo.remove(pInfo); - m_TEHooks->Delete(name); - delete pInfo; - } - _DecRefCounter(); - } else { - return false; - } - } else { - return false; - } - - return true; -} - -void TempEntHooks::OnPlaybackTempEntity(IRecipientFilter &filter, float delay, const void *pSender, const SendTable *pST, int classID) -{ - TEHookInfo *pInfo; - const char *name = g_TEManager.GetNameFromThisPtr(const_cast(pSender)); - - if (m_TEHooks->Retrieve(name, reinterpret_cast(&pInfo))) - { - SourceHook::List::iterator iter; - IPluginFunction *pFunc; - size_t size; - cell_t res = static_cast(Pl_Continue); - - TempEntityInfo *oldinfo = g_CurrentTE; - g_CurrentTE = pInfo->te; - size = _FillInPlayers(g_TEPlayers, &filter); - - for (iter=pInfo->lst.begin(); iter!=pInfo->lst.end(); iter++) - { - pFunc = (*iter); - pFunc->PushString(name); - pFunc->PushArray(g_TEPlayers, size); - pFunc->PushCell(size); - pFunc->PushFloat(delay); - pFunc->Execute(&res); - - if (res != Pl_Continue) - { - g_CurrentTE = oldinfo; - RETURN_META(MRES_SUPERCEDE); - } - } - - g_CurrentTE = oldinfo; - RETURN_META(MRES_IGNORED); - } -} - -/********************** -* * -* Temp Entity Natives * -* * -***********************/ - -TempEntHooks s_TempEntHooks; - -static cell_t smn_TEStart(IPluginContext *pContext, const cell_t *params) -{ - if (!g_TEManager.IsAvailable()) - { - return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); - } - - char *name; - pContext->LocalToString(params[1], &name); - - g_CurrentTE = g_TEManager.GetTempEntityInfo(name); - if (!g_CurrentTE) - { - return pContext->ThrowNativeError("Invalid TempEntity name: \"%s\"", name); - } - - return 1; -} - -static cell_t smn_TEWriteNum(IPluginContext *pContext, const cell_t *params) -{ - if (!g_TEManager.IsAvailable()) - { - return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); - } - if (!g_CurrentTE) - { - return pContext->ThrowNativeError("No TempEntity call is in progress"); - } - - char *prop; - pContext->LocalToString(params[1], &prop); - - if (!g_CurrentTE->TE_SetEntData(prop, params[2])) - { - return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop); - } - - return 1; -} - -static cell_t smn_TEReadNum(IPluginContext *pContext, const cell_t *params) -{ - if (!g_TEManager.IsAvailable()) - { - return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); - } - if (!g_CurrentTE) - { - return pContext->ThrowNativeError("No TempEntity call is in progress"); - } - - char *prop; - int val; - pContext->LocalToString(params[1], &prop); - - if (!g_CurrentTE->TE_GetEntData(prop, &val)) - { - return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop); - } - - return val; -} - -static cell_t smn_TE_WriteFloat(IPluginContext *pContext, const cell_t *params) -{ - if (!g_TEManager.IsAvailable()) - { - return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); - } - if (!g_CurrentTE) - { - return pContext->ThrowNativeError("No TempEntity call is in progress"); - } - - char *prop; - pContext->LocalToString(params[1], &prop); - - if (!g_CurrentTE->TE_SetEntDataFloat(prop, sp_ctof(params[2]))) - { - return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop); - } - - return 1; -} - -static cell_t smn_TE_ReadFloat(IPluginContext *pContext, const cell_t *params) -{ - if (!g_TEManager.IsAvailable()) - { - return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); - } - if (!g_CurrentTE) - { - return pContext->ThrowNativeError("No TempEntity call is in progress"); - } - - char *prop; - float val; - pContext->LocalToString(params[1], &prop); - - if (!g_CurrentTE->TE_GetEntDataFloat(prop, &val)) - { - return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop); - } - - return sp_ftoc(val); -} - -static cell_t smn_TEWriteVector(IPluginContext *pContext, const cell_t *params) -{ - if (!g_TEManager.IsAvailable()) - { - return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); - } - if (!g_CurrentTE) - { - return pContext->ThrowNativeError("No TempEntity call is in progress"); - } - - char *prop; - pContext->LocalToString(params[1], &prop); - - cell_t *addr; - pContext->LocalToPhysAddr(params[2], &addr); - float vec[3] = {sp_ctof(addr[0]), sp_ctof(addr[1]), sp_ctof(addr[2])}; - - if (!g_CurrentTE->TE_SetEntDataVector(prop, vec)) - { - return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop); - } - - return 1; -} - -static cell_t smn_TEReadVector(IPluginContext *pContext, const cell_t *params) -{ - if (!g_TEManager.IsAvailable()) - { - return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); - } - if (!g_CurrentTE) - { - return pContext->ThrowNativeError("No TempEntity call is in progress"); - } - - char *prop; - pContext->LocalToString(params[1], &prop); - - cell_t *addr; - float vec[3]; - pContext->LocalToPhysAddr(params[2], &addr); - - if (!g_CurrentTE->TE_GetEntDataVector(prop, vec)) - { - return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop); - } - - addr[0] = sp_ftoc(vec[0]); - addr[1] = sp_ftoc(vec[1]); - addr[2] = sp_ftoc(vec[2]); - - return 1; -} - -static cell_t smn_TEWriteFloatArray(IPluginContext *pContext, const cell_t *params) -{ - if (!g_TEManager.IsAvailable()) - { - return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); - } - if (!g_CurrentTE) - { - return pContext->ThrowNativeError("No TempEntity call is in progress"); - } - - char *prop; - pContext->LocalToString(params[1], &prop); - - cell_t *addr; - pContext->LocalToPhysAddr(params[2], &addr); - - if (!g_CurrentTE->TE_SetEntDataFloatArray(prop, addr, params[3])) - { - return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop); - } - - return 1; -} - -static cell_t smn_TESend(IPluginContext *pContext, const cell_t *params) -{ - if (!g_TEManager.IsAvailable()) - { - return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); - } - if (!g_CurrentTE) - { - return pContext->ThrowNativeError("No TempEntity call is in progress"); - } - - cell_t *cl_array; - unsigned int numClients; - int client; - IGamePlayer *pPlayer = NULL; - - pContext->LocalToPhysAddr(params[1], &cl_array); - numClients = params[2]; - - /* Client validation */ - for (unsigned int i = 0; i < numClients; i++) - { - client = cl_array[i]; - pPlayer = playerhelpers->GetGamePlayer(client); - - if (!pPlayer) - { - return pContext->ThrowNativeError("Client index %d is invalid", client); - } else if (!pPlayer->IsInGame()) { - return pContext->ThrowNativeError("Client %d is not connected", client); - } - } - - g_TERecFilter.Reset(); - g_TERecFilter.Initialize(cl_array, numClients); - - g_CurrentTE->Send(g_TERecFilter, sp_ctof(params[3])); - g_CurrentTE = NULL; - - return 1; -} - -static cell_t smn_TEIsValidProp(IPluginContext *pContext, const cell_t *params) -{ - if (!g_TEManager.IsAvailable()) - { - return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); - } - if (!g_CurrentTE) - { - return pContext->ThrowNativeError("No TempEntity call is in progress"); - } - - char *prop; - pContext->LocalToString(params[1], &prop); - - return g_CurrentTE->IsValidProp(prop) ? 1 : 0; -} - -static cell_t smn_AddTempEntHook(IPluginContext *pContext, const cell_t *params) -{ - char *name; - IPluginFunction *pFunc; - - if (!g_TEManager.IsAvailable()) - { - return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); - } - - pContext->LocalToString(params[1], &name); - pFunc = pContext->GetFunctionById(params[2]); - if (!pFunc) - { - return pContext->ThrowNativeError("Invalid function id (%X)", params[2]); - } - - if (!s_TempEntHooks.AddHook(name, pFunc)) - { - return pContext->ThrowNativeError("Invalid TempEntity name: \"%s\"", name); - } - - return 1; -} - -static cell_t smn_RemoveTempEntHook(IPluginContext *pContext, const cell_t *params) -{ - char *name; - IPluginFunction *pFunc; - - if (!g_TEManager.IsAvailable()) - { - return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report"); - } - - pContext->LocalToString(params[1], &name); - pFunc = pContext->GetFunctionById(params[2]); - if (!pFunc) - { - return pContext->ThrowNativeError("Invalid function id (%X)", params[2]); - } - - if (!s_TempEntHooks.RemoveHook(name, pFunc)) - { - return pContext->ThrowNativeError("Invalid hooked TempEntity name or function"); - } - - return 1; -} - -sp_nativeinfo_t g_TENatives[] = -{ - {"TE_Start", smn_TEStart}, - {"TE_WriteNum", smn_TEWriteNum}, - {"TE_ReadNum", smn_TEReadNum}, - {"TE_WriteFloat", smn_TE_WriteFloat}, - {"TE_ReadFloat", smn_TE_ReadFloat}, - {"TE_WriteVector", smn_TEWriteVector}, - {"TE_ReadVector", smn_TEReadVector}, - {"TE_WriteAngles", smn_TEWriteVector}, - {"TE_Send", smn_TESend}, - {"TE_IsValidProp", smn_TEIsValidProp}, - {"TE_WriteFloatArray", smn_TEWriteFloatArray}, - {"AddTempEntHook", smn_AddTempEntHook}, - {"RemoveTempEntHook", smn_RemoveTempEntHook}, - {NULL, NULL} -}; diff --git a/extensions/sdktools/trnatives.cpp b/extensions/sdktools/trnatives.cpp deleted file mode 100644 index 58ab0c1a..00000000 --- a/extensions/sdktools/trnatives.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "extension.h" -#include - -class CSMTraceFilter : public CTraceFilter -{ -public: - bool ShouldHitEntity(IHandleEntity *pEntity, int contentsMask) - { - cell_t res = 1; - edict_t *pEdict = gameents->BaseEntityToEdict(reinterpret_cast(pEntity)); - m_pFunc->PushCell(engine->IndexOfEdict(pEdict)); - m_pFunc->PushCell(contentsMask); - m_pFunc->PushCell(m_Data); - m_pFunc->Execute(&res); - - return (res) ? true : false; - } - void SetFunctionPtr(IPluginFunction *pFunc, cell_t data) - { - m_pFunc = pFunc; - m_Data = data; - } -private: - IPluginFunction *m_pFunc; - cell_t m_Data; -}; - -/* Used for the global trace version */ -Ray_t g_Ray; -trace_t g_Trace; -Vector g_StartVec; -Vector g_EndVec; -Vector g_HullMins; -Vector g_HullMaxs; -QAngle g_DirAngles; -CTraceFilterHitAll g_HitAllFilter; -CSMTraceFilter g_SMTraceFilter; - -enum -{ - RayType_EndPoint, - RayType_Infinite -}; - -static cell_t smn_TRTraceRay(IPluginContext *pContext, const cell_t *params) -{ - cell_t *startaddr, *endaddr; - pContext->LocalToPhysAddr(params[1], &startaddr); - pContext->LocalToPhysAddr(params[2], &endaddr); - - g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); - - switch (params[4]) - { - case RayType_EndPoint: - { - g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); - break; - } - case RayType_Infinite: - { - g_DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); - AngleVectors(g_DirAngles, &g_EndVec); - - /* Make it unitary and get the ending point */ - g_EndVec.NormalizeInPlace(); - g_EndVec = g_StartVec + g_EndVec * MAX_TRACE_LENGTH; - break; - } - } - - g_Ray.Init(g_StartVec, g_EndVec); - enginetrace->TraceRay(g_Ray, params[3], &g_HitAllFilter, &g_Trace); - - return 1; -} - -static cell_t smn_TRTraceHull(IPluginContext *pContext, const cell_t *params) -{ - cell_t *startaddr, *endaddr, *mins, *maxs; - pContext->LocalToPhysAddr(params[1], &startaddr); - pContext->LocalToPhysAddr(params[2], &endaddr); - pContext->LocalToPhysAddr(params[3], &mins); - pContext->LocalToPhysAddr(params[4], &maxs); - - g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); - g_HullMins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2])); - g_HullMaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2])); - g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); - - g_Ray.Init(g_StartVec, g_EndVec, g_HullMins, g_HullMaxs); - enginetrace->TraceRay(g_Ray, params[5], &g_HitAllFilter, &g_Trace); - - return 1; -} - -static cell_t smn_TRTraceRayFilter(IPluginContext *pContext, const cell_t *params) -{ - cell_t *startaddr, *endaddr; - IPluginFunction *pFunc; - cell_t data; - - pFunc = pContext->GetFunctionById(params[5]); - if (!pFunc) - { - return pContext->ThrowNativeError("Invalid function id (%X)", params[5]); - } - - if (params[0] >= 6) - { - data = params[6]; - } - else - { - data = 0; - } - - g_SMTraceFilter.SetFunctionPtr(pFunc, data); - pContext->LocalToPhysAddr(params[1], &startaddr); - pContext->LocalToPhysAddr(params[2], &endaddr); - - g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); - - switch (params[4]) - { - case RayType_EndPoint: - { - g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); - break; - } - case RayType_Infinite: - { - g_DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); - AngleVectors(g_DirAngles, &g_EndVec); - - /* Make it unitary and get the ending point */ - g_EndVec.NormalizeInPlace(); - g_EndVec = g_StartVec + g_EndVec * MAX_TRACE_LENGTH; - break; - } - } - - g_Ray.Init(g_StartVec, g_EndVec); - enginetrace->TraceRay(g_Ray, params[3], &g_SMTraceFilter, &g_Trace); - - return 1; -} - -static cell_t smn_TRTraceHullFilter(IPluginContext *pContext, const cell_t *params) -{ - cell_t data; - IPluginFunction *pFunc; - cell_t *startaddr, *endaddr, *mins, *maxs; - - pFunc = pContext->GetFunctionById(params[6]); - if (!pFunc) - { - return pContext->ThrowNativeError("Invalid function id (%X)", params[5]); - } - - data = params[7]; - - g_SMTraceFilter.SetFunctionPtr(pFunc, data); - pContext->LocalToPhysAddr(params[1], &startaddr); - pContext->LocalToPhysAddr(params[2], &endaddr); - pContext->LocalToPhysAddr(params[3], &mins); - pContext->LocalToPhysAddr(params[4], &maxs); - - g_StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); - g_HullMins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2])); - g_HullMaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2])); - g_EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); - - g_Ray.Init(g_StartVec, g_EndVec, g_HullMins, g_HullMaxs); - enginetrace->TraceRay(g_Ray, params[5], &g_SMTraceFilter, &g_Trace); - - return 1; -} - - -static cell_t smn_TRTraceRayEx(IPluginContext *pContext, const cell_t *params) -{ - cell_t *startaddr, *endaddr; - pContext->LocalToPhysAddr(params[1], &startaddr); - pContext->LocalToPhysAddr(params[2], &endaddr); - - Vector StartVec, EndVec; - Ray_t ray; - - StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); - - switch (params[4]) - { - case RayType_EndPoint: - { - EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); - break; - } - case RayType_Infinite: - { - QAngle DirAngles; - DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); - AngleVectors(DirAngles, &EndVec); - - /* Make it unitary and get the ending point */ - EndVec.NormalizeInPlace(); - EndVec = StartVec + EndVec * MAX_TRACE_LENGTH; - break; - } - } - - trace_t *tr = new trace_t; - ray.Init(StartVec, EndVec); - enginetrace->TraceRay(ray, params[3], &g_HitAllFilter, tr); - - HandleError herr; - Handle_t hndl; - if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr))) - { - delete tr; - return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr); - } - - return hndl; -} - -static cell_t smn_TRTraceHullEx(IPluginContext *pContext, const cell_t *params) -{ - cell_t *startaddr, *endaddr, *mins, *maxs; - pContext->LocalToPhysAddr(params[1], &startaddr); - pContext->LocalToPhysAddr(params[2], &endaddr); - pContext->LocalToPhysAddr(params[3], &mins); - pContext->LocalToPhysAddr(params[4], &maxs); - - Ray_t ray; - Vector StartVec, EndVec, vmins, vmaxs; - - StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); - vmins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2])); - vmaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2])); - EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); - - ray.Init(StartVec, EndVec, vmins, vmaxs); - - trace_t *tr = new trace_t; - enginetrace->TraceRay(ray, params[5], &g_HitAllFilter, tr); - - HandleError herr; - Handle_t hndl; - if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr))) - { - delete tr; - return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr); - } - - return hndl; -} - -static cell_t smn_TRTraceRayFilterEx(IPluginContext *pContext, const cell_t *params) -{ - IPluginFunction *pFunc; - cell_t *startaddr, *endaddr; - cell_t data; - - pFunc = pContext->GetFunctionById(params[5]); - if (!pFunc) - { - return pContext->ThrowNativeError("Invalid function id (%X)", params[5]); - } - pContext->LocalToPhysAddr(params[1], &startaddr); - pContext->LocalToPhysAddr(params[2], &endaddr); - - Vector StartVec, EndVec; - CSMTraceFilter smfilter; - Ray_t ray; - - if (params[0] >= 6) - { - data = params[6]; - } - else - { - data = 0; - } - - smfilter.SetFunctionPtr(pFunc, data); - StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); - - switch (params[4]) - { - case RayType_EndPoint: - { - EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); - break; - } - case RayType_Infinite: - { - QAngle DirAngles; - DirAngles.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); - AngleVectors(DirAngles, &EndVec); - - /* Make it unitary and get the ending point */ - EndVec.NormalizeInPlace(); - EndVec = StartVec + EndVec * MAX_TRACE_LENGTH; - break; - } - } - - trace_t *tr = new trace_t; - ray.Init(StartVec, EndVec); - enginetrace->TraceRay(ray, params[3], &smfilter, tr); - - HandleError herr; - Handle_t hndl; - if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr))) - { - delete tr; - return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr); - } - - return hndl; -} - -static cell_t smn_TRTraceHullFilterEx(IPluginContext *pContext, const cell_t *params) -{ - IPluginFunction *pFunc; - cell_t *startaddr, *endaddr, *mins, *maxs; - cell_t data; - - pFunc = pContext->GetFunctionById(params[6]); - if (!pFunc) - { - return pContext->ThrowNativeError("Invalid function id (%X)", params[5]); - } - pContext->LocalToPhysAddr(params[1], &startaddr); - pContext->LocalToPhysAddr(params[2], &endaddr); - pContext->LocalToPhysAddr(params[3], &mins); - pContext->LocalToPhysAddr(params[4], &maxs); - - Vector StartVec, EndVec, vmins, vmaxs; - CSMTraceFilter smfilter; - Ray_t ray; - - data = params[7]; - - smfilter.SetFunctionPtr(pFunc, data); - StartVec.Init(sp_ctof(startaddr[0]), sp_ctof(startaddr[1]), sp_ctof(startaddr[2])); - vmins.Init(sp_ctof(mins[0]), sp_ctof(mins[1]), sp_ctof(mins[2])); - vmaxs.Init(sp_ctof(maxs[0]), sp_ctof(maxs[1]), sp_ctof(maxs[2])); - EndVec.Init(sp_ctof(endaddr[0]), sp_ctof(endaddr[1]), sp_ctof(endaddr[2])); - - ray.Init(StartVec, EndVec, vmins, vmaxs); - - trace_t *tr = new trace_t; - enginetrace->TraceRay(ray, params[5], &smfilter, tr); - - HandleError herr; - Handle_t hndl; - if (!(hndl=handlesys->CreateHandle(g_TraceHandle, tr, pContext->GetIdentity(), myself->GetIdentity(), &herr))) - { - delete tr; - return pContext->ThrowNativeError("Unable to create a new trace handle (error %d)", herr); - } - - return hndl; -} - -static cell_t smn_TRGetFraction(IPluginContext *pContext, const cell_t *params) -{ - trace_t *tr; - HandleError err; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if (params[1] == BAD_HANDLE) - { - tr = &g_Trace; - } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { - return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); - } - - return sp_ftoc(tr->fraction); -} - -static cell_t smn_TRGetPlaneNormal(IPluginContext *pContext, const cell_t *params) -{ - trace_t *tr; - HandleError err; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if (params[1] == BAD_HANDLE) - { - tr = &g_Trace; - } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { - return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); - } - - Vector *normal = &tr->plane.normal; - - cell_t *r; - pContext->LocalToPhysAddr(params[2], &r); - r[0] = sp_ftoc(normal->x); - r[1] = sp_ftoc(normal->y); - r[2] = sp_ftoc(normal->z); - - return 1; -} - - -static cell_t smn_TRGetEndPosition(IPluginContext *pContext, const cell_t *params) -{ - trace_t *tr; - HandleError err; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if (params[2] == BAD_HANDLE) - { - tr = &g_Trace; - } else if ((err = handlesys->ReadHandle(params[2], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { - return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[2], err); - } - - cell_t *addr; - pContext->LocalToPhysAddr(params[1], &addr); - - addr[0] = sp_ftoc(tr->endpos.x); - addr[1] = sp_ftoc(tr->endpos.y); - addr[2] = sp_ftoc(tr->endpos.z); - - return 1; -} - -static cell_t smn_TRDidHit(IPluginContext *pContext, const cell_t *params) -{ - trace_t *tr; - HandleError err; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if (params[1] == BAD_HANDLE) - { - tr = &g_Trace; - } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { - return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); - } - - return tr->DidHit() ? 1 : 0; -} - -static cell_t smn_TRGetHitGroup(IPluginContext *pContext, const cell_t *params) -{ - trace_t *tr; - HandleError err; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if (params[1] == BAD_HANDLE) - { - tr = &g_Trace; - } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { - return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); - } - - return tr->hitgroup; -} - -static cell_t smn_TRGetEntityIndex(IPluginContext *pContext, const cell_t *params) -{ - trace_t *tr; - HandleError err; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if (params[1] == BAD_HANDLE) - { - tr = &g_Trace; - } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { - return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); - } - - edict_t *pEdict = gameents->BaseEntityToEdict(tr->m_pEnt); - return engine->IndexOfEdict(pEdict); -} - -static cell_t smn_TRGetPointContents(IPluginContext *pContext, const cell_t *params) -{ - cell_t *vec, *ent; - IHandleEntity *hentity; - Vector pos; - int mask; - - pContext->LocalToPhysAddr(params[1], &vec); - pContext->LocalToPhysAddr(params[2], &ent); - - pos.x = sp_ctof(vec[0]); - pos.y = sp_ctof(vec[1]); - pos.z = sp_ctof(vec[2]); - - if (*ent == -1) - { - mask = enginetrace->GetPointContents(pos); - } else { - mask = enginetrace->GetPointContents(pos, &hentity); - edict_t *pEdict = gameents->BaseEntityToEdict(reinterpret_cast(hentity)); - *ent = engine->IndexOfEdict(pEdict); - } - - return mask; -} - -static cell_t smn_TRGetPointContentsEnt(IPluginContext *pContext, const cell_t *params) -{ - edict_t *pEdict = engine->PEntityOfEntIndex(params[1]); - if (!pEdict || pEdict->IsFree()) - { - return pContext->ThrowNativeError("Entity %d is invalid", params[1]); - } - - cell_t *addr; - Vector pos; - - pContext->LocalToPhysAddr(params[2], &addr); - - pos.x = sp_ctof(addr[0]); - pos.y = sp_ctof(addr[1]); - pos.z = sp_ctof(addr[2]); - - return enginetrace->GetPointContents_Collideable(pEdict->GetCollideable(), pos); -} - -sp_nativeinfo_t g_TRNatives[] = -{ - {"TR_TraceRay", smn_TRTraceRay}, - {"TR_TraceHull", smn_TRTraceHull}, - {"TR_TraceRayEx", smn_TRTraceRayEx}, - {"TR_TraceHullEx", smn_TRTraceHullEx}, - {"TR_GetFraction", smn_TRGetFraction}, - {"TR_GetEndPosition", smn_TRGetEndPosition}, - {"TR_GetEntityIndex", smn_TRGetEntityIndex}, - {"TR_DidHit", smn_TRDidHit}, - {"TR_GetHitGroup", smn_TRGetHitGroup}, - {"TR_GetPointContents", smn_TRGetPointContents}, - {"TR_GetPointContentsEnt", smn_TRGetPointContentsEnt}, - {"TR_TraceRayFilter", smn_TRTraceRayFilter}, - {"TR_TraceRayFilterEx", smn_TRTraceRayFilterEx}, - {"TR_TraceHullFilter", smn_TRTraceHullFilter}, - {"TR_TraceHullFilterEx", smn_TRTraceHullFilterEx}, - {"TR_GetPlaneNormal", smn_TRGetPlaneNormal}, - {NULL, NULL} -}; diff --git a/extensions/sdktools/util.h b/extensions/sdktools/util.h deleted file mode 100644 index e3f46fa8..00000000 --- a/extensions/sdktools/util.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_UTIL_H_ -#define _INCLUDE_SOURCEMOD_UTIL_H_ - -#include "utldict.h" - -abstract_class IEntityFactory -{ -public: - virtual IServerNetworkable *Create( const char *pClassName ) = 0; - virtual void Destroy( IServerNetworkable *pNetworkable ) = 0; - virtual size_t GetEntitySize() = 0; -}; - -abstract_class IEntityFactoryDictionary -{ -public: - virtual void InstallFactory( IEntityFactory *pFactory, const char *pClassName ) = 0; - virtual IServerNetworkable *Create( const char *pClassName ) = 0; - virtual void Destroy( const char *pClassName, IServerNetworkable *pNetworkable ) = 0; - virtual IEntityFactory *FindFactory( const char *pClassName ) = 0; - virtual const char *GetCannonicalName( const char *pClassName ) = 0; -}; - -class CEntityFactoryDictionary : public IEntityFactoryDictionary -{ -public: - CEntityFactoryDictionary(); - - virtual void InstallFactory( IEntityFactory *pFactory, const char *pClassName ); - virtual IServerNetworkable *Create( const char *pClassName ); - virtual void Destroy( const char *pClassName, IServerNetworkable *pNetworkable ); - virtual const char *GetCannonicalName( const char *pClassName ); - void ReportEntitySizes(); - -private: - IEntityFactory *FindFactory( const char *pClassName ); -public: - CUtlDict< IEntityFactory *, unsigned short > m_Factories; -}; - -#endif //_INCLUDE_SOURCEMOD_UTIL_H_ diff --git a/extensions/sdktools/vcallbuilder.cpp b/extensions/sdktools/vcallbuilder.cpp deleted file mode 100644 index b6eca41d..00000000 --- a/extensions/sdktools/vcallbuilder.cpp +++ /dev/null @@ -1,369 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "vcallbuilder.h" -#include "extension.h" - -ValveCall::ValveCall() -{ - call = NULL; - vparams = NULL; - retinfo = NULL; - thisinfo = NULL; - retbuf = NULL; -} - -ValveCall::~ValveCall() -{ - while (!stk.empty()) - { - unsigned char *ptr = stk.front(); - delete [] ptr; - stk.pop(); - } - if (call) - { - call->Destroy(); - } - delete [] retbuf; - delete [] vparams; -} - -unsigned char *ValveCall::stk_get() -{ - unsigned char *ptr; - if (stk.empty()) - { - ptr = new unsigned char[stackSize]; - } else { - ptr = stk.front(); - stk.pop(); - } - return ptr; -} - -void ValveCall::stk_put(unsigned char *ptr) -{ - stk.push(ptr); -} - -ValveCall *CreateValveCall(void *addr, - ValveCallType vcalltype, - const ValvePassInfo *retInfo, - const ValvePassInfo *params, - unsigned int numParams) -{ - if (numParams > 32) - { - return NULL; - } - - ValveCall *vc = new ValveCall; - - vc->type = vcalltype; - - size_t size = 0; - vc->stackSize = 0; - - /* Get return information - encode only */ - PassInfo retBuf; - size_t retBufSize = 0; - bool retbuf_needs_extra; - if (retInfo) - { - if ((size = ValveParamToBinParam(retInfo->vtype, retInfo->type, retInfo->flags, &retBuf, retbuf_needs_extra)) == 0) - { - delete vc; - return NULL; - } - retBufSize = retBuf.size; - } - - /* Get parameter info */ - PassInfo paramBuf[32]; - size_t sizes[32]; - size_t normSize = 0; - size_t extraSize = 0; - for (unsigned int i=0; itype = PassType_Basic; - switch (vcalltype) - { - case ValveCall_Entity: - thisinfo->vtype = Valve_CBaseEntity; - thisinfo->flags = PASSFLAG_BYVAL; - thisinfo->decflags |= VDECODE_FLAG_ALLOWWORLD; - break; - case ValveCall_Player: - thisinfo->vtype = Valve_CBasePlayer; - thisinfo->flags = PASSFLAG_BYVAL; - thisinfo->decflags = 0; - break; - default: - thisinfo->vtype = Valve_POD; - thisinfo->flags = PASSFLAG_ASPOINTER; - thisinfo->decflags = 0; - break; - } - thisinfo->encflags = 0; - thisinfo->offset = 0; - normSize += sizeof(void *); - cv = CallConv_ThisCall; - } - - /* Now we can try creating the call */ - if ((vc->call = g_pBinTools->CreateCall(addr, - cv, - (retInfo ? &retBuf : NULL), - paramBuf, - numParams)) - == NULL) - { - if (!vc->call) - { - delete vc; - return NULL; - } - } - - /* Allocate extra space for thisptr AND ret buffer, even if we don't use it */ - vc->vparams = new ValvePassInfo[numParams + 2]; - - /* We've got the call and everything is encoded. - * It's time to save the valve specific information and helper variables. - */ - if (retInfo) - { - /* Allocate and copy */ - vc->retinfo = &(vc->vparams[numParams]); - *vc->retinfo = *retInfo; - vc->retinfo->offset = 0; - vc->retinfo->obj_offset = retbuf_needs_extra ? sizeof(void *) : 0; - /* Allocate stack space */ - vc->retbuf = new unsigned char[retBufSize]; - } else { - vc->retinfo = NULL; - vc->retbuf = NULL; - } - - if (thisinfo) - { - /* Allocate and copy */ - vc->thisinfo = &(vc->vparams[numParams + 1]); - *vc->thisinfo = *thisinfo; - vc->thisinfo->offset = 0; - vc->thisinfo->obj_offset = 0; - } else { - vc->thisinfo = NULL; - } - - /* Now, save info about each parameter. */ - size_t last_extra_offset = 0; - for (unsigned int i=0; ivparams[i] = params[i]; - vc->vparams[i].offset = vc->call->GetParamInfo(i)->offset; - vc->vparams[i].obj_offset = last_extra_offset; - last_extra_offset += sizes[i]; - } - - vc->stackSize = normSize + extraSize; - vc->stackEnd = normSize; - - return vc; -} - -ValveCall *CreateValveVCall(unsigned int vtableIdx, - ValveCallType vcalltype, - const ValvePassInfo *retInfo, - const ValvePassInfo *params, - unsigned int numParams) -{ - if (numParams > 32) - { - return NULL; - } - - ValveCall *vc = new ValveCall; - - vc->type = vcalltype; - - size_t size = 0; - vc->stackSize = 0; - - /* Get return information - encode only */ - PassInfo retBuf; - size_t retBufSize = 0; - bool retbuf_needs_extra; - if (retInfo) - { - if ((size = ValveParamToBinParam(retInfo->vtype, retInfo->type, retInfo->flags, &retBuf, retbuf_needs_extra)) == 0) - { - delete vc; - return NULL; - } - retBufSize = retBuf.size; - } - - /* Get parameter info */ - PassInfo paramBuf[32]; - size_t sizes[32]; - size_t normSize = 0; - size_t extraSize = 0; - for (unsigned int i=0; icall = g_pBinTools->CreateVCall(vtableIdx, - 0, - 0, - (retInfo ? &retBuf : NULL), - paramBuf, - numParams)) - == NULL) - { - if (!vc->call) - { - delete vc; - return NULL; - } - } - - /* Allocate extra space for thisptr AND ret buffer, even if we don't use it */ - vc->vparams = new ValvePassInfo[numParams + 2]; - - /* We've got the call and everything is encoded. - * It's time to save the valve specific information and helper variables. - */ - if (retInfo) - { - /* Allocate and copy */ - vc->retinfo = &(vc->vparams[numParams]); - *vc->retinfo = *retInfo; - vc->retinfo->offset = 0; - vc->retinfo->obj_offset = retbuf_needs_extra ? sizeof(void *) : 0; - /* Allocate stack space */ - vc->retbuf = new unsigned char[retBufSize]; - } else { - vc->retinfo = NULL; - vc->retbuf = NULL; - } - - /* Save the this info for the dynamic decoder */ - vc->thisinfo = &(vc->vparams[numParams + 1]); - vc->thisinfo->type = PassType_Basic; - switch (vcalltype) - { - case ValveCall_Entity: - vc->thisinfo->vtype = Valve_CBaseEntity; - vc->thisinfo->flags = PASSFLAG_BYVAL; - vc->thisinfo->decflags = VDECODE_FLAG_ALLOWWORLD; - break; - case ValveCall_Player: - vc->thisinfo->vtype = Valve_CBasePlayer; - vc->thisinfo->flags = PASSFLAG_BYVAL; - vc->thisinfo->decflags = 0; - break; - default: - vc->thisinfo->vtype = Valve_POD; - vc->thisinfo->flags = PASSFLAG_ASPOINTER; - vc->thisinfo->decflags = 0; - break; - } - vc->thisinfo->encflags = 0; - vc->thisinfo->offset = 0; - vc->thisinfo->obj_offset = 0; - normSize += sizeof(void *); - - /* Now, save info about each parameter. */ - size_t last_extra_offset = 0; - for (unsigned int i=0; ivparams[i] = params[i]; - vc->vparams[i].offset = vc->call->GetParamInfo(i)->offset; - vc->vparams[i].obj_offset = last_extra_offset; - last_extra_offset += sizes[i]; - } - - vc->stackSize = normSize + extraSize; - vc->stackEnd = normSize; - - return vc; -} diff --git a/extensions/sdktools/vcallbuilder.h b/extensions/sdktools/vcallbuilder.h deleted file mode 100644 index 3237fe5d..00000000 --- a/extensions/sdktools/vcallbuilder.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_VALVE_CALLER_H_ -#define _INCLUDE_SOURCEMOD_VALVE_CALLER_H_ - -#include -#include -#include "vdecoder.h" - -using namespace SourceMod; - -/** - * @brief Info necessary to call a Valve function - */ -struct ValveCall -{ - ICallWrapper *call; /**< From IBinTools */ - ValveCallType type; /**< Call type */ - ValvePassInfo *vparams; /**< Valve parameter info */ - ValvePassInfo *retinfo; /**< Return buffer info */ - ValvePassInfo *thisinfo; /**< Thiscall info */ - size_t stackSize; /**< Stack size */ - size_t stackEnd; /**< End of the bintools stack */ - unsigned char *retbuf; /**< Return buffer */ - SourceHook::CStack stk; /**< Parameter stack */ - - unsigned char *stk_get(); - void stk_put(unsigned char *ptr); - ValveCall(); - ~ValveCall(); -}; - -ValveCall *CreateValveVCall(unsigned int vtableIdx, - ValveCallType vcalltype, - const ValvePassInfo *retInfo, - const ValvePassInfo *params, - unsigned int numParams); - -ValveCall *CreateValveCall(void *addr, - ValveCallType vcalltype, - const ValvePassInfo *retInfo, - const ValvePassInfo *params, - unsigned int numParams); - -#endif //_INCLUDE_SOURCEMOD_VALVE_CALLER_H_ diff --git a/extensions/sdktools/vcaller.cpp b/extensions/sdktools/vcaller.cpp deleted file mode 100644 index 6ea1f131..00000000 --- a/extensions/sdktools/vcaller.cpp +++ /dev/null @@ -1,455 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "extension.h" -#include "vcallbuilder.h" -#include "vglobals.h" - -enum SDKLibrary -{ - SDKLibrary_Server, /**< server.dll/server_i486.so */ - SDKLibrary_Engine, /**< engine.dll/engine_*.so */ -}; - -enum SDKPassMethod -{ - SDKPass_Pointer, /**< Pass as a pointer */ - SDKPass_Plain, /**< Pass as plain data */ - SDKPass_ByValue, /**< Pass an object by value */ - SDKPass_ByRef, /**< Pass an object by reference */ -}; - -int s_vtbl_index = -1; -void *s_call_addr = NULL; -ValveCallType s_vcalltype = ValveCall_Static; -bool s_has_return = false; -ValvePassInfo s_return; -unsigned int s_numparams = 0; -ValvePassInfo s_params[SP_MAX_EXEC_PARAMS]; - -inline void DecodePassMethod(ValveType vtype, SDKPassMethod method, PassType &type, unsigned int &flags) -{ - if (method == SDKPass_Pointer || method == SDKPass_ByRef) - { - type = PassType_Basic; - if (vtype == Valve_POD - || vtype == Valve_Float - || vtype == Valve_Bool) - { - flags = PASSFLAG_BYVAL | PASSFLAG_ASPOINTER; - } else { - flags = PASSFLAG_BYVAL; - } - } else if (method == SDKPass_Plain) { - type = PassType_Basic; - flags = PASSFLAG_BYVAL; - } else if (method == SDKPass_ByValue) { - if (vtype == Valve_Vector - || vtype == Valve_QAngle) - { - type = PassType_Object; - } else { - type = PassType_Basic; - } - flags = PASSFLAG_BYVAL; - } -} - -static cell_t StartPrepSDKCall(IPluginContext *pContext, const cell_t *params) -{ - s_numparams = 0; - s_vtbl_index = -1; - s_call_addr = NULL; - s_has_return = false; - s_vcalltype = (ValveCallType)params[1]; - - return 1; -} - -static cell_t PrepSDKCall_SetVirtual(IPluginContext *pContext, const cell_t *params) -{ - s_vtbl_index = params[1]; - - return 1; -} - -static cell_t PrepSDKCall_SetSignature(IPluginContext *pContext, const cell_t *params) -{ - void *addrInBase = NULL; - if (params[1] == SDKLibrary_Server) - { - addrInBase = (void *)g_SMAPI->GetServerFactory(false); - } else if (params[1] == SDKLibrary_Engine) { - addrInBase = (void *)g_SMAPI->GetEngineFactory(false); - } - if (addrInBase == NULL) - { - return 0; - } - - char *sig; - pContext->LocalToString(params[2], &sig); - -#if defined PLATFORM_LINUX - if (sig[0] == '@') - { - Dl_info info; - if (dladdr(addrInBase, &info) == 0) - { - return 0; - } - void *handle = dlopen(info.dli_fname, RTLD_NOW); - if (!handle) - { - return 0; - } - s_call_addr = dlsym(handle, &sig[1]); - dlclose(handle); - - return (s_call_addr != NULL) ? 1 : 0; - } -#endif - - s_call_addr = memutils->FindPattern(addrInBase, sig, params[3]); - - return (s_call_addr != NULL) ? 1 : 0; -} - -static cell_t PrepSDKCall_SetFromConf(IPluginContext *pContext, const cell_t *params) -{ - IGameConfig *conf; - - if (params[1] == BAD_HANDLE) - { - conf = g_pGameConf; - } else { - HandleError err; - if ((conf = gameconfs->ReadHandle(params[1], pContext->GetIdentity(), &err)) == NULL) - { - return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); - } - } - - char *key; - pContext->LocalToString(params[3], &key); - - if (params[2] == 0) - { - return conf->GetOffset(key, &s_vtbl_index) ? 1 : 0; - } else if (params[2] == 1) { - bool result = conf->GetMemSig(key, &s_call_addr) ? 1 : 0; - return (result && s_call_addr != NULL) ? 1 : 0; - } - - return 0; -} - -static cell_t PrepSDKCall_SetReturnInfo(IPluginContext *pContext, const cell_t *params) -{ - s_has_return = true; - s_return.vtype = (ValveType)params[1]; - DecodePassMethod(s_return.vtype, (SDKPassMethod)params[2], s_return.type, s_return.flags); - s_return.decflags = params[3]; - s_return.encflags = params[4]; - - return 1; -} - -static cell_t PrepSDKCall_AddParameter(IPluginContext *pContext, const cell_t *params) -{ - if (s_numparams >= SP_MAX_EXEC_PARAMS) - { - return pContext->ThrowNativeError("Parameter limit for SDK calls reached"); - } - - ValvePassInfo *info = &s_params[s_numparams++]; - info->vtype = (ValveType)params[1]; - SDKPassMethod method = (SDKPassMethod)params[2]; - DecodePassMethod(info->vtype, method, info->type, info->flags); - info->decflags = params[3] | VDECODE_FLAG_BYREF; - info->encflags = params[4]; - - /* Since SDKPass_ByRef acts like SDKPass_Pointer we can't allow NULL, just in case */ - if (method == SDKPass_ByRef) - { - info->decflags &= ~VDECODE_FLAG_ALLOWNULL; - } - - return 1; -} - -static cell_t EndPrepSDKCall(IPluginContext *pContext, const cell_t *params) -{ - ValveCall *vc = NULL; - if (s_vtbl_index > -1) - { - vc = CreateValveVCall(s_vtbl_index, s_vcalltype, s_has_return ? &s_return : NULL, s_params, s_numparams); - } else if (s_call_addr) { - vc = CreateValveCall(s_call_addr, s_vcalltype, s_has_return ? &s_return : NULL, s_params, s_numparams); - } - - if (!vc) - { - return BAD_HANDLE; - } - - if (vc->thisinfo) - { - vc->thisinfo->decflags |= VDECODE_FLAG_BYREF; - } - - Handle_t hndl = handlesys->CreateHandle(g_CallHandle, vc, pContext->GetIdentity(), myself->GetIdentity(), NULL); - if (!hndl) - { - delete vc; - } - - return hndl; -} - -static cell_t SDKCall(IPluginContext *pContext, const cell_t *params) -{ - ValveCall *vc; - HandleError err; - HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); - - if ((err = handlesys->ReadHandle(params[1], g_CallHandle, &sec, (void **)&vc)) != HandleError_None) - { - return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); - } - - unsigned char *ptr = vc->stk_get(); - - unsigned int numparams = (unsigned)params[0]; - unsigned int startparam = 2; - /* Do we need to write a thispointer? */ - - if (vc->thisinfo) - { - switch (vc->type) - { - case ValveCall_Entity: - case ValveCall_Player: - { - if (startparam > numparams) - { - vc->stk_put(ptr); - return pContext->ThrowNativeError("Expected 1 parameter for entity pointer; found none"); - } - - if (DecodeValveParam(pContext, - params[startparam], - vc, - vc->thisinfo, - ptr) == Data_Fail) - { - vc->stk_put(ptr); - return 0; - } - startparam++; - } - break; - case ValveCall_GameRules: - { - if (g_pGameRules == NULL) - { - vc->stk_put(ptr); - return pContext->ThrowNativeError("GameRules unsupported or not available; file a bug report"); - } - - void *gamerules = *g_pGameRules; - - if (gamerules == NULL) - { - vc->stk_put(ptr); - return pContext->ThrowNativeError("GameRules not available before map is loaded"); - } - *(void **)ptr = gamerules; - } - break; - case ValveCall_EntityList: - { - if (g_EntList == NULL) - { - vc->stk_put(ptr); - return pContext->ThrowNativeError("EntityList unsupported or not available; file a bug report"); - } - - *(void **)ptr = g_EntList; - } - break; - } - } - - /* See if we need to skip any more parameters */ - unsigned int retparam = startparam; - if (vc->retinfo) - { - if (vc->retinfo->vtype == Valve_String) - { - startparam += 2; - } else if (vc->retinfo->vtype == Valve_Vector - || vc->retinfo->vtype == Valve_QAngle) - { - startparam += 1; - } - } - - unsigned int callparams = vc->call->GetParamCount(); - bool will_copyback = false; - for (unsigned int i=0; i numparams) - { - vc->stk_put(ptr); - return pContext->ThrowNativeError("Expected %dth parameter, found none", p); - } - if (DecodeValveParam(pContext, - params[p], - vc, - &(vc->vparams[i]), - ptr) == Data_Fail) - { - vc->stk_put(ptr); - return 0; - } - if (vc->vparams[i].encflags & VENCODE_FLAG_COPYBACK) - { - will_copyback = true; - } - } - - /* Make the actual call */ - vc->call->Execute(ptr, vc->retbuf); - - /* Do we need to copy anything back? */ - if (will_copyback) - { - for (unsigned int i=0; ivparams[i].encflags & VENCODE_FLAG_COPYBACK) - { - if (EncodeValveParam(pContext, - params[startparam + i], - vc, - &vc->vparams[i], - ptr) == Data_Fail) - { - vc->stk_put(ptr); - return 0; - } - } - } - } - - /* Save stack once and for all */ - vc->stk_put(ptr); - - /* Figure out how to decode the return information */ - if (vc->retinfo) - { - if (vc->retinfo->vtype == Valve_String) - { - if (numparams < 3) - { - return pContext->ThrowNativeError("Expected arguments (2,3) for string storage"); - } - cell_t *addr; - size_t written; - pContext->LocalToPhysAddr(params[retparam+1], &addr); - pContext->StringToLocalUTF8(params[retparam], *addr, *(char **)vc->retbuf, &written); - return (cell_t)written; - } else if (vc->retinfo->vtype == Valve_Vector - || vc->retinfo->vtype == Valve_QAngle) - { - if (numparams < 2) - { - return pContext->ThrowNativeError("Expected argument (2) for Float[3] storage"); - } - if (EncodeValveParam(pContext, params[retparam], vc, vc->retinfo, vc->retbuf) - == Data_Fail) - { - return 0; - } - } else if (vc->retinfo->vtype == Valve_CBaseEntity - || vc->retinfo->vtype == Valve_CBasePlayer) - { - CBaseEntity *pEntity = *(CBaseEntity **)(vc->retbuf); - if (!pEntity) - { - return -1; - } - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); - if (!pEdict || pEdict->IsFree()) - { - return -1; - } - return engine->IndexOfEdict(pEdict); - } else if (vc->retinfo->vtype == Valve_Edict) { - edict_t *pEdict = *(edict_t **)(vc->retbuf); - if (!pEdict || pEdict->IsFree()) - { - return -1; - } - return engine->IndexOfEdict(pEdict); - } else if (vc->retinfo->vtype == Valve_Bool) { - bool *addr = (bool *)vc->retbuf; - if (vc->retinfo->flags & PASSFLAG_ASPOINTER) - { - addr = *(bool **)addr; - } - return *addr ? 1 : 0; - } else { - cell_t *addr = (cell_t *)vc->retbuf; - if (vc->retinfo->flags & PASSFLAG_ASPOINTER) - { - addr = *(cell_t **)addr; - } - return *addr; - } - } - - return 0; -} - -sp_nativeinfo_t g_CallNatives[] = -{ - {"StartPrepSDKCall", StartPrepSDKCall}, - {"PrepSDKCall_SetVirtual", PrepSDKCall_SetVirtual}, - {"PrepSDKCall_SetSignature", PrepSDKCall_SetSignature}, - {"PrepSDKCall_SetFromConf", PrepSDKCall_SetFromConf}, - {"PrepSDKCall_SetReturnInfo", PrepSDKCall_SetReturnInfo}, - {"PrepSDKCall_AddParameter", PrepSDKCall_AddParameter}, - {"EndPrepSDKCall", EndPrepSDKCall}, - {"SDKCall", SDKCall}, - {NULL, NULL}, -}; diff --git a/extensions/sdktools/vdecoder.cpp b/extensions/sdktools/vdecoder.cpp deleted file mode 100644 index 03f0dcff..00000000 --- a/extensions/sdktools/vdecoder.cpp +++ /dev/null @@ -1,612 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "smsdk_ext.h" -#include "extension.h" -#include "vdecoder.h" -#include "vcallbuilder.h" - -using namespace SourceMod; -using namespace SourcePawn; - -/** - * For object pointers, the data looks like this instead: - * 4 bytes: POINTER TO LATER - * + bytes: Object internal data - * - * We use the virtual stack as extra fake stack space and create a temp object. - * If these objects had destructors, we'd need to fake destroy toom of course. - * Of course, BinTools only reads the first four bytes and passes the pointer. - */ - -size_t ValveParamToBinParam(ValveType type, - PassType pass, - unsigned int flags, - PassInfo *info, - bool &needs_extra) -{ - needs_extra = false; - switch (type) - { - case Valve_Vector: - { - size_t mySize = sizeof(Vector *); - if (pass == PassType_Basic) - { - if (flags & PASSFLAG_BYREF) - { - return 0; - } - info->type = PassType_Basic; - info->flags = flags; - info->size = sizeof(Vector *); - mySize = sizeof(Vector); - needs_extra = true; - } else if (pass == PassType_Object) { - info->type = PassType_Object; - info->flags = flags | PASSFLAG_OASSIGNOP | PASSFLAG_OCTOR; - info->size = sizeof(Vector); - } else { - return 0; - } - return mySize; - } - case Valve_QAngle: - { - size_t mySize = sizeof(QAngle *); - if (pass == PassType_Basic) - { - if (flags & PASSFLAG_BYREF) - { - return 0; - } - info->type = PassType_Basic; - info->flags = flags; - info->size = sizeof(QAngle *); - mySize = sizeof(QAngle); - needs_extra = true; - } else if (pass == PassType_Object) { - info->type = PassType_Object; - info->flags = flags | PASSFLAG_OASSIGNOP | PASSFLAG_OCTOR; - info->size = sizeof(QAngle); - } else { - return 0; - } - return mySize; - } - case Valve_CBaseEntity: - case Valve_CBasePlayer: - case Valve_Edict: - case Valve_String: - { - if (pass != PassType_Basic || (flags & PASSFLAG_BYREF)) - { - return 0; - } - info->type = PassType_Basic; - info->flags = flags; - info->size = sizeof(void *); - return sizeof(void *); - } - case Valve_POD: - { - info->type = PassType_Basic; - info->flags = flags; - if (flags & PASSFLAG_ASPOINTER) - { - needs_extra = true; - info->size = sizeof(int *); - return sizeof(int *) + sizeof(int); - } else { - info->size = sizeof(int); - return sizeof(int); - } - } - case Valve_Bool: - { - info->type = PassType_Basic; - info->flags = flags; - if (flags & PASSFLAG_ASPOINTER) - { - needs_extra = true; - info->size = sizeof(bool *); - return sizeof(bool *) + sizeof(bool); - } else { - info->size = sizeof(bool); - return sizeof(bool); - } - } - case Valve_Float: - { - info->flags = flags; - if (flags & PASSFLAG_ASPOINTER) - { - needs_extra = true; - info->type = PassType_Basic; - info->size = sizeof(float *); - return sizeof(float *) + sizeof(float); - } else { - info->type = PassType_Float; - info->size = sizeof(float); - return sizeof(float); - } - } - } - - return 0; -} - -DataStatus EncodeValveParam(IPluginContext *pContext, - cell_t param, - const ValveCall *pCall, - const ValvePassInfo *data, - const void *_buffer) -{ - const void *buffer = (const unsigned char *)_buffer + data->offset; - switch (data->vtype) - { - case Valve_Vector: - { - Vector *v = NULL; - - if (data->type == PassType_Basic) - { - v = *(Vector **)buffer; - } else if (data->type == PassType_Object) { - v = (Vector *)buffer; - } - - cell_t *addr; - pContext->LocalToPhysAddr(param, &addr); - - addr[0] = sp_ftoc(v->x); - addr[1] = sp_ftoc(v->y); - addr[2] = sp_ftoc(v->z); - - return Data_Okay; - } - case Valve_QAngle: - { - QAngle *q = NULL; - - if (data->type == PassType_Basic) - { - q = *(QAngle **)buffer; - } else if (data->type == PassType_Object) { - q = (QAngle *)buffer; - } - - cell_t *addr; - pContext->LocalToPhysAddr(param, &addr); - - addr[0] = sp_ftoc(q->x); - addr[1] = sp_ftoc(q->y); - addr[2] = sp_ftoc(q->z); - - return Data_Okay; - } - case Valve_CBaseEntity: - case Valve_CBasePlayer: - { - cell_t *addr; - pContext->LocalToPhysAddr(param, &addr); - - CBaseEntity *pEntity = *(CBaseEntity **)buffer; - if (pEntity) - { - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); - *addr = engine->IndexOfEdict(pEdict); - } else { - *addr = -1; - } - - return Data_Okay; - } - case Valve_Edict: - { - cell_t *addr; - pContext->LocalToPhysAddr(param, &addr); - - edict_t *pEdict = *(edict_t **)buffer; - if (pEdict) - { - *addr = engine->IndexOfEdict(pEdict); - } else { - *addr = -1; - } - - return Data_Okay; - } - case Valve_POD: - case Valve_Float: - { - cell_t *addr; - pContext->LocalToPhysAddr(param, &addr); - - if (data->flags & PASSFLAG_ASPOINTER) - { - buffer = *(cell_t **)buffer; - } - - *addr = *(cell_t *)buffer; - - return Data_Okay; - } - case Valve_Bool: - { - cell_t *addr; - pContext->LocalToPhysAddr(param, &addr); - - if (data->flags & PASSFLAG_ASPOINTER) - { - buffer = *(bool **)buffer; - } - - *addr = *(bool *)buffer ? 1 : 0; - - return Data_Okay; - } - } - - return Data_Fail; -} - -DataStatus DecodeValveParam(IPluginContext *pContext, - cell_t param, - const ValveCall *pCall, - const ValvePassInfo *data, - void *_buffer) -{ - void *buffer = (unsigned char *)_buffer + data->offset; - switch (data->vtype) - { - case Valve_Vector: - { - cell_t *addr; - int err; - err = pContext->LocalToPhysAddr(param, &addr); - - unsigned char *mem = (unsigned char *)buffer; - if (data->type == PassType_Basic) - { - /* Store the object in the next N bytes, and store - * a pointer to that object right beforehand. - */ - Vector **realPtr = (Vector **)buffer; - - if (addr == pContext->GetNullRef(SP_NULL_VECTOR)) - { - if (data->decflags & VDECODE_FLAG_ALLOWNULL) - { - *realPtr = NULL; - return Data_Okay; - } else { - pContext->ThrowNativeError("NULL not allowed"); - return Data_Fail; - } - } else { - mem = (unsigned char *)_buffer + pCall->stackEnd + data->obj_offset; - *realPtr = (Vector *)mem; - } - } - - if (err != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, "Could not read plugin data"); - return Data_Fail; - } - - /* Use placement new to initialize the object cleanly - * This has no destructor so we don't need to do - * DestroyValveParam() or something :] - */ - Vector *v = new (mem) Vector( - sp_ctof(addr[0]), - sp_ctof(addr[1]), - sp_ctof(addr[2])); - - return Data_Okay; - } - case Valve_QAngle: - { - cell_t *addr; - int err; - err = pContext->LocalToPhysAddr(param, &addr); - - unsigned char *mem = (unsigned char *)buffer; - if (data->type == PassType_Basic) - { - /* Store the object in the next N bytes, and store - * a pointer to that object right beforehand. - */ - QAngle **realPtr = (QAngle **)buffer; - - if (addr == pContext->GetNullRef(SP_NULL_VECTOR)) - { - if (!(data->decflags & VDECODE_FLAG_ALLOWNULL)) - { - pContext->ThrowNativeError("NULL not allowed"); - return Data_Fail; - } else { - *realPtr = NULL; - return Data_Okay; - } - } else { - mem = (unsigned char *)_buffer + pCall->stackEnd + data->obj_offset; - *realPtr = (QAngle *)mem; - } - } - - if (err != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, "Could not read plugin data"); - return Data_Fail; - } - - /* Use placement new to initialize the object cleanly - * This has no destructor so we don't need to do - * DestroyValveParam() or something :] - */ - QAngle *v = new (mem) QAngle( - sp_ctof(addr[0]), - sp_ctof(addr[1]), - sp_ctof(addr[2])); - - return Data_Okay; - } - case Valve_CBasePlayer: - { - edict_t *pEdict; - if (data->decflags & VDECODE_FLAG_BYREF) - { - cell_t *addr; - pContext->LocalToPhysAddr(param, &addr); - param = *addr; - } - if (param >= 1 && param <= playerhelpers->GetMaxClients()) - { - IGamePlayer *player = playerhelpers->GetGamePlayer(param); - if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME) - && !player->IsConnected()) - { - pContext->ThrowNativeError("Client %d is not connected", param); - return Data_Fail; - } else if (!player->IsInGame()) { - pContext->ThrowNativeError("Client %d is not in game", param); - return Data_Fail; - } - pEdict = player->GetEdict(); - } else if (param == -1) { - if (data->decflags & VDECODE_FLAG_ALLOWNULL) - { - pEdict = NULL; - } else { - pContext->ThrowNativeError("NULL not allowed"); - return Data_Fail; - } - } else if (param == 0) { - if (data->decflags & VDECODE_FLAG_ALLOWWORLD) - { - pEdict = engine->PEntityOfEntIndex(0); - } else { - pContext->ThrowNativeError("World not allowed"); - return Data_Fail; - } - } else { - pContext->ThrowNativeError("Entity index %d is not a valid client", param); - return Data_Fail; - } - CBaseEntity *pEntity = NULL; - if (pEdict) - { - IServerUnknown *pUnknown = pEdict->GetUnknown(); - if (!pUnknown) - { - pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", param); - return Data_Fail; - } - pEntity = pUnknown->GetBaseEntity(); - if (!pEntity) - { - pContext->ThrowNativeError("Entity %d is not a CBaseEntity", param); - return Data_Fail; - } - } - - CBaseEntity **ebuf = (CBaseEntity **)buffer; - *ebuf = pEntity; - - return Data_Okay; - } - case Valve_CBaseEntity: - { - edict_t *pEdict; - if (data->decflags & VDECODE_FLAG_BYREF) - { - cell_t *addr; - pContext->LocalToPhysAddr(param, &addr); - param = *addr; - } - if (param >= 1 && param <= playerhelpers->GetMaxClients()) - { - IGamePlayer *player = playerhelpers->GetGamePlayer(param); - if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME) - && !player->IsConnected()) - { - pContext->ThrowNativeError("Client %d is not connected", param); - return Data_Fail; - } else if (!player->IsInGame()) { - pContext->ThrowNativeError("Client %d is not in game", param); - return Data_Fail; - } - pEdict = player->GetEdict(); - } else if (param == -1) { - if (data->decflags & VDECODE_FLAG_ALLOWNULL) - { - pEdict = NULL; - } else { - pContext->ThrowNativeError("NULL not allowed"); - return Data_Fail; - } - } else if (param == 0) { - if (data->decflags & VDECODE_FLAG_ALLOWWORLD) - { - pEdict = engine->PEntityOfEntIndex(0); - } else { - pContext->ThrowNativeError("World not allowed"); - return Data_Fail; - } - } else { - pEdict = engine->PEntityOfEntIndex(param); - if (!pEdict || pEdict->IsFree()) - { - pContext->ThrowNativeError("Entity %d is not valid or is freed", param); - return Data_Fail; - } - } - CBaseEntity *pEntity = NULL; - if (pEdict) - { - IServerUnknown *pUnknown = pEdict->GetUnknown(); - if (!pUnknown) - { - pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", param); - return Data_Fail; - } - pEntity = pUnknown->GetBaseEntity(); - if (!pEntity) - { - pContext->ThrowNativeError("Entity %d is not a CBaseEntity", param); - return Data_Fail; - } - } - - CBaseEntity **ebuf = (CBaseEntity **)buffer; - *ebuf = pEntity; - - return Data_Okay; - } - case Valve_Edict: - { - edict_t *pEdict; - if (data->decflags & VDECODE_FLAG_BYREF) - { - cell_t *addr; - pContext->LocalToPhysAddr(param, &addr); - param = *addr; - } - if (param >= 1 && param <= playerhelpers->GetMaxClients()) - { - IGamePlayer *player = playerhelpers->GetGamePlayer(param); - if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME) - && !player->IsConnected()) - { - pContext->ThrowNativeError("Client %d is not connected", param); - return Data_Fail; - } else if (!player->IsInGame()) { - pContext->ThrowNativeError("Client %d is not in game", param); - return Data_Fail; - } - pEdict = player->GetEdict(); - } else if (param == -1) { - if (data->decflags & VDECODE_FLAG_ALLOWNULL) - { - pEdict = NULL; - } else { - pContext->ThrowNativeError("NULL not allowed"); - return Data_Fail; - } - } else if (param == 0) { - if (data->decflags & VDECODE_FLAG_ALLOWWORLD) - { - pEdict = engine->PEntityOfEntIndex(0); - } else { - pContext->ThrowNativeError("World not allowed"); - return Data_Fail; - } - } else { - pEdict = engine->PEntityOfEntIndex(param); - if (!pEdict || pEdict->IsFree()) - { - pContext->ThrowNativeError("Entity %d is not valid or is freed", param); - return Data_Fail; - } - } - - edict_t **ebuf = (edict_t **)buffer; - *ebuf = pEdict; - - return Data_Okay; - } - case Valve_POD: - case Valve_Float: - { - if (data->decflags & VDECODE_FLAG_BYREF) - { - cell_t *addr; - pContext->LocalToPhysAddr(param, &addr); - param = *addr; - } - if (data->flags & PASSFLAG_ASPOINTER) - { - *(void **)buffer = (unsigned char *)_buffer + pCall->stackEnd + data->obj_offset; - buffer = *(void **)buffer; - } - *(cell_t *)buffer = param; - return Data_Okay; - } - case Valve_Bool: - { - if (data->decflags & VDECODE_FLAG_BYREF) - { - cell_t *addr; - pContext->LocalToPhysAddr(param, &addr); - param = *addr; - } - if (data->flags & PASSFLAG_ASPOINTER) - { - *(bool **)buffer = (bool *)((unsigned char *)_buffer + pCall->stackEnd + data->obj_offset); - buffer = *(bool **)buffer; - } - *(bool *)buffer = param ? true : false; - return Data_Okay; - } - case Valve_String: - { - char *addr; - pContext->LocalToString(param, &addr); - *(char **)buffer = addr; - return Data_Okay; - } - } - - return Data_Fail; -} diff --git a/extensions/sdktools/vdecoder.h b/extensions/sdktools/vdecoder.h deleted file mode 100644 index f397d7bb..00000000 --- a/extensions/sdktools/vdecoder.h +++ /dev/null @@ -1,151 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_VDECODER_H_ -#define _INCLUDE_SOURCEMOD_VDECODER_H_ - -#include -#include -#include - -using namespace SourceMod; -using namespace SourcePawn; - -/** - * @brief Encapsulates types from the SDK - */ -enum ValveType -{ - Valve_CBaseEntity, /**< CBaseEntity */ - Valve_CBasePlayer, /**< CBasePlayer (disallow normal ents) */ - Valve_Vector, /**< Vector */ - Valve_QAngle, /**< QAngle */ - Valve_POD, /**< Plain old data */ - Valve_Float, /**< Float */ - Valve_Edict, /**< Edict */ - Valve_String, /**< String */ - Valve_Bool, /**< Boolean */ -}; - -enum DataStatus -{ - Data_Fail = 0, - Data_Okay = 1, -}; - -#define VDECODE_FLAG_ALLOWNULL (1<<0) /**< Allow NULL for pointers */ -#define VDECODE_FLAG_ALLOWNOTINGAME (1<<1) /**< Allow players not in game */ -#define VDECODE_FLAG_ALLOWWORLD (1<<2) /**< Allow World entity */ -#define VDECODE_FLAG_BYREF (1<<3) /**< Floats/ints by reference */ - -#define VENCODE_FLAG_COPYBACK (1<<0) /**< Copy back data */ - -#define PASSFLAG_ASPOINTER (1<<30) /**< Not an actual passflag, used internally */ - -/** - * @brief Valve pre-defined calling types - */ -enum ValveCallType -{ - ValveCall_Static, /**< Static call */ - ValveCall_Entity, /**< Thiscall (CBaseEntity implicit first parameter) */ - ValveCall_Player, /**< Thiscall (CBasePlayer implicit first parameter) */ - ValveCall_GameRules, /**< Thiscall (CGameRules implicit first paramater) */ - ValveCall_EntityList, /**< Thiscall (CGlobalEntityList implicit first paramater) */ -}; - -/** - * @brief Valve parameter info - */ -struct ValvePassInfo -{ - ValveType vtype; /**< IN: Valve type */ - unsigned int decflags; /**< IN: VDECODE_FLAG_* */ - unsigned int encflags; /**< IN: VENCODE_FLAG_* */ - PassType type; /**< IN: Pass information */ - unsigned int flags; /**< IN: Pass flags */ - size_t offset; /**< OUT: stack offset */ - size_t obj_offset; /**< OUT: object offset at end of the stack */ -}; - -struct ValveCall; - -/** - * @brief Converts a valve parameter to a bintools parameter. - * - * @param type Valve type. - * @param pass Either basic or object. - * @param flags Either BYVAL or BYREF. - * @param info Buffer to store param info in. - * @return Number of bytes this will use in the virtual stack, - * or 0 if conversion was impossible. - */ -size_t ValveParamToBinParam(ValveType type, - PassType pass, - unsigned int flags, - PassInfo *info, - bool &needs_extra); - -/** - * @brief Decodes data from a plugin to native data. - * - * Note: If you're going to return false, make sure to - * throw an error. - * - * @param pContext Plugin context. - * @param param Parameter value from params array. - * @param buffer Buffer space in the virutal stack. - * @return True on success, false otherwise. - */ -DataStatus DecodeValveParam(IPluginContext *pContext, - cell_t param, - const ValveCall *pCall, - const ValvePassInfo *vdata, - void *buffer); - -/** - * @brief Encodes native data back into a plugin. - * - * Note: If you're going to return false, make sure to - * throw an error. - * - * @param pContext Plugin context. - * @param param Parameter value from params array. - * @param buffer Buffer space in the virutal stack. - * @return True on success, false otherwise. - */ -DataStatus EncodeValveParam(IPluginContext *pContext, - cell_t param, - const ValveCall *pCall, - const ValvePassInfo *vdata, - const void *buffer); - -#endif //_INCLUDE_SOURCEMOD_VDECODER_H_ diff --git a/extensions/sdktools/version.rc b/extensions/sdktools/version.rc deleted file mode 100644 index 546028f6..00000000 --- a/extensions/sdktools/version.rc +++ /dev/null @@ -1,104 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -//#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -#include "svn_version.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION SVN_FILE_VERSION - PRODUCTVERSION SVN_FILE_VERSION - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "Comments", "SDKTools Extension" - VALUE "FileDescription", "SourceMod SDKTools Extension" - VALUE "FileVersion", SVN_FULL_VERSION - VALUE "InternalName", "SourceMod SDKTools Extension" - VALUE "LegalCopyright", "Copyright (c) 2004-2008, AlliedModders LLC" - VALUE "OriginalFilename", "sdktools.ext.dll" - VALUE "ProductName", "SourceMod SDKTools Extension" - VALUE "ProductVersion", SVN_FULL_VERSION - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0, 1200 - END -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/extensions/sdktools/vglobals.cpp b/extensions/sdktools/vglobals.cpp deleted file mode 100644 index 9a0ba0f8..00000000 --- a/extensions/sdktools/vglobals.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "extension.h" - -void **g_pGameRules = NULL; -void *g_EntList = NULL; - -#ifdef PLATFORM_WINDOWS -void InitializeValveGlobals() -{ - char *addr = NULL; - int offset; - - /* gEntList and/or g_pEntityList */ - if (!g_pGameConf->GetMemSig("LevelShutdown", (void **)&addr) || !addr) - { - return; - } - if (!g_pGameConf->GetOffset("gEntList", &offset) || !offset) - { - return; - } - g_EntList = *reinterpret_cast(addr + offset); - - /* g_pGameRules */ - if (!g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) || !addr) - { - return; - } - if (!g_pGameConf->GetOffset("g_pGameRules", &offset) || !offset) - { - return; - } - g_pGameRules = *reinterpret_cast(addr + offset); -} -#elif defined PLATFORM_LINUX -void InitializeValveGlobals() -{ - char *addr = NULL; - - /* gEntList and/or g_pEntityList */ - if (!g_pGameConf->GetMemSig("gEntList", (void **)&addr) || !addr) - { - return; - } - g_EntList = reinterpret_cast(addr); - - /* g_pGameRules */ - if (!g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) || !addr) - { - return; - } - g_pGameRules = reinterpret_cast(addr); -} -#endif - -bool vcmp(const void *_addr1, const void *_addr2, size_t len) -{ - unsigned char *addr1 = (unsigned char *)_addr1; - unsigned char *addr2 = (unsigned char *)_addr2; - - for (size_t i=0; iGetOffset("sv", &offset)) - { - return; - } -#if defined METAMOD_PLAPI_VERSION - /* Get the CreateFakeClient function pointer */ - if (!(vfunc=SH_GET_ORIG_VFNPTR_ENTRY(engine, &IVEngineServer::CreateFakeClient))) - { - return; - } - - /* Check if we're on the expected function */ - if (!vcmp(vfunc, ISERVER_WIN_SIG, ISERVER_WIN_SIG_LEN)) - { - return; - } - - /* Finally we have the interface we were looking for */ - iserver = *reinterpret_cast(reinterpret_cast(vfunc) + offset); -#else - /* Get the interface manually */ - SourceHook::MemFuncInfo info = {true, -1, 0, 0}; - SourceHook::GetFuncInfo(&IVEngineServer::CreateFakeClient, info); - - vfunc = enginePatch->GetOrigFunc(info.vtbloffs, info.vtblindex); - if (!vfunc) - { - void **vtable = *reinterpret_cast(enginePatch->GetThisPtr() + info.thisptroffs + info.vtbloffs); - vfunc = vtable[info.vtblindex]; - } - /* Check if we're on the expected function */ - if (!vcmp(vfunc, ISERVER_WIN_SIG, ISERVER_WIN_SIG_LEN)) - { - return; - } - - iserver = *reinterpret_cast(reinterpret_cast(vfunc) + offset); -#endif -} -#elif defined PLATFORM_POSIX -void GetIServer() -{ - void *addr; - if (!g_pGameConf->GetMemSig("sv", &addr) || !addr) - { - return; - } - - iserver = reinterpret_cast(addr); -} -#endif diff --git a/extensions/sdktools/vglobals.h b/extensions/sdktools/vglobals.h deleted file mode 100644 index d3783089..00000000 --- a/extensions/sdktools/vglobals.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SDKTOOLS_VGLOBALS_H_ -#define _INCLUDE_SDKTOOLS_VGLOBALS_H_ - -extern void **g_pGameRules; -extern void *g_EntList; - -void InitializeValveGlobals(); -void GetIServer(); - -#endif // _INCLUDE_SDKTOOLS_VGLOBALS_H_ diff --git a/extensions/sdktools/vhelpers.cpp b/extensions/sdktools/vhelpers.cpp deleted file mode 100644 index b0d1507c..00000000 --- a/extensions/sdktools/vhelpers.cpp +++ /dev/null @@ -1,826 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "extension.h" -#include "util.h" -#include "vhelpers.h" - -CallHelper s_Teleport; -CallHelper s_GetVelocity; -CallHelper s_EyeAngles; - -class CTraceFilterSimple : public CTraceFilterEntitiesOnly -{ -public: - CTraceFilterSimple(const IHandleEntity *passentity): m_pPassEnt(passentity) - { - } - virtual bool ShouldHitEntity(IHandleEntity *pServerEntity, int contentsMask) - { - if (pServerEntity == m_pPassEnt) - { - return false; - } - return true; - } -private: - const IHandleEntity *m_pPassEnt; -}; - -bool SetupTeleport() -{ - if (s_Teleport.setup) - { - return s_Teleport.supported; - } - - /* Setup Teleport */ - int offset; - if (g_pGameConf->GetOffset("Teleport", &offset)) - { - PassInfo info[3]; - info[0].flags = info[1].flags = info[2].flags = PASSFLAG_BYVAL; - info[0].size = info[1].size = info[2].size = sizeof(void *); - info[0].type = info[1].type = info[2].type = PassType_Basic; - - s_Teleport.call = g_pBinTools->CreateVCall(offset, 0, 0, NULL, info, 3); - - if (s_Teleport.call != NULL) - { - s_Teleport.supported = true; - } - } - - s_Teleport.setup = true; - - return s_Teleport.supported; -} - -void Teleport(CBaseEntity *pEntity, Vector *origin, QAngle *ang, Vector *velocity) -{ - unsigned char params[sizeof(void *) * 4]; - unsigned char *vptr = params; - *(CBaseEntity **)vptr = pEntity; - vptr += sizeof(CBaseEntity *); - *(Vector **)vptr = origin; - vptr += sizeof(Vector *); - *(QAngle **)vptr = ang; - vptr += sizeof(QAngle *); - *(Vector **)vptr = velocity; - - s_Teleport.call->Execute(params, NULL); -} - -bool IsTeleportSupported() -{ - return SetupTeleport(); -} - -bool SetupGetVelocity() -{ - if (s_GetVelocity.setup) - { - return s_GetVelocity.supported; - } - - int offset; - if (g_pGameConf->GetOffset("GetVelocity", &offset)) - { - PassInfo info[2]; - info[0].flags = info[1].flags = PASSFLAG_BYVAL; - info[0].size = info[1].size = sizeof(void *); - info[0].type = info[1].type = PassType_Basic; - - s_GetVelocity.call = g_pBinTools->CreateVCall(offset, 0, 0, NULL, info, 2); - - if (s_GetVelocity.call != NULL) - { - s_GetVelocity.supported = true; - } - } - - s_GetVelocity.setup = true; - - return s_GetVelocity.supported; -} - -void GetVelocity(CBaseEntity *pEntity, Vector *velocity, AngularImpulse *angvelocity) -{ - unsigned char params[sizeof(void *) * 3]; - unsigned char *vptr = params; - *(CBaseEntity **)vptr = pEntity; - vptr += sizeof(CBaseEntity *); - *(Vector **)vptr = velocity; - vptr += sizeof(Vector *); - *(AngularImpulse **)vptr = angvelocity; - - s_GetVelocity.call->Execute(params, NULL); -} - -bool IsGetVelocitySupported() -{ - return SetupGetVelocity(); -} - -bool SetupGetEyeAngles() -{ - if (s_EyeAngles.setup) - { - return s_EyeAngles.supported; - } - - int offset; - if (g_pGameConf->GetOffset("EyeAngles", &offset)) - { - PassInfo info[1]; - info[0].flags = PASSFLAG_BYVAL; - info[0].size = sizeof(void *); - info[0].type = PassType_Basic; - - s_EyeAngles.call = g_pBinTools->CreateVCall(offset, 0, 0, info, NULL, 0); - - if (s_EyeAngles.call != NULL) - { - s_EyeAngles.supported = true; - } - } - - s_EyeAngles.setup = true; - - return s_EyeAngles.supported; -} - -bool GetEyeAngles(CBaseEntity *pEntity, QAngle *pAngles) -{ - if (!IsEyeAnglesSupported()) - { - return false; - } - - QAngle *pRetAngle = NULL; - unsigned char params[sizeof(void *)]; - unsigned char *vptr = params; - - *(CBaseEntity **)vptr = pEntity; - - s_EyeAngles.call->Execute(params, &pRetAngle); - - if (pRetAngle == NULL) - { - return false; - } - - *pAngles = *pRetAngle; - - return true; -} - -int GetClientAimTarget(edict_t *pEdict, bool only_players) -{ - CBaseEntity *pEntity = pEdict->GetUnknown() ? pEdict->GetUnknown()->GetBaseEntity() : NULL; - - if (pEntity == NULL) - { - return -1; - } - - Vector eye_position; - QAngle eye_angles; - - /* Get the private information we need */ - serverClients->ClientEarPosition(pEdict, &eye_position); - if (!GetEyeAngles(pEntity, &eye_angles)) - { - return -2; - } - - Vector aim_dir; - AngleVectors(eye_angles, &aim_dir); - VectorNormalize(aim_dir); - - Vector vec_end = eye_position + aim_dir * 8000; - - Ray_t ray; - ray.Init(eye_position, vec_end); - - trace_t tr; - CTraceFilterSimple simple(pEdict->GetIServerEntity()); - - enginetrace->TraceRay(ray, MASK_SOLID|CONTENTS_DEBRIS|CONTENTS_HITBOX, &simple, &tr); - - if (tr.fraction == 1.0f || tr.m_pEnt == NULL) - { - return -1; - } - - edict_t *pTarget = gameents->BaseEntityToEdict(tr.m_pEnt); - if (pTarget == NULL) - { - return -1; - } - - int ent_index = engine->IndexOfEdict(pTarget); - - IGamePlayer *pTargetPlayer = playerhelpers->GetGamePlayer(ent_index); - if (pTargetPlayer != NULL && !pTargetPlayer->IsInGame()) - { - return -1; - } - else if (only_players && pTargetPlayer == NULL) - { - return -1; - } - - return ent_index; -} - -bool IsEyeAnglesSupported() -{ - return SetupGetEyeAngles(); -} - -bool GetPlayerInfo(int client, player_info_t *info) -{ -#if defined ORANGEBOX_BUILD - return engine->GetPlayerInfo(client, info); -#else - return (iserver) ? iserver->GetPlayerInfo(client-1, info) : false; -#endif -} - -void ShutdownHelpers() -{ - s_Teleport.Shutdown(); - s_GetVelocity.Shutdown(); - s_EyeAngles.Shutdown(); -} - -const char *GetDTTypeName(int type) -{ - switch (type) - { - case DPT_Int: - { - return "integer"; - } - case DPT_Float: - { - return "float"; - } - case DPT_Vector: - { - return "vector"; - } - case DPT_String: - { - return "string"; - } - case DPT_Array: - { - return "array"; - } - case DPT_DataTable: - { - return "datatable"; - } - default: - { - return NULL; - } - } - - return NULL; -} - -void UTIL_DrawSendTable_XML(FILE *fp, SendTable *pTable, int space_count) -{ - char spaces[255]; - - for (int i = 0; i < space_count; i++) - { - spaces[i] = ' '; - } - spaces[space_count] = '\0'; - - const char *type_name; - SendTable *pOtherTable; - SendProp *pProp; - - fprintf(fp, " %s\n", spaces, pTable->GetName()); - for (int i = 0; i < pTable->GetNumProps(); i++) - { - pProp = pTable->GetProp(i); - - fprintf(fp, " %s\n", spaces, pProp->GetName()); - - if ((type_name = GetDTTypeName(pProp->GetType())) != NULL) - { - fprintf(fp, " %s%s\n", spaces, type_name); - } - else - { - fprintf(fp, " %s%d\n", spaces, pProp->GetType()); - } - - fprintf(fp, " %s%d\n", spaces, pProp->GetOffset()); - fprintf(fp, " %s%d\n", spaces, pProp->m_nBits); - - if ((pOtherTable = pTable->GetProp(i)->GetDataTable()) != NULL) - { - UTIL_DrawSendTable_XML(fp, pOtherTable, space_count + 3); - } - - fprintf(fp, " %s\n", spaces); - } - fprintf(fp, " %s\n", spaces); -} - -void UTIL_DrawServerClass_XML(FILE *fp, ServerClass *sc) -{ - fprintf(fp, "\n", sc->GetName()); - UTIL_DrawSendTable_XML(fp, sc->m_pTable, 0); - fprintf(fp, "\n"); -} - -void UTIL_DrawSendTable(FILE *fp, SendTable *pTable, int level) -{ - char spaces[255]; - for (int i=0; iGetName()); - - for (int i=0; iGetNumProps(); i++) - { - pProp = pTable->GetProp(i); - name = pProp->GetName(); - if (pProp->GetDataTable()) - { - UTIL_DrawSendTable(fp, pProp->GetDataTable(), level + 1); - } - else - { - type = GetDTTypeName(pProp->GetType()); - - if (type != NULL) - { - fprintf(fp, - "%s-Member: %s (offset %d) (type %s) (bits %d)\n", - spaces, - pProp->GetName(), - pProp->GetOffset(), - type, - pProp->m_nBits); - } - else - { - fprintf(fp, - "%s-Member: %s (offset %d) (type %d) (bits %d)\n", - spaces, - pProp->GetName(), - pProp->GetOffset(), - pProp->GetType(), - pProp->m_nBits); - } - } - } -} - -CON_COMMAND(sm_dump_netprops_xml, "Dumps the networkable property table as an XML file") -{ -#if !defined ORANGEBOX_BUILD - CCommand args; -#endif - - if (args.ArgC() < 2) - { - META_CONPRINT("Usage: sm_dump_netprops_xml \n"); - return; - } - - const char *file = args.Arg(1); - if (!file || file[0] == '\0') - { - META_CONPRINT("Usage: sm_dump_netprops_xml \n"); - return; - } - - char path[PLATFORM_MAX_PATH]; - g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file); - - FILE *fp = NULL; - if ((fp = fopen(path, "wt")) == NULL) - { - META_CONPRINTF("Could not open file \"%s\"\n", path); - return; - } - - fprintf(fp, "\n\n"); - fprintf(fp, "\n\n", g_pSM->GetGameFolderName()); - - ServerClass *pBase = gamedll->GetAllServerClasses(); - while (pBase != NULL) - { - UTIL_DrawServerClass_XML(fp, pBase); - pBase = pBase->m_pNext; - } - - fclose(fp); -} - -CON_COMMAND(sm_dump_netprops, "Dumps the networkable property table as a text file") -{ -#if !defined ORANGEBOX_BUILD - CCommand args; -#endif - - if (args.ArgC() < 2) - { - META_CONPRINT("Usage: sm_dump_netprops \n"); - return; - } - - const char *file = args.Arg(1); - if (!file || file[0] == '\0') - { - META_CONPRINT("Usage: sm_dump_netprops \n"); - return; - } - - char path[PLATFORM_MAX_PATH]; - g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file); - - FILE *fp = NULL; - if ((fp = fopen(path, "wt")) == NULL) - { - META_CONPRINTF("Could not open file \"%s\"\n", path); - return; - } - - fprintf(fp, "// Dump of all network properties for \"%s\" follows\n//\n\n", g_pSM->GetGameFolderName()); - - ServerClass *pBase = gamedll->GetAllServerClasses(); - while (pBase != NULL) - { - fprintf(fp, "%s:\n", pBase->GetName()); - UTIL_DrawSendTable(fp, pBase->m_pTable, 1); - pBase = pBase->m_pNext; - } - - fclose(fp); -} - -#if defined SUBPLATFORM_SECURECRT -void _ignore_invalid_parameter( - const wchar_t * expression, - const wchar_t * function, - const wchar_t * file, - unsigned int line, - uintptr_t pReserved - ) -{ - /* Wow we don't care, thanks Microsoft. */ -} -#endif - -CON_COMMAND(sm_dump_classes, "Dumps the class list as a text file") -{ -#if !defined ORANGEBOX_BUILD - CCommand args; -#endif - - if (args.ArgC() < 2) - { - META_CONPRINT("Usage: sm_dump_classes \n"); - return; - } - - const char *file = args.Arg(1); - if (!file || file[0] == '\0') - { - META_CONPRINT("Usage: sm_dump_classes \n"); - return; - } - - ICallWrapper *pWrapper = NULL; - - if (!pWrapper) - { - PassInfo retData; - retData.flags = PASSFLAG_BYVAL; - retData.size = sizeof(void *); - retData.type = PassType_Basic; - - void *addr; - if (!g_pGameConf->GetMemSig("EntityFactory", &addr) || addr == NULL) - { - META_CONPRINT("Failed to locate function\n"); - return; - } - - pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &retData, NULL, 0); - } - - - void *returnData = NULL; - - pWrapper->Execute(NULL, &returnData); - - pWrapper->Destroy(); - - if (returnData == NULL) - { - return; - } - - CEntityFactoryDictionary *dict = ( CEntityFactoryDictionary * )returnData; - - if ( !dict ) - { - return; - } - - char path[PLATFORM_MAX_PATH]; - g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file); - - FILE *fp = NULL; - if ((fp = fopen(path, "wt")) == NULL) - { - META_CONPRINTF("Could not open file \"%s\"\n", path); - return; - } - - char buffer[80]; - buffer[0] = 0; - -#if defined SUBPLATFORM_SECURECRT - _invalid_parameter_handler handler = _set_invalid_parameter_handler(_ignore_invalid_parameter); -#endif - - time_t t = g_pSM->GetAdjustedTime(); - size_t written = strftime(buffer, sizeof(buffer), "%d/%m/%Y", localtime(&t)); - -#if defined SUBPLATFORM_SECURECRT - _set_invalid_parameter_handler(handler); -#endif - - fprintf(fp, "// Dump of all classes for \"%s\" as at %s\n//\n\n", g_pSM->GetGameFolderName(), buffer); - - for ( int i = dict->m_Factories.First(); i != dict->m_Factories.InvalidIndex(); i = dict->m_Factories.Next( i ) ) - { - IServerNetworkable *entity = dict->Create(dict->m_Factories.GetElementName(i)); - ServerClass *sclass = entity->GetServerClass(); - fprintf(fp,"%s - %s\n",sclass->GetName(), dict->m_Factories.GetElementName(i)); - - typedescription_t *datamap = gamehelpers->FindInDataMap(gamehelpers->GetDataMap(entity->GetBaseEntity()), "m_iEFlags"); - - int *eflags = (int *)((char *)entity->GetBaseEntity() + datamap->fieldOffset[TD_OFFSET_NORMAL]); - *eflags |= (1<<0); // EFL_KILLME - } - - fclose(fp); - -} - -char *UTIL_FlagsToString(int flags) -{ - static char str[1024]; - str[0] = 0; - - if (flags & FTYPEDESC_GLOBAL) - { - strcat(str, "Global|"); - } - if (flags & FTYPEDESC_SAVE) - { - strcat(str, "Save|"); - } - if (flags & FTYPEDESC_KEY) - { - strcat(str, "Key|"); - } - if (flags & FTYPEDESC_INPUT) - { - strcat(str, "Input|"); - } - if (flags & FTYPEDESC_OUTPUT) - { - strcat(str, "Output|"); - } - if (flags & FTYPEDESC_FUNCTIONTABLE) - { - strcat(str, "FunctionTable|"); - } - if (flags & FTYPEDESC_PTR) - { - strcat(str, "Ptr|"); - } - if (flags & FTYPEDESC_OVERRIDE) - { - strcat(str, "Override|"); - } - - int len = strlen(str) - 1; - if (len > 0) - { - str[len] = 0; // Strip the final '|' - } - - return str; -} - -void UTIL_DrawDataTable(FILE *fp, datamap_t *pMap, int level) -{ - char spaces[255]; - - for (int i=0; idataNumFields; i++) - { - if (pMap->dataDesc[i].fieldName == NULL) - { - continue; - } - - if (pMap->dataDesc[i].td) - { - fprintf(fp, " %sSub-Class Table (%d Deep): %s - %s\n", spaces, level+1, pMap->dataDesc[i].fieldName, pMap->dataDesc[i].td->dataClassName); - UTIL_DrawDataTable(fp, pMap->dataDesc[i].td, level+1); - } - else - { - externalname = pMap->dataDesc[i].externalName; - flags = UTIL_FlagsToString(pMap->dataDesc[i].flags); - - if (externalname == NULL) - { - fprintf(fp,"%s- %s (%s)(%i Bytes)\n", spaces, pMap->dataDesc[i].fieldName, flags, pMap->dataDesc[i].fieldSizeInBytes); - } - else - { - fprintf(fp,"%s- %s (%s)(%i Bytes) - %s\n", spaces, pMap->dataDesc[i].fieldName, flags, pMap->dataDesc[i].fieldSizeInBytes, externalname); - } - } - } - pMap = pMap->baseMap; - } -} - -CON_COMMAND(sm_dump_datamaps, "Dumps the data map list as a text file") -{ -#if !defined ORANGEBOX_BUILD - CCommand args; -#endif - - if (args.ArgC() < 2) - { - META_CONPRINT("Usage: sm_dump_datamaps \n"); - return; - } - - const char *file = args.Arg(1); - if (!file || file[0] == '\0') - { - META_CONPRINT("Usage: sm_dump_datamaps \n"); - return; - } - - ICallWrapper *pWrapper = NULL; - - if (!pWrapper) - { - PassInfo retData; - retData.flags = PASSFLAG_BYVAL; - retData.size = sizeof(void *); - retData.type = PassType_Basic; - - void *addr; - if (!g_pGameConf->GetMemSig("EntityFactory", &addr) || addr == NULL) - { - META_CONPRINT("Failed to locate function\n"); - return; - } - - pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &retData, NULL, 0); - } - - - void *returnData = NULL; - - pWrapper->Execute(NULL, &returnData); - - pWrapper->Destroy(); - - if (returnData == NULL) - { - return; - } - - CEntityFactoryDictionary *dict = ( CEntityFactoryDictionary * )returnData; - - if ( !dict ) - { - return; - } - - char path[PLATFORM_MAX_PATH]; - g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file); - - FILE *fp = NULL; - if ((fp = fopen(path, "wt")) == NULL) - { - META_CONPRINTF("Could not open file \"%s\"\n", path); - return; - } - - char buffer[80]; - buffer[0] = 0; - -#if defined SUBPLATFORM_SECURECRT - _invalid_parameter_handler handler = _set_invalid_parameter_handler(_ignore_invalid_parameter); -#endif - - time_t t = g_pSM->GetAdjustedTime(); - size_t written = strftime(buffer, sizeof(buffer), "%d/%m/%Y", localtime(&t)); - -#if defined SUBPLATFORM_SECURECRT - _set_invalid_parameter_handler(handler); -#endif - - fprintf(fp, "// Dump of all datamaps for \"%s\" as at %s\n//\n//\n", g_pSM->GetGameFolderName(), buffer); - - - fprintf(fp, "// Flag Details:\n//\n"); - - fprintf(fp, "// Global: This field is masked for global entity save/restore\n"); - fprintf(fp, "// Save: This field is saved to disk\n"); - fprintf(fp, "// Key: This field can be requested and written to by string name at load time\n"); - fprintf(fp, "// Input: This field can be written to by string name at run time, and a function called\n"); - fprintf(fp, "// Output: This field propogates it's value to all targets whenever it changes\n"); - fprintf(fp, "// FunctionTable: This is a table entry for a member function pointer\n"); - fprintf(fp, "// Ptr: This field is a pointer, not an embedded object\n"); - fprintf(fp, "// Override: The field is an override for one in a base class (only used by prediction system for now)\n"); - - fprintf(fp, "//\n\n"); - - for ( int i = dict->m_Factories.First(); i != dict->m_Factories.InvalidIndex(); i = dict->m_Factories.Next( i ) ) - { - IServerNetworkable *entity = dict->Create(dict->m_Factories.GetElementName(i)); - ServerClass *sclass = entity->GetServerClass(); - datamap_t *pMap = gamehelpers->GetDataMap(entity->GetBaseEntity()); - - fprintf(fp,"%s - %s\n", sclass->GetName(), dict->m_Factories.GetElementName(i)); - - UTIL_DrawDataTable(fp, pMap, 0); - - typedescription_t *datamap = gamehelpers->FindInDataMap(pMap, "m_iEFlags"); - - int *eflags = (int *)((char *)entity->GetBaseEntity() + datamap->fieldOffset[TD_OFFSET_NORMAL]); - *eflags |= (1<<0); // EFL_KILLME - } - - fclose(fp); - -} diff --git a/extensions/sdktools/vhelpers.h b/extensions/sdktools/vhelpers.h deleted file mode 100644 index 46cbdb81..00000000 --- a/extensions/sdktools/vhelpers.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SDKTOOLS_VHELPERS_H_ -#define _INCLUDE_SDKTOOLS_VHELPERS_H_ - -#include -#include -#include - -using namespace SourceMod; - -struct CallHelper -{ - CallHelper() : call(NULL), supported(false), setup(false) - { - } - void Shutdown() - { - if (call) - { - call->Destroy(); - call = NULL; - supported = false; - } - } - ICallWrapper *call; - bool supported; - bool setup; -}; - -void Teleport(CBaseEntity *pEntity, Vector *origin, QAngle *ang, Vector *velocity); -bool IsTeleportSupported(); - -void GetVelocity(CBaseEntity *pEntity, Vector *velocity, AngularImpulse *angvelocity); -bool IsGetVelocitySupported(); - -bool GetEyeAngles(CBaseEntity *pEntity, QAngle *pAngles); -bool IsEyeAnglesSupported(); - -int GetClientAimTarget(edict_t *pEdict, bool only_players); - -bool GetPlayerInfo(int client, player_info_t *info); - -void ShutdownHelpers(); - -#endif //_INCLUDE_SDKTOOLS_VHELPERS_H_ diff --git a/extensions/sdktools/vnatives.cpp b/extensions/sdktools/vnatives.cpp deleted file mode 100644 index 5dff4cd0..00000000 --- a/extensions/sdktools/vnatives.cpp +++ /dev/null @@ -1,1006 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include -#include "extension.h" -#include "vcallbuilder.h" -#include "vnatives.h" -#include "vhelpers.h" -#include "vglobals.h" -#include "CellRecipientFilter.h" -#include -#include -#include "iserver.h" - -SourceHook::List g_RegCalls; -SourceHook::List g_CallWraps; - -inline void InitPass(ValvePassInfo &info, ValveType vtype, PassType type, unsigned int flags, unsigned int decflags=0) -{ - info.decflags = decflags; - info.encflags = 0; - info.flags = flags; - info.type = type; - info.vtype = vtype; -} - -#define START_CALL() \ - unsigned char *vptr = pCall->stk_get(); - -#define FINISH_CALL_SIMPLE(vret) \ - pCall->call->Execute(vptr, vret); \ - pCall->stk_put(vptr); - -#define ENCODE_VALVE_PARAM(num, which, vnum) \ - if (EncodeValveParam(pContext, \ - params[num], \ - pCall, \ - &pCall->which[vnum], \ - vptr) \ - == Data_Fail) \ - { \ - return 0; \ - } - -#define DECODE_VALVE_PARAM(num, which, vnum) \ - if (DecodeValveParam(pContext, \ - params[num], \ - pCall, \ - &pCall->which[vnum], \ - vptr) \ - == Data_Fail) \ - { \ - return 0; \ - } - -bool CreateBaseCall(const char *name, - ValveCallType vcalltype, - const ValvePassInfo *retinfo, - const ValvePassInfo params[], - unsigned int numParams, - ValveCall **vaddr) -{ - int offset; - ValveCall *call; - if (g_pGameConf->GetOffset(name, &offset)) - { - call = CreateValveVCall(offset, vcalltype, retinfo, params, numParams); - if (call) - { - g_RegCalls.push_back(call); - } - *vaddr = call; - return true; - } else { - void *addr; - if (g_pGameConf->GetMemSig(name, &addr)) - { - call = CreateValveCall(addr, vcalltype, retinfo, params, numParams); - if (call) - { - g_RegCalls.push_back(call); - } - *vaddr = call; - return true; - } - } - return false; -} - -static cell_t RemovePlayerItem(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[2]; - InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("RemovePlayerItem", ValveCall_Player, &pass[1], pass, 1, &pCall)) - { - return pContext->ThrowNativeError("\"RemovePlayerItem\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"RemovePlayerItem\" wrapper failed to initialized"); - } - } - - bool ret; - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - DECODE_VALVE_PARAM(2, vparams, 0); - FINISH_CALL_SIMPLE(&ret); - return ret ? 1 : 0; -} - -static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[3]; - InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("GiveNamedItem", ValveCall_Player, &pass[2], pass, 2, &pCall)) - { - return pContext->ThrowNativeError("\"GiveNamedItem\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"GiveNamedItem\" wrapper failed to initialized"); - } - } - - CBaseEntity *pEntity = NULL; - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - DECODE_VALVE_PARAM(2, vparams, 0); - DECODE_VALVE_PARAM(3, vparams, 1); - FINISH_CALL_SIMPLE(&pEntity); - - if (pEntity == NULL) - { - return -1; - } - - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); - if (!pEdict) - { - return -1; - } - - return engine->IndexOfEdict(pEdict); -} - -static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[2]; - InitPass(pass[0], Valve_POD, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[1], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("Weapon_GetSlot", ValveCall_Player, &pass[1], pass, 1, &pCall)) - { - return pContext->ThrowNativeError("\"Weapon_GetSlot\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"Weapon_GetSlot\" wrapper failed to initialized"); - } - } - - CBaseEntity *pEntity; - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - DECODE_VALVE_PARAM(2, vparams, 0); - FINISH_CALL_SIMPLE(&pEntity); - - if (pEntity == NULL) - { - return -1; - } - - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); - if (!pEdict) - { - return -1; - } - - return engine->IndexOfEdict(pEdict); -} - -static cell_t IgniteEntity(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[4]; - InitPass(pass[0], Valve_Float, PassType_Float, PASSFLAG_BYVAL); - InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[2], Valve_Float, PassType_Float, PASSFLAG_BYVAL); - InitPass(pass[3], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("Ignite", ValveCall_Entity, NULL, pass, 4, &pCall)) - { - return pContext->ThrowNativeError("\"Ignite\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"Ignite\" wrapper failed to initialized"); - } - } - - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - DECODE_VALVE_PARAM(2, vparams, 0); - DECODE_VALVE_PARAM(3, vparams, 1); - DECODE_VALVE_PARAM(4, vparams, 2); - DECODE_VALVE_PARAM(5, vparams, 3); - FINISH_CALL_SIMPLE(NULL); - - return 1; -} - -static cell_t ExtinguishEntity(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - if (!CreateBaseCall("Extinguish", ValveCall_Entity, NULL, NULL, 0, &pCall)) - { - return pContext->ThrowNativeError("\"Extinguish\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"Extinguish\" wrapper failed to initialized"); - } - } - - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - FINISH_CALL_SIMPLE(NULL); - - return 1; -} - -static cell_t TeleportEntity(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[3]; - InitPass(pass[0], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL); - InitPass(pass[1], Valve_QAngle, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL); - InitPass(pass[2], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL); - if (!CreateBaseCall("Teleport", ValveCall_Entity, NULL, pass, 3, &pCall)) - { - return pContext->ThrowNativeError("\"Teleport\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"Teleport\" wrapper failed to initialized"); - } - } - - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - DECODE_VALVE_PARAM(2, vparams, 0); - DECODE_VALVE_PARAM(3, vparams, 1); - DECODE_VALVE_PARAM(4, vparams, 2); - FINISH_CALL_SIMPLE(NULL); - - return 1; -} - -#if defined ORANGEBOX_BUILD -/* :TODO: This is Team Fortress 2 specific */ -static cell_t ForcePlayerSuicide(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[2]; - InitPass(pass[0], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("CommitSuicide", ValveCall_Player, NULL, pass, 2, &pCall)) - { - return pContext->ThrowNativeError("\"CommitSuicide\" not supported by this mod"); - } - else if (!pCall) - { - return pContext->ThrowNativeError("\"CommitSuicide\" wrapper failed to initialized"); - } - } - - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - *(bool *)(vptr + 4) = false; - *(bool *)(vptr + 5) = false; - FINISH_CALL_SIMPLE(NULL); - - return 1; -} -#else -static cell_t ForcePlayerSuicide(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - if (!CreateBaseCall("CommitSuicide", ValveCall_Player, NULL, NULL, 0, &pCall)) - { - return pContext->ThrowNativeError("\"CommitSuicide\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"CommitSuicide\" wrapper failed to initialized"); - } - } - - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - FINISH_CALL_SIMPLE(NULL); - - return 1; -} -#endif - -static cell_t SetClientViewEntity(IPluginContext *pContext, const cell_t *params) -{ - IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]); - if (player == NULL) - { - return pContext->ThrowNativeError("Invalid client index %d", params[1]); - } - if (!player->IsInGame()) - { - return pContext->ThrowNativeError("Client %d is not in game", params[1]); - } - - edict_t *pEdict = engine->PEntityOfEntIndex(params[2]); - if (!pEdict || pEdict->IsFree()) - { - return pContext->ThrowNativeError("Entity %d is not valid", params[2]); - } - - engine->SetView(player->GetEdict(), pEdict); - - return 1; -} - -static SourceHook::String *g_lightstyle[MAX_LIGHTSTYLES] = {NULL}; -static cell_t SetLightStyle(IPluginContext *pContext, const cell_t *params) -{ - int style = params[1]; - if (style >= MAX_LIGHTSTYLES) - { - return pContext->ThrowNativeError("Light style %d is invalid (range: 0-%d)", style, MAX_LIGHTSTYLES - 1); - } - - if (g_lightstyle[style] == NULL) - { - /* We allocate and never free this because the Engine wants to hold onto it :\ - * in theory we could hook light style and know whether we're supposed to free - * this or not on shutdown, but for ~4K of memory MAX, it doesn't seem worth it yet. - * So, it's a :TODO:! - */ - g_lightstyle[style] = new SourceHook::String(); - } - - char *str; - pContext->LocalToString(params[2], &str); - - g_lightstyle[style]->assign(str); - - engine->LightStyle(style, g_lightstyle[style]->c_str()); - - return 1; -} - -static cell_t SlapPlayer(IPluginContext *pContext, const cell_t *params) -{ - static bool s_slap_supported = false; - static bool s_slap_setup = false; - static ICallWrapper *s_teleport = NULL; - static int s_health_offs = 0; - static int s_sound_count = 0; - static int s_frag_offs = 0; - - if (!s_slap_setup) - { - int tries = 0; - - s_slap_setup = true; - - if (IsTeleportSupported()) - { - tries++; - } - if (IsGetVelocitySupported()) - { - tries++; - } - - /* Setup health */ - if (g_pGameConf->GetOffset("m_iHealth", &s_health_offs) && s_health_offs) - { - tries++; - } - - if (tries == 3) - { - s_slap_supported = true; - - const char *key; - if ((key = g_pGameConf->GetKeyValue("SlapSoundCount")) != NULL) - { - s_sound_count = atoi(key); - } - } - } - - if (!s_slap_supported) - { - return pContext->ThrowNativeError("This function is not supported on this mod"); - } - - /* First check if the client is valid */ - int client = params[1]; - IGamePlayer *player = playerhelpers->GetGamePlayer(client); - if (!player) - { - return pContext->ThrowNativeError("Client %d is not valid", client); - } else if (!player->IsInGame()) { - return pContext->ThrowNativeError("Client %d is not in game", client); - } - - edict_t *pEdict = player->GetEdict(); - CBaseEntity *pEntity = pEdict->GetUnknown()->GetBaseEntity(); - - /* See if we should be taking away health */ - bool should_slay = false; - if (params[2]) - { - int *health = (int *)((char *)pEntity + s_health_offs); - if (*health - params[2] <= 0) - { - *health = 1; - should_slay = true; - } else { - *health -= params[2]; - } - } - - /* Teleport in a random direction - thank you, Mani!*/ - Vector velocity; - GetVelocity(pEntity, &velocity, NULL); - velocity.x += ((rand() % 180) + 50) * (((rand() % 2) == 1) ? -1 : 1); - velocity.y += ((rand() % 180) + 50) * (((rand() % 2) == 1) ? -1 : 1); - velocity.z += rand() % 200 + 100; - Teleport(pEntity, NULL, NULL, &velocity); - - /* Play a random sound */ - if (params[3] && s_sound_count > 0) - { - char name[48]; - const char *sound_name; - cell_t player_list[256], total_players = 0; - int maxClients = playerhelpers->GetMaxClients(); - - int r = (rand() % s_sound_count) + 1; - snprintf(name, sizeof(name), "SlapSound%d", r); - - if ((sound_name = g_pGameConf->GetKeyValue(name)) != NULL) - { - IGamePlayer *other; - for (int i=1; i<=maxClients; i++) - { - other = playerhelpers->GetGamePlayer(i); - if (other->IsInGame()) - { - player_list[total_players++] = i; - } - } - - const Vector & pos = pEdict->GetCollideable()->GetCollisionOrigin(); - CellRecipientFilter rf; - rf.SetToReliable(true); - rf.Initialize(player_list, total_players); - engsound->EmitSound(rf, client, CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, &pos); - } - } - - if (!s_frag_offs) - { - const char *frag_prop = g_pGameConf->GetKeyValue("m_iFrags"); - if (frag_prop) - { - datamap_t *pMap = gamehelpers->GetDataMap(pEntity); - typedescription_t *pType = gamehelpers->FindInDataMap(pMap, frag_prop); - if (pType != NULL) - { - s_frag_offs = pType->fieldOffset[TD_OFFSET_NORMAL]; - } - } - if (!s_frag_offs) - { - s_frag_offs = -1; - } - } - - int old_frags = 0; - if (s_frag_offs > 0) - { - old_frags = *(int *)((char *)pEntity + s_frag_offs); - } - - /* Force suicide */ - if (should_slay) - { - pluginhelpers->ClientCommand(pEdict, "kill\n"); - } - - if (s_frag_offs > 0) - { - *(int *)((char *)pEntity + s_frag_offs) = old_frags; - } - - return 1; -} - -static cell_t GetClientEyePosition(IPluginContext *pContext, const cell_t *params) -{ - IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]); - if (player == NULL) - { - return pContext->ThrowNativeError("Invalid client index %d", params[1]); - } - if (!player->IsInGame()) - { - return pContext->ThrowNativeError("Client %d is not in game", params[1]); - } - - Vector pos; - serverClients->ClientEarPosition(player->GetEdict(), &pos); - - cell_t *addr; - pContext->LocalToPhysAddr(params[2], &addr); - addr[0] = sp_ftoc(pos.x); - addr[1] = sp_ftoc(pos.y); - addr[2] = sp_ftoc(pos.z); - - return 1; -} - -static cell_t GetClientEyeAngles(IPluginContext *pContext, const cell_t *params) -{ - int client = params[1]; - IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); - - if (!pPlayer) - { - return pContext->ThrowNativeError("Invalid client index %d", client); - } - else if (!pPlayer->IsInGame()) - { - return pContext->ThrowNativeError("Client %d is not in game", client); - } - - edict_t *pEdict = pPlayer->GetEdict(); - CBaseEntity *pEntity = pEdict->GetUnknown() ? pEdict->GetUnknown()->GetBaseEntity() : NULL; - - /* We always set the angles for backwards compatibility -- - * The original function had no return value. - */ - QAngle angles; - bool got_angles = false; - - if (pEntity != NULL) - { - got_angles = GetEyeAngles(pEntity, &angles); - } - - cell_t *addr; - pContext->LocalToPhysAddr(params[2], &addr); - addr[0] = sp_ftoc(angles.x); - addr[1] = sp_ftoc(angles.y); - addr[2] = sp_ftoc(angles.z); - - return got_angles ? 1 : 0; -} - -static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[3]; - InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL|VDECODE_FLAG_ALLOWWORLD); - InitPass(pass[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("FindEntityByClassname", ValveCall_EntityList, &pass[2], pass, 2, &pCall)) - { - return pContext->ThrowNativeError("\"FindEntityByClassname\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"FindEntityByClassname\" wrapper failed to initialized"); - } - } - - CBaseEntity *pEntity; - START_CALL(); - *(void **)vptr = g_EntList; - DECODE_VALVE_PARAM(1, vparams, 0); - DECODE_VALVE_PARAM(2, vparams, 1); - FINISH_CALL_SIMPLE(&pEntity); - - if (pEntity == NULL) - { - return -1; - } - - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); - if (!pEdict) - { - return -1; - } - - return engine->IndexOfEdict(pEdict); -} - -static cell_t CreateEntityByName(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[3]; - InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("CreateEntityByName", ValveCall_Static, &pass[2], pass, 2, &pCall)) - { - return pContext->ThrowNativeError("\"CreateEntityByName\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"CreateEntityByName\" wrapper failed to initialized"); - } - } - - CBaseEntity *pEntity = NULL; - START_CALL(); - DECODE_VALVE_PARAM(1, vparams, 0); - DECODE_VALVE_PARAM(2, vparams, 1); - FINISH_CALL_SIMPLE(&pEntity); - - if (pEntity == NULL) - { - return -1; - } - - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); - if (!pEdict) - { - return -1; - } - - return engine->IndexOfEdict(pEdict); -} - -static cell_t DispatchSpawn(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[2]; - InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("DispatchSpawn", ValveCall_Static, &pass[1], pass, 1, &pCall)) - { - return pContext->ThrowNativeError("\"DispatchSpawn\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"DispatchSpawn\" wrapper failed to initialized"); - } - } - - int ret; - START_CALL(); - DECODE_VALVE_PARAM(1, vparams, 0); - FINISH_CALL_SIMPLE(&ret); - - return (ret == -1) ? 0 : 1; -} - -static cell_t DispatchKeyValue(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[3]; - InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[2], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("DispatchKeyValue", ValveCall_Entity, &pass[2], pass, 2, &pCall)) - { - return pContext->ThrowNativeError("\"DispatchKeyValue\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"DispatchKeyValue\" wrapper failed to initialized"); - } - } - - bool ret; - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - DECODE_VALVE_PARAM(2, vparams, 0); - DECODE_VALVE_PARAM(3, vparams, 1); - FINISH_CALL_SIMPLE(&ret); - - return (ret) ? 1 : 0; -} - -static cell_t DispatchKeyValueFloat(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[3]; - InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL); - InitPass(pass[1], Valve_Float, PassType_Float, PASSFLAG_BYVAL); - InitPass(pass[2], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("DispatchKeyValueFloat", ValveCall_Entity, &pass[2], pass, 2, &pCall)) - { - return pContext->ThrowNativeError("\"DispatchKeyValueFloat\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"DispatchKeyValueFloat\" wrapper failed to initialized"); - } - } - - bool ret; - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - DECODE_VALVE_PARAM(2, vparams, 0); - DECODE_VALVE_PARAM(3, vparams, 1); - FINISH_CALL_SIMPLE(&ret); - - return (ret) ? 1 : 0; -} - -static cell_t DispatchKeyValueVector(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[3]; - InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL); -#if defined ORANGEBOX_BUILD - InitPass(pass[1], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL); -#else - InitPass(pass[1], Valve_Vector, PassType_Object, PASSFLAG_BYVAL|PASSFLAG_OCTOR|PASSFLAG_OASSIGNOP); -#endif - InitPass(pass[2], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("DispatchKeyValueVector", ValveCall_Entity, &pass[2], pass, 2, &pCall)) - { - return pContext->ThrowNativeError("\"DispatchKeyValueVector\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"DispatchKeyValueVector\" wrapper failed to initialized"); - } - } - - bool ret; - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - DECODE_VALVE_PARAM(2, vparams, 0); - DECODE_VALVE_PARAM(3, vparams, 1); - FINISH_CALL_SIMPLE(&ret); - - return (ret) ? 1 : 0; -} - -static cell_t sm_GetClientAimTarget(IPluginContext *pContext, const cell_t *params) -{ - int client = params[1]; - IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); - - if (!pPlayer) - { - return pContext->ThrowNativeError("Invalid client index %d", client); - } - else if (!pPlayer->IsInGame()) - { - return pContext->ThrowNativeError("Client %d is not in game", client); - } - - return GetClientAimTarget(pPlayer->GetEdict(), params[2] ? true : false); -} - -static cell_t sm_SetEntityModel(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[1]; - InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("SetEntityModel", ValveCall_Entity, NULL, pass, 1, &pCall)) - { - return pContext->ThrowNativeError("\"SetEntityModel\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"SetEntityModel\" wrapper failed to initialized"); - } - } - - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - DECODE_VALVE_PARAM(2, vparams, 0); - FINISH_CALL_SIMPLE(NULL); - - return 1; -} - -static cell_t GetPlayerDecalFile(IPluginContext *pContext, const cell_t *params) -{ - IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]); - if (player == NULL) - { - return pContext->ThrowNativeError("Invalid client index %d", params[1]); - } - if (!player->IsInGame()) - { - return pContext->ThrowNativeError("Client %d is not in game", params[1]); - } - - player_info_t info; - char *buffer; - - if (!GetPlayerInfo(params[1], &info) || !info.customFiles[0]) - { - return 0; - } - - pContext->LocalToString(params[2], &buffer); - Q_binarytohex((byte *)&info.customFiles[0], sizeof(info.customFiles[0]), buffer, params[3]); - - return 1; -} - -static cell_t GetServerNetStats(IPluginContext *pContext, const cell_t *params) -{ - if (iserver == NULL) - { - return pContext->ThrowNativeError("IServer interface not supported, file a bug report."); - } - - float in, out; - cell_t *pIn, *pOut; - - pContext->LocalToPhysAddr(params[1], &pIn); - pContext->LocalToPhysAddr(params[2], &pOut); - iserver->GetNetStats(in, out); - - *pIn = sp_ftoc(in); - *pOut = sp_ftoc(out); - - return 1; -} - -static cell_t WeaponEquip(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo pass[1]; - InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); - if (!CreateBaseCall("WeaponEquip", ValveCall_Player, NULL, pass, 1, &pCall)) - { - return pContext->ThrowNativeError("\"WeaponEquip\" not supported by this mod"); - } else if (!pCall) { - return pContext->ThrowNativeError("\"WeaponEquip\" wrapper failed to initialized"); - } - } - - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - DECODE_VALVE_PARAM(2, vparams, 0); - FINISH_CALL_SIMPLE(NULL); - - return 1; -} - -static cell_t ActivateEntity(IPluginContext *pContext, const cell_t *params) -{ - static ValveCall *pCall = NULL; - if (!pCall) - { - if (!CreateBaseCall("Activate", ValveCall_Entity, NULL, NULL, 0, &pCall)) - { - return pContext->ThrowNativeError("\"Activate\" not supported by this mod"); - } - else if (!pCall) - { - return pContext->ThrowNativeError("\"Activate\" wrapper failed to initialized"); - } - } - - START_CALL(); - DECODE_VALVE_PARAM(1, thisinfo, 0); - FINISH_CALL_SIMPLE(NULL); - - return 1; -} - -static cell_t SetClientInfo(IPluginContext *pContext, const cell_t *params) -{ - IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]); - IClient *pClient = iserver->GetClient(params[1]-1); - if (player == NULL || pClient == NULL) - { - return pContext->ThrowNativeError("Invalid client index %d", params[1]); - } - if (!player->IsConnected()) - { - return pContext->ThrowNativeError("Client %d is not connected", params[1]); - } - - static ValveCall *pCall = NULL; - if (!pCall) - { - ValvePassInfo params[2]; - InitPass(params[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL); - InitPass(params[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL); - - if (!CreateBaseCall("SetUserCvar", ValveCall_Entity, NULL, params, 2, &pCall)) - { - return pContext->ThrowNativeError("\"SetUserCvar\" not supported by this mod"); - } - else if (!pCall) - { - return pContext->ThrowNativeError("\"SetUserCvar\" wrapper failed to initialized"); - } - } - - static int changedOffset = -1; - - if (changedOffset == -1) - { - if (!g_pGameConf->GetOffset("InfoChanged", &changedOffset)) - { - return pContext->ThrowNativeError("\"SetUserCvar\" not supported by this mod"); - } - } - - unsigned char *CGameClient = (unsigned char *)pClient - 4; - - START_CALL(); - /* Not really a CBaseEntity* but this works */ - CBaseEntity **ebuf = (CBaseEntity **)vptr; - *ebuf = (CBaseEntity *)CGameClient; - DECODE_VALVE_PARAM(2, vparams, 0); - DECODE_VALVE_PARAM(3, vparams, 1); - FINISH_CALL_SIMPLE(NULL); - - uint8_t* changed = (uint8_t *)(CGameClient + changedOffset); - *changed = 1; - - return 1; -} - -sp_nativeinfo_t g_Natives[] = -{ - {"ExtinguishEntity", ExtinguishEntity}, - {"ForcePlayerSuicide", ForcePlayerSuicide}, - {"GivePlayerItem", GiveNamedItem}, - {"GetPlayerWeaponSlot", GetPlayerWeaponSlot}, - {"IgniteEntity", IgniteEntity}, - {"RemovePlayerItem", RemovePlayerItem}, - {"TeleportEntity", TeleportEntity}, - {"SetClientViewEntity", SetClientViewEntity}, - {"SetLightStyle", SetLightStyle}, - {"SlapPlayer", SlapPlayer}, - {"GetClientEyePosition", GetClientEyePosition}, - {"GetClientEyeAngles", GetClientEyeAngles}, - {"FindEntityByClassname", FindEntityByClassname}, - {"CreateEntityByName", CreateEntityByName}, - {"DispatchSpawn", DispatchSpawn}, - {"DispatchKeyValue", DispatchKeyValue}, - {"DispatchKeyValueFloat", DispatchKeyValueFloat}, - {"DispatchKeyValueVector", DispatchKeyValueVector}, - {"GetClientAimTarget", sm_GetClientAimTarget}, - {"SetEntityModel", sm_SetEntityModel}, - {"GetPlayerDecalFile", GetPlayerDecalFile}, - {"GetServerNetStats", GetServerNetStats}, - {"EquipPlayerWeapon", WeaponEquip}, - {"ActivateEntity", ActivateEntity}, - {"SetClientInfo", SetClientInfo}, - {NULL, NULL}, -}; diff --git a/extensions/sdktools/vnatives.h b/extensions/sdktools/vnatives.h deleted file mode 100644 index 74612360..00000000 --- a/extensions/sdktools/vnatives.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SDKTOOLS_VNATIVES_H_ -#define _INCLUDE_SDKTOOLS_VNATIVES_H_ - -#include - -extern SourceHook::List g_RegCalls; -extern sp_nativeinfo_t g_Natives[]; -extern sp_nativeinfo_t g_SoundNatives[]; - -#endif //_INCLUDE_SDKTOOLS_VNATIVES_H_ diff --git a/extensions/sdktools/voice.cpp b/extensions/sdktools/voice.cpp deleted file mode 100644 index 28ed4f50..00000000 --- a/extensions/sdktools/voice.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include - -#define SPEAK_NORMAL 0 -#define SPEAK_MUTED 1 -#define SPEAK_ALL 2 -#define SPEAK_LISTENALL 4 -#define SPEAK_TEAM 8 -#define SPEAK_LISTENTEAM 16 -#define LISTEN_DEFAULT 0 -#define LISTEN_NO 1 -#define LISTEN_YES 2 - -size_t g_VoiceFlags[65]; -size_t g_VoiceHookCount = 0; -int g_VoiceMap[65][65]; - -SH_DECL_HOOK3(IVoiceServer, SetClientListening, SH_NOATTRIB, 0, bool, int, int, bool); - -bool DecHookCount(int amount = 1); -bool DecHookCount(int amount) -{ - g_VoiceHookCount -= amount; - if (g_VoiceHookCount == 0) - { - SH_REMOVE_HOOK_MEMFUNC(IVoiceServer, SetClientListening, voiceserver, &g_SdkTools, &SDKTools::OnSetClientListening, false); - return true; - } - - return false; -} - -void IncHookCount() -{ - if (!g_VoiceHookCount++) - { - SH_ADD_HOOK_MEMFUNC(IVoiceServer, SetClientListening, voiceserver, &g_SdkTools, &SDKTools::OnSetClientListening, false); - } -} - -void SDKTools::VoiceInit() -{ - memset(g_VoiceMap, 0, sizeof(g_VoiceMap)); -} - -bool SDKTools::OnSetClientListening(int iReceiver, int iSender, bool bListen) -{ - if (g_VoiceMap[iReceiver][iSender] == LISTEN_NO) - { - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, bListen, &IVoiceServer::SetClientListening, (iReceiver, iSender, false)); - } - else if (g_VoiceMap[iReceiver][iSender] == LISTEN_YES) - { - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, bListen, &IVoiceServer::SetClientListening, (iReceiver, iSender, true)); - } - - if (g_VoiceFlags[iSender] & SPEAK_MUTED) - { - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, bListen, &IVoiceServer::SetClientListening, (iReceiver, iSender, false)); - } - - if ((g_VoiceFlags[iSender] & SPEAK_ALL) || (g_VoiceFlags[iReceiver] & SPEAK_LISTENALL)) - { - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, bListen, &IVoiceServer::SetClientListening, (iReceiver, iSender, true)); - } - - if ((g_VoiceFlags[iSender] & SPEAK_TEAM) || (g_VoiceFlags[iReceiver] & SPEAK_LISTENTEAM)) - { - IGamePlayer *pReceiver = playerhelpers->GetGamePlayer(iReceiver); - IGamePlayer *pSender = playerhelpers->GetGamePlayer(iSender); - - if (pReceiver && pSender && pReceiver->IsInGame() && pSender->IsInGame()) - { - IPlayerInfo *pRInfo = pReceiver->GetPlayerInfo(); - IPlayerInfo *pSInfo = pSender->GetPlayerInfo(); - - if (pRInfo && pSInfo && pRInfo->GetTeamIndex() == pSInfo->GetTeamIndex()) - { - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, bListen, &IVoiceServer::SetClientListening, (iReceiver, iSender, true)); - } - } - } - - RETURN_META_VALUE(MRES_IGNORED, bListen); -} - -void SDKTools::OnClientDisconnecting(int client) -{ - int max_clients = playerhelpers->GetMaxClients(); - - if (g_VoiceHookCount == 0) - { - return; - } - - /* This can probably be optimized more, but I doubt it's that much - * of an actual bottleneck. - */ - - /* Reset clients who receive from us */ - for (int i = 1; i <= max_clients; i++) - { - if (i == client) - { - continue; - } - - if (g_VoiceMap[i][client] != LISTEN_DEFAULT) - { - g_VoiceMap[i][client] = LISTEN_DEFAULT; - if (DecHookCount()) - { - return; - } - } - } - - /* Reset clients who send to us. I'm shoving a count in the 0 index! */ - if (g_VoiceMap[client][0] > 0) - { - DecHookCount(g_VoiceMap[client][0]); - memset(&g_VoiceMap[client], 0, sizeof(int) * 65); - } - - if (g_VoiceFlags[client]) - { - g_VoiceFlags[client] = 0; - DecHookCount(); - } -} - -static cell_t SetClientListeningFlags(IPluginContext *pContext, const cell_t *params) -{ - IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]); - if (player == NULL) - { - return pContext->ThrowNativeError("Client index %d is invalid", params[1]); - } - else if (!player->IsConnected()) - { - return pContext->ThrowNativeError("Client %d is not connected", params[1]); - } - - if (!params[2] && g_VoiceFlags[params[1]]) - { - DecHookCount(); - } - else if (!g_VoiceFlags[params[1]] && params[2]) - { - IncHookCount(); - } - - g_VoiceFlags[params[1]] = params[2]; - - return 1; -} - -static cell_t GetClientListeningFlags(IPluginContext *pContext, const cell_t *params) -{ - IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]); - if (player == NULL) - { - return pContext->ThrowNativeError("Client index %d is invalid", params[1]); - } - else if (!player->IsConnected()) - { - return pContext->ThrowNativeError("Client %d is not connected", params[1]); - } - - return g_VoiceFlags[params[1]]; -} - -static cell_t SetClientListening(IPluginContext *pContext, const cell_t *params) -{ - int r, s; - IGamePlayer *player; - - player = playerhelpers->GetGamePlayer(params[1]); - if (player == NULL) - { - return pContext->ThrowNativeError("(Receiver) client index %d is invalid", params[1]); - } - else if (!player->IsConnected()) - { - return pContext->ThrowNativeError("(Receiver) client %d is not connected", params[1]); - } - - player = playerhelpers->GetGamePlayer(params[2]); - if (player == NULL) - { - return pContext->ThrowNativeError("(Sender) client index %d is invalid", params[2]); - } - else if (!player->IsConnected()) - { - return pContext->ThrowNativeError("(Sender) client %d is not connected", params[2]); - } - - r = params[1]; - s = params[2]; - - if (g_VoiceMap[r][s] == LISTEN_DEFAULT && params[3] != LISTEN_DEFAULT) - { - g_VoiceMap[r][s] = params[3]; - g_VoiceMap[r][0]++; - IncHookCount(); - } - else if (g_VoiceMap[r][s] != LISTEN_DEFAULT && params[3] == LISTEN_DEFAULT) - { - g_VoiceMap[r][s] = params[3]; - g_VoiceMap[r][0]--; - DecHookCount(); - } - else - { - g_VoiceMap[r][s] = params[3]; - } - - return 1; -} - -static cell_t GetClientListening(IPluginContext *pContext, const cell_t *params) -{ - IGamePlayer *player; - - player = playerhelpers->GetGamePlayer(params[1]); - if (player == NULL) - { - return pContext->ThrowNativeError("(Receiver) client index %d is invalid", params[1]); - } - else if (!player->IsConnected()) - { - return pContext->ThrowNativeError("(Receiver) client %d is not connected", params[1]); - } - - player = playerhelpers->GetGamePlayer(params[2]); - if (player == NULL) - { - return pContext->ThrowNativeError("(Sender) client index %d is invalid", params[2]); - } - else if (!player->IsConnected()) - { - return pContext->ThrowNativeError("(Sender) client %d is not connected", params[2]); - } - - return g_VoiceMap[params[1]][params[2]]; -} - -sp_nativeinfo_t g_VoiceNatives[] = -{ - {"SetClientListeningFlags", SetClientListeningFlags}, - {"GetClientListeningFlags", GetClientListeningFlags}, - {"SetClientListening", SetClientListening}, - {"GetClientListening", GetClientListening}, - {NULL, NULL}, -}; diff --git a/extensions/sdktools/vsound.cpp b/extensions/sdktools/vsound.cpp deleted file mode 100644 index 224d5c50..00000000 --- a/extensions/sdktools/vsound.cpp +++ /dev/null @@ -1,789 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "vsound.h" -#include - -SH_DECL_HOOK8_void(IVEngineServer, EmitAmbientSound, SH_NOATTRIB, 0, int, const Vector &, const char *, float, soundlevel_t, int, int, float); -SH_DECL_HOOK14_void(IEngineSound, EmitSound, SH_NOATTRIB, 0, IRecipientFilter &, int, int, const char *, float, float, int, int, const Vector *, const Vector *, CUtlVector *, bool, float, int); -SH_DECL_HOOK14_void(IEngineSound, EmitSound, SH_NOATTRIB, 1, IRecipientFilter &, int, int, const char *, float, soundlevel_t, int, int, const Vector *, const Vector *, CUtlVector *, bool, float, int); - -bool g_InSoundHook = false; - -/*************************** -* * -* Sound Related Hook Class * -* * -****************************/ - -size_t SoundHooks::_FillInPlayers(int *pl_array, IRecipientFilter *pFilter) -{ - size_t size = static_cast(pFilter->GetRecipientCount()); - - for (size_t i=0; iGetRecipientIndex(i); - } - - return size; -} - -void SoundHooks::_IncRefCounter(int type) -{ - if (type == NORMAL_SOUND_HOOK) - { - if (m_NormalCount++ == 0) - { - SH_ADD_HOOK_MEMFUNC(IEngineSound, EmitSound, engsound, this, &SoundHooks::OnEmitSound, false); - SH_ADD_HOOK_MEMFUNC(IEngineSound, EmitSound, engsound, this, &SoundHooks::OnEmitSound2, false); - } - } - else if (type == AMBIENT_SOUND_HOOK) - { - if (m_AmbientCount++ == 0) - { - SH_ADD_HOOK_MEMFUNC(IVEngineServer, EmitAmbientSound, engine, this, &SoundHooks::OnEmitAmbientSound, false); - } - } -} - -void SoundHooks::_DecRefCounter(int type) -{ - if (type == NORMAL_SOUND_HOOK) - { - if (--m_NormalCount == 0) - { - SH_REMOVE_HOOK_MEMFUNC(IEngineSound, EmitSound, engsound, this, &SoundHooks::OnEmitSound, false); - SH_REMOVE_HOOK_MEMFUNC(IEngineSound, EmitSound, engsound, this, &SoundHooks::OnEmitSound2, false); - } - } - else if (type == AMBIENT_SOUND_HOOK) - { - if (--m_AmbientCount == 0) - { - SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, EmitAmbientSound, engine, this, &SoundHooks::OnEmitAmbientSound, false); - } - } -} - -void SoundHooks::Initialize() -{ - plsys->AddPluginsListener(this); -} - -void SoundHooks::Shutdown() -{ - plsys->RemovePluginsListener(this); - if (m_NormalCount) - { - SH_REMOVE_HOOK_MEMFUNC(IEngineSound, EmitSound, engsound, this, &SoundHooks::OnEmitSound, false); - SH_REMOVE_HOOK_MEMFUNC(IEngineSound, EmitSound, engsound, this, &SoundHooks::OnEmitSound2, false); - } - if (m_AmbientCount) - { - SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, EmitAmbientSound, engine, this, &SoundHooks::OnEmitAmbientSound, false); - } -} - -void SoundHooks::OnPluginUnloaded(IPlugin *plugin) -{ - SoundHookIter iter; - IPluginContext *pContext = plugin->GetBaseContext(); - - if (m_AmbientCount) - { - for (iter=m_AmbientFuncs.begin(); iter!=m_AmbientFuncs.end(); ) - { - if ((*iter)->GetParentContext() == pContext) - { - iter = m_AmbientFuncs.erase(iter); - _DecRefCounter(AMBIENT_SOUND_HOOK); - } - else - { - iter++; - } - } - } - if (m_NormalCount) - { - for (iter=m_NormalFuncs.begin(); iter!=m_NormalFuncs.end(); ) - { - if ((*iter)->GetParentContext() == pContext) - { - iter = m_NormalFuncs.erase(iter); - _DecRefCounter(NORMAL_SOUND_HOOK); - } - else - { - iter++; - } - } - } -} - -void SoundHooks::AddHook(int type, IPluginFunction *pFunc) -{ - if (type == NORMAL_SOUND_HOOK) - { - m_NormalFuncs.push_back(pFunc); - _IncRefCounter(NORMAL_SOUND_HOOK); - } - else if (type == AMBIENT_SOUND_HOOK) - { - m_AmbientFuncs.push_back(pFunc); - _IncRefCounter(AMBIENT_SOUND_HOOK); - } -} - -bool SoundHooks::RemoveHook(int type, IPluginFunction *pFunc) -{ - SoundHookIter iter; - if (type == NORMAL_SOUND_HOOK) - { - if ((iter=m_NormalFuncs.find(pFunc)) != m_NormalFuncs.end()) - { - m_NormalFuncs.erase(iter); - _DecRefCounter(NORMAL_SOUND_HOOK); - return true; - } - else - { - return false; - } - } - else if (type == AMBIENT_SOUND_HOOK) - { - if ((iter=m_AmbientFuncs.find(pFunc)) != m_AmbientFuncs.end()) - { - m_AmbientFuncs.erase(iter); - _DecRefCounter(AMBIENT_SOUND_HOOK); - return true; - } - else - { - return false; - } - } - - return false; -} - -void SoundHooks::OnEmitAmbientSound(int entindex, const Vector &pos, const char *samp, float vol, - soundlevel_t soundlevel, int fFlags, int pitch, float delay) -{ - SoundHookIter iter; - IPluginFunction *pFunc; - cell_t vec[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)}; - cell_t res = static_cast(Pl_Continue); - char buffer[PLATFORM_MAX_PATH]; - strcpy(buffer, samp); - - for (iter=m_AmbientFuncs.begin(); iter!=m_AmbientFuncs.end(); iter++) - { - pFunc = (*iter); - pFunc->PushStringEx(buffer, sizeof(buffer), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); - pFunc->PushCellByRef(&entindex); - pFunc->PushFloatByRef(&vol); - pFunc->PushCellByRef(reinterpret_cast(&soundlevel)); - pFunc->PushCellByRef(&pitch); - pFunc->PushArray(vec, 3, SM_PARAM_COPYBACK); - pFunc->PushCellByRef(&fFlags); - pFunc->PushFloatByRef(&delay); - g_InSoundHook = true; - pFunc->Execute(&res); - g_InSoundHook = false; - - switch (res) - { - case Pl_Handled: - case Pl_Stop: - { - RETURN_META(MRES_SUPERCEDE); - } - case Pl_Changed: - { - Vector vec2; - vec2.x = sp_ctof(vec[0]); - vec2.y = sp_ctof(vec[1]); - vec2.z = sp_ctof(vec[2]); - RETURN_META_NEWPARAMS(MRES_IGNORED, &IVEngineServer::EmitAmbientSound, - (entindex, vec2, buffer, vol, soundlevel, fFlags, pitch, delay)); - } - } - } -} - -void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample, - float flVolume, soundlevel_t iSoundlevel, int iFlags, int iPitch, const Vector *pOrigin, - const Vector *pDirection, CUtlVector *pUtlVecOrigins, bool bUpdatePositions, - float soundtime, int speakerentity) -{ - SoundHookIter iter; - IPluginFunction *pFunc; - cell_t res = static_cast(Pl_Continue); - char buffer[PLATFORM_MAX_PATH]; - strcpy(buffer, pSample); - - for (iter=m_NormalFuncs.begin(); iter!=m_NormalFuncs.end(); iter++) - { - int players[64], size; - size = _FillInPlayers(players, &filter); - pFunc = (*iter); - - pFunc->PushArray(players, 64, SM_PARAM_COPYBACK); - pFunc->PushCellByRef(&size); - pFunc->PushStringEx(buffer, sizeof(buffer), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); - pFunc->PushCellByRef(&iEntIndex); - pFunc->PushCellByRef(&iChannel); - pFunc->PushFloatByRef(&flVolume); - pFunc->PushCellByRef(reinterpret_cast(&iSoundlevel)); - pFunc->PushCellByRef(&iPitch); - pFunc->PushCellByRef(&iFlags); - g_InSoundHook = true; - pFunc->Execute(&res); - g_InSoundHook = false; - - switch (res) - { - case Pl_Handled: - case Pl_Stop: - { - RETURN_META(MRES_SUPERCEDE); - } - case Pl_Changed: - { - CellRecipientFilter crf; - crf.Initialize(players, size); - RETURN_META_NEWPARAMS( - MRES_IGNORED, - static_cast *, bool, float, int)>(&IEngineSound::EmitSound), - (crf, iEntIndex, iChannel, buffer, flVolume, iSoundlevel, iFlags, iPitch, pOrigin, - pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity) - ); - } - } - } -} - -void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample, - float flVolume, float flAttenuation, int iFlags, int iPitch, const Vector *pOrigin, - const Vector *pDirection, CUtlVector *pUtlVecOrigins, bool bUpdatePositions, - float soundtime, int speakerentity) -{ - SoundHookIter iter; - IPluginFunction *pFunc; - cell_t res = static_cast(Pl_Continue); - cell_t sndlevel = static_cast(ATTN_TO_SNDLVL(flAttenuation)); - char buffer[PLATFORM_MAX_PATH]; - strcpy(buffer, pSample); - - for (iter=m_NormalFuncs.begin(); iter!=m_NormalFuncs.end(); iter++) - { - int players[64], size; - size = _FillInPlayers(players, &filter); - pFunc = (*iter); - - pFunc->PushArray(players, 64, SM_PARAM_COPYBACK); - pFunc->PushCellByRef(&size); - pFunc->PushStringEx(buffer, sizeof(buffer), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); - pFunc->PushCellByRef(&iEntIndex); - pFunc->PushCellByRef(&iChannel); - pFunc->PushFloatByRef(&flVolume); - pFunc->PushCellByRef(&sndlevel); - pFunc->PushCellByRef(&iPitch); - pFunc->PushCellByRef(&iFlags); - g_InSoundHook = true; - pFunc->Execute(&res); - g_InSoundHook = false; - - switch (res) - { - case Pl_Handled: - case Pl_Stop: - { - RETURN_META(MRES_SUPERCEDE); - } - case Pl_Changed: - { - CellRecipientFilter crf; - crf.Initialize(players, size); - RETURN_META_NEWPARAMS( - MRES_IGNORED, - static_cast *, bool, float, int)>(&IEngineSound::EmitSound), - (crf, iEntIndex, iChannel, buffer, flVolume, SNDLVL_TO_ATTN(static_cast(sndlevel)), - iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity) - ); - } - } - } -} - -/************************ -* * -* Sound Related Natives * -* * -*************************/ - -SoundHooks s_SoundHooks; - -static cell_t PrefetchSound(IPluginContext *pContext, const cell_t *params) -{ - char *name; - pContext->LocalToString(params[1], &name); - - engsound->PrefetchSound(name); - - return 1; -} - -static cell_t GetSoundDuration(IPluginContext *pContext, const cell_t *params) -{ - char *name; - pContext->LocalToString(params[1], &name); - - return sp_ftoc(engsound->GetSoundDuration(name)); -} - -static cell_t EmitAmbientSound(IPluginContext *pContext, const cell_t *params) -{ - cell_t entity; - Vector pos; - char *name; - float vol, delay; - int pitch, flags, level; - - entity = params[3]; - - cell_t *addr; - pContext->LocalToPhysAddr(params[2], &addr); - pos.x = sp_ctof(addr[0]); - pos.y = sp_ctof(addr[1]); - pos.z = sp_ctof(addr[2]); - - pContext->LocalToString(params[1], &name); - - vol = sp_ctof(params[6]); - level = params[4]; - flags = params[5]; - pitch = params[7]; - delay = sp_ctof(params[8]); - - if (g_InSoundHook) - { - ENGINE_CALL(EmitAmbientSound)(entity, pos, name, vol, (soundlevel_t)level, flags, pitch, delay); - } - else - { - engine->EmitAmbientSound(entity, pos, name, vol, (soundlevel_t)level, flags, pitch, delay); - } - - return 1; -} - -static cell_t FadeClientVolume(IPluginContext *pContext, const cell_t *params) -{ - int client = params[1]; - if (client < 1 || client > playerhelpers->GetMaxClients()) - { - return pContext->ThrowNativeError("Client index %d is not valid", client); - } - - IGamePlayer *player = playerhelpers->GetGamePlayer(client); - if (!player->IsInGame()) - { - return pContext->ThrowNativeError("Client index %d is not in game", client); - } - - engine->FadeClientVolume(player->GetEdict(), - sp_ctof(params[2]), - sp_ctof(params[3]), - sp_ctof(params[4]), - sp_ctof(params[5])); - - return 1; -} - -static cell_t StopSound(IPluginContext *pContext, const cell_t *params) -{ - int entity = params[1]; - int channel = params[2]; - - char *name; - pContext->LocalToString(params[3], &name); - - engsound->StopSound(entity, channel, name); - - return 1; -} - -static cell_t EmitSound(IPluginContext *pContext, const cell_t *params) -{ - cell_t *addr, *cl_array; - CellRecipientFilter crf; - unsigned int numClients; - int client; - IGamePlayer *pPlayer = NULL; - - pContext->LocalToPhysAddr(params[1], &cl_array); - numClients = params[2]; - - /* Client validation */ - for (unsigned int i = 0; i < numClients; i++) - { - client = cl_array[i]; - pPlayer = playerhelpers->GetGamePlayer(client); - - if (!pPlayer) - { - return pContext->ThrowNativeError("Client index %d is invalid", client); - } else if (!pPlayer->IsInGame()) { - return pContext->ThrowNativeError("Client %d is not connected", client); - } - } - - crf.Initialize(cl_array, numClients); - - char *sample; - pContext->LocalToString(params[3], &sample); - - int entity = params[4]; - int channel = params[5]; - int level = params[6]; - int flags = params[7]; - float vol = sp_ctof(params[8]); - int pitch = params[9]; - int speakerentity = params[10]; - - Vector *pOrigin = NULL, origin; - Vector *pDir = NULL, dir; - - pContext->LocalToPhysAddr(params[11], &addr); - if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) - { - pOrigin = &origin; - origin.x = sp_ctof(addr[0]); - origin.y = sp_ctof(addr[1]); - origin.z = sp_ctof(addr[2]); - } - - pContext->LocalToPhysAddr(params[12], &addr); - if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) - { - pDir = &dir; - dir.x = sp_ctof(addr[0]); - dir.y = sp_ctof(addr[1]); - dir.z = sp_ctof(addr[2]); - } - - bool updatePos = params[13] ? true : false; - float soundtime = sp_ctof(params[14]); - - CUtlVector *pOrigVec = NULL; - CUtlVector origvec; - if (params[0] > 14) - { - pOrigVec = &origvec; - for (cell_t i = 15; i <= params[0]; i++) - { - Vector vec; - pContext->LocalToPhysAddr(params[i], &addr); - vec.x = sp_ctof(addr[0]); - vec.y = sp_ctof(addr[1]); - vec.z = sp_ctof(addr[2]); - origvec.AddToTail(vec); - } - } - - /* If we're going to a "local player" and this is a dedicated server, - * intelligently redirect each sound. - */ - - if (entity == -2 && engine->IsDedicatedServer()) - { - for (unsigned int i = 0; i < numClients; i++) - { - cell_t player[1]; - player[0] = cl_array[i]; - crf.Reset(); - crf.Initialize(player, 1); - if (g_InSoundHook) - { - SH_CALL(enginesoundPatch, - static_cast *, bool, float, int)> - (&IEngineSound::EmitSound)) - (crf, - player[0], - channel, - sample, - vol, - (soundlevel_t)level, - flags, - pitch, - pOrigin, - pDir, - pOrigVec, - updatePos, - soundtime, - speakerentity); - } - else - { - engsound->EmitSound(crf, - player[0], - channel, - sample, - vol, - (soundlevel_t)level, - flags, - pitch, - pOrigin, - pDir, - pOrigVec, - updatePos, - soundtime, - speakerentity); - } - } - } else { - if (g_InSoundHook) - { - SH_CALL(enginesoundPatch, - static_cast *, bool, float, int)> - (&IEngineSound::EmitSound)) - (crf, - entity, - channel, - sample, - vol, - (soundlevel_t)level, - flags, - pitch, - pOrigin, - pDir, - pOrigVec, - updatePos, - soundtime, - speakerentity); - } - else - { - engsound->EmitSound(crf, - entity, - channel, - sample, - vol, - (soundlevel_t)level, - flags, - pitch, - pOrigin, - pDir, - pOrigVec, - updatePos, - soundtime, - speakerentity); - } - } - - return 1; -} - -static cell_t EmitSentence(IPluginContext *pContext, const cell_t *params) -{ - cell_t *addr; - CellRecipientFilter crf; - unsigned int numClients; - int client; - IGamePlayer *pPlayer = NULL; - - pContext->LocalToPhysAddr(params[1], &addr); - numClients = params[2]; - - /* Client validation */ - for (unsigned int i = 0; i < numClients; i++) - { - client = addr[i]; - pPlayer = playerhelpers->GetGamePlayer(client); - - if (!pPlayer) - { - return pContext->ThrowNativeError("Client index %d is invalid", client); - } else if (!pPlayer->IsInGame()) { - return pContext->ThrowNativeError("Client %d is not connected", client); - } - } - - crf.Initialize(addr, numClients); - - int sentence = params[3]; - int entity = params[4]; - int channel = params[5]; - int level = params[6]; - int flags = params[7]; - float vol = sp_ctof(params[8]); - int pitch = params[9]; - int speakerentity = params[10]; - - Vector *pOrigin = NULL, origin; - Vector *pDir = NULL, dir; - - pContext->LocalToPhysAddr(params[11], &addr); - if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) - { - pOrigin = &origin; - origin.x = sp_ctof(addr[0]); - origin.y = sp_ctof(addr[1]); - origin.z = sp_ctof(addr[2]); - } - - pContext->LocalToPhysAddr(params[12], &addr); - if (addr != pContext->GetNullRef(SP_NULL_VECTOR)) - { - pDir = &dir; - dir.x = sp_ctof(addr[0]); - dir.y = sp_ctof(addr[1]); - dir.z = sp_ctof(addr[2]); - } - - bool updatePos = params[13] ? true : false; - float soundtime = sp_ctof(params[14]); - - CUtlVector *pOrigVec = NULL; - CUtlVector origvec; - if (params[0] > 14) - { - pOrigVec = &origvec; - for (cell_t i = 15; i <= params[0]; i++) - { - Vector vec; - pContext->LocalToPhysAddr(params[i], &addr); - vec.x = sp_ctof(addr[0]); - vec.y = sp_ctof(addr[1]); - vec.z = sp_ctof(addr[2]); - origvec.AddToTail(vec); - } - } - - engsound->EmitSentenceByIndex(crf, - entity, - channel, - sentence, - vol, - (soundlevel_t)level, - flags, - pitch, - pOrigin, - pDir, - pOrigVec, - updatePos, - soundtime, - speakerentity); - - return 1; -} - -static cell_t smn_AddAmbientSoundHook(IPluginContext *pContext, const cell_t *params) -{ - IPluginFunction *pFunc = pContext->GetFunctionById(params[1]); - if (!pFunc) - { - return pContext->ThrowNativeError("Invalid function id (%X)", params[1]); - } - - s_SoundHooks.AddHook(AMBIENT_SOUND_HOOK, pFunc); - - return 1; -} - -static cell_t smn_AddNormalSoundHook(IPluginContext *pContext, const cell_t *params) -{ - IPluginFunction *pFunc = pContext->GetFunctionById(params[1]); - if (!pFunc) - { - return pContext->ThrowNativeError("Invalid function id (%X)", params[1]); - } - - s_SoundHooks.AddHook(NORMAL_SOUND_HOOK, pFunc); - - return 1; -} - -static cell_t smn_RemoveAmbientSoundHook(IPluginContext *pContext, const cell_t *params) -{ - IPluginFunction *pFunc = pContext->GetFunctionById(params[1]); - if (!pFunc) - { - return pContext->ThrowNativeError("Invalid function id (%X)", params[1]); - } - - if (!s_SoundHooks.RemoveHook(AMBIENT_SOUND_HOOK, pFunc)) - { - return pContext->ThrowNativeError("Invalid hooked function"); - } - - return 1; -} - -static cell_t smn_RemoveNormalSoundHook(IPluginContext *pContext, const cell_t *params) -{ - IPluginFunction *pFunc = pContext->GetFunctionById(params[1]); - if (!pFunc) - { - return pContext->ThrowNativeError("Invalid function id (%X)", params[1]); - } - - if (!s_SoundHooks.RemoveHook(NORMAL_SOUND_HOOK, pFunc)) - { - return pContext->ThrowNativeError("Invalid hooked function"); - } - - return 1; -} - -sp_nativeinfo_t g_SoundNatives[] = -{ - {"EmitAmbientSound", EmitAmbientSound}, - {"EmitSentence", EmitSentence}, - {"EmitSound", EmitSound}, - {"FadeClientVolume", FadeClientVolume}, - {"GetSoundDuration", GetSoundDuration}, - {"PrefetchSound", PrefetchSound}, - {"StopSound", StopSound}, - {"AddAmbientSoundHook", smn_AddAmbientSoundHook}, - {"AddNormalSoundHook", smn_AddNormalSoundHook}, - {"RemoveAmbientSoundHook", smn_RemoveAmbientSoundHook}, - {"RemoveNormalSoundHook", smn_RemoveNormalSoundHook}, - {NULL, NULL}, -}; diff --git a/extensions/sdktools/vsound.h b/extensions/sdktools/vsound.h deleted file mode 100644 index 0536b558..00000000 --- a/extensions/sdktools/vsound.h +++ /dev/null @@ -1,76 +0,0 @@ -/** -* vim: set ts=4 : -* ============================================================================= -* SourceMod SDKTools Extension -* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. -* ============================================================================= -* -* This program is free software; you can redistribute it and/or modify it under -* the terms of the GNU General Public License, version 3.0, as published by the -* Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -* details. -* -* You should have received a copy of the GNU General Public License along with -* this program. If not, see . -* -* As a special exception, AlliedModders LLC gives you permission to link the -* code of this program (as well as its derivative works) to "Half-Life 2," the -* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software -* by the Valve Corporation. You must obey the GNU General Public License in -* all respects for all other code used. Additionally, AlliedModders LLC grants -* this exception to all derivative works. AlliedModders LLC defines further -* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), -* or . -* -* Version: $Id$ -*/ - -#ifndef _INCLUDE_SOURCEMOD_VSOUND_H_ -#define _INCLUDE_SOURCEMOD_VSOUND_H_ - -#include -#include "extension.h" -#include "CellRecipientFilter.h" - -#define NORMAL_SOUND_HOOK 0 -#define AMBIENT_SOUND_HOOK 1 - -typedef SourceHook::List::iterator SoundHookIter; - -class SoundHooks : public IPluginsListener -{ -public: //IPluginsListener - void OnPluginUnloaded(IPlugin *plugin); -public: - void Initialize(); - void Shutdown(); - void AddHook(int type, IPluginFunction *pFunc); - bool RemoveHook(int type, IPluginFunction *pFunc); - void OnEmitAmbientSound(int entindex, const Vector &pos, const char *samp, float vol, - soundlevel_t soundlevel, int fFlags, int pitch, float delay); - void OnEmitSound(IRecipientFilter& filter, int iEntIndex, int iChannel, const char *pSample, float flVolume, - soundlevel_t iSoundlevel, int iFlags, int iPitch, const Vector *pOrigin, - const Vector *pDirection, CUtlVector *pUtlVecOrigins, bool bUpdatePositions, - float soundtime, int speakerentity); - void OnEmitSound2(IRecipientFilter& filter, int iEntIndex, int iChannel, const char *pSample, float flVolume, - float flAttenuation, int iFlags, int iPitch, const Vector *pOrigin, - const Vector *pDirection, CUtlVector *pUtlVecOrigins, bool bUpdatePositions, - float soundtime, int speakerentity); -private: - size_t _FillInPlayers(int *pl_array, IRecipientFilter *pFilter); - void _IncRefCounter(int type); - void _DecRefCounter(int type); -private: - SourceHook::List m_AmbientFuncs; - SourceHook::List m_NormalFuncs; - size_t m_NormalCount; - size_t m_AmbientCount; -}; - -extern SoundHooks s_SoundHooks; - -#endif //_INCLUDE_SOURCEMOD_VSOUND_H_ diff --git a/extensions/sdktools/vstringtable.cpp b/extensions/sdktools/vstringtable.cpp deleted file mode 100644 index 522e4e47..00000000 --- a/extensions/sdktools/vstringtable.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SDKTools Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "extension.h" - -static cell_t LockStringTables(IPluginContext *pContext, const cell_t *params) -{ - bool lock = params[1] ? true : false; - - return engine->LockNetworkStringTables(lock) ? 1 : 0; -} - -static cell_t FindStringTable(IPluginContext *pContext, const cell_t *params) -{ - char *name; - pContext->LocalToString(params[1], &name); - - INetworkStringTable *pTable = netstringtables->FindTable(name); - - if (!pTable) - { - return INVALID_STRING_TABLE; - } - - return pTable->GetTableId(); -} - -static cell_t GetNumStringTables(IPluginContext *pContext, const cell_t *params) -{ - return netstringtables->GetNumTables(); -} - -static cell_t GetStringTableNumStrings(IPluginContext *pContext, const cell_t *params) -{ - TABLEID idx = static_cast(params[1]); - INetworkStringTable *pTable = netstringtables->GetTable(idx); - - if (!pTable) - { - return pContext->ThrowNativeError("Invalid string table index %d", idx); - } - - return pTable->GetNumStrings(); -} - -static cell_t GetStringTableMaxStrings(IPluginContext *pContext, const cell_t *params) -{ - TABLEID idx = static_cast(params[1]); - INetworkStringTable *pTable = netstringtables->GetTable(idx); - - if (!pTable) - { - return pContext->ThrowNativeError("Invalid string table index %d", idx); - } - - return pTable->GetMaxStrings(); -} - -static cell_t GetStringTableName(IPluginContext *pContext, const cell_t *params) -{ - TABLEID idx = static_cast(params[1]); - INetworkStringTable *pTable = netstringtables->GetTable(idx); - size_t numBytes; - - if (!pTable) - { - return pContext->ThrowNativeError("Invalid string table index %d", idx); - } - - pContext->StringToLocalUTF8(params[2], params[3], pTable->GetTableName(), &numBytes); - - return numBytes; -} - -static cell_t FindStringIndex(IPluginContext *pContext, const cell_t *params) -{ - TABLEID idx = static_cast(params[1]); - INetworkStringTable *pTable = netstringtables->GetTable(idx); - char *str; - - if (!pTable) - { - return pContext->ThrowNativeError("Invalid string table index %d", idx); - } - - pContext->LocalToString(params[2], &str); - - return pTable->FindStringIndex(str); -} - -static cell_t ReadStringTable(IPluginContext *pContext, const cell_t *params) -{ - TABLEID idx = static_cast(params[1]); - INetworkStringTable *pTable = netstringtables->GetTable(idx); - int stringidx; - const char *value; - size_t numBytes; - - if (!pTable) - { - return pContext->ThrowNativeError("Invalid string table index %d", idx); - } - - stringidx = params[2]; - value = pTable->GetString(stringidx); - - if (!value) - { - return pContext->ThrowNativeError("Invalid string index specified for table (index %d) (table \"%s\")", stringidx, pTable->GetTableName()); - } - - pContext->StringToLocalUTF8(params[3], params[4], value, &numBytes); - - return numBytes; -} - -static cell_t GetStringTableDataLength(IPluginContext *pContext, const cell_t *params) -{ - TABLEID idx = static_cast(params[1]); - INetworkStringTable *pTable = netstringtables->GetTable(idx); - int stringidx; - const void *userdata; - int datalen; - - if (!pTable) - { - return pContext->ThrowNativeError("Invalid string table index %d", idx); - } - - stringidx = params[2]; - if (stringidx < 0 || stringidx >= pTable->GetNumStrings()) - { - return pContext->ThrowNativeError("Invalid string index specified for table (index %d) (table \"%s\")", stringidx, pTable->GetTableName()); - } - - userdata = pTable->GetStringUserData(stringidx, &datalen); - if (!userdata) - { - datalen = 0; - } - - return datalen; -} - -static cell_t GetStringTableData(IPluginContext *pContext, const cell_t *params) -{ - TABLEID idx = static_cast(params[1]); - INetworkStringTable *pTable = netstringtables->GetTable(idx); - int stringidx; - const char *userdata; - int datalen; - size_t numBytes; - - if (!pTable) - { - return pContext->ThrowNativeError("Invalid string table index %d", idx); - } - - stringidx = params[2]; - if (stringidx < 0 || stringidx >= pTable->GetNumStrings()) - { - return pContext->ThrowNativeError("Invalid string index specified for table (index %d) (table \"%s\")", stringidx, pTable->GetTableName()); - } - - userdata = (const char *)pTable->GetStringUserData(stringidx, &datalen); - if (!userdata) - { - userdata = ""; - } - - pContext->StringToLocalUTF8(params[3], params[4], userdata, &numBytes); - - return numBytes; -} - -static cell_t SetStringTableData(IPluginContext *pContext, const cell_t *params) -{ - TABLEID idx = static_cast(params[1]); - INetworkStringTable *pTable = netstringtables->GetTable(idx); - int stringidx; - char *userdata; - - if (!pTable) - { - return pContext->ThrowNativeError("Invalid string table index %d", idx); - } - - stringidx = params[2]; - if (stringidx < 0 || stringidx >= pTable->GetNumStrings()) - { - return pContext->ThrowNativeError("Invalid string index specified for table (index %d) (table \"%s\")", stringidx, pTable->GetTableName()); - } - - pContext->LocalToString(params[3], &userdata); - pTable->SetStringUserData(stringidx, params[4], userdata); - - return 1; -} - -static cell_t AddToStringTable(IPluginContext *pContext, const cell_t *params) -{ - TABLEID idx = static_cast(params[1]); - INetworkStringTable *pTable = netstringtables->GetTable(idx); - char *str, *userdata; - - if (!pTable) - { - return pContext->ThrowNativeError("Invalid string table index %d", idx); - } - - pContext->LocalToString(params[2], &str); - pContext->LocalToString(params[3], &userdata); - -#if defined ORANGEBOX_BUILD - pTable->AddString(true, str, params[4], userdata); -#else - pTable->AddString(str, params[4], userdata); -#endif - - return 1; -} - -sp_nativeinfo_t g_StringTableNatives[] = -{ - {"LockStringTables", LockStringTables}, - {"FindStringTable", FindStringTable}, - {"GetNumStringTables", GetNumStringTables}, - {"GetStringTableNumStrings", GetStringTableNumStrings}, - {"GetStringTableMaxStrings", GetStringTableMaxStrings}, - {"GetStringTableName", GetStringTableName}, - {"FindStringIndex", FindStringIndex}, - {"ReadStringTable", ReadStringTable}, - {"GetStringTableDataLength", GetStringTableDataLength}, - {"GetStringTableData", GetStringTableData}, - {"SetStringTableData", SetStringTableData}, - {"AddToStringTable", AddToStringTable}, - {NULL, NULL}, -}; diff --git a/extensions/sqlite/Makefile b/extensions/sqlite/Makefile deleted file mode 100644 index 90e4f810..00000000 --- a/extensions/sqlite/Makefile +++ /dev/null @@ -1,155 +0,0 @@ -# (C)2004-2008 SourceMod Development Team -# Makefile written by David "BAILOPAN" Anderson - -SMSDK = ../.. -SRCDS_BASE = ~/srcds -HL2SDK_ORIG = ../../../hl2sdk -HL2SDK_OB = ../../../hl2sdk-ob -SOURCEMM14 = ../../../sourcemm-1.4 -SOURCEMM16 = ../../../sourcemm-1.6 - -##################################### -### EDIT BELOW FOR OTHER PROJECTS ### -##################################### - -PROJECT = dbi.sqlite - -#Uncomment for Metamod: Source enabled extension -#USEMETA = true - -OBJECTS = sdk/smsdk_ext.cpp sdk/sm_memtable.cpp extension.cpp \ - driver/SqDatabase.cpp driver/SqDriver.cpp driver/SqQuery.cpp \ - driver/SqResults.cpp - -OBJECTS += sqlite-source/alter.c sqlite-source/analyze.c \ - sqlite-source/attach.c sqlite-source/auth.c sqlite-source/btree.c \ - sqlite-source/build.c sqlite-source/callback.c sqlite-source/complete.c \ - sqlite-source/date.c sqlite-source/delete.c sqlite-source/expr.c \ - sqlite-source/func.c sqlite-source/hash.c sqlite-source/insert.c \ - sqlite-source/legacy.c sqlite-source/main.c sqlite-source/malloc.c \ - sqlite-source/opcodes.c sqlite-source/os.c sqlite-source/os_unix.c \ - sqlite-source/pager.c sqlite-source/parse.c sqlite-source/pragma.c \ - sqlite-source/prepare.c sqlite-source/printf.c sqlite-source/random.c \ - sqlite-source/select.c sqlite-source/table.c sqlite-source/tokenize.c \ - sqlite-source/trigger.c sqlite-source/update.c sqlite-source/utf.c \ - sqlite-source/util.c sqlite-source/vacuum.c sqlite-source/vdbe.c \ - sqlite-source/vdbeapi.c sqlite-source/vdbeaux.c sqlite-source/vdbeblob.c \ - sqlite-source/vdbefifo.c sqlite-source/vdbemem.c sqlite-source/vtab.c \ - sqlite-source/where.c sqlite-source/btmutex.c sqlite-source/journal.c \ - sqlite-source/mem1.c sqlite-source/mem2.c sqlite-source/mutex.c \ - sqlite-source/mutex_unix.c - -############################################## -### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ### -############################################## - -C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing -C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3 -C_GCC4_FLAGS = -fvisibility=hidden -CPP_GCC4_FLAGS = -fvisibility-inlines-hidden -CPP = gcc-4.1 - -override ENGSET = false -ifeq "$(ENGINE)" "original" - HL2SDK = $(HL2SDK_ORIG) - HL2PUB = $(HL2SDK_ORIG)/public - HL2LIB = $(HL2SDK_ORIG)/linux_sdk - METAMOD = $(SOURCEMM14) - INCLUDE += -I$(HL2SDK)/public/dlls - SRCDS = $(SRCDS_BASE) - override ENGSET = true -endif -ifeq "$(ENGINE)" "orangebox" - HL2SDK = $(HL2SDK_OB) - HL2PUB = $(HL2SDK_OB)/public - HL2LIB = $(HL2SDK_OB)/linux_sdk - CFLAGS += -DORANGEBOX_BUILD - METAMOD = $(SOURCEMM16) - INCLUDE += -I$(HL2SDK)/public/game/server - SRCDS = $(SRCDS_BASE)/orangebox - override ENGSET = true -endif - -ifeq "$(USEMETA)" "true" - LINK_HL2 = $(HL2LIB)/tier1_i486.a vstdlib_i486.so tier0_i486.so - - LINK += $(LINK_HL2) - - INCLUDE += -I. -I.. -Isdk -I$(HL2PUB) -I$(HL2PUB)/engine -I$(HL2PUB)/tier0 -I$(HL2PUB)/tier1 \ - -I$(METAMOD) -I$(METAMOD)/sourcehook -I$(METAMOD)/sourcemm -I$(SMSDK)/public \ - -I$(SMSDK)/public/sourcepawn -else - INCLUDE += -I. -I.. -Isdk -I$(SMSDK)/public -I$(SMSDK)/public/sourcepawn -I$(SOURCEMM16)/sourcehook -endif - -LINK += -static-libgcc -lpthread - -CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \ - -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror \ - -Wno-uninitialized -mfpmath=sse -msse -DSOURCEMOD_BUILD -DHAVE_STDINT_H -DSQLITE_THREADSAFE \ - -DSQLITE_OMIT_LOAD_EXTENSION -m32 -CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti - -################################################ -### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ### -################################################ - -ifeq "$(DEBUG)" "true" - BIN_DIR = Debug - CFLAGS += $(C_DEBUG_FLAGS) -else - BIN_DIR = Release - CFLAGS += $(C_OPT_FLAGS) -endif - -ifeq "$(USEMETA)" "true" - BIN_DIR := $(BIN_DIR).$(ENGINE) -endif - -GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1) -ifeq "$(GCC_VERSION)" "4" - CFLAGS += $(C_GCC4_FLAGS) - CPPFLAGS += $(CPP_GCC4_FLAGS) -endif - -BINARY = $(PROJECT).ext.so - -OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) -OBJ_LINUX := $(OBJ_LINUX:%.c=$(BIN_DIR)/%.o) - -$(BIN_DIR)/%.o: %.cpp - $(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< - -$(BIN_DIR)/%.o: %.c - $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $< - -all: check - mkdir -p $(BIN_DIR)/sdk - mkdir -p $(BIN_DIR)/driver - mkdir -p $(BIN_DIR)/sqlite-source - if [ "$(USEMETA)" == "true" ]; then \ - ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so; \ - ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so; \ - fi - $(MAKE) -f Makefile extension - -check: - if [ "$(USEMETA)" == "true" ] && [ "$(ENGSET)" == "false" ]; then \ - echo "You must supply ENGINE=orangebox or ENGINE=original"; \ - exit 1; \ - fi - -extension: check $(OBJ_LINUX) - $(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -shared -ldl -lm -o$(BIN_DIR)/$(BINARY) - -debug: - $(MAKE) -f Makefile all DEBUG=true - -default: all - -clean: check - rm -rf $(BIN_DIR)/*.o - rm -rf $(BIN_DIR)/sdk/*.o - rm -rf $(BIN_DIR)/driver/*.o - rm -rf $(BIN_DIR)/sqlite-source/*.o - rm -rf $(BIN_DIR)/$(BINARY) diff --git a/extensions/sqlite/driver/SqDatabase.cpp b/extensions/sqlite/driver/SqDatabase.cpp deleted file mode 100644 index 07724238..00000000 --- a/extensions/sqlite/driver/SqDatabase.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "extension.h" -#include "SqDatabase.h" -#include "SqQuery.h" - -SqDatabase::SqDatabase(sqlite3 *sq3, bool persistent) : - m_sq3(sq3), m_refcount(1), m_pFullLock(NULL), m_Persistent(persistent) -{ - m_pRefLock = threader->MakeMutex(); -} - -SqDatabase::~SqDatabase() -{ - m_pRefLock->DestroyThis(); - if (m_pFullLock) - { - m_pFullLock->DestroyThis(); - } - sqlite3_close(m_sq3); -} - -void SqDatabase::IncReferenceCount() -{ - m_pRefLock->Lock(); - m_refcount++; - m_pRefLock->Unlock(); -} - -bool SqDatabase::Close() -{ - m_pRefLock->Lock(); - if (m_refcount > 1) - { - m_refcount--; - m_pRefLock->Unlock(); - return false; - } - m_pRefLock->Unlock(); - - if (m_Persistent) - { - g_SqDriver.RemovePersistent(this); - } - - delete this; - - return true; -} - -const char *SqDatabase::GetError(int *errorCode/* =NULL */) -{ - return sqlite3_errmsg(m_sq3); -} - -bool SqDatabase::LockForFullAtomicOperation() -{ - if (!m_pFullLock) - { - m_pFullLock = threader->MakeMutex(); - if (!m_pFullLock) - { - return false; - } - } - - m_pFullLock->Lock(); - - return true; -} - -void SqDatabase::UnlockFromFullAtomicOperation() -{ - if (m_pFullLock) - { - m_pFullLock->Unlock(); - } -} - -IDBDriver *SqDatabase::GetDriver() -{ - return &g_SqDriver; -} - -bool SqDatabase::QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize) -{ - char *res = sqlite3_snprintf(static_cast(maxlen), buffer, "%q", str); - - if (res != NULL && newSize != NULL) - { - *newSize = strlen(buffer); - } - - return (res != NULL); -} - -unsigned int SqDatabase::GetInsertID() -{ - return (unsigned int)sqlite3_last_insert_rowid(m_sq3); -} - -unsigned int SqDatabase::GetAffectedRows() -{ - return (unsigned int)sqlite3_changes(m_sq3); -} - -bool SqDatabase::DoSimpleQuery(const char *query) -{ - IQuery *pQuery = DoQuery(query); - if (!pQuery) - { - return false; - } - pQuery->Destroy(); - return true; -} - -/* this sounds like daiquiri.. i'm tired. */ -IQuery *SqDatabase::DoQuery(const char *query) -{ - IPreparedQuery *pQuery = PrepareQuery(query, NULL, 0, NULL); - if (!pQuery) - { - return NULL; - } - if (!pQuery->Execute()) - { - pQuery->Destroy(); - return NULL; - } - return pQuery; -} - -bool SqDatabase::DoSimpleQueryEx(const char *query, size_t len) -{ - IQuery *pQuery = DoQueryEx(query, len); - if (!pQuery) - { - return false; - } - pQuery->Destroy(); - return true; -} - -IQuery *SqDatabase::DoQueryEx(const char *query, size_t len) -{ - IPreparedQuery *pQuery = PrepareQueryEx(query, len, NULL, 0, NULL); - if (!pQuery) - { - return NULL; - } - if (!pQuery->Execute()) - { - pQuery->Destroy(); - return NULL; - } - return pQuery; -} - -IPreparedQuery *SqDatabase::PrepareQuery(const char *query, - char *error, - size_t maxlength, - int *errCode/* =NULL */) -{ - sqlite3_stmt *stmt = NULL; - if ((m_LastErrorCode = sqlite3_prepare_v2(m_sq3, query, -1, &stmt, NULL)) != SQLITE_OK - || !stmt) - { - const char *msg; - if (m_LastErrorCode != SQLITE_OK) - { - msg = sqlite3_errmsg(m_sq3); - } else { - msg = "Invalid query string"; - m_LastErrorCode = SQLITE_ERROR; - } - if (error) - { - strncopy(error, msg, maxlength); - } - m_LastError.assign(msg); - return NULL; - } - return new SqQuery(this, stmt); -} - -IPreparedQuery *SqDatabase::PrepareQueryEx(const char *query, - size_t len, - char *error, - size_t maxlength, - int *errCode/* =NULL */) -{ - sqlite3_stmt *stmt = NULL; - if ((m_LastErrorCode = sqlite3_prepare_v2(m_sq3, query, len, &stmt, NULL)) != SQLITE_OK - || !stmt) - { - const char *msg; - if (m_LastErrorCode != SQLITE_OK) - { - msg = sqlite3_errmsg(m_sq3); - } else { - msg = "Invalid query string"; - m_LastErrorCode = SQLITE_ERROR; - } - if (error) - { - strncopy(error, msg, maxlength); - } - m_LastError.assign(msg); - return NULL; - } - return new SqQuery(this, stmt); -} - -sqlite3 *SqDatabase::GetDb() -{ - return m_sq3; -} diff --git a/extensions/sqlite/driver/SqDatabase.h b/extensions/sqlite/driver/SqDatabase.h deleted file mode 100644 index 591bdd9d..00000000 --- a/extensions/sqlite/driver/SqDatabase.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SQLITE_SOURCEMOD_DATABASE_H_ -#define _INCLUDE_SQLITE_SOURCEMOD_DATABASE_H_ - -#include -#include "SqDriver.h" - -class SqDatabase : public IDatabase -{ -public: - SqDatabase(sqlite3 *sq3, bool persistent); - ~SqDatabase(); -public: - bool Close(); - const char *GetError(int *errorCode=NULL); - bool DoSimpleQuery(const char *query); - IQuery *DoQuery(const char *query); - IPreparedQuery *PrepareQuery(const char *query, char *error, size_t maxlength, int *errCode=NULL); - IPreparedQuery *PrepareQueryEx(const char *query, size_t len, char *error, size_t maxlength, int *errCode=NULL); - bool QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize); - unsigned int GetAffectedRows(); - unsigned int GetInsertID(); - bool LockForFullAtomicOperation(); - void UnlockFromFullAtomicOperation(); - void IncReferenceCount(); - IDBDriver *GetDriver(); - bool DoSimpleQueryEx(const char *query, size_t len); - IQuery *DoQueryEx(const char *query, size_t len); -public: - sqlite3 *GetDb(); -private: - sqlite3 *m_sq3; - unsigned int m_refcount; - IMutex *m_pFullLock; - IMutex *m_pRefLock; - bool m_Persistent; - String m_LastError; - int m_LastErrorCode; -}; - -#endif //_INCLUDE_SQLITE_SOURCEMOD_DATABASE_H_ diff --git a/extensions/sqlite/driver/SqDriver.cpp b/extensions/sqlite/driver/SqDriver.cpp deleted file mode 100644 index 397fed5b..00000000 --- a/extensions/sqlite/driver/SqDriver.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include "extension.h" -#include "SqDriver.h" -#include "SqDatabase.h" - -SqDriver g_SqDriver; - -unsigned int strncopy(char *dest, const char *src, size_t count) -{ - if (!count) - { - return 0; - } - - char *start = dest; - while ((*src) && (--count)) - { - *dest++ = *src++; - } - *dest = '\0'; - - return (dest - start); -} - -int busy_handler(void *unused1, int unused2) -{ -#if defined PLATFORM_WINDOWS - Sleep(100); -#elif defined PLATFORM_LINUX - usleep(100000); -#endif - return 1; -} - -SqDriver::SqDriver() -{ - m_Handle = BAD_HANDLE; - m_pOpenLock = NULL; - m_bThreadSafe = false; -} - -void SqDriver::Initialize() -{ - m_pOpenLock = threader->MakeMutex(); - - InitializeThreadSafety(); -} - -void SqDriver::Shutdown() -{ - if (m_pOpenLock) - { - m_pOpenLock->DestroyThis(); - } - - if (m_bThreadSafe) - { - sqlite3_enable_shared_cache(0); - } -} - -bool SqDriver::IsThreadSafe() -{ - return true; -} - -bool SqDriver::InitializeThreadSafety() -{ - if (m_bThreadSafe) - { - return true; - } - - if (sqlite3_threadsafe() == 0) - { - return false; - } - - if (sqlite3_enable_shared_cache(1) != SQLITE_OK) - { - return false; - } - - m_bThreadSafe = true; - - return true; -} - -void SqDriver::ShutdownThreadSafety() -{ - return; -} - -IdentityToken_t *SqDriver::GetIdentity() -{ - return myself->GetIdentity(); -} - -const char *SqDriver::GetProductName() -{ - return "SQLite"; -} - -const char *SqDriver::GetIdentifier() -{ - return "sqlite"; -} - -Handle_t SqDriver::GetHandle() -{ - if (m_Handle == BAD_HANDLE) - { - m_Handle = dbi->CreateHandle(DBHandle_Driver, this, myself->GetIdentity()); - } - - return m_Handle; -} - -inline bool IsPathSepChar(char c) -{ -#if defined PLATFORM_WINDOWS - return (c == '\\' || c == '/'); -#elif defined PLATFORM_LINUX - return (c == '/'); -#endif -} - -IDatabase *SqDriver::Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength) -{ - /* We wrap most of the open process in a mutex just to be safe */ - m_pOpenLock->Lock(); - - /* Format our path */ - char path[PLATFORM_MAX_PATH]; - size_t len = libsys->PathFormat(path, sizeof(path), "sqlite/%s", info->database); - - /* Chop any filename off */ - for (size_t i = len-1; - i >= 0 && i <= len-1; - i--) - { - if (IsPathSepChar(path[i])) - { - path[i] = '\0'; - break; - } - } - - /* Test the full path */ - char fullpath[PLATFORM_MAX_PATH]; - g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "data/%s", path); - if (!libsys->IsPathDirectory(fullpath)) - { - /* Make sure the data folder exists */ - len = g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "data"); - if (!libsys->IsPathDirectory(fullpath)) - { - if (!libsys->CreateFolder(fullpath)) - { - strncopy(error, "Could not create or open \"data\" folder\"", maxlength); - m_pOpenLock->Unlock(); - return NULL; - } - } - - /* The data folder exists - create each subdir as needed! */ - char *cur_ptr = path; - - do - { - /* Find the next suitable path */ - char *next_ptr = cur_ptr; - while (*next_ptr != '\0') - { - if (IsPathSepChar(*next_ptr)) - { - *next_ptr = '\0'; - next_ptr++; - break; - } - next_ptr++; - } - if (*next_ptr == '\0') - { - next_ptr = NULL; - } - len += libsys->PathFormat(&fullpath[len], sizeof(fullpath)-len, "/%s", cur_ptr); - if (!libsys->IsPathDirectory(fullpath) && !libsys->CreateFolder(fullpath)) - { - break; - } - cur_ptr = next_ptr; - } while (cur_ptr); - } - - /* Build the FINAL path. */ - g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "data/sqlite/%s.sq3", info->database); - - /* If we're requesting a persistent connection, see if something is already open */ - if (persistent) - { - /* See if anything in the cache matches */ - List::iterator iter; - for (iter = m_Cache.begin(); iter != m_Cache.end(); iter++) - { - if ((*iter).path.compare(fullpath) == 0) - { - (*iter).db->IncReferenceCount(); - m_pOpenLock->Unlock(); - return (*iter).db; - } - } - } - - /* Try to open a new connection */ - sqlite3 *sql; - int err = sqlite3_open(fullpath, &sql); - if (err != SQLITE_OK) - { - strncopy(error, sqlite3_errmsg(sql), maxlength); - sqlite3_close(sql); - m_pOpenLock->Unlock(); - return NULL; - } - - sqlite3_busy_handler(sql, busy_handler, NULL); - - SqDatabase *pdb = new SqDatabase(sql, persistent); - - if (persistent) - { - SqDbInfo pinfo; - pinfo.path = fullpath; - pinfo.db = pdb; - m_Cache.push_back(pinfo); - } - - m_pOpenLock->Unlock(); - - return pdb; -} - -void SqDriver::RemovePersistent(IDatabase *pdb) -{ - List::iterator iter; - for (iter = m_Cache.begin(); iter != m_Cache.end(); iter++) - { - if ((*iter).db == pdb) - { - iter = m_Cache.erase(iter); - return; - } - } -} diff --git a/extensions/sqlite/driver/SqDriver.h b/extensions/sqlite/driver/SqDriver.h deleted file mode 100644 index f73d1092..00000000 --- a/extensions/sqlite/driver/SqDriver.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SQLITE_SOURCEMOD_DRIVER_H_ -#define _INCLUDE_SQLITE_SOURCEMOD_DRIVER_H_ - -#include -#include -#include -#include -#include "sqlite-source/sqlite3.h" - -using namespace SourceMod; -using namespace SourceHook; - -struct SqDbInfo -{ - String path; - IDatabase *db; -}; - -/** - * Tee-hee.. sounds like "screw driver," except maybe if - * Elmer Fudd was saying it. - */ -class SqDriver : public IDBDriver -{ -public: - SqDriver(); - void Initialize(); - void Shutdown(); -public: - IDatabase *Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength); - const char *GetIdentifier(); - const char *GetProductName(); - Handle_t GetHandle(); - IdentityToken_t *GetIdentity(); - bool IsThreadSafe(); - bool InitializeThreadSafety(); - void ShutdownThreadSafety(); -public: - void RemovePersistent(IDatabase *pdb); -private: - Handle_t m_Handle; - IMutex *m_pOpenLock; - List m_Cache; - bool m_bThreadSafe; -}; - -extern SqDriver g_SqDriver; - -unsigned int strncopy(char *dest, const char *src, size_t count); - -#endif //_INCLUDE_SQLITE_SOURCEMOD_DRIVER_H_ diff --git a/extensions/sqlite/driver/SqQuery.cpp b/extensions/sqlite/driver/SqQuery.cpp deleted file mode 100644 index b1753e81..00000000 --- a/extensions/sqlite/driver/SqQuery.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "SqQuery.h" - -SqQuery::SqQuery(SqDatabase *parent, sqlite3_stmt *stmt) : - m_pParent(parent), m_pStmt(stmt), m_pResults(NULL), m_AffectedRows(0), m_InsertID(0) -{ - m_ParamCount = sqlite3_bind_parameter_count(m_pStmt); - m_ColCount = sqlite3_column_count(m_pStmt); - m_pParent->IncReferenceCount(); -} - -SqQuery::~SqQuery() -{ - delete m_pResults; - sqlite3_finalize(m_pStmt); - m_pParent->Close(); -} - -IResultSet *SqQuery::GetResultSet() -{ - return m_pResults; -} - -bool SqQuery::FetchMoreResults() -{ - /* We never have multiple result sets */ - return false; -} - -void SqQuery::Destroy() -{ - delete this; -} - -bool SqQuery::BindParamFloat(unsigned int param, float f) -{ - /* SQLite is 1 indexed */ - param++; - - if (param > m_ParamCount) - { - return false; - } - - return (sqlite3_bind_double(m_pStmt, param, (double)f) == SQLITE_OK); -} - -bool SqQuery::BindParamNull(unsigned int param) -{ - /* SQLite is 1 indexed */ - param++; - - if (param > m_ParamCount) - { - return false; - } - - return (sqlite3_bind_null(m_pStmt, param) == SQLITE_OK); -} - -bool SqQuery::BindParamString(unsigned int param, const char *text, bool copy) -{ - /* SQLite is 1 indexed */ - param++; - - if (param > m_ParamCount) - { - return false; - } - - return (sqlite3_bind_text(m_pStmt, param, text, -1, copy ? SQLITE_TRANSIENT : SQLITE_STATIC) == SQLITE_OK); -} - -bool SqQuery::BindParamInt(unsigned int param, int num, bool signd/* =true */) -{ - /* SQLite is 1 indexed */ - param++; - - if (param > m_ParamCount) - { - return false; - } - - return (sqlite3_bind_int(m_pStmt, param, num) == SQLITE_OK); -} - -bool SqQuery::BindParamBlob(unsigned int param, const void *data, size_t length, bool copy) -{ - /* SQLite is 1 indexed */ - param++; - - if (param > m_ParamCount) - { - return false; - } - - return (sqlite3_bind_blob(m_pStmt, param, data, length, copy ? SQLITE_TRANSIENT : SQLITE_STATIC) == SQLITE_OK); -} - -sqlite3_stmt *SqQuery::GetStmt() -{ - return m_pStmt; -} - -bool SqQuery::Execute() -{ - int rc; - - /* If we don't have a result set and we have a column count, - * create a result set pre-emptively. This is in case there - * are no rows in the upcoming result set. - */ - if (!m_pResults && m_ColCount) - { - m_pResults = new SqResults(this); - } - - /* If we've got results, throw them away */ - if (m_pResults) - { - m_pResults->ResetResultCount(); - } - - /* Fetch each row, if any */ - while ((rc = sqlite3_step(m_pStmt)) == SQLITE_ROW) - { - /* This should NEVER happen but we're being safe. */ - if (!m_pResults) - { - m_pResults = new SqResults(this); - } - m_pResults->PushResult(); - } - - sqlite3 *db = m_pParent->GetDb(); - if (rc != SQLITE_OK && rc != SQLITE_DONE && rc == sqlite3_errcode(db)) - { - /* Something happened... */ - m_LastErrorCode = rc; - m_LastError.assign(sqlite3_errmsg(db)); - m_AffectedRows = 0; - m_InsertID = 0; - } else { - m_LastErrorCode = SQLITE_OK; - m_AffectedRows = (unsigned int)sqlite3_changes(db); - m_InsertID = (unsigned int)sqlite3_last_insert_rowid(db); - } - - /* Reset everything for the next execute */ - sqlite3_reset(m_pStmt); - sqlite3_clear_bindings(m_pStmt); - - return (m_LastErrorCode == SQLITE_OK); -} - -const char *SqQuery::GetError(int *errCode/* =NULL */) -{ - if (errCode) - { - *errCode = m_LastErrorCode; - } - return m_LastError.c_str(); -} - -unsigned int SqQuery::GetAffectedRows() -{ - return m_AffectedRows; -} - -unsigned int SqQuery::GetInsertID() -{ - return m_InsertID; -} - - diff --git a/extensions/sqlite/driver/SqQuery.h b/extensions/sqlite/driver/SqQuery.h deleted file mode 100644 index 16bef53f..00000000 --- a/extensions/sqlite/driver/SqQuery.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SQLITE_SOURCEMOD_QUERY_H_ -#define _INCLUDE_SQLITE_SOURCEMOD_QUERY_H_ - -#include "SqDatabase.h" -#include "SqResults.h" - -class SqQuery : - public IPreparedQuery -{ -public: - SqQuery(SqDatabase *parent, sqlite3_stmt *stmt); - ~SqQuery(); -public: //IQuery - IResultSet *GetResultSet(); - bool FetchMoreResults(); - void Destroy(); -public: //IPreparedQuery - bool BindParamInt(unsigned int param, int num, bool signd=true); - bool BindParamFloat(unsigned int param, float f); - bool BindParamNull(unsigned int param); - bool BindParamString(unsigned int param, const char *text, bool copy); - bool BindParamBlob(unsigned int param, const void *data, size_t length, bool copy); - bool Execute(); - const char *GetError(int *errCode=NULL); - unsigned int GetAffectedRows(); - unsigned int GetInsertID(); -public: //IResultSet - unsigned int GetRowCount(); - unsigned int GetFieldCount(); - const char *FieldNumToName(unsigned int columnId); - bool FieldNameToNum(const char *name, unsigned int *columnId); - bool MoreRows(); - IResultRow *FetchRow(); - IResultRow *CurrentRow(); - bool Rewind(); - DBType GetFieldType(unsigned int field); - DBType GetFieldDataType(unsigned int field); -public: //IResultRow - DBResult GetString(unsigned int columnId, const char **pString, size_t *length); - DBResult CopyString(unsigned int columnId, - char *buffer, - size_t maxlength, - size_t *written); - DBResult GetFloat(unsigned int columnId, float *pFloat); - DBResult GetInt(unsigned int columnId, int *pInt); - bool IsNull(unsigned int columnId); - size_t GetDataSize(unsigned int columnId); - DBResult GetBlob(unsigned int columnId, const void **pData, size_t *length); - DBResult CopyBlob(unsigned int columnId, void *buffer, size_t maxlength, size_t *written); -public: - sqlite3_stmt *GetStmt(); -private: - SqDatabase *m_pParent; - sqlite3_stmt *m_pStmt; - SqResults *m_pResults; - unsigned int m_ParamCount; - String m_LastError; - int m_LastErrorCode; - unsigned int m_AffectedRows; - unsigned int m_InsertID; - unsigned int m_ColCount; -}; - -#endif //_INCLUDE_SQLITE_SOURCEMOD_QUERY_H_ diff --git a/extensions/sqlite/driver/SqResults.cpp b/extensions/sqlite/driver/SqResults.cpp deleted file mode 100644 index 0809ab6a..00000000 --- a/extensions/sqlite/driver/SqResults.cpp +++ /dev/null @@ -1,482 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include "extension.h" -#include "SqResults.h" -#include "SqQuery.h" - -SqResults::SqResults(SqQuery *query) : - m_pStmt(query->GetStmt()), m_Strings(1024), - m_RowCount(0), m_MaxRows(0), m_Rows(NULL), - m_CurRow(0), m_NextRow(0) -{ - m_ColCount = sqlite3_column_count(m_pStmt); - if (m_ColCount) - { - m_ColNames = new String[m_ColCount]; - for (unsigned int i=0; i= m_ColCount) - { - return NULL; - } - - return m_ColNames[columnId].c_str(); -} - -bool SqResults::FieldNameToNum(const char *name, unsigned int *columnId) -{ - for (unsigned int i=0; iReset(); -} - -void SqResults::PushResult() -{ - /* First make sure we can fit one more row */ - if (m_RowCount + 1 > m_MaxRows) - { - /* Create a new array */ - if (!m_Rows) - { - m_MaxRows = 8; - m_Rows = (SqField *)malloc(sizeof(SqField) * m_ColCount * m_MaxRows); - } else { - m_MaxRows *= 2; - m_Rows = (SqField *)realloc(m_Rows, sizeof(SqField) * m_ColCount * m_MaxRows); - } - } - - SqField *row = &m_Rows[m_RowCount * m_ColCount]; - for (unsigned int i=0; iCreateMem(bytes, &pAddr); - memcpy(pAddr, pOrig, bytes); - } else { - row[i].u.idx = -1; - } - row[i].size = sqlite3_column_bytes(m_pStmt, i); - } else if (row[i].type == SQLITE_TEXT) { - const char *str = (const char *)sqlite3_column_text(m_pStmt, i); - if (str) - { - row[i].u.idx = m_Strings.AddString(str); - } else { - row[i].u.idx = -1; - } - row[i].size = sqlite3_column_bytes(m_pStmt, i); - } else { - row[i].size = 0; - } - } - - /* Finally, increase the row count */ - m_RowCount++; -} - -bool SqResults::MoreRows() -{ - return (m_CurRow < m_RowCount); -} - -IResultRow *SqResults::FetchRow() -{ - m_CurRow = m_NextRow; - if (m_CurRow >= m_RowCount) - { - return NULL; - } - m_NextRow++; - return this; -} - -IResultRow *SqResults::CurrentRow() -{ - if (!m_RowCount || m_CurRow >= m_RowCount) - { - return NULL; - } - return this; -} - -bool SqResults::Rewind() -{ - m_CurRow = 0; - m_NextRow = 0; - return true; -} - -SqField *SqResults::GetField(unsigned int col) -{ - if (m_CurRow >= m_RowCount || col >= m_ColCount) - { - return NULL; - } - - return &m_Rows[(m_CurRow * m_ColCount) + col]; -} - -DBType SqResults::GetFieldType(unsigned int field) -{ - /* Leaving unimplemented... */ - return DBType_Unknown; -} - -DBType SqResults::GetFieldDataType(unsigned int field) -{ - /* Leaving unimplemented... */ - return DBType_Unknown; -} - -DBResult SqResults::GetString(unsigned int columnId, const char **pString, size_t *_length) -{ - SqField *field = GetField(columnId); - if (!field) - { - return DBVal_Error; - } - - DBResult res = DBVal_Data; - const char *ptr = NULL; - size_t length = 0; - if (field->type == SQLITE_TEXT || field->type == SQLITE_BLOB) - { - ptr = m_Strings.GetString(field->u.idx); - length = field->size; - } else if (field->type == SQLITE_INTEGER) { - char number[24]; - field->size = UTIL_Format(number, sizeof(number), "%d", field->u.idx); - field->type = SQLITE_TEXT; - field->u.idx = m_Strings.AddString(number); - ptr = m_Strings.GetString(field->u.idx); - length = field->size; - } else if (field->type == SQLITE_FLOAT) { - char number[24]; - field->size = UTIL_Format(number, sizeof(number), "%f", field->u.f); - field->type = SQLITE_TEXT; - field->u.idx = m_Strings.AddString(number); - ptr = m_Strings.GetString(field->u.idx); - length = field->size; - } else if (field->type == SQLITE_NULL) { - res = DBVal_Null; - } - - if (!ptr) - { - ptr = ""; - } - - if (pString) - { - *pString = ptr; - } - if (_length) - { - *_length = length; - } - - return res; -} - -DBResult SqResults::CopyString(unsigned int columnId, char *buffer, size_t maxlength, size_t *written) -{ - SqField *field = GetField(columnId); - if (!field) - { - return DBVal_Error; - } - - DBResult res = DBVal_Data; - if (field->type == SQLITE_TEXT || field->type == SQLITE_BLOB) - { - const char *ptr = m_Strings.GetString(field->u.idx); - if (!ptr) - { - ptr = ""; - field->type = SQLITE_TEXT; - res = DBVal_Null; - } - size_t wr = 0; - if (field->type == SQLITE_TEXT) - { - wr = strncopy(buffer, ptr, maxlength); - } else if (field->type == SQLITE_BLOB) { - wr = (maxlength < field->size) ? maxlength : field->size; - memcpy(buffer, ptr, wr); - } - if (written) - { - *written = wr; - } - return res; - } else if (field->type == SQLITE_INTEGER) { - size_t wr = 0; - if (buffer) - { - wr = UTIL_Format(buffer, maxlength, "%d", field->u.idx); - } - if (written) - { - *written = wr; - } - return DBVal_Data; - } else if (field->type == SQLITE_FLOAT) { - size_t wr = 0; - if (buffer) - { - wr = UTIL_Format(buffer, maxlength, "%f", field->u.f); - } - if (written) - { - *written = wr; - } - return DBVal_Data; - } - - if (buffer) - { - strncopy(buffer, "", maxlength); - } - if (written) - { - *written = 0; - } - - return DBVal_Null; -} - -bool SqResults::IsNull(unsigned int columnId) -{ - SqField *field = GetField(columnId); - if (!field) - { - return true; - } - - return (field->type == SQLITE_NULL); -} - -unsigned int SqResults::GetDataSize(unsigned int columnId) -{ - SqField *field = GetField(columnId); - if (!field) - { - return 0; - } - - return field->size; -} - -DBResult SqResults::GetFloat(unsigned int columnId, float *pFloat) -{ - SqField *field = GetField(columnId); - if (!field) - { - return DBVal_Error; - } else if (field->type == SQLITE_BLOB) { - return DBVal_Error; - } - - float fVal = 0.0f; - if (field->type == SQLITE_FLOAT) - { - fVal = field->u.f; - } else if (field->type == SQLITE_TEXT) { - const char *ptr = m_Strings.GetString(field->u.idx); - if (ptr) - { - fVal = (float)atof(ptr); - } - } else if (field->type == SQLITE_INTEGER) { - fVal = (float)field->u.idx; - } - - if (pFloat) - { - *pFloat = fVal; - } - - return (field->type == SQLITE_NULL) ? DBVal_Null : DBVal_Data; -} - -DBResult SqResults::GetInt(unsigned int columnId, int *pInt) -{ - SqField *field = GetField(columnId); - if (!field) - { - return DBVal_Error; - } else if (field->type == SQLITE_BLOB) { - return DBVal_Error; - } - - int val = 0; - if (field->type == SQLITE_INTEGER) - { - val = field->u.idx; - } else if (field->type == SQLITE_TEXT) { - const char *ptr = m_Strings.GetString(field->u.idx); - if (ptr) - { - val = atoi(ptr); - } - } else if (field->type == SQLITE_FLOAT) { - val = (int)field->u.f; - } - - if (pInt) - { - *pInt = val; - } - - return (field->type == SQLITE_NULL) ? DBVal_Null : DBVal_Data; -} - -DBResult SqResults::GetBlob(unsigned int columnId, const void **pData, size_t *length) -{ - SqField *field = GetField(columnId); - if (!field) - { - return DBVal_Error; - } - - void *addr = NULL; - - if (field->type == SQLITE_TEXT || field->type == SQLITE_BLOB) - { - addr = m_pMemory->GetAddress(field->u.idx); - } else if (field->type == SQLITE_FLOAT || field->type == SQLITE_INTEGER) { - addr = &(field->u); - } - - if (pData) - { - *pData = addr; - } - - if (length) - { - *length = field->size; - } - - return (field->type == SQLITE_NULL) ? DBVal_Null : DBVal_Data; -} - -DBResult SqResults::CopyBlob(unsigned int columnId, void *buffer, size_t maxlength, size_t *written) -{ - SqField *field = GetField(columnId); - if (!field) - { - return DBVal_Error; - } - - void *addr = NULL; - - if (field->type == SQLITE_TEXT || field->type == SQLITE_BLOB) - { - addr = m_pMemory->GetAddress(field->u.idx); - } else if (field->type == SQLITE_FLOAT || field->type == SQLITE_INTEGER) { - addr = &(field->u); - } - - size_t toCopy = field->size > maxlength ? maxlength : field->size; - if (buffer && addr && toCopy) - { - memcpy(buffer, addr, toCopy); - } else { - toCopy = 0; - } - - if (written) - { - *written = toCopy; - } - - return (field->type == SQLITE_NULL) ? DBVal_Null : DBVal_Data; -} diff --git a/extensions/sqlite/driver/SqResults.h b/extensions/sqlite/driver/SqResults.h deleted file mode 100644 index afc366a2..00000000 --- a/extensions/sqlite/driver/SqResults.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SQLITE_SOURCEMOD_RESULT_SET_H_ -#define _INCLUDE_SQLITE_SOURCEMOD_RESULT_SET_H_ - -#include "SqDriver.h" -#include "sm_memtable.h" - -class SqQuery; - -struct SqField -{ - int type; - union - { - int idx; - float f; - } u; - size_t size; -}; - -class SqResults : - public IResultSet, - public IResultRow -{ - friend class SqQuery; -public: - SqResults(SqQuery *query); - ~SqResults(); -public: //IResultSet - unsigned int GetRowCount(); - unsigned int GetFieldCount(); - const char *FieldNumToName(unsigned int columnId); - bool FieldNameToNum(const char *name, unsigned int *columnId); - bool MoreRows(); - IResultRow *FetchRow(); - IResultRow *CurrentRow(); - bool Rewind(); - DBType GetFieldType(unsigned int field); - DBType GetFieldDataType(unsigned int field); -public: //IResultRow - DBResult GetString(unsigned int columnId, const char **pString, size_t *length); - DBResult CopyString(unsigned int columnId, - char *buffer, - size_t maxlength, - size_t *written); - DBResult GetFloat(unsigned int columnId, float *pFloat); - DBResult GetInt(unsigned int columnId, int *pInt); - bool IsNull(unsigned int columnId); - size_t GetDataSize(unsigned int columnId); - DBResult GetBlob(unsigned int columnId, const void **pData, size_t *length); - DBResult CopyBlob(unsigned int columnId, void *buffer, size_t maxlength, size_t *written); -public: - void ResetResultCount(); - void PushResult(); -private: - SqField *GetField(unsigned int col); -private: - sqlite3_stmt *m_pStmt; /** DOES NOT CHANGE */ - String *m_ColNames; /** DOES NOT CHANGE */ - unsigned int m_ColCount; /** DOES NOT CHANGE */ - BaseStringTable m_Strings; /** DOES NOT CHANGE */ - BaseMemTable *m_pMemory; /** DOES NOT CHANGE */ - unsigned int m_RowCount; - unsigned int m_MaxRows; - SqField *m_Rows; - unsigned int m_CurRow; - unsigned int m_NextRow; -}; - -#endif //_INCLUDE_SQLITE_SOURCEMOD_RESULT_SET_H_ diff --git a/extensions/sqlite/extension.cpp b/extensions/sqlite/extension.cpp deleted file mode 100644 index 960f86bf..00000000 --- a/extensions/sqlite/extension.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include "extension.h" -#include "driver/SqDriver.h" - -/** - * @file extension.cpp - * @brief Implement extension code here. - */ - -SqliteExt g_SqliteExt; /**< Global singleton for extension's main interface */ - -SMEXT_LINK(&g_SqliteExt); - -bool SqliteExt::SDK_OnLoad(char *error, size_t maxlength, bool late) -{ - g_SqDriver.Initialize(); - dbi->AddDriver(&g_SqDriver); - - return true; -} - -void SqliteExt::SDK_OnUnload() -{ - dbi->RemoveDriver(&g_SqDriver); - g_SqDriver.Shutdown(); -} - -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - size_t len = vsnprintf(buffer, maxlength, fmt, ap); - va_end(ap); - - if (len >= maxlength) - { - buffer[maxlength - 1] = '\0'; - return (maxlength - 1); - } else { - return len; - } -} diff --git a/extensions/sqlite/extension.h b/extensions/sqlite/extension.h deleted file mode 100644 index c6f89db9..00000000 --- a/extensions/sqlite/extension.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ -#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ - -/** - * @file extension.h - * @brief Sample extension code header. - */ - -#include "smsdk_ext.h" - - -/** - * @brief Sample implementation of the SDK Extension. - * Note: Uncomment one of the pre-defined virtual functions in order to use it. - */ -class SqliteExt : public SDKExtension -{ -public: - /** - * @brief This is called after the initial loading sequence has been processed. - * - * @param error Error message buffer. - * @param maxlength Size of error message buffer. - * @param late Whether or not the module was loaded after map load. - * @return True to succeed loading, false to fail. - */ - virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late); - - /** - * @brief This is called right before the extension is unloaded. - */ - virtual void SDK_OnUnload(); - - /** - * @brief This is called once all known extensions have been loaded. - * Note: It is is a good idea to add natives here, if any are provided. - */ - //virtual void SDK_OnAllLoaded(); - - /** - * @brief Called when the pause state is changed. - */ - //virtual void SDK_OnPauseChange(bool paused); - - /** - * @brief this is called when Core wants to know if your extension is working. - * - * @param error Error message buffer. - * @param maxlength Size of error message buffer. - * @return True if working, false otherwise. - */ - //virtual bool QueryRunning(char *error, size_t maxlength); -public: -#if defined SMEXT_CONF_METAMOD - /** - * @brief Called when Metamod is attached, before the extension version is called. - * - * @param error Error buffer. - * @param maxlength Maximum size of error buffer. - * @param late Whether or not Metamod considers this a late load. - * @return True to succeed, false to fail. - */ - //virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late); - - /** - * @brief Called when Metamod is detaching, after the extension version is called. - * NOTE: By default this is blocked unless sent from SourceMod. - * - * @param error Error buffer. - * @param maxlength Maximum size of error buffer. - * @return True to succeed, false to fail. - */ - //virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength); - - /** - * @brief Called when Metamod's pause state is changing. - * NOTE: By default this is blocked unless sent from SourceMod. - * - * @param paused Pause state being set. - * @param error Error buffer. - * @param maxlength Maximum size of error buffer. - * @return True to succeed, false to fail. - */ - //virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength); -#endif -}; - -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...); - -#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ diff --git a/extensions/sqlite/msvc8/sm_sqlite.sln b/extensions/sqlite/msvc8/sm_sqlite.sln deleted file mode 100644 index 1805b0c9..00000000 --- a/extensions/sqlite/msvc8/sm_sqlite.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sm_sqlite", "sm_sqlite.vcproj", "{B3E797CF-4E77-4C9D-B8A8-7589B6902206}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.ActiveCfg = Debug|Win32 - {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.Build.0 = Debug|Win32 - {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.ActiveCfg = Release|Win32 - {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/extensions/sqlite/msvc8/sm_sqlite.vcproj b/extensions/sqlite/msvc8/sm_sqlite.vcproj deleted file mode 100644 index cfe66a8b..00000000 --- a/extensions/sqlite/msvc8/sm_sqlite.vcproj +++ /dev/null @@ -1,893 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/extensions/sqlite/sdk/sm_memtable.cpp b/extensions/sqlite/sdk/sm_memtable.cpp deleted file mode 100644 index 8f18b136..00000000 --- a/extensions/sqlite/sdk/sm_memtable.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include -#include "sm_memtable.h" - -BaseMemTable::BaseMemTable(unsigned int init_size) -{ - membase = (unsigned char *)malloc(init_size); - size = init_size; - tail = 0; -} - -BaseMemTable::~BaseMemTable() -{ - free(membase); - membase = NULL; -} - -int BaseMemTable::CreateMem(unsigned int addsize, void **addr) -{ - int idx = (int)tail; - - while (tail + addsize >= size) - { - size *= 2; - membase = (unsigned char *)realloc(membase, size); - } - - tail += addsize; - - if (addr) - { - *addr = (void *)&membase[idx]; - } - - return idx; -} - -void *BaseMemTable::GetAddress(int index) -{ - if (index < 0 || (unsigned int)index >= tail) - { - return NULL; - } - - return &membase[index]; -} - -void BaseMemTable::Reset() -{ - tail = 0; -} - -BaseStringTable::BaseStringTable(unsigned int init_size) : m_table(init_size) -{ -} - -BaseStringTable::~BaseStringTable() -{ -} - -int BaseStringTable::AddString(const char *string) -{ - size_t len = strlen(string) + 1; - int idx; - char *addr; - - idx = m_table.CreateMem(len, (void **)&addr); - strcpy(addr, string); - - return idx; -} - -/*const char *BaseStringTable::GetString(int str) -{ - return (const char *)m_table.GetAddress(str); -}*/ - -void BaseStringTable::Reset() -{ - m_table.Reset(); -} diff --git a/extensions/sqlite/sdk/sm_memtable.h b/extensions/sqlite/sdk/sm_memtable.h deleted file mode 100644 index 53ba5ff8..00000000 --- a/extensions/sqlite/sdk/sm_memtable.h +++ /dev/null @@ -1,105 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_ -#define _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_ - -class BaseMemTable -{ -public: - BaseMemTable(unsigned int init_size); - ~BaseMemTable(); -public: - /** - * Allocates 'size' bytes of memory. - * Optionally outputs the address through 'addr'. - * Returns an index >= 0 on success, < 0 on failure. - */ - int CreateMem(unsigned int size, void **addr); - - /** - * Given an index into the memory table, returns its address. - * Returns NULL if invalid. - */ - void *GetAddress(int index); - - /** - * Scraps the memory table. For caching purposes, the memory - * is not freed, however subsequent calls to CreateMem() will - * begin at the first index again. - */ - void Reset(); - - -private: - unsigned char *membase; - unsigned int size; - unsigned int tail; -}; - -class BaseStringTable -{ -public: - BaseStringTable(unsigned int init_size); - ~BaseStringTable(); -public: - /** - * Adds a string to the string table and returns its index. - */ - int AddString(const char *string); - - /** - * Given an index into the string table, returns the associated string. - */ - inline const char *GetString(int str) - { - return (const char *)m_table.GetAddress(str); - } - - /** - * Scraps the string table. For caching purposes, the memory - * is not freed, however subsequent calls to AddString() will - * begin at the first index again. - */ - void Reset(); - - /** - * Returns the parent BaseMemTable that this string table uses. - */ - inline BaseMemTable *GetMemTable() - { - return &m_table; - } -private: - BaseMemTable m_table; -}; - -#endif //_INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_ diff --git a/extensions/sqlite/sdk/smsdk_config.h b/extensions/sqlite/sdk/smsdk_config.h deleted file mode 100644 index 8911183b..00000000 --- a/extensions/sqlite/sdk/smsdk_config.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod SQLite Extension - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ -#define _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ - -#include "svn_version.h" - -/** - * @file smsdk_config.h - * @brief Contains macros for configuring basic extension information. - */ - -/* Basic information exposed publicly */ -#define SMEXT_CONF_NAME "SQLite" -#define SMEXT_CONF_DESCRIPTION "SQLite Driver" -#define SMEXT_CONF_VERSION SVN_FULL_VERSION -#define SMEXT_CONF_AUTHOR "AlliedModders LLC" -#define SMEXT_CONF_URL "http://www.sourcemod.net/" -#define SMEXT_CONF_LOGTAG "SQLITE" -#define SMEXT_CONF_LICENSE "GPL" -#define SMEXT_CONF_DATESTRING __DATE__ " " __TIME__ - -/** - * @brief Exposes plugin's main interface. - */ -#define SMEXT_LINK(name) SDKExtension *g_pExtensionIface = name; - -/** - * @brief Sets whether or not this plugin required Metamod. - * NOTE: Uncomment to enable, comment to disable. - */ -//#define SMEXT_CONF_METAMOD - -/** Enable interfaces you want to use here by uncommenting lines */ -//#define SMEXT_ENABLE_FORWARDSYS -//#define SMEXT_ENABLE_HANDLESYS -//#define SMEXT_ENABLE_PLAYERHELPERS -#define SMEXT_ENABLE_DBMANAGER -//#define SMEXT_ENABLE_GAMECONF -//#define SMEXT_ENABLE_MEMUTILS -//#define SMEXT_ENABLE_GAMEHELPERS -//#define SMEXT_ENABLE_TIMERSYS -#define SMEXT_ENABLE_THREADER -#define SMEXT_ENABLE_LIBSYS - -#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ diff --git a/extensions/sqlite/sdk/smsdk_ext.cpp b/extensions/sqlite/sdk/smsdk_ext.cpp deleted file mode 100644 index c504da48..00000000 --- a/extensions/sqlite/sdk/smsdk_ext.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Base Extension Code - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ -#include -#include -#include "smsdk_ext.h" - -/** - * @file smsdk_ext.cpp - * @brief Contains wrappers for making Extensions easier to write. - */ - -IExtension *myself = NULL; /**< Ourself */ -IShareSys *g_pShareSys = NULL; /**< Share system */ -IShareSys *sharesys = NULL; /**< Share system */ -ISourceMod *g_pSM = NULL; /**< SourceMod helpers */ -ISourceMod *smutils = NULL; /**< SourceMod helpers */ - -#if defined SMEXT_ENABLE_FORWARDSYS -IForwardManager *g_pForwards = NULL; /**< Forward system */ -IForwardManager *forwards = NULL; /**< Forward system */ -#endif -#if defined SMEXT_ENABLE_HANDLESYS -IHandleSys *g_pHandleSys = NULL; /**< Handle system */ -IHandleSys *handlesys = NULL; /**< Handle system */ -#endif -#if defined SMEXT_ENABLE_PLAYERHELPERS -IPlayerManager *playerhelpers = NULL; /**< Player helpers */ -#endif //SMEXT_ENABLE_PLAYERHELPERS -#if defined SMEXT_ENABLE_DBMANAGER -IDBManager *dbi = NULL; /**< DB Manager */ -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMECONF -IGameConfigManager *gameconfs = NULL; /**< Game config manager */ -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_MEMUTILS -IMemoryUtils *memutils = NULL; -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMEHELPERS -IGameHelpers *gamehelpers = NULL; -#endif -#if defined SMEXT_ENABLE_TIMERSYS -ITimerSystem *timersys = NULL; -#endif -#if defined SMEXT_ENABLE_ADTFACTORY -IADTFactory *adtfactory = NULL; -#endif -#if defined SMEXT_ENABLE_THREADER -IThreader *threader = NULL; -#endif -#if defined SMEXT_ENABLE_LIBSYS -ILibrarySys *libsys = NULL; -#endif - -/** Exports the main interface */ -PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI() -{ - return g_pExtensionIface; -} - -SDKExtension::SDKExtension() -{ -#if defined SMEXT_CONF_METAMOD - m_SourceMMLoaded = false; - m_WeAreUnloaded = false; - m_WeGotPauseChange = false; -#endif -} - -bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late) -{ - g_pShareSys = sharesys = sys; - myself = me; - -#if defined SMEXT_CONF_METAMOD - m_WeAreUnloaded = true; - - if (!m_SourceMMLoaded) - { - if (error) - { - snprintf(error, maxlength, "Metamod attach failed"); - } - return false; - } -#endif - SM_GET_IFACE(SOURCEMOD, g_pSM); - smutils = g_pSM; -#if defined SMEXT_ENABLE_HANDLESYS - SM_GET_IFACE(HANDLESYSTEM, g_pHandleSys); - handlesys = g_pHandleSys; -#endif -#if defined SMEXT_ENABLE_FORWARDSYS - SM_GET_IFACE(FORWARDMANAGER, g_pForwards); - forwards = g_pForwards; -#endif -#if defined SMEXT_ENABLE_PLAYERHELPERS - SM_GET_IFACE(PLAYERMANAGER, playerhelpers); -#endif -#if defined SMEXT_ENABLE_DBMANAGER - SM_GET_IFACE(DBI, dbi); -#endif -#if defined SMEXT_ENABLE_GAMECONF - SM_GET_IFACE(GAMECONFIG, gameconfs); -#endif -#if defined SMEXT_ENABLE_MEMUTILS - SM_GET_IFACE(MEMORYUTILS, memutils); -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS - SM_GET_IFACE(GAMEHELPERS, gamehelpers); -#endif -#if defined SMEXT_ENABLE_TIMERSYS - SM_GET_IFACE(TIMERSYS, timersys); -#endif -#if defined SMEXT_ENABLE_ADTFACTORY - SM_GET_IFACE(ADTFACTORY, adtfactory); -#endif -#if defined SMEXT_ENABLE_THREADER - SM_GET_IFACE(THREADER, threader); -#endif -#if defined SMEXT_ENABLE_LIBSYS - SM_GET_IFACE(LIBRARYSYS, libsys); -#endif - - if (SDK_OnLoad(error, maxlength, late)) - { -#if defined SMEXT_CONF_METAMOD - m_WeAreUnloaded = true; -#endif - return true; - } - - return false; -} - -bool SDKExtension::IsMetamodExtension() -{ -#if defined SMEXT_CONF_METAMOD - return true; -#else - return false; -#endif -} - -void SDKExtension::OnExtensionPauseChange(bool state) -{ -#if defined SMEXT_CONF_METAMOD - m_WeGotPauseChange = true; -#endif - SDK_OnPauseChange(state); -} - -void SDKExtension::OnExtensionsAllLoaded() -{ - SDK_OnAllLoaded(); -} - -void SDKExtension::OnExtensionUnload() -{ -#if defined SMEXT_CONF_METAMOD - m_WeAreUnloaded = true; -#endif - SDK_OnUnload(); -} - -const char *SDKExtension::GetExtensionAuthor() -{ - return SMEXT_CONF_AUTHOR; -} - -const char *SDKExtension::GetExtensionDateString() -{ - return SMEXT_CONF_DATESTRING; -} - -const char *SDKExtension::GetExtensionDescription() -{ - return SMEXT_CONF_DESCRIPTION; -} - -const char *SDKExtension::GetExtensionVerString() -{ - return SMEXT_CONF_VERSION; -} - -const char *SDKExtension::GetExtensionName() -{ - return SMEXT_CONF_NAME; -} - -const char *SDKExtension::GetExtensionTag() -{ - return SMEXT_CONF_LOGTAG; -} - -const char *SDKExtension::GetExtensionURL() -{ - return SMEXT_CONF_URL; -} - -bool SDKExtension::SDK_OnLoad(char *error, size_t maxlength, bool late) -{ - return true; -} - -void SDKExtension::SDK_OnUnload() -{ -} - -void SDKExtension::SDK_OnPauseChange(bool paused) -{ -} - -void SDKExtension::SDK_OnAllLoaded() -{ -} - -#if defined SMEXT_CONF_METAMOD - -PluginId g_PLID = 0; /**< Metamod plugin ID */ -ISmmPlugin *g_PLAPI = NULL; /**< Metamod plugin API */ -SourceHook::ISourceHook *g_SHPtr = NULL; /**< SourceHook pointer */ -ISmmAPI *g_SMAPI = NULL; /**< SourceMM API pointer */ - -IVEngineServer *engine = NULL; /**< IVEngineServer pointer */ -IServerGameDLL *gamedll = NULL; /**< IServerGameDLL pointer */ - -/** Exposes the extension to Metamod */ -SMM_API void *PL_EXPOSURE(const char *name, int *code) -{ - if (name && !strcmp(name, PLAPI_NAME)) - { - if (code) - { - *code = IFACE_OK; - } - return static_cast(g_pExtensionIface); - } - - if (code) - { - *code = IFACE_FAILED; - } - - return NULL; -} - -bool SDKExtension::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) -{ - PLUGIN_SAVEVARS(); - - GET_V_IFACE_ANY(serverFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); - GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); - - m_SourceMMLoaded = true; - - return SDK_OnMetamodLoad(ismm, error, maxlen, late); -} - -bool SDKExtension::Unload(char *error, size_t maxlen) -{ - if (!m_WeAreUnloaded) - { - if (error) - { - snprintf(error, maxlen, "This extension must be unloaded by SourceMod."); - } - return false; - } - - return SDK_OnMetamodUnload(error, maxlen); -} - -bool SDKExtension::Pause(char *error, size_t maxlen) -{ - if (!m_WeGotPauseChange) - { - if (error) - { - snprintf(error, maxlen, "This extension must be paused by SourceMod."); - } - return false; - } - - m_WeGotPauseChange = false; - - return SDK_OnMetamodPauseChange(true, error, maxlen); -} - -bool SDKExtension::Unpause(char *error, size_t maxlen) -{ - if (!m_WeGotPauseChange) - { - if (error) - { - snprintf(error, maxlen, "This extension must be unpaused by SourceMod."); - } - return false; - } - - m_WeGotPauseChange = false; - - return SDK_OnMetamodPauseChange(false, error, maxlen); -} - -const char *SDKExtension::GetAuthor() -{ - return GetExtensionAuthor(); -} - -const char *SDKExtension::GetDate() -{ - return GetExtensionDateString(); -} - -const char *SDKExtension::GetDescription() -{ - return GetExtensionDescription(); -} - -const char *SDKExtension::GetLicense() -{ - return SMEXT_CONF_LICENSE; -} - -const char *SDKExtension::GetLogTag() -{ - return GetExtensionTag(); -} - -const char *SDKExtension::GetName() -{ - return GetExtensionName(); -} - -const char *SDKExtension::GetURL() -{ - return GetExtensionURL(); -} - -const char *SDKExtension::GetVersion() -{ - return GetExtensionVerString(); -} - -bool SDKExtension::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late) -{ - return true; -} - -bool SDKExtension::SDK_OnMetamodUnload(char *error, size_t maxlength) -{ - return true; -} - -bool SDKExtension::SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength) -{ - return true; -} - -#endif - -/* Overload a few things to prevent libstdc++ linking */ -#if defined __linux__ -extern "C" void __cxa_pure_virtual(void) -{ -} - -void *operator new(size_t size) -{ - return malloc(size); -} - -void *operator new[](size_t size) -{ - return malloc(size); -} - -void operator delete(void *ptr) -{ - free(ptr); -} - -void operator delete[](void * ptr) -{ - free(ptr); -} -#endif diff --git a/extensions/sqlite/sdk/smsdk_ext.h b/extensions/sqlite/sdk/smsdk_ext.h deleted file mode 100644 index d77d84db..00000000 --- a/extensions/sqlite/sdk/smsdk_ext.h +++ /dev/null @@ -1,300 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod Base Extension Code - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ -#define _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ - -/** - * @file smsdk_ext.h - * @brief Contains wrappers for making Extensions easier to write. - */ - -#include "smsdk_config.h" -#include -#include -#include -#include -#include -#if defined SMEXT_ENABLE_FORWARDSYS -#include -#endif //SMEXT_ENABLE_FORWARDSYS -#if defined SMEXT_ENABLE_PLAYERHELPERS -#include -#endif //SMEXT_ENABLE_PlAYERHELPERS -#if defined SMEXT_ENABLE_DBMANAGER -#include -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMECONF -#include -#endif -#if defined SMEXT_ENABLE_MEMUTILS -#include -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS -#include -#endif -#if defined SMEXT_ENABLE_TIMERSYS -#include -#endif -#if defined SMEXT_ENABLE_ADTFACTORY -#include -#endif -#if defined SMEXT_ENABLE_THREADER -#include -#endif -#if defined SMEXT_ENABLE_LIBSYS -#include -#endif - -#if defined SMEXT_CONF_METAMOD -#include -#include -#endif - -using namespace SourceMod; -using namespace SourcePawn; - -class SDKExtension : -#if defined SMEXT_CONF_METAMOD - public ISmmPlugin, -#endif - public IExtensionInterface -{ -public: - /** Constructor */ - SDKExtension(); -public: - /** - * @brief This is called after the initial loading sequence has been processed. - * - * @param error Error message buffer. - * @param maxlength Size of error message buffer. - * @param late Whether or not the module was loaded after map load. - * @return True to succeed loading, false to fail. - */ - virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late); - - /** - * @brief This is called right before the extension is unloaded. - */ - virtual void SDK_OnUnload(); - - /** - * @brief This is called once all known extensions have been loaded. - */ - virtual void SDK_OnAllLoaded(); - - /** - * @brief Called when the pause state is changed. - */ - virtual void SDK_OnPauseChange(bool paused); - -#if defined SMEXT_CONF_METAMOD - /** - * @brief Called when Metamod is attached, before the extension version is called. - * - * @param error Error buffer. - * @param maxlength Maximum size of error buffer. - * @param late Whether or not Metamod considers this a late load. - * @return True to succeed, false to fail. - */ - virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late); - - /** - * @brief Called when Metamod is detaching, after the extension version is called. - * NOTE: By default this is blocked unless sent from SourceMod. - * - * @param error Error buffer. - * @param maxlength Maximum size of error buffer. - * @return True to succeed, false to fail. - */ - virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength); - - /** - * @brief Called when Metamod's pause state is changing. - * NOTE: By default this is blocked unless sent from SourceMod. - * - * @param paused Pause state being set. - * @param error Error buffer. - * @param maxlength Maximum size of error buffer. - * @return True to succeed, false to fail. - */ - virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength); -#endif - -public: //IExtensionInterface - virtual bool OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late); - virtual void OnExtensionUnload(); - virtual void OnExtensionsAllLoaded(); - - /** Returns whether or not this is a Metamod-based extension */ - virtual bool IsMetamodExtension(); - - /** - * @brief Called when the pause state changes. - * - * @param state True if being paused, false if being unpaused. - */ - virtual void OnExtensionPauseChange(bool state); - - /** Returns name */ - virtual const char *GetExtensionName(); - /** Returns URL */ - virtual const char *GetExtensionURL(); - /** Returns log tag */ - virtual const char *GetExtensionTag(); - /** Returns author */ - virtual const char *GetExtensionAuthor(); - /** Returns version string */ - virtual const char *GetExtensionVerString(); - /** Returns description string */ - virtual const char *GetExtensionDescription(); - /** Returns date string */ - virtual const char *GetExtensionDateString(); -#if defined SMEXT_CONF_METAMOD -public: //ISmmPlugin - /** Called when the extension is attached to Metamod. */ - virtual bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlength, bool late); - /** Returns the author to MM */ - virtual const char *GetAuthor(); - /** Returns the name to MM */ - virtual const char *GetName(); - /** Returns the description to MM */ - virtual const char *GetDescription(); - /** Returns the URL to MM */ - virtual const char *GetURL(); - /** Returns the license to MM */ - virtual const char *GetLicense(); - /** Returns the version string to MM */ - virtual const char *GetVersion(); - /** Returns the date string to MM */ - virtual const char *GetDate(); - /** Returns the logtag to MM */ - virtual const char *GetLogTag(); - /** Called on unload */ - virtual bool Unload(char *error, size_t maxlength); - /** Called on pause */ - virtual bool Pause(char *error, size_t maxlength); - /** Called on unpause */ - virtual bool Unpause(char *error, size_t maxlength); -private: - bool m_SourceMMLoaded; - bool m_WeAreUnloaded; - bool m_WeGotPauseChange; -#endif -}; - -extern SDKExtension *g_pExtensionIface; -extern IExtension *myself; - -extern IShareSys *g_pShareSys; -extern IShareSys *sharesys; /* Note: Newer name */ -extern ISourceMod *g_pSM; -extern ISourceMod *smutils; /* Note: Newer name */ - -/* Optional interfaces are below */ -#if defined SMEXT_ENABLE_FORWARDSYS -extern IForwardManager *g_pForwards; -extern IForwardManager *forwards; /* Note: Newer name */ -#endif //SMEXT_ENABLE_FORWARDSYS -#if defined SMEXT_ENABLE_HANDLESYS -extern IHandleSys *g_pHandleSys; -extern IHandleSys *handlesys; /* Note: Newer name */ -#endif //SMEXT_ENABLE_HANDLESYS -#if defined SMEXT_ENABLE_PLAYERHELPERS -extern IPlayerManager *playerhelpers; -#endif //SMEXT_ENABLE_PLAYERHELPERS -#if defined SMEXT_ENABLE_DBMANAGER -extern IDBManager *dbi; -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMECONF -extern IGameConfigManager *gameconfs; -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_MEMUTILS -extern IMemoryUtils *memutils; -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS -extern IGameHelpers *gamehelpers; -#endif -#if defined SMEXT_ENABLE_TIMERSYS -extern ITimerSystem *timersys; -#endif -#if defined SMEXT_ENABLE_ADTFACTORY -extern IADTFactory *adtfactory; -#endif -#if defined SMEXT_ENABLE_THREADER -extern IThreader *threader; -#endif -#if defined SMEXT_ENABLE_LIBSYS -extern ILibrarySys *libsys; -#endif - -#if defined SMEXT_CONF_METAMOD -PLUGIN_GLOBALVARS(); -extern IVEngineServer *engine; -extern IServerGameDLL *gamedll; -#endif - -/** Creates a SourceMod interface macro pair */ -#define SM_MKIFACE(name) SMINTERFACE_##name##_NAME, SMINTERFACE_##name##_VERSION -/** Automates retrieving SourceMod interfaces */ -#define SM_GET_IFACE(prefix, addr) \ - if (!g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr)) \ - { \ - if (error != NULL && maxlength) \ - { \ - size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \ - if (len >= maxlength) \ - { \ - error[maxlength - 1] = '\0'; \ - } \ - } \ - return false; \ - } -/** Automates retrieving SourceMod interfaces when needed outside of SDK_OnLoad() */ -#define SM_GET_LATE_IFACE(prefix, addr) \ - g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr) -/** Validates a SourceMod interface pointer */ -#define SM_CHECK_IFACE(prefix, addr) \ - if (!addr) \ - { \ - if (error != NULL && maxlength) \ - { \ - size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \ - if (len >= maxlength) \ - { \ - error[maxlength - 1] = '\0'; \ - } \ - } \ - return false; \ - } - -#endif // _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ diff --git a/extensions/sqlite/sqlite-source/alter.c b/extensions/sqlite/sqlite-source/alter.c deleted file mode 100644 index 8b8d914a..00000000 --- a/extensions/sqlite/sqlite-source/alter.c +++ /dev/null @@ -1,622 +0,0 @@ -/* -** 2005 February 15 -** -** 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 file contains C code routines that used to generate VDBE code -** that implements the ALTER TABLE command. -** -** $Id$ -*/ -#include "sqliteInt.h" -#include - -/* -** The code in this file only exists if we are not omitting the -** ALTER TABLE logic from the build. -*/ -#ifndef SQLITE_OMIT_ALTERTABLE - - -/* -** This function is used by SQL generated to implement the -** ALTER TABLE command. The first argument is the text of a CREATE TABLE or -** CREATE INDEX command. The second is a table name. The table name in -** the CREATE TABLE or CREATE INDEX statement is replaced with the third -** argument and the result returned. Examples: -** -** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def') -** -> 'CREATE TABLE def(a, b, c)' -** -** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def') -** -> 'CREATE INDEX i ON def(a, b, c)' -*/ -static void renameTableFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - unsigned char const *zSql = sqlite3_value_text(argv[0]); - unsigned char const *zTableName = sqlite3_value_text(argv[1]); - - int token; - Token tname; - unsigned char const *zCsr = zSql; - int len = 0; - char *zRet; - - sqlite3 *db = sqlite3_user_data(context); - - /* The principle used to locate the table name in the CREATE TABLE - ** statement is that the table name is the first token that is immediatedly - ** followed by a left parenthesis - TK_LP - or "USING" TK_USING. - */ - if( zSql ){ - do { - if( !*zCsr ){ - /* Ran out of input before finding an opening bracket. Return NULL. */ - return; - } - - /* Store the token that zCsr points to in tname. */ - tname.z = zCsr; - tname.n = len; - - /* Advance zCsr to the next token. Store that token type in 'token', - ** and it's length in 'len' (to be used next iteration of this loop). - */ - do { - zCsr += len; - len = sqlite3GetToken(zCsr, &token); - } while( token==TK_SPACE ); - assert( len>0 ); - } while( token!=TK_LP && token!=TK_USING ); - - zRet = sqlite3MPrintf(db, "%.*s%Q%s", tname.z - zSql, zSql, - zTableName, tname.z+tname.n); - sqlite3_result_text(context, zRet, -1, sqlite3_free); - } -} - -#ifndef SQLITE_OMIT_TRIGGER -/* This function is used by SQL generated to implement the -** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER -** statement. The second is a table name. The table name in the CREATE -** TRIGGER statement is replaced with the third argument and the result -** returned. This is analagous to renameTableFunc() above, except for CREATE -** TRIGGER, not CREATE INDEX and CREATE TABLE. -*/ -static void renameTriggerFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - unsigned char const *zSql = sqlite3_value_text(argv[0]); - unsigned char const *zTableName = sqlite3_value_text(argv[1]); - - int token; - Token tname; - int dist = 3; - unsigned char const *zCsr = zSql; - int len = 0; - char *zRet; - - sqlite3 *db = sqlite3_user_data(context); - - /* The principle used to locate the table name in the CREATE TRIGGER - ** statement is that the table name is the first token that is immediatedly - ** preceded by either TK_ON or TK_DOT and immediatedly followed by one - ** of TK_WHEN, TK_BEGIN or TK_FOR. - */ - if( zSql ){ - do { - - if( !*zCsr ){ - /* Ran out of input before finding the table name. Return NULL. */ - return; - } - - /* Store the token that zCsr points to in tname. */ - tname.z = zCsr; - tname.n = len; - - /* Advance zCsr to the next token. Store that token type in 'token', - ** and it's length in 'len' (to be used next iteration of this loop). - */ - do { - zCsr += len; - len = sqlite3GetToken(zCsr, &token); - }while( token==TK_SPACE ); - assert( len>0 ); - - /* Variable 'dist' stores the number of tokens read since the most - ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN - ** token is read and 'dist' equals 2, the condition stated above - ** to be met. - ** - ** Note that ON cannot be a database, table or column name, so - ** there is no need to worry about syntax like - ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc. - */ - dist++; - if( token==TK_DOT || token==TK_ON ){ - dist = 0; - } - } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); - - /* Variable tname now contains the token that is the old table-name - ** in the CREATE TRIGGER statement. - */ - zRet = sqlite3MPrintf(db, "%.*s%Q%s", tname.z - zSql, zSql, - zTableName, tname.z+tname.n); - sqlite3_result_text(context, zRet, -1, sqlite3_free); - } -} -#endif /* !SQLITE_OMIT_TRIGGER */ - -/* -** Register built-in functions used to help implement ALTER TABLE -*/ -void sqlite3AlterFunctions(sqlite3 *db){ - static const struct { - char *zName; - signed char nArg; - void (*xFunc)(sqlite3_context*,int,sqlite3_value **); - } aFuncs[] = { - { "sqlite_rename_table", 2, renameTableFunc}, -#ifndef SQLITE_OMIT_TRIGGER - { "sqlite_rename_trigger", 2, renameTriggerFunc}, -#endif - }; - int i; - - for(i=0; idb->aDb[1].pSchema; /* Temp db schema */ - - /* If the table is not located in the temp-db (in which case NULL is - ** returned, loop through the tables list of triggers. For each trigger - ** that is not part of the temp-db schema, add a clause to the WHERE - ** expression being built up in zWhere. - */ - if( pTab->pSchema!=pTempSchema ){ - sqlite3 *db = pParse->db; - for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){ - if( pTrig->pSchema==pTempSchema ){ - if( !zWhere ){ - zWhere = sqlite3MPrintf(db, "name=%Q", pTrig->name); - }else{ - tmp = zWhere; - zWhere = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, pTrig->name); - sqlite3_free(tmp); - } - } - } - } - return zWhere; -} - -/* -** Generate code to drop and reload the internal representation of table -** pTab from the database, including triggers and temporary triggers. -** Argument zName is the name of the table in the database schema at -** the time the generated code is executed. This can be different from -** pTab->zName if this function is being called to code part of an -** "ALTER TABLE RENAME TO" statement. -*/ -static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){ - Vdbe *v; - char *zWhere; - int iDb; /* Index of database containing pTab */ -#ifndef SQLITE_OMIT_TRIGGER - Trigger *pTrig; -#endif - - v = sqlite3GetVdbe(pParse); - if( !v ) return; - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - assert( iDb>=0 ); - -#ifndef SQLITE_OMIT_TRIGGER - /* Drop any table triggers from the internal schema. */ - for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){ - int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); - assert( iTrigDb==iDb || iTrigDb==1 ); - sqlite3VdbeOp3(v, OP_DropTrigger, iTrigDb, 0, pTrig->name, 0); - } -#endif - - /* Drop the table and index from the internal schema */ - sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0); - - /* Reload the table, index and permanent trigger schemas. */ - zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName); - if( !zWhere ) return; - sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC); - -#ifndef SQLITE_OMIT_TRIGGER - /* Now, if the table is not stored in the temp database, reload any temp - ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. - */ - if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ - sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zWhere, P3_DYNAMIC); - } -#endif -} - -/* -** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" -** command. -*/ -void sqlite3AlterRenameTable( - Parse *pParse, /* Parser context. */ - SrcList *pSrc, /* The table to rename. */ - Token *pName /* The new table name. */ -){ - int iDb; /* Database that contains the table */ - char *zDb; /* Name of database iDb */ - Table *pTab; /* Table being renamed */ - char *zName = 0; /* NULL-terminated version of pName */ - sqlite3 *db = pParse->db; /* Database connection */ - int nTabName; /* Number of UTF-8 characters in zTabName */ - const char *zTabName; /* Original name of the table */ - Vdbe *v; -#ifndef SQLITE_OMIT_TRIGGER - char *zWhere = 0; /* Where clause to locate temp triggers */ -#endif - int isVirtualRename = 0; /* True if this is a v-table with an xRename() */ - - if( db->mallocFailed ) goto exit_rename_table; - assert( pSrc->nSrc==1 ); - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - - pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); - if( !pTab ) goto exit_rename_table; - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - zDb = db->aDb[iDb].zName; - - /* Get a NULL terminated version of the new table name. */ - zName = sqlite3NameFromToken(db, pName); - if( !zName ) goto exit_rename_table; - - /* Check that a table or index named 'zName' does not already exist - ** in database iDb. If so, this is an error. - */ - if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ - sqlite3ErrorMsg(pParse, - "there is already another table or index with this name: %s", zName); - goto exit_rename_table; - } - - /* Make sure it is not a system table being altered, or a reserved name - ** that the table is being renamed to. - */ - if( strlen(pTab->zName)>6 && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ){ - sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName); - goto exit_rename_table; - } - if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ - goto exit_rename_table; - } - -#ifndef SQLITE_OMIT_AUTHORIZATION - /* Invoke the authorization callback. */ - if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ - goto exit_rename_table; - } -#endif - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto exit_rename_table; - } - if( IsVirtual(pTab) && pTab->pMod->pModule->xRename ){ - isVirtualRename = 1; - } -#endif - - /* Begin a transaction and code the VerifyCookie for database iDb. - ** Then modify the schema cookie (since the ALTER TABLE modifies the - ** schema). Open a statement transaction if the table is a virtual - ** table. - */ - v = sqlite3GetVdbe(pParse); - if( v==0 ){ - goto exit_rename_table; - } - sqlite3BeginWriteOperation(pParse, isVirtualRename, iDb); - sqlite3ChangeCookie(db, v, iDb); - - /* If this is a virtual table, invoke the xRename() function if - ** one is defined. The xRename() callback will modify the names - ** of any resources used by the v-table implementation (including other - ** SQLite tables) that are identified by the name of the virtual table. - */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( isVirtualRename ){ - sqlite3VdbeOp3(v, OP_String8, 0, 0, zName, 0); - sqlite3VdbeOp3(v, OP_VRename, 0, 0, (const char*)pTab->pVtab, P3_VTAB); - } -#endif - - /* figure out how many UTF-8 characters are in zName */ - zTabName = pTab->zName; - nTabName = sqlite3Utf8CharLen(zTabName, -1); - - /* Modify the sqlite_master table to use the new table name. */ - sqlite3NestedParse(pParse, - "UPDATE %Q.%s SET " -#ifdef SQLITE_OMIT_TRIGGER - "sql = sqlite_rename_table(sql, %Q), " -#else - "sql = CASE " - "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" - "ELSE sqlite_rename_table(sql, %Q) END, " -#endif - "tbl_name = %Q, " - "name = CASE " - "WHEN type='table' THEN %Q " - "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " - "'sqlite_autoindex_' || %Q || substr(name,%d+18,10) " - "ELSE name END " - "WHERE tbl_name=%Q AND " - "(type='table' OR type='index' OR type='trigger');", - zDb, SCHEMA_TABLE(iDb), zName, zName, zName, -#ifndef SQLITE_OMIT_TRIGGER - zName, -#endif - zName, nTabName, zTabName - ); - -#ifndef SQLITE_OMIT_AUTOINCREMENT - /* If the sqlite_sequence table exists in this database, then update - ** it with the new table name. - */ - if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ - sqlite3NestedParse(pParse, - "UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q", - zDb, zName, pTab->zName); - } -#endif - -#ifndef SQLITE_OMIT_TRIGGER - /* If there are TEMP triggers on this table, modify the sqlite_temp_master - ** table. Don't do this if the table being ALTERed is itself located in - ** the temp database. - */ - if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ - sqlite3NestedParse(pParse, - "UPDATE sqlite_temp_master SET " - "sql = sqlite_rename_trigger(sql, %Q), " - "tbl_name = %Q " - "WHERE %s;", zName, zName, zWhere); - sqlite3_free(zWhere); - } -#endif - - /* Drop and reload the internal table schema. */ - reloadTableSchema(pParse, pTab, zName); - -exit_rename_table: - sqlite3SrcListDelete(pSrc); - sqlite3_free(zName); -} - - -/* -** This function is called after an "ALTER TABLE ... ADD" statement -** has been parsed. Argument pColDef contains the text of the new -** column definition. -** -** The Table structure pParse->pNewTable was extended to include -** the new column during parsing. -*/ -void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ - Table *pNew; /* Copy of pParse->pNewTable */ - Table *pTab; /* Table being altered */ - int iDb; /* Database number */ - const char *zDb; /* Database name */ - const char *zTab; /* Table name */ - char *zCol; /* Null-terminated column definition */ - Column *pCol; /* The new column */ - Expr *pDflt; /* Default value for the new column */ - sqlite3 *db; /* The database connection; */ - - if( pParse->nErr ) return; - pNew = pParse->pNewTable; - assert( pNew ); - - db = pParse->db; - assert( sqlite3BtreeHoldsAllMutexes(db) ); - iDb = sqlite3SchemaToIndex(db, pNew->pSchema); - zDb = db->aDb[iDb].zName; - zTab = pNew->zName; - pCol = &pNew->aCol[pNew->nCol-1]; - pDflt = pCol->pDflt; - pTab = sqlite3FindTable(db, zTab, zDb); - assert( pTab ); - -#ifndef SQLITE_OMIT_AUTHORIZATION - /* Invoke the authorization callback. */ - if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ - return; - } -#endif - - /* If the default value for the new column was specified with a - ** literal NULL, then set pDflt to 0. This simplifies checking - ** for an SQL NULL default below. - */ - if( pDflt && pDflt->op==TK_NULL ){ - pDflt = 0; - } - - /* Check that the new column is not specified as PRIMARY KEY or UNIQUE. - ** If there is a NOT NULL constraint, then the default value for the - ** column must not be NULL. - */ - if( pCol->isPrimKey ){ - sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); - return; - } - if( pNew->pIndex ){ - sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); - return; - } - if( pCol->notNull && !pDflt ){ - sqlite3ErrorMsg(pParse, - "Cannot add a NOT NULL column with default value NULL"); - return; - } - - /* Ensure the default expression is something that sqlite3ValueFromExpr() - ** can handle (i.e. not CURRENT_TIME etc.) - */ - if( pDflt ){ - sqlite3_value *pVal; - if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ - db->mallocFailed = 1; - return; - } - if( !pVal ){ - sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default"); - return; - } - sqlite3ValueFree(pVal); - } - - /* Modify the CREATE TABLE statement. */ - zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); - if( zCol ){ - char *zEnd = &zCol[pColDef->n-1]; - while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){ - *zEnd-- = '\0'; - } - sqlite3NestedParse(pParse, - "UPDATE %Q.%s SET " - "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d,length(sql)) " - "WHERE type = 'table' AND name = %Q", - zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, - zTab - ); - sqlite3_free(zCol); - } - - /* If the default value of the new column is NULL, then set the file - ** format to 2. If the default value of the new column is not NULL, - ** the file format becomes 3. - */ - sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2); - - /* Reload the schema of the modified table. */ - reloadTableSchema(pParse, pTab, pTab->zName); -} - -/* -** This function is called by the parser after the table-name in -** an "ALTER TABLE ADD" statement is parsed. Argument -** pSrc is the full-name of the table being altered. -** -** This routine makes a (partial) copy of the Table structure -** for the table being altered and sets Parse.pNewTable to point -** to it. Routines called by the parser as the column definition -** is parsed (i.e. sqlite3AddColumn()) add the new Column data to -** the copy. The copy of the Table structure is deleted by tokenize.c -** after parsing is finished. -** -** Routine sqlite3AlterFinishAddColumn() will be called to complete -** coding the "ALTER TABLE ... ADD" statement. -*/ -void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ - Table *pNew; - Table *pTab; - Vdbe *v; - int iDb; - int i; - int nAlloc; - sqlite3 *db = pParse->db; - - /* Look up the table being altered. */ - assert( pParse->pNewTable==0 ); - assert( sqlite3BtreeHoldsAllMutexes(db) ); - if( db->mallocFailed ) goto exit_begin_add_column; - pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); - if( !pTab ) goto exit_begin_add_column; - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); - goto exit_begin_add_column; - } -#endif - - /* Make sure this is not an attempt to ALTER a view. */ - if( pTab->pSelect ){ - sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); - goto exit_begin_add_column; - } - - assert( pTab->addColOffset>0 ); - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - - /* Put a copy of the Table struct in Parse.pNewTable for the - ** sqlite3AddColumn() function and friends to modify. - */ - pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table)); - if( !pNew ) goto exit_begin_add_column; - pParse->pNewTable = pNew; - pNew->nRef = 1; - pNew->nCol = pTab->nCol; - assert( pNew->nCol>0 ); - nAlloc = (((pNew->nCol-1)/8)*8)+8; - assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); - pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); - pNew->zName = sqlite3DbStrDup(db, pTab->zName); - if( !pNew->aCol || !pNew->zName ){ - db->mallocFailed = 1; - goto exit_begin_add_column; - } - memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); - for(i=0; inCol; i++){ - Column *pCol = &pNew->aCol[i]; - pCol->zName = sqlite3DbStrDup(db, pCol->zName); - pCol->zColl = 0; - pCol->zType = 0; - pCol->pDflt = 0; - } - pNew->pSchema = db->aDb[iDb].pSchema; - pNew->addColOffset = pTab->addColOffset; - pNew->nRef = 1; - - /* Begin a transaction and increment the schema cookie. */ - sqlite3BeginWriteOperation(pParse, 0, iDb); - v = sqlite3GetVdbe(pParse); - if( !v ) goto exit_begin_add_column; - sqlite3ChangeCookie(db, v, iDb); - -exit_begin_add_column: - sqlite3SrcListDelete(pSrc); - return; -} -#endif /* SQLITE_ALTER_TABLE */ diff --git a/extensions/sqlite/sqlite-source/analyze.c b/extensions/sqlite/sqlite-source/analyze.c deleted file mode 100644 index 7aef3f67..00000000 --- a/extensions/sqlite/sqlite-source/analyze.c +++ /dev/null @@ -1,418 +0,0 @@ -/* -** 2005 July 8 -** -** 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 file contains code associated with the ANALYZE command. -** -** @(#) $Id$ -*/ -#ifndef SQLITE_OMIT_ANALYZE -#include "sqliteInt.h" - -/* -** This routine generates code that opens the sqlite_stat1 table on cursor -** iStatCur. -** -** If the sqlite_stat1 tables does not previously exist, it is created. -** If it does previously exist, all entires associated with table zWhere -** are removed. If zWhere==0 then all entries are removed. -*/ -static void openStatTable( - Parse *pParse, /* Parsing context */ - int iDb, /* The database we are looking in */ - int iStatCur, /* Open the sqlite_stat1 table on this cursor */ - const char *zWhere /* Delete entries associated with this table */ -){ - sqlite3 *db = pParse->db; - Db *pDb; - int iRootPage; - Table *pStat; - Vdbe *v = sqlite3GetVdbe(pParse); - - if( v==0 ) return; - assert( sqlite3BtreeHoldsAllMutexes(db) ); - assert( sqlite3VdbeDb(v)==db ); - pDb = &db->aDb[iDb]; - if( (pStat = sqlite3FindTable(db, "sqlite_stat1", pDb->zName))==0 ){ - /* The sqlite_stat1 tables does not exist. Create it. - ** Note that a side-effect of the CREATE TABLE statement is to leave - ** the rootpage of the new table on the top of the stack. This is - ** important because the OpenWrite opcode below will be needing it. */ - sqlite3NestedParse(pParse, - "CREATE TABLE %Q.sqlite_stat1(tbl,idx,stat)", - pDb->zName - ); - iRootPage = 0; /* Cause rootpage to be taken from top of stack */ - }else if( zWhere ){ - /* The sqlite_stat1 table exists. Delete all entries associated with - ** the table zWhere. */ - sqlite3NestedParse(pParse, - "DELETE FROM %Q.sqlite_stat1 WHERE tbl=%Q", - pDb->zName, zWhere - ); - iRootPage = pStat->tnum; - }else{ - /* The sqlite_stat1 table already exists. Delete all rows. */ - iRootPage = pStat->tnum; - sqlite3VdbeAddOp(v, OP_Clear, pStat->tnum, iDb); - } - - /* Open the sqlite_stat1 table for writing. Unless it was created - ** by this vdbe program, lock it for writing at the shared-cache level. - ** If this vdbe did create the sqlite_stat1 table, then it must have - ** already obtained a schema-lock, making the write-lock redundant. - */ - if( iRootPage>0 ){ - sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1"); - } - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenWrite, iStatCur, iRootPage); - sqlite3VdbeAddOp(v, OP_SetNumColumns, iStatCur, 3); -} - -/* -** Generate code to do an analysis of all indices associated with -** a single table. -*/ -static void analyzeOneTable( - Parse *pParse, /* Parser context */ - Table *pTab, /* Table whose indices are to be analyzed */ - int iStatCur, /* Cursor that writes to the sqlite_stat1 table */ - int iMem /* Available memory locations begin here */ -){ - Index *pIdx; /* An index to being analyzed */ - int iIdxCur; /* Cursor number for index being analyzed */ - int nCol; /* Number of columns in the index */ - Vdbe *v; /* The virtual machine being built up */ - int i; /* Loop counter */ - int topOfLoop; /* The top of the loop */ - int endOfLoop; /* The end of the loop */ - int addr; /* The address of an instruction */ - int iDb; /* Index of database containing pTab */ - - v = sqlite3GetVdbe(pParse); - if( v==0 || pTab==0 || pTab->pIndex==0 ){ - /* Do no analysis for tables that have no indices */ - return; - } - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - assert( iDb>=0 ); -#ifndef SQLITE_OMIT_AUTHORIZATION - if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, - pParse->db->aDb[iDb].zName ) ){ - return; - } -#endif - - /* Establish a read-lock on the table at the shared-cache level. */ - sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - - iIdxCur = pParse->nTab; - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); - - /* Open a cursor to the index to be analyzed - */ - assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) ); - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); - VdbeComment((v, "# %s", pIdx->zName)); - sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, - (char *)pKey, P3_KEYINFO_HANDOFF); - nCol = pIdx->nColumn; - if( iMem+nCol*2>=pParse->nMem ){ - pParse->nMem = iMem+nCol*2+1; - } - sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, nCol+1); - - /* Memory cells are used as follows: - ** - ** mem[iMem]: The total number of rows in the table. - ** mem[iMem+1]: Number of distinct values in column 1 - ** ... - ** mem[iMem+nCol]: Number of distinct values in column N - ** mem[iMem+nCol+1] Last observed value of column 1 - ** ... - ** mem[iMem+nCol+nCol]: Last observed value of column N - ** - ** Cells iMem through iMem+nCol are initialized to 0. The others - ** are initialized to NULL. - */ - for(i=0; i<=nCol; i++){ - sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem+i); - } - for(i=0; i0 then it is always the case the D>0 so division by zero - ** is never possible. - */ - sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0); - addr = sqlite3VdbeAddOp(v, OP_IfNot, 0, 0); - sqlite3VdbeAddOp(v, OP_NewRowid, iStatCur, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0); - sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, " ", 0); - for(i=0; idb; - Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ - HashElem *k; - int iStatCur; - int iMem; - - sqlite3BeginWriteOperation(pParse, 0, iDb); - iStatCur = pParse->nTab++; - openStatTable(pParse, iDb, iStatCur, 0); - iMem = pParse->nMem; - for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ - Table *pTab = (Table*)sqliteHashData(k); - analyzeOneTable(pParse, pTab, iStatCur, iMem); - } - loadAnalysis(pParse, iDb); -} - -/* -** Generate code that will do an analysis of a single table in -** a database. -*/ -static void analyzeTable(Parse *pParse, Table *pTab){ - int iDb; - int iStatCur; - - assert( pTab!=0 ); - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - sqlite3BeginWriteOperation(pParse, 0, iDb); - iStatCur = pParse->nTab++; - openStatTable(pParse, iDb, iStatCur, pTab->zName); - analyzeOneTable(pParse, pTab, iStatCur, pParse->nMem); - loadAnalysis(pParse, iDb); -} - -/* -** Generate code for the ANALYZE command. The parser calls this routine -** when it recognizes an ANALYZE command. -** -** ANALYZE -- 1 -** ANALYZE -- 2 -** ANALYZE ?.? -- 3 -** -** Form 1 causes all indices in all attached databases to be analyzed. -** Form 2 analyzes all indices the single database named. -** Form 3 analyzes all indices associated with the named table. -*/ -void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ - sqlite3 *db = pParse->db; - int iDb; - int i; - char *z, *zDb; - Table *pTab; - Token *pTableName; - - /* Read the database schema. If an error occurs, leave an error message - ** and code in pParse and return NULL. */ - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - return; - } - - if( pName1==0 ){ - /* Form 1: Analyze everything */ - for(i=0; inDb; i++){ - if( i==1 ) continue; /* Do not analyze the TEMP database */ - analyzeDatabase(pParse, i); - } - }else if( pName2==0 || pName2->n==0 ){ - /* Form 2: Analyze the database or table named */ - iDb = sqlite3FindDb(db, pName1); - if( iDb>=0 ){ - analyzeDatabase(pParse, iDb); - }else{ - z = sqlite3NameFromToken(db, pName1); - pTab = sqlite3LocateTable(pParse, z, 0); - sqlite3_free(z); - if( pTab ){ - analyzeTable(pParse, pTab); - } - } - }else{ - /* Form 3: Analyze the fully qualified table name */ - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); - if( iDb>=0 ){ - zDb = db->aDb[iDb].zName; - z = sqlite3NameFromToken(db, pTableName); - if( z ){ - pTab = sqlite3LocateTable(pParse, z, zDb); - sqlite3_free(z); - if( pTab ){ - analyzeTable(pParse, pTab); - } - } - } - } -} - -/* -** Used to pass information from the analyzer reader through to the -** callback routine. -*/ -typedef struct analysisInfo analysisInfo; -struct analysisInfo { - sqlite3 *db; - const char *zDatabase; -}; - -/* -** This callback is invoked once for each index when reading the -** sqlite_stat1 table. -** -** argv[0] = name of the index -** argv[1] = results of analysis - on integer for each column -*/ -static int analysisLoader(void *pData, int argc, char **argv, char **azNotUsed){ - analysisInfo *pInfo = (analysisInfo*)pData; - Index *pIndex; - int i, c; - unsigned int v; - const char *z; - - assert( argc==2 ); - if( argv==0 || argv[0]==0 || argv[1]==0 ){ - return 0; - } - pIndex = sqlite3FindIndex(pInfo->db, argv[0], pInfo->zDatabase); - if( pIndex==0 ){ - return 0; - } - z = argv[1]; - for(i=0; *z && i<=pIndex->nColumn; i++){ - v = 0; - while( (c=z[0])>='0' && c<='9' ){ - v = v*10 + c - '0'; - z++; - } - pIndex->aiRowEst[i] = v; - if( *z==' ' ) z++; - } - return 0; -} - -/* -** Load the content of the sqlite_stat1 table into the index hash tables. -*/ -int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ - analysisInfo sInfo; - HashElem *i; - char *zSql; - int rc; - - assert( iDb>=0 && iDbnDb ); - assert( db->aDb[iDb].pBt!=0 ); - assert( sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); - - /* Clear any prior statistics */ - for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ - Index *pIdx = sqliteHashData(i); - sqlite3DefaultRowEst(pIdx); - } - - /* Check to make sure the sqlite_stat1 table existss */ - sInfo.db = db; - sInfo.zDatabase = db->aDb[iDb].zName; - if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){ - return SQLITE_ERROR; - } - - - /* Load new statistics out of the sqlite_stat1 table */ - zSql = sqlite3MPrintf(db, "SELECT idx, stat FROM %Q.sqlite_stat1", - sInfo.zDatabase); - sqlite3SafetyOff(db); - rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); - sqlite3SafetyOn(db); - sqlite3_free(zSql); - return rc; -} - - -#endif /* SQLITE_OMIT_ANALYZE */ diff --git a/extensions/sqlite/sqlite-source/attach.c b/extensions/sqlite/sqlite-source/attach.c deleted file mode 100644 index 271116b7..00000000 --- a/extensions/sqlite/sqlite-source/attach.c +++ /dev/null @@ -1,521 +0,0 @@ -/* -** 2003 April 6 -** -** 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 file contains code used to implement the ATTACH and DETACH commands. -** -** $Id$ -*/ -#include "sqliteInt.h" - -#ifndef SQLITE_OMIT_ATTACH -/* -** Resolve an expression that was part of an ATTACH or DETACH statement. This -** is slightly different from resolving a normal SQL expression, because simple -** identifiers are treated as strings, not possible column names or aliases. -** -** i.e. if the parser sees: -** -** ATTACH DATABASE abc AS def -** -** it treats the two expressions as literal strings 'abc' and 'def' instead of -** looking for columns of the same name. -** -** This only applies to the root node of pExpr, so the statement: -** -** ATTACH DATABASE abc||def AS 'db2' -** -** will fail because neither abc or def can be resolved. -*/ -static int resolveAttachExpr(NameContext *pName, Expr *pExpr) -{ - int rc = SQLITE_OK; - if( pExpr ){ - if( pExpr->op!=TK_ID ){ - rc = sqlite3ExprResolveNames(pName, pExpr); - if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){ - sqlite3ErrorMsg(pName->pParse, "invalid name: \"%T\"", &pExpr->span); - return SQLITE_ERROR; - } - }else{ - pExpr->op = TK_STRING; - } - } - return rc; -} - -/* -** An SQL user-function registered to do the work of an ATTACH statement. The -** three arguments to the function come directly from an attach statement: -** -** ATTACH DATABASE x AS y KEY z -** -** SELECT sqlite_attach(x, y, z) -** -** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the -** third argument. -*/ -static void attachFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int i; - int rc = 0; - sqlite3 *db = sqlite3_user_data(context); - const char *zName; - const char *zFile; - Db *aNew; - char *zErrDyn = 0; - char zErr[128]; - - zFile = (const char *)sqlite3_value_text(argv[0]); - zName = (const char *)sqlite3_value_text(argv[1]); - if( zFile==0 ) zFile = ""; - if( zName==0 ) zName = ""; - - /* Check for the following errors: - ** - ** * Too many attached databases, - ** * Transaction currently open - ** * Specified database name already being used. - */ - if( db->nDb>=SQLITE_MAX_ATTACHED+2 ){ - sqlite3_snprintf( - sizeof(zErr), zErr, "too many attached databases - max %d", - SQLITE_MAX_ATTACHED - ); - goto attach_error; - } - if( !db->autoCommit ){ - sqlite3_snprintf(sizeof(zErr), zErr, - "cannot ATTACH database within transaction"); - goto attach_error; - } - for(i=0; inDb; i++){ - char *z = db->aDb[i].zName; - if( z && zName && sqlite3StrICmp(z, zName)==0 ){ - sqlite3_snprintf(sizeof(zErr), zErr, - "database %s is already in use", zName); - goto attach_error; - } - } - - /* Allocate the new entry in the db->aDb[] array and initialise the schema - ** hash tables. - */ - if( db->aDb==db->aDbStatic ){ - aNew = sqlite3_malloc( sizeof(db->aDb[0])*3 ); - if( aNew==0 ){ - db->mallocFailed = 1; - return; - } - memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); - }else{ - aNew = sqlite3_realloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); - if( aNew==0 ){ - db->mallocFailed = 1; - return; - } - } - db->aDb = aNew; - aNew = &db->aDb[db->nDb++]; - memset(aNew, 0, sizeof(*aNew)); - - /* Open the database file. If the btree is successfully opened, use - ** it to obtain the database schema. At this point the schema may - ** or may not be initialised. - */ - rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE, - db->openFlags | SQLITE_OPEN_MAIN_DB, - &aNew->pBt); - if( rc==SQLITE_OK ){ - aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt); - if( !aNew->pSchema ){ - rc = SQLITE_NOMEM; - }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){ - sqlite3_snprintf(sizeof(zErr), zErr, - "attached databases must use the same text encoding as main database"); - goto attach_error; - } - sqlite3PagerLockingMode(sqlite3BtreePager(aNew->pBt), db->dfltLockMode); - } - aNew->zName = sqlite3DbStrDup(db, zName); - aNew->safety_level = 3; - -#if SQLITE_HAS_CODEC - { - extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); - extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); - int nKey; - char *zKey; - int t = sqlite3_value_type(argv[2]); - switch( t ){ - case SQLITE_INTEGER: - case SQLITE_FLOAT: - zErrDyn = sqlite3DbStrDup(db, "Invalid key value"); - rc = SQLITE_ERROR; - break; - - case SQLITE_TEXT: - case SQLITE_BLOB: - nKey = sqlite3_value_bytes(argv[2]); - zKey = (char *)sqlite3_value_blob(argv[2]); - sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); - break; - - case SQLITE_NULL: - /* No key specified. Use the key from the main database */ - sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); - sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); - break; - } - } -#endif - - /* If the file was opened successfully, read the schema for the new database. - ** If this fails, or if opening the file failed, then close the file and - ** remove the entry from the db->aDb[] array. i.e. put everything back the way - ** we found it. - */ - if( rc==SQLITE_OK ){ - sqlite3SafetyOn(db); - rc = sqlite3Init(db, &zErrDyn); - sqlite3SafetyOff(db); - } - if( rc ){ - int iDb = db->nDb - 1; - assert( iDb>=2 ); - if( db->aDb[iDb].pBt ){ - sqlite3BtreeClose(db->aDb[iDb].pBt); - db->aDb[iDb].pBt = 0; - db->aDb[iDb].pSchema = 0; - } - sqlite3ResetInternalSchema(db, 0); - db->nDb = iDb; - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - db->mallocFailed = 1; - sqlite3_snprintf(sizeof(zErr),zErr, "out of memory"); - }else{ - sqlite3_snprintf(sizeof(zErr),zErr, "unable to open database: %s", zFile); - } - goto attach_error; - } - - return; - -attach_error: - /* Return an error if we get here */ - if( zErrDyn ){ - sqlite3_result_error(context, zErrDyn, -1); - sqlite3_free(zErrDyn); - }else{ - zErr[sizeof(zErr)-1] = 0; - sqlite3_result_error(context, zErr, -1); - } -} - -/* -** An SQL user-function registered to do the work of an DETACH statement. The -** three arguments to the function come directly from a detach statement: -** -** DETACH DATABASE x -** -** SELECT sqlite_detach(x) -*/ -static void detachFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const char *zName = (const char *)sqlite3_value_text(argv[0]); - sqlite3 *db = sqlite3_user_data(context); - int i; - Db *pDb = 0; - char zErr[128]; - - if( zName==0 ) zName = ""; - for(i=0; inDb; i++){ - pDb = &db->aDb[i]; - if( pDb->pBt==0 ) continue; - if( sqlite3StrICmp(pDb->zName, zName)==0 ) break; - } - - if( i>=db->nDb ){ - sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName); - goto detach_error; - } - if( i<2 ){ - sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); - goto detach_error; - } - if( !db->autoCommit ){ - sqlite3_snprintf(sizeof(zErr), zErr, - "cannot DETACH database within transaction"); - goto detach_error; - } - if( sqlite3BtreeIsInReadTrans(pDb->pBt) ){ - sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); - goto detach_error; - } - - sqlite3BtreeClose(pDb->pBt); - pDb->pBt = 0; - pDb->pSchema = 0; - sqlite3ResetInternalSchema(db, 0); - return; - -detach_error: - sqlite3_result_error(context, zErr, -1); -} - -/* -** This procedure generates VDBE code for a single invocation of either the -** sqlite_detach() or sqlite_attach() SQL user functions. -*/ -static void codeAttach( - Parse *pParse, /* The parser context */ - int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */ - const char *zFunc, /* Either "sqlite_attach" or "sqlite_detach */ - int nFunc, /* Number of args to pass to zFunc */ - Expr *pAuthArg, /* Expression to pass to authorization callback */ - Expr *pFilename, /* Name of database file */ - Expr *pDbname, /* Name of the database to use internally */ - Expr *pKey /* Database key for encryption extension */ -){ - int rc; - NameContext sName; - Vdbe *v; - FuncDef *pFunc; - sqlite3* db = pParse->db; - -#ifndef SQLITE_OMIT_AUTHORIZATION - assert( db->mallocFailed || pAuthArg ); - if( pAuthArg ){ - char *zAuthArg = sqlite3NameFromToken(db, &pAuthArg->span); - if( !zAuthArg ){ - goto attach_end; - } - rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); - sqlite3_free(zAuthArg); - if(rc!=SQLITE_OK ){ - goto attach_end; - } - } -#endif /* SQLITE_OMIT_AUTHORIZATION */ - - memset(&sName, 0, sizeof(NameContext)); - sName.pParse = pParse; - - if( - SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) || - SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) || - SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) - ){ - pParse->nErr++; - goto attach_end; - } - - v = sqlite3GetVdbe(pParse); - sqlite3ExprCode(pParse, pFilename); - sqlite3ExprCode(pParse, pDbname); - sqlite3ExprCode(pParse, pKey); - - assert( v || db->mallocFailed ); - if( v ){ - sqlite3VdbeAddOp(v, OP_Function, 0, nFunc); - pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0); - sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF); - - /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this - ** statement only). For DETACH, set it to false (expire all existing - ** statements). - */ - sqlite3VdbeAddOp(v, OP_Expire, (type==SQLITE_ATTACH), 0); - } - -attach_end: - sqlite3ExprDelete(pFilename); - sqlite3ExprDelete(pDbname); - sqlite3ExprDelete(pKey); -} - -/* -** Called by the parser to compile a DETACH statement. -** -** DETACH pDbname -*/ -void sqlite3Detach(Parse *pParse, Expr *pDbname){ - codeAttach(pParse, SQLITE_DETACH, "sqlite_detach", 1, pDbname, 0, 0, pDbname); -} - -/* -** Called by the parser to compile an ATTACH statement. -** -** ATTACH p AS pDbname KEY pKey -*/ -void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ - codeAttach(pParse, SQLITE_ATTACH, "sqlite_attach", 3, p, p, pDbname, pKey); -} -#endif /* SQLITE_OMIT_ATTACH */ - -/* -** Register the functions sqlite_attach and sqlite_detach. -*/ -void sqlite3AttachFunctions(sqlite3 *db){ -#ifndef SQLITE_OMIT_ATTACH - static const int enc = SQLITE_UTF8; - sqlite3CreateFunc(db, "sqlite_attach", 3, enc, db, attachFunc, 0, 0); - sqlite3CreateFunc(db, "sqlite_detach", 1, enc, db, detachFunc, 0, 0); -#endif -} - -/* -** Initialize a DbFixer structure. This routine must be called prior -** to passing the structure to one of the sqliteFixAAAA() routines below. -** -** The return value indicates whether or not fixation is required. TRUE -** means we do need to fix the database references, FALSE means we do not. -*/ -int sqlite3FixInit( - DbFixer *pFix, /* The fixer to be initialized */ - Parse *pParse, /* Error messages will be written here */ - int iDb, /* This is the database that must be used */ - const char *zType, /* "view", "trigger", or "index" */ - const Token *pName /* Name of the view, trigger, or index */ -){ - sqlite3 *db; - - if( iDb<0 || iDb==1 ) return 0; - db = pParse->db; - assert( db->nDb>iDb ); - pFix->pParse = pParse; - pFix->zDb = db->aDb[iDb].zName; - pFix->zType = zType; - pFix->pName = pName; - return 1; -} - -/* -** The following set of routines walk through the parse tree and assign -** a specific database to all table references where the database name -** was left unspecified in the original SQL statement. The pFix structure -** must have been initialized by a prior call to sqlite3FixInit(). -** -** These routines are used to make sure that an index, trigger, or -** view in one database does not refer to objects in a different database. -** (Exception: indices, triggers, and views in the TEMP database are -** allowed to refer to anything.) If a reference is explicitly made -** to an object in a different database, an error message is added to -** pParse->zErrMsg and these routines return non-zero. If everything -** checks out, these routines return 0. -*/ -int sqlite3FixSrcList( - DbFixer *pFix, /* Context of the fixation */ - SrcList *pList /* The Source list to check and modify */ -){ - int i; - const char *zDb; - struct SrcList_item *pItem; - - if( pList==0 ) return 0; - zDb = pFix->zDb; - for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pItem->zDatabase==0 ){ - pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb); - }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){ - sqlite3ErrorMsg(pFix->pParse, - "%s %T cannot reference objects in database %s", - pFix->zType, pFix->pName, pItem->zDatabase); - return 1; - } -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) - if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; - if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; -#endif - } - return 0; -} -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) -int sqlite3FixSelect( - DbFixer *pFix, /* Context of the fixation */ - Select *pSelect /* The SELECT statement to be fixed to one database */ -){ - while( pSelect ){ - if( sqlite3FixExprList(pFix, pSelect->pEList) ){ - return 1; - } - if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ - return 1; - } - pSelect = pSelect->pPrior; - } - return 0; -} -int sqlite3FixExpr( - DbFixer *pFix, /* Context of the fixation */ - Expr *pExpr /* The expression to be fixed to one database */ -){ - while( pExpr ){ - if( sqlite3FixSelect(pFix, pExpr->pSelect) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pExpr->pList) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pExpr->pRight) ){ - return 1; - } - pExpr = pExpr->pLeft; - } - return 0; -} -int sqlite3FixExprList( - DbFixer *pFix, /* Context of the fixation */ - ExprList *pList /* The expression to be fixed to one database */ -){ - int i; - struct ExprList_item *pItem; - if( pList==0 ) return 0; - for(i=0, pItem=pList->a; inExpr; i++, pItem++){ - if( sqlite3FixExpr(pFix, pItem->pExpr) ){ - return 1; - } - } - return 0; -} -#endif - -#ifndef SQLITE_OMIT_TRIGGER -int sqlite3FixTriggerStep( - DbFixer *pFix, /* Context of the fixation */ - TriggerStep *pStep /* The trigger step be fixed to one database */ -){ - while( pStep ){ - if( sqlite3FixSelect(pFix, pStep->pSelect) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pStep->pWhere) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pStep->pExprList) ){ - return 1; - } - pStep = pStep->pNext; - } - return 0; -} -#endif diff --git a/extensions/sqlite/sqlite-source/auth.c b/extensions/sqlite/sqlite-source/auth.c deleted file mode 100644 index dd83eda0..00000000 --- a/extensions/sqlite/sqlite-source/auth.c +++ /dev/null @@ -1,234 +0,0 @@ -/* -** 2003 January 11 -** -** 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 file contains code used to implement the sqlite3_set_authorizer() -** API. This facility is an optional feature of the library. Embedded -** systems that do not need this facility may omit it by recompiling -** the library with -DSQLITE_OMIT_AUTHORIZATION=1 -** -** $Id$ -*/ -#include "sqliteInt.h" - -/* -** All of the code in this file may be omitted by defining a single -** macro. -*/ -#ifndef SQLITE_OMIT_AUTHORIZATION - -/* -** Set or clear the access authorization function. -** -** The access authorization function is be called during the compilation -** phase to verify that the user has read and/or write access permission on -** various fields of the database. The first argument to the auth function -** is a copy of the 3rd argument to this routine. The second argument -** to the auth function is one of these constants: -** -** SQLITE_CREATE_INDEX -** SQLITE_CREATE_TABLE -** SQLITE_CREATE_TEMP_INDEX -** SQLITE_CREATE_TEMP_TABLE -** SQLITE_CREATE_TEMP_TRIGGER -** SQLITE_CREATE_TEMP_VIEW -** SQLITE_CREATE_TRIGGER -** SQLITE_CREATE_VIEW -** SQLITE_DELETE -** SQLITE_DROP_INDEX -** SQLITE_DROP_TABLE -** SQLITE_DROP_TEMP_INDEX -** SQLITE_DROP_TEMP_TABLE -** SQLITE_DROP_TEMP_TRIGGER -** SQLITE_DROP_TEMP_VIEW -** SQLITE_DROP_TRIGGER -** SQLITE_DROP_VIEW -** SQLITE_INSERT -** SQLITE_PRAGMA -** SQLITE_READ -** SQLITE_SELECT -** SQLITE_TRANSACTION -** SQLITE_UPDATE -** -** The third and fourth arguments to the auth function are the name of -** the table and the column that are being accessed. The auth function -** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If -** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY -** means that the SQL statement will never-run - the sqlite3_exec() call -** will return with an error. SQLITE_IGNORE means that the SQL statement -** should run but attempts to read the specified column will return NULL -** and attempts to write the column will be ignored. -** -** Setting the auth function to NULL disables this hook. The default -** setting of the auth function is NULL. -*/ -int sqlite3_set_authorizer( - sqlite3 *db, - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), - void *pArg -){ - sqlite3_mutex_enter(db->mutex); - db->xAuth = xAuth; - db->pAuthArg = pArg; - sqlite3ExpirePreparedStatements(db); - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} - -/* -** Write an error message into pParse->zErrMsg that explains that the -** user-supplied authorization function returned an illegal value. -*/ -static void sqliteAuthBadReturnCode(Parse *pParse, int rc){ - sqlite3ErrorMsg(pParse, "illegal return value (%d) from the " - "authorization function - should be SQLITE_OK, SQLITE_IGNORE, " - "or SQLITE_DENY", rc); - pParse->rc = SQLITE_ERROR; -} - -/* -** The pExpr should be a TK_COLUMN expression. The table referred to -** is in pTabList or else it is the NEW or OLD table of a trigger. -** Check to see if it is OK to read this particular column. -** -** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN -** instruction into a TK_NULL. If the auth function returns SQLITE_DENY, -** then generate an error. -*/ -void sqlite3AuthRead( - Parse *pParse, /* The parser context */ - Expr *pExpr, /* The expression to check authorization on */ - Schema *pSchema, /* The schema of the expression */ - SrcList *pTabList /* All table that pExpr might refer to */ -){ - sqlite3 *db = pParse->db; - int rc; - Table *pTab = 0; /* The table being read */ - const char *zCol; /* Name of the column of the table */ - int iSrc; /* Index in pTabList->a[] of table being read */ - const char *zDBase; /* Name of database being accessed */ - TriggerStack *pStack; /* The stack of current triggers */ - int iDb; /* The index of the database the expression refers to */ - - if( db->xAuth==0 ) return; - if( pExpr->op!=TK_COLUMN ) return; - iDb = sqlite3SchemaToIndex(pParse->db, pSchema); - if( iDb<0 ){ - /* An attempt to read a column out of a subquery or other - ** temporary table. */ - return; - } - for(iSrc=0; pTabList && iSrcnSrc; iSrc++){ - if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break; - } - if( iSrc>=0 && pTabList && iSrcnSrc ){ - pTab = pTabList->a[iSrc].pTab; - }else if( (pStack = pParse->trigStack)!=0 ){ - /* This must be an attempt to read the NEW or OLD pseudo-tables - ** of a trigger. - */ - assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx ); - pTab = pStack->pTab; - } - if( pTab==0 ) return; - if( pExpr->iColumn>=0 ){ - assert( pExpr->iColumnnCol ); - zCol = pTab->aCol[pExpr->iColumn].zName; - }else if( pTab->iPKey>=0 ){ - assert( pTab->iPKeynCol ); - zCol = pTab->aCol[pTab->iPKey].zName; - }else{ - zCol = "ROWID"; - } - assert( iDb>=0 && iDbnDb ); - zDBase = db->aDb[iDb].zName; - rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase, - pParse->zAuthContext); - if( rc==SQLITE_IGNORE ){ - pExpr->op = TK_NULL; - }else if( rc==SQLITE_DENY ){ - if( db->nDb>2 || iDb!=0 ){ - sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited", - zDBase, pTab->zName, zCol); - }else{ - sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited",pTab->zName,zCol); - } - pParse->rc = SQLITE_AUTH; - }else if( rc!=SQLITE_OK ){ - sqliteAuthBadReturnCode(pParse, rc); - } -} - -/* -** Do an authorization check using the code and arguments given. Return -** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY -** is returned, then the error count and error message in pParse are -** modified appropriately. -*/ -int sqlite3AuthCheck( - Parse *pParse, - int code, - const char *zArg1, - const char *zArg2, - const char *zArg3 -){ - sqlite3 *db = pParse->db; - int rc; - - /* Don't do any authorization checks if the database is initialising - ** or if the parser is being invoked from within sqlite3_declare_vtab. - */ - if( db->init.busy || IN_DECLARE_VTAB ){ - return SQLITE_OK; - } - - if( db->xAuth==0 ){ - return SQLITE_OK; - } - rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext); - if( rc==SQLITE_DENY ){ - sqlite3ErrorMsg(pParse, "not authorized"); - pParse->rc = SQLITE_AUTH; - }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ - rc = SQLITE_DENY; - sqliteAuthBadReturnCode(pParse, rc); - } - return rc; -} - -/* -** Push an authorization context. After this routine is called, the -** zArg3 argument to authorization callbacks will be zContext until -** popped. Or if pParse==0, this routine is a no-op. -*/ -void sqlite3AuthContextPush( - Parse *pParse, - AuthContext *pContext, - const char *zContext -){ - pContext->pParse = pParse; - if( pParse ){ - pContext->zAuthContext = pParse->zAuthContext; - pParse->zAuthContext = zContext; - } -} - -/* -** Pop an authorization context that was previously pushed -** by sqlite3AuthContextPush -*/ -void sqlite3AuthContextPop(AuthContext *pContext){ - if( pContext->pParse ){ - pContext->pParse->zAuthContext = pContext->zAuthContext; - pContext->pParse = 0; - } -} - -#endif /* SQLITE_OMIT_AUTHORIZATION */ diff --git a/extensions/sqlite/sqlite-source/btmutex.c b/extensions/sqlite/sqlite-source/btmutex.c deleted file mode 100644 index 5866ffeb..00000000 --- a/extensions/sqlite/sqlite-source/btmutex.c +++ /dev/null @@ -1,315 +0,0 @@ -/* -** 2007 August 27 -** -** 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. -** -************************************************************************* -** -** $Id$ -** -** This file contains code used to implement mutexes on Btree objects. -** This code really belongs in btree.c. But btree.c is getting too -** big and we want to break it down some. This packaged seemed like -** a good breakout. -*/ -#include "btreeInt.h" -#if SQLITE_THREADSAFE && !defined(SQLITE_OMIT_SHARED_CACHE) - - -/* -** Enter a mutex on the given BTree object. -** -** If the object is not sharable, then no mutex is ever required -** and this routine is a no-op. The underlying mutex is non-recursive. -** But we keep a reference count in Btree.wantToLock so the behavior -** of this interface is recursive. -** -** To avoid deadlocks, multiple Btrees are locked in the same order -** by all database connections. The p->pNext is a list of other -** Btrees belonging to the same database connection as the p Btree -** which need to be locked after p. If we cannot get a lock on -** p, then first unlock all of the others on p->pNext, then wait -** for the lock to become available on p, then relock all of the -** subsequent Btrees that desire a lock. -*/ -void sqlite3BtreeEnter(Btree *p){ - Btree *pLater; - - /* Some basic sanity checking on the Btree. The list of Btrees - ** connected by pNext and pPrev should be in sorted order by - ** Btree.pBt value. All elements of the list should belong to - ** the same connection. Only shared Btrees are on the list. */ - assert( p->pNext==0 || p->pNext->pBt>p->pBt ); - assert( p->pPrev==0 || p->pPrev->pBtpBt ); - assert( p->pNext==0 || p->pNext->pSqlite==p->pSqlite ); - assert( p->pPrev==0 || p->pPrev->pSqlite==p->pSqlite ); - assert( p->sharable || (p->pNext==0 && p->pPrev==0) ); - - /* Check for locking consistency */ - assert( !p->locked || p->wantToLock>0 ); - assert( p->sharable || p->wantToLock==0 ); - - /* We should already hold a lock on the database connection */ - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - - if( !p->sharable ) return; - p->wantToLock++; - if( p->locked ) return; - - /* In most cases, we should be able to acquire the lock we - ** want without having to go throught the ascending lock - ** procedure that follows. Just be sure not to block. - */ - if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){ - p->locked = 1; - return; - } - - /* To avoid deadlock, first release all locks with a larger - ** BtShared address. Then acquire our lock. Then reacquire - ** the other BtShared locks that we used to hold in ascending - ** order. - */ - for(pLater=p->pNext; pLater; pLater=pLater->pNext){ - assert( pLater->sharable ); - assert( pLater->pNext==0 || pLater->pNext->pBt>pLater->pBt ); - assert( !pLater->locked || pLater->wantToLock>0 ); - if( pLater->locked ){ - sqlite3_mutex_leave(pLater->pBt->mutex); - pLater->locked = 0; - } - } - sqlite3_mutex_enter(p->pBt->mutex); - p->locked = 1; - for(pLater=p->pNext; pLater; pLater=pLater->pNext){ - if( pLater->wantToLock ){ - sqlite3_mutex_enter(pLater->pBt->mutex); - pLater->locked = 1; - } - } -} - -/* -** Exit the recursive mutex on a Btree. -*/ -void sqlite3BtreeLeave(Btree *p){ - if( p->sharable ){ - assert( p->wantToLock>0 ); - p->wantToLock--; - if( p->wantToLock==0 ){ - assert( p->locked ); - sqlite3_mutex_leave(p->pBt->mutex); - p->locked = 0; - } - } -} - -#ifndef NDEBUG -/* -** Return true if the BtShared mutex is held on the btree. -** -** This routine makes no determination one why or another if the -** database connection mutex is held. -** -** This routine is used only from within assert() statements. -*/ -int sqlite3BtreeHoldsMutex(Btree *p){ - return (p->sharable==0 || - (p->locked && p->wantToLock && sqlite3_mutex_held(p->pBt->mutex))); -} -#endif - - -#ifndef SQLITE_OMIT_INCRBLOB -/* -** Enter and leave a mutex on a Btree given a cursor owned by that -** Btree. These entry points are used by incremental I/O and can be -** omitted if that module is not used. -*/ -void sqlite3BtreeEnterCursor(BtCursor *pCur){ - sqlite3BtreeEnter(pCur->pBtree); -} -void sqlite3BtreeLeaveCursor(BtCursor *pCur){ - sqlite3BtreeLeave(pCur->pBtree); -} -#endif /* SQLITE_OMIT_INCRBLOB */ - - -/* -** Enter the mutex on every Btree associated with a database -** connection. This is needed (for example) prior to parsing -** a statement since we will be comparing table and column names -** against all schemas and we do not want those schemas being -** reset out from under us. -** -** There is a corresponding leave-all procedures. -** -** Enter the mutexes in accending order by BtShared pointer address -** to avoid the possibility of deadlock when two threads with -** two or more btrees in common both try to lock all their btrees -** at the same instant. -*/ -void sqlite3BtreeEnterAll(sqlite3 *db){ - int i; - Btree *p, *pLater; - assert( sqlite3_mutex_held(db->mutex) ); - for(i=0; inDb; i++){ - p = db->aDb[i].pBt; - if( p && p->sharable ){ - p->wantToLock++; - if( !p->locked ){ - assert( p->wantToLock==1 ); - while( p->pPrev ) p = p->pPrev; - while( p->locked && p->pNext ) p = p->pNext; - for(pLater = p->pNext; pLater; pLater=pLater->pNext){ - if( pLater->locked ){ - sqlite3_mutex_leave(pLater->pBt->mutex); - pLater->locked = 0; - } - } - while( p ){ - sqlite3_mutex_enter(p->pBt->mutex); - p->locked++; - p = p->pNext; - } - } - } - } -} -void sqlite3BtreeLeaveAll(sqlite3 *db){ - int i; - Btree *p; - assert( sqlite3_mutex_held(db->mutex) ); - for(i=0; inDb; i++){ - p = db->aDb[i].pBt; - if( p && p->sharable ){ - assert( p->wantToLock>0 ); - p->wantToLock--; - if( p->wantToLock==0 ){ - assert( p->locked ); - sqlite3_mutex_leave(p->pBt->mutex); - p->locked = 0; - } - } - } -} - -#ifndef NDEBUG -/* -** Return true if the current thread holds the database connection -** mutex and all required BtShared mutexes. -** -** This routine is used inside assert() statements only. -*/ -int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){ - int i; - if( !sqlite3_mutex_held(db->mutex) ){ - return 0; - } - for(i=0; inDb; i++){ - Btree *p; - p = db->aDb[i].pBt; - if( p && p->sharable && - (p->wantToLock==0 || !sqlite3_mutex_held(p->pBt->mutex)) ){ - return 0; - } - } - return 1; -} -#endif /* NDEBUG */ - -/* -** Potentially dd a new Btree pointer to a BtreeMutexArray. -** Really only add the Btree if it can possibly be shared with -** another database connection. -** -** The Btrees are kept in sorted order by pBtree->pBt. That -** way when we go to enter all the mutexes, we can enter them -** in order without every having to backup and retry and without -** worrying about deadlock. -** -** The number of shared btrees will always be small (usually 0 or 1) -** so an insertion sort is an adequate algorithm here. -*/ -void sqlite3BtreeMutexArrayInsert(BtreeMutexArray *pArray, Btree *pBtree){ - int i, j; - BtShared *pBt; - if( pBtree==0 || pBtree->sharable==0 ) return; -#ifndef NDEBUG - { - for(i=0; inMutex; i++){ - assert( pArray->aBtree[i]!=pBtree ); - } - } -#endif - assert( pArray->nMutex>=0 ); - assert( pArray->nMutexaBtree)/sizeof(pArray->aBtree[0])-1 ); - pBt = pBtree->pBt; - for(i=0; inMutex; i++){ - assert( pArray->aBtree[i]!=pBtree ); - if( pArray->aBtree[i]->pBt>pBt ){ - for(j=pArray->nMutex; j>i; j--){ - pArray->aBtree[j] = pArray->aBtree[j-1]; - } - pArray->aBtree[i] = pBtree; - pArray->nMutex++; - return; - } - } - pArray->aBtree[pArray->nMutex++] = pBtree; -} - -/* -** Enter the mutex of every btree in the array. This routine is -** called at the beginning of sqlite3VdbeExec(). The mutexes are -** exited at the end of the same function. -*/ -void sqlite3BtreeMutexArrayEnter(BtreeMutexArray *pArray){ - int i; - for(i=0; inMutex; i++){ - Btree *p = pArray->aBtree[i]; - /* Some basic sanity checking */ - assert( i==0 || pArray->aBtree[i-1]->pBtpBt ); - assert( !p->locked || p->wantToLock>0 ); - - /* We should already hold a lock on the database connection */ - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - - p->wantToLock++; - if( !p->locked && p->sharable ){ - sqlite3_mutex_enter(p->pBt->mutex); - p->locked = 1; - } - } -} - -/* -** Leave the mutex of every btree in the group. -*/ -void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray){ - int i; - for(i=0; inMutex; i++){ - Btree *p = pArray->aBtree[i]; - /* Some basic sanity checking */ - assert( i==0 || pArray->aBtree[i-1]->pBtpBt ); - assert( p->locked || !p->sharable ); - assert( p->wantToLock>0 ); - - /* We should already hold a lock on the database connection */ - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - - p->wantToLock--; - if( p->wantToLock==0 && p->locked ){ - sqlite3_mutex_leave(p->pBt->mutex); - p->locked = 0; - } - } -} - - -#endif /* SQLITE_THREADSAFE && !SQLITE_OMIT_SHARED_CACHE */ diff --git a/extensions/sqlite/sqlite-source/btree.c b/extensions/sqlite/sqlite-source/btree.c deleted file mode 100644 index 0ba3655a..00000000 --- a/extensions/sqlite/sqlite-source/btree.c +++ /dev/null @@ -1,6890 +0,0 @@ -/* -** 2004 April 6 -** -** 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. -** -************************************************************************* -** $Id$ -** -** This file implements a external (disk-based) database using BTrees. -** See the header comment on "btreeInt.h" for additional information. -** Including a description of file format and an overview of operation. -*/ -#include "btreeInt.h" - -/* -** The header string that appears at the beginning of every -** SQLite database. -*/ -static const char zMagicHeader[] = SQLITE_FILE_HEADER; - -/* -** Set this global variable to 1 to enable tracing using the TRACE -** macro. -*/ -#if SQLITE_TEST -int sqlite3_btree_trace=0; /* True to enable tracing */ -#endif - - - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** A flag to indicate whether or not shared cache is enabled. Also, -** a list of BtShared objects that are eligible for participation -** in shared cache. The variables have file scope during normal builds, -** but the test harness needs to access these variables so we make them -** global for test builds. -*/ -#ifdef SQLITE_TEST -BtShared *sqlite3SharedCacheList = 0; -int sqlite3SharedCacheEnabled = 0; -#else -static BtShared *sqlite3SharedCacheList = 0; -static int sqlite3SharedCacheEnabled = 0; -#endif -#endif /* SQLITE_OMIT_SHARED_CACHE */ - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** Enable or disable the shared pager and schema features. -** -** This routine has no effect on existing database connections. -** The shared cache setting effects only future calls to -** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2(). -*/ -int sqlite3_enable_shared_cache(int enable){ - sqlite3SharedCacheEnabled = enable; - return SQLITE_OK; -} -#endif - - -/* -** Forward declaration -*/ -static int checkReadLocks(Btree*,Pgno,BtCursor*); - - -#ifdef SQLITE_OMIT_SHARED_CACHE - /* - ** The functions queryTableLock(), lockTable() and unlockAllTables() - ** manipulate entries in the BtShared.pLock linked list used to store - ** shared-cache table level locks. If the library is compiled with the - ** shared-cache feature disabled, then there is only ever one user - ** of each BtShared structure and so this locking is not necessary. - ** So define the lock related functions as no-ops. - */ - #define queryTableLock(a,b,c) SQLITE_OK - #define lockTable(a,b,c) SQLITE_OK - #define unlockAllTables(a) -#endif - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** Query to see if btree handle p may obtain a lock of type eLock -** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return -** SQLITE_OK if the lock may be obtained (by calling lockTable()), or -** SQLITE_LOCKED if not. -*/ -static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){ - BtShared *pBt = p->pBt; - BtLock *pIter; - - assert( sqlite3BtreeHoldsMutex(p) ); - - /* This is a no-op if the shared-cache is not enabled */ - if( !p->sharable ){ - return SQLITE_OK; - } - - /* This (along with lockTable()) is where the ReadUncommitted flag is - ** dealt with. If the caller is querying for a read-lock and the flag is - ** set, it is unconditionally granted - even if there are write-locks - ** on the table. If a write-lock is requested, the ReadUncommitted flag - ** is not considered. - ** - ** In function lockTable(), if a read-lock is demanded and the - ** ReadUncommitted flag is set, no entry is added to the locks list - ** (BtShared.pLock). - ** - ** To summarize: If the ReadUncommitted flag is set, then read cursors do - ** not create or respect table locks. The locking procedure for a - ** write-cursor does not change. - */ - if( - !p->pSqlite || - 0==(p->pSqlite->flags&SQLITE_ReadUncommitted) || - eLock==WRITE_LOCK || - iTab==MASTER_ROOT - ){ - for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ - if( pIter->pBtree!=p && pIter->iTable==iTab && - (pIter->eLock!=eLock || eLock!=READ_LOCK) ){ - return SQLITE_LOCKED; - } - } - } - return SQLITE_OK; -} -#endif /* !SQLITE_OMIT_SHARED_CACHE */ - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** Add a lock on the table with root-page iTable to the shared-btree used -** by Btree handle p. Parameter eLock must be either READ_LOCK or -** WRITE_LOCK. -** -** SQLITE_OK is returned if the lock is added successfully. SQLITE_BUSY and -** SQLITE_NOMEM may also be returned. -*/ -static int lockTable(Btree *p, Pgno iTable, u8 eLock){ - BtShared *pBt = p->pBt; - BtLock *pLock = 0; - BtLock *pIter; - - assert( sqlite3BtreeHoldsMutex(p) ); - - /* This is a no-op if the shared-cache is not enabled */ - if( !p->sharable ){ - return SQLITE_OK; - } - - assert( SQLITE_OK==queryTableLock(p, iTable, eLock) ); - - /* If the read-uncommitted flag is set and a read-lock is requested, - ** return early without adding an entry to the BtShared.pLock list. See - ** comment in function queryTableLock() for more info on handling - ** the ReadUncommitted flag. - */ - if( - (p->pSqlite) && - (p->pSqlite->flags&SQLITE_ReadUncommitted) && - (eLock==READ_LOCK) && - iTable!=MASTER_ROOT - ){ - return SQLITE_OK; - } - - /* First search the list for an existing lock on this table. */ - for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ - if( pIter->iTable==iTable && pIter->pBtree==p ){ - pLock = pIter; - break; - } - } - - /* If the above search did not find a BtLock struct associating Btree p - ** with table iTable, allocate one and link it into the list. - */ - if( !pLock ){ - pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock)); - if( !pLock ){ - return SQLITE_NOMEM; - } - pLock->iTable = iTable; - pLock->pBtree = p; - pLock->pNext = pBt->pLock; - pBt->pLock = pLock; - } - - /* Set the BtLock.eLock variable to the maximum of the current lock - ** and the requested lock. This means if a write-lock was already held - ** and a read-lock requested, we don't incorrectly downgrade the lock. - */ - assert( WRITE_LOCK>READ_LOCK ); - if( eLock>pLock->eLock ){ - pLock->eLock = eLock; - } - - return SQLITE_OK; -} -#endif /* !SQLITE_OMIT_SHARED_CACHE */ - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** Release all the table locks (locks obtained via calls to the lockTable() -** procedure) held by Btree handle p. -*/ -static void unlockAllTables(Btree *p){ - BtLock **ppIter = &p->pBt->pLock; - - assert( sqlite3BtreeHoldsMutex(p) ); - assert( p->sharable || 0==*ppIter ); - - while( *ppIter ){ - BtLock *pLock = *ppIter; - if( pLock->pBtree==p ){ - *ppIter = pLock->pNext; - sqlite3_free(pLock); - }else{ - ppIter = &pLock->pNext; - } - } -} -#endif /* SQLITE_OMIT_SHARED_CACHE */ - -static void releasePage(MemPage *pPage); /* Forward reference */ - -/* -** Verify that the cursor holds a mutex on the BtShared -*/ -#ifndef NDEBUG -static int cursorHoldsMutex(BtCursor *p){ - return sqlite3_mutex_held(p->pBt->mutex); -} -#endif - - -#ifndef SQLITE_OMIT_INCRBLOB -/* -** Invalidate the overflow page-list cache for cursor pCur, if any. -*/ -static void invalidateOverflowCache(BtCursor *pCur){ - assert( cursorHoldsMutex(pCur) ); - sqlite3_free(pCur->aOverflow); - pCur->aOverflow = 0; -} - -/* -** Invalidate the overflow page-list cache for all cursors opened -** on the shared btree structure pBt. -*/ -static void invalidateAllOverflowCache(BtShared *pBt){ - BtCursor *p; - assert( sqlite3_mutex_held(pBt->mutex) ); - for(p=pBt->pCursor; p; p=p->pNext){ - invalidateOverflowCache(p); - } -} -#else - #define invalidateOverflowCache(x) - #define invalidateAllOverflowCache(x) -#endif - -/* -** Save the current cursor position in the variables BtCursor.nKey -** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. -*/ -static int saveCursorPosition(BtCursor *pCur){ - int rc; - - assert( CURSOR_VALID==pCur->eState ); - assert( 0==pCur->pKey ); - assert( cursorHoldsMutex(pCur) ); - - rc = sqlite3BtreeKeySize(pCur, &pCur->nKey); - - /* If this is an intKey table, then the above call to BtreeKeySize() - ** stores the integer key in pCur->nKey. In this case this value is - ** all that is required. Otherwise, if pCur is not open on an intKey - ** table, then malloc space for and store the pCur->nKey bytes of key - ** data. - */ - if( rc==SQLITE_OK && 0==pCur->pPage->intKey){ - void *pKey = sqlite3_malloc(pCur->nKey); - if( pKey ){ - rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey); - if( rc==SQLITE_OK ){ - pCur->pKey = pKey; - }else{ - sqlite3_free(pKey); - } - }else{ - rc = SQLITE_NOMEM; - } - } - assert( !pCur->pPage->intKey || !pCur->pKey ); - - if( rc==SQLITE_OK ){ - releasePage(pCur->pPage); - pCur->pPage = 0; - pCur->eState = CURSOR_REQUIRESEEK; - } - - invalidateOverflowCache(pCur); - return rc; -} - -/* -** Save the positions of all cursors except pExcept open on the table -** with root-page iRoot. Usually, this is called just before cursor -** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()). -*/ -static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ - BtCursor *p; - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pExcept==0 || pExcept->pBt==pBt ); - for(p=pBt->pCursor; p; p=p->pNext){ - if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && - p->eState==CURSOR_VALID ){ - int rc = saveCursorPosition(p); - if( SQLITE_OK!=rc ){ - return rc; - } - } - } - return SQLITE_OK; -} - -/* -** Clear the current cursor position. -*/ -static void clearCursorPosition(BtCursor *pCur){ - assert( cursorHoldsMutex(pCur) ); - sqlite3_free(pCur->pKey); - pCur->pKey = 0; - pCur->eState = CURSOR_INVALID; -} - -/* -** Restore the cursor to the position it was in (or as close to as possible) -** when saveCursorPosition() was called. Note that this call deletes the -** saved position info stored by saveCursorPosition(), so there can be -** at most one effective restoreOrClearCursorPosition() call after each -** saveCursorPosition(). -** -** If the second argument argument - doSeek - is false, then instead of -** returning the cursor to it's saved position, any saved position is deleted -** and the cursor state set to CURSOR_INVALID. -*/ -int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur){ - int rc; - assert( cursorHoldsMutex(pCur) ); - assert( pCur->eState>=CURSOR_REQUIRESEEK ); - if( pCur->eState==CURSOR_FAULT ){ - return pCur->skip; - } -#ifndef SQLITE_OMIT_INCRBLOB - if( pCur->isIncrblobHandle ){ - return SQLITE_ABORT; - } -#endif - pCur->eState = CURSOR_INVALID; - rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip); - if( rc==SQLITE_OK ){ - sqlite3_free(pCur->pKey); - pCur->pKey = 0; - assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); - } - return rc; -} - -#define restoreOrClearCursorPosition(p) \ - (p->eState>=CURSOR_REQUIRESEEK ? \ - sqlite3BtreeRestoreOrClearCursorPosition(p) : \ - SQLITE_OK) - -#ifndef SQLITE_OMIT_AUTOVACUUM -/* -** Given a page number of a regular database page, return the page -** number for the pointer-map page that contains the entry for the -** input page number. -*/ -static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){ - int nPagesPerMapPage, iPtrMap, ret; - assert( sqlite3_mutex_held(pBt->mutex) ); - nPagesPerMapPage = (pBt->usableSize/5)+1; - iPtrMap = (pgno-2)/nPagesPerMapPage; - ret = (iPtrMap*nPagesPerMapPage) + 2; - if( ret==PENDING_BYTE_PAGE(pBt) ){ - ret++; - } - return ret; -} - -/* -** Write an entry into the pointer map. -** -** This routine updates the pointer map entry for page number 'key' -** so that it maps to type 'eType' and parent page number 'pgno'. -** An error code is returned if something goes wrong, otherwise SQLITE_OK. -*/ -static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){ - DbPage *pDbPage; /* The pointer map page */ - u8 *pPtrmap; /* The pointer map data */ - Pgno iPtrmap; /* The pointer map page number */ - int offset; /* Offset in pointer map page */ - int rc; - - assert( sqlite3_mutex_held(pBt->mutex) ); - /* The master-journal page number must never be used as a pointer map page */ - assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) ); - - assert( pBt->autoVacuum ); - if( key==0 ){ - return SQLITE_CORRUPT_BKPT; - } - iPtrmap = PTRMAP_PAGENO(pBt, key); - rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage); - if( rc!=SQLITE_OK ){ - return rc; - } - offset = PTRMAP_PTROFFSET(pBt, key); - pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); - - if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ - TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent)); - rc = sqlite3PagerWrite(pDbPage); - if( rc==SQLITE_OK ){ - pPtrmap[offset] = eType; - put4byte(&pPtrmap[offset+1], parent); - } - } - - sqlite3PagerUnref(pDbPage); - return rc; -} - -/* -** Read an entry from the pointer map. -** -** This routine retrieves the pointer map entry for page 'key', writing -** the type and parent page number to *pEType and *pPgno respectively. -** An error code is returned if something goes wrong, otherwise SQLITE_OK. -*/ -static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ - DbPage *pDbPage; /* The pointer map page */ - int iPtrmap; /* Pointer map page index */ - u8 *pPtrmap; /* Pointer map page data */ - int offset; /* Offset of entry in pointer map */ - int rc; - - assert( sqlite3_mutex_held(pBt->mutex) ); - - iPtrmap = PTRMAP_PAGENO(pBt, key); - rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage); - if( rc!=0 ){ - return rc; - } - pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); - - offset = PTRMAP_PTROFFSET(pBt, key); - assert( pEType!=0 ); - *pEType = pPtrmap[offset]; - if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); - - sqlite3PagerUnref(pDbPage); - if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT; - return SQLITE_OK; -} - -#endif /* SQLITE_OMIT_AUTOVACUUM */ - -/* -** Given a btree page and a cell index (0 means the first cell on -** the page, 1 means the second cell, and so forth) return a pointer -** to the cell content. -** -** This routine works only for pages that do not contain overflow cells. -*/ -#define findCell(pPage, iCell) \ - ((pPage)->aData + get2byte(&(pPage)->aData[(pPage)->cellOffset+2*(iCell)])) -#ifdef SQLITE_TEST -u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell){ - assert( iCell>=0 ); - assert( iCellaData[pPage->hdrOffset+3]) ); - return findCell(pPage, iCell); -} -#endif - -/* -** This a more complex version of sqlite3BtreeFindCell() that works for -** pages that do contain overflow cells. See insert -*/ -static u8 *findOverflowCell(MemPage *pPage, int iCell){ - int i; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - for(i=pPage->nOverflow-1; i>=0; i--){ - int k; - struct _OvflCell *pOvfl; - pOvfl = &pPage->aOvfl[i]; - k = pOvfl->idx; - if( k<=iCell ){ - if( k==iCell ){ - return pOvfl->pCell; - } - iCell--; - } - } - return findCell(pPage, iCell); -} - -/* -** Parse a cell content block and fill in the CellInfo structure. There -** are two versions of this function. sqlite3BtreeParseCell() takes a -** cell index as the second argument and sqlite3BtreeParseCellPtr() -** takes a pointer to the body of the cell as its second argument. -** -** Within this file, the parseCell() macro can be called instead of -** sqlite3BtreeParseCellPtr(). Using some compilers, this will be faster. -*/ -void sqlite3BtreeParseCellPtr( - MemPage *pPage, /* Page containing the cell */ - u8 *pCell, /* Pointer to the cell text. */ - CellInfo *pInfo /* Fill in this structure */ -){ - int n; /* Number bytes in cell content header */ - u32 nPayload; /* Number of bytes of cell payload */ - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - - pInfo->pCell = pCell; - assert( pPage->leaf==0 || pPage->leaf==1 ); - n = pPage->childPtrSize; - assert( n==4-4*pPage->leaf ); - if( pPage->hasData ){ - n += getVarint32(&pCell[n], &nPayload); - }else{ - nPayload = 0; - } - pInfo->nData = nPayload; - if( pPage->intKey ){ - n += getVarint(&pCell[n], (u64 *)&pInfo->nKey); - }else{ - u32 x; - n += getVarint32(&pCell[n], &x); - pInfo->nKey = x; - nPayload += x; - } - pInfo->nPayload = nPayload; - pInfo->nHeader = n; - if( nPayload<=pPage->maxLocal ){ - /* This is the (easy) common case where the entire payload fits - ** on the local page. No overflow is required. - */ - int nSize; /* Total size of cell content in bytes */ - pInfo->nLocal = nPayload; - pInfo->iOverflow = 0; - nSize = nPayload + n; - if( nSize<4 ){ - nSize = 4; /* Minimum cell size is 4 */ - } - pInfo->nSize = nSize; - }else{ - /* If the payload will not fit completely on the local page, we have - ** to decide how much to store locally and how much to spill onto - ** overflow pages. The strategy is to minimize the amount of unused - ** space on overflow pages while keeping the amount of local storage - ** in between minLocal and maxLocal. - ** - ** Warning: changing the way overflow payload is distributed in any - ** way will result in an incompatible file format. - */ - int minLocal; /* Minimum amount of payload held locally */ - int maxLocal; /* Maximum amount of payload held locally */ - int surplus; /* Overflow payload available for local storage */ - - minLocal = pPage->minLocal; - maxLocal = pPage->maxLocal; - surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4); - if( surplus <= maxLocal ){ - pInfo->nLocal = surplus; - }else{ - pInfo->nLocal = minLocal; - } - pInfo->iOverflow = pInfo->nLocal + n; - pInfo->nSize = pInfo->iOverflow + 4; - } -} -#define parseCell(pPage, iCell, pInfo) \ - sqlite3BtreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo)) -void sqlite3BtreeParseCell( - MemPage *pPage, /* Page containing the cell */ - int iCell, /* The cell index. First cell is 0 */ - CellInfo *pInfo /* Fill in this structure */ -){ - parseCell(pPage, iCell, pInfo); -} - -/* -** Compute the total number of bytes that a Cell needs in the cell -** data area of the btree-page. The return number includes the cell -** data header and the local payload, but not any overflow page or -** the space used by the cell pointer. -*/ -#ifndef NDEBUG -static int cellSize(MemPage *pPage, int iCell){ - CellInfo info; - sqlite3BtreeParseCell(pPage, iCell, &info); - return info.nSize; -} -#endif -static int cellSizePtr(MemPage *pPage, u8 *pCell){ - CellInfo info; - sqlite3BtreeParseCellPtr(pPage, pCell, &info); - return info.nSize; -} - -#ifndef SQLITE_OMIT_AUTOVACUUM -/* -** If the cell pCell, part of page pPage contains a pointer -** to an overflow page, insert an entry into the pointer-map -** for the overflow page. -*/ -static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){ - if( pCell ){ - CellInfo info; - sqlite3BtreeParseCellPtr(pPage, pCell, &info); - assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload ); - if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){ - Pgno ovfl = get4byte(&pCell[info.iOverflow]); - return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno); - } - } - return SQLITE_OK; -} -/* -** If the cell with index iCell on page pPage contains a pointer -** to an overflow page, insert an entry into the pointer-map -** for the overflow page. -*/ -static int ptrmapPutOvfl(MemPage *pPage, int iCell){ - u8 *pCell; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pCell = findOverflowCell(pPage, iCell); - return ptrmapPutOvflPtr(pPage, pCell); -} -#endif - - -/* -** Defragment the page given. All Cells are moved to the -** end of the page and all free space is collected into one -** big FreeBlk that occurs in between the header and cell -** pointer array and the cell content area. -*/ -static int defragmentPage(MemPage *pPage){ - int i; /* Loop counter */ - int pc; /* Address of a i-th cell */ - int addr; /* Offset of first byte after cell pointer array */ - int hdr; /* Offset to the page header */ - int size; /* Size of a cell */ - int usableSize; /* Number of usable bytes on a page */ - int cellOffset; /* Offset to the cell pointer array */ - int brk; /* Offset to the cell content area */ - int nCell; /* Number of cells on the page */ - unsigned char *data; /* The page data */ - unsigned char *temp; /* Temp area for cell content */ - - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( pPage->pBt!=0 ); - assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); - assert( pPage->nOverflow==0 ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - temp = sqlite3_malloc( pPage->pBt->pageSize ); - if( temp==0 ) return SQLITE_NOMEM; - data = pPage->aData; - hdr = pPage->hdrOffset; - cellOffset = pPage->cellOffset; - nCell = pPage->nCell; - assert( nCell==get2byte(&data[hdr+3]) ); - usableSize = pPage->pBt->usableSize; - brk = get2byte(&data[hdr+5]); - memcpy(&temp[brk], &data[brk], usableSize - brk); - brk = usableSize; - for(i=0; ipBt->usableSize ); - size = cellSizePtr(pPage, &temp[pc]); - brk -= size; - memcpy(&data[brk], &temp[pc], size); - put2byte(pAddr, brk); - } - assert( brk>=cellOffset+2*nCell ); - put2byte(&data[hdr+5], brk); - data[hdr+1] = 0; - data[hdr+2] = 0; - data[hdr+7] = 0; - addr = cellOffset+2*nCell; - memset(&data[addr], 0, brk-addr); - sqlite3_free(temp); - return SQLITE_OK; -} - -/* -** Allocate nByte bytes of space on a page. -** -** Return the index into pPage->aData[] of the first byte of -** the new allocation. Or return 0 if there is not enough free -** space on the page to satisfy the allocation request. -** -** If the page contains nBytes of free space but does not contain -** nBytes of contiguous free space, then this routine automatically -** calls defragementPage() to consolidate all free space before -** allocating the new chunk. -*/ -static int allocateSpace(MemPage *pPage, int nByte){ - int addr, pc, hdr; - int size; - int nFrag; - int top; - int nCell; - int cellOffset; - unsigned char *data; - - data = pPage->aData; - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( pPage->pBt ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - if( nByte<4 ) nByte = 4; - if( pPage->nFreenOverflow>0 ) return 0; - pPage->nFree -= nByte; - hdr = pPage->hdrOffset; - - nFrag = data[hdr+7]; - if( nFrag<60 ){ - /* Search the freelist looking for a slot big enough to satisfy the - ** space request. */ - addr = hdr+1; - while( (pc = get2byte(&data[addr]))>0 ){ - size = get2byte(&data[pc+2]); - if( size>=nByte ){ - if( sizecellOffset; - if( nFrag>=60 || cellOffset + 2*nCell > top - nByte ){ - if( defragmentPage(pPage) ) return 0; - top = get2byte(&data[hdr+5]); - } - top -= nByte; - assert( cellOffset + 2*nCell <= top ); - put2byte(&data[hdr+5], top); - return top; -} - -/* -** Return a section of the pPage->aData to the freelist. -** The first byte of the new free block is pPage->aDisk[start] -** and the size of the block is "size" bytes. -** -** Most of the effort here is involved in coalesing adjacent -** free blocks into a single big free block. -*/ -static void freeSpace(MemPage *pPage, int start, int size){ - int addr, pbegin, hdr; - unsigned char *data = pPage->aData; - - assert( pPage->pBt!=0 ); - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( start>=pPage->hdrOffset+6+(pPage->leaf?0:4) ); - assert( (start + size)<=pPage->pBt->usableSize ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - if( size<4 ) size = 4; - -#ifdef SQLITE_SECURE_DELETE - /* Overwrite deleted information with zeros when the SECURE_DELETE - ** option is enabled at compile-time */ - memset(&data[start], 0, size); -#endif - - /* Add the space back into the linked list of freeblocks */ - hdr = pPage->hdrOffset; - addr = hdr + 1; - while( (pbegin = get2byte(&data[addr]))0 ){ - assert( pbegin<=pPage->pBt->usableSize-4 ); - assert( pbegin>addr ); - addr = pbegin; - } - assert( pbegin<=pPage->pBt->usableSize-4 ); - assert( pbegin>addr || pbegin==0 ); - put2byte(&data[addr], start); - put2byte(&data[start], pbegin); - put2byte(&data[start+2], size); - pPage->nFree += size; - - /* Coalesce adjacent free blocks */ - addr = pPage->hdrOffset + 1; - while( (pbegin = get2byte(&data[addr]))>0 ){ - int pnext, psize; - assert( pbegin>addr ); - assert( pbegin<=pPage->pBt->usableSize-4 ); - pnext = get2byte(&data[pbegin]); - psize = get2byte(&data[pbegin+2]); - if( pbegin + psize + 3 >= pnext && pnext>0 ){ - int frag = pnext - (pbegin+psize); - assert( frag<=data[pPage->hdrOffset+7] ); - data[pPage->hdrOffset+7] -= frag; - put2byte(&data[pbegin], get2byte(&data[pnext])); - put2byte(&data[pbegin+2], pnext+get2byte(&data[pnext+2])-pbegin); - }else{ - addr = pbegin; - } - } - - /* If the cell content area begins with a freeblock, remove it. */ - if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){ - int top; - pbegin = get2byte(&data[hdr+1]); - memcpy(&data[hdr+1], &data[pbegin], 2); - top = get2byte(&data[hdr+5]); - put2byte(&data[hdr+5], top + get2byte(&data[pbegin+2])); - } -} - -/* -** Decode the flags byte (the first byte of the header) for a page -** and initialize fields of the MemPage structure accordingly. -*/ -static void decodeFlags(MemPage *pPage, int flagByte){ - BtShared *pBt; /* A copy of pPage->pBt */ - - assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pPage->intKey = (flagByte & (PTF_INTKEY|PTF_LEAFDATA))!=0; - pPage->zeroData = (flagByte & PTF_ZERODATA)!=0; - pPage->leaf = (flagByte & PTF_LEAF)!=0; - pPage->childPtrSize = 4*(pPage->leaf==0); - pBt = pPage->pBt; - if( flagByte & PTF_LEAFDATA ){ - pPage->leafData = 1; - pPage->maxLocal = pBt->maxLeaf; - pPage->minLocal = pBt->minLeaf; - }else{ - pPage->leafData = 0; - pPage->maxLocal = pBt->maxLocal; - pPage->minLocal = pBt->minLocal; - } - pPage->hasData = !(pPage->zeroData || (!pPage->leaf && pPage->leafData)); -} - -/* -** Initialize the auxiliary information for a disk block. -** -** The pParent parameter must be a pointer to the MemPage which -** is the parent of the page being initialized. The root of a -** BTree has no parent and so for that page, pParent==NULL. -** -** Return SQLITE_OK on success. If we see that the page does -** not contain a well-formed database page, then return -** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not -** guarantee that the page is well-formed. It only shows that -** we failed to detect any corruption. -*/ -int sqlite3BtreeInitPage( - MemPage *pPage, /* The page to be initialized */ - MemPage *pParent /* The parent. Might be NULL */ -){ - int pc; /* Address of a freeblock within pPage->aData[] */ - int hdr; /* Offset to beginning of page header */ - u8 *data; /* Equal to pPage->aData */ - BtShared *pBt; /* The main btree structure */ - int usableSize; /* Amount of usable space on each page */ - int cellOffset; /* Offset from start of page to first cell pointer */ - int nFree; /* Number of unused bytes on the page */ - int top; /* First byte of the cell content area */ - - pBt = pPage->pBt; - assert( pBt!=0 ); - assert( pParent==0 || pParent->pBt==pBt ); - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); - assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); - assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); - if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){ - /* The parent page should never change unless the file is corrupt */ - return SQLITE_CORRUPT_BKPT; - } - if( pPage->isInit ) return SQLITE_OK; - if( pPage->pParent==0 && pParent!=0 ){ - pPage->pParent = pParent; - sqlite3PagerRef(pParent->pDbPage); - } - hdr = pPage->hdrOffset; - data = pPage->aData; - decodeFlags(pPage, data[hdr]); - pPage->nOverflow = 0; - pPage->idxShift = 0; - usableSize = pBt->usableSize; - pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf; - top = get2byte(&data[hdr+5]); - pPage->nCell = get2byte(&data[hdr+3]); - if( pPage->nCell>MX_CELL(pBt) ){ - /* To many cells for a single page. The page must be corrupt */ - return SQLITE_CORRUPT_BKPT; - } - if( pPage->nCell==0 && pParent!=0 && pParent->pgno!=1 ){ - /* All pages must have at least one cell, except for root pages */ - return SQLITE_CORRUPT_BKPT; - } - - /* Compute the total free space on the page */ - pc = get2byte(&data[hdr+1]); - nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell); - while( pc>0 ){ - int next, size; - if( pc>usableSize-4 ){ - /* Free block is off the page */ - return SQLITE_CORRUPT_BKPT; - } - next = get2byte(&data[pc]); - size = get2byte(&data[pc+2]); - if( next>0 && next<=pc+size+3 ){ - /* Free blocks must be in accending order */ - return SQLITE_CORRUPT_BKPT; - } - nFree += size; - pc = next; - } - pPage->nFree = nFree; - if( nFree>=usableSize ){ - /* Free space cannot exceed total page size */ - return SQLITE_CORRUPT_BKPT; - } - - pPage->isInit = 1; - return SQLITE_OK; -} - -/* -** Set up a raw page so that it looks like a database page holding -** no entries. -*/ -static void zeroPage(MemPage *pPage, int flags){ - unsigned char *data = pPage->aData; - BtShared *pBt = pPage->pBt; - int hdr = pPage->hdrOffset; - int first; - - assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno ); - assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); - assert( sqlite3PagerGetData(pPage->pDbPage) == data ); - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( sqlite3_mutex_held(pBt->mutex) ); - memset(&data[hdr], 0, pBt->usableSize - hdr); - data[hdr] = flags; - first = hdr + 8 + 4*((flags&PTF_LEAF)==0); - memset(&data[hdr+1], 0, 4); - data[hdr+7] = 0; - put2byte(&data[hdr+5], pBt->usableSize); - pPage->nFree = pBt->usableSize - first; - decodeFlags(pPage, flags); - pPage->hdrOffset = hdr; - pPage->cellOffset = first; - pPage->nOverflow = 0; - pPage->idxShift = 0; - pPage->nCell = 0; - pPage->isInit = 1; -} - -/* -** Get a page from the pager. Initialize the MemPage.pBt and -** MemPage.aData elements if needed. -** -** If the noContent flag is set, it means that we do not care about -** the content of the page at this time. So do not go to the disk -** to fetch the content. Just fill in the content with zeros for now. -** If in the future we call sqlite3PagerWrite() on this page, that -** means we have started to be concerned about content and the disk -** read should occur at that point. -*/ -int sqlite3BtreeGetPage( - BtShared *pBt, /* The btree */ - Pgno pgno, /* Number of the page to fetch */ - MemPage **ppPage, /* Return the page in this parameter */ - int noContent /* Do not load page content if true */ -){ - int rc; - MemPage *pPage; - DbPage *pDbPage; - - assert( sqlite3_mutex_held(pBt->mutex) ); - rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent); - if( rc ) return rc; - pPage = (MemPage *)sqlite3PagerGetExtra(pDbPage); - pPage->aData = sqlite3PagerGetData(pDbPage); - pPage->pDbPage = pDbPage; - pPage->pBt = pBt; - pPage->pgno = pgno; - pPage->hdrOffset = pPage->pgno==1 ? 100 : 0; - *ppPage = pPage; - return SQLITE_OK; -} - -/* -** Get a page from the pager and initialize it. This routine -** is just a convenience wrapper around separate calls to -** sqlite3BtreeGetPage() and sqlite3BtreeInitPage(). -*/ -static int getAndInitPage( - BtShared *pBt, /* The database file */ - Pgno pgno, /* Number of the page to get */ - MemPage **ppPage, /* Write the page pointer here */ - MemPage *pParent /* Parent of the page */ -){ - int rc; - assert( sqlite3_mutex_held(pBt->mutex) ); - if( pgno==0 ){ - return SQLITE_CORRUPT_BKPT; - } - rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0); - if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){ - rc = sqlite3BtreeInitPage(*ppPage, pParent); - } - return rc; -} - -/* -** Release a MemPage. This should be called once for each prior -** call to sqlite3BtreeGetPage. -*/ -static void releasePage(MemPage *pPage){ - if( pPage ){ - assert( pPage->aData ); - assert( pPage->pBt ); - assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); - assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - sqlite3PagerUnref(pPage->pDbPage); - } -} - -/* -** This routine is called when the reference count for a page -** reaches zero. We need to unref the pParent pointer when that -** happens. -*/ -static void pageDestructor(DbPage *pData, int pageSize){ - MemPage *pPage; - assert( (pageSize & 7)==0 ); - pPage = (MemPage *)sqlite3PagerGetExtra(pData); - assert( pPage->isInit==0 || sqlite3_mutex_held(pPage->pBt->mutex) ); - if( pPage->pParent ){ - MemPage *pParent = pPage->pParent; - assert( pParent->pBt==pPage->pBt ); - pPage->pParent = 0; - releasePage(pParent); - } - pPage->isInit = 0; -} - -/* -** During a rollback, when the pager reloads information into the cache -** so that the cache is restored to its original state at the start of -** the transaction, for each page restored this routine is called. -** -** This routine needs to reset the extra data section at the end of the -** page to agree with the restored data. -*/ -static void pageReinit(DbPage *pData, int pageSize){ - MemPage *pPage; - assert( (pageSize & 7)==0 ); - pPage = (MemPage *)sqlite3PagerGetExtra(pData); - if( pPage->isInit ){ - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pPage->isInit = 0; - sqlite3BtreeInitPage(pPage, pPage->pParent); - } -} - -/* -** Open a database file. -** -** zFilename is the name of the database file. If zFilename is NULL -** a new database with a random name is created. This randomly named -** database file will be deleted when sqlite3BtreeClose() is called. -** If zFilename is ":memory:" then an in-memory database is created -** that is automatically destroyed when it is closed. -*/ -int sqlite3BtreeOpen( - const char *zFilename, /* Name of the file containing the BTree database */ - sqlite3 *pSqlite, /* Associated database handle */ - Btree **ppBtree, /* Pointer to new Btree object written here */ - int flags, /* Options */ - int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */ -){ - sqlite3_vfs *pVfs; /* The VFS to use for this btree */ - BtShared *pBt = 0; /* Shared part of btree structure */ - Btree *p; /* Handle to return */ - int rc = SQLITE_OK; - int nReserve; - unsigned char zDbHeader[100]; - - /* Set the variable isMemdb to true for an in-memory database, or - ** false for a file-based database. This symbol is only required if - ** either of the shared-data or autovacuum features are compiled - ** into the library. - */ -#if !defined(SQLITE_OMIT_SHARED_CACHE) || !defined(SQLITE_OMIT_AUTOVACUUM) - #ifdef SQLITE_OMIT_MEMORYDB - const int isMemdb = 0; - #else - const int isMemdb = zFilename && !strcmp(zFilename, ":memory:"); - #endif -#endif - - assert( pSqlite!=0 ); - assert( sqlite3_mutex_held(pSqlite->mutex) ); - - pVfs = pSqlite->pVfs; - p = sqlite3MallocZero(sizeof(Btree)); - if( !p ){ - return SQLITE_NOMEM; - } - p->inTrans = TRANS_NONE; - p->pSqlite = pSqlite; - -#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) - /* - ** If this Btree is a candidate for shared cache, try to find an - ** existing BtShared object that we can share with - */ - if( (flags & BTREE_PRIVATE)==0 - && isMemdb==0 - && (pSqlite->flags & SQLITE_Vtab)==0 - && zFilename && zFilename[0] - ){ - if( sqlite3SharedCacheEnabled ){ - int nFullPathname = pVfs->mxPathname+1; - char *zFullPathname = (char *)sqlite3_malloc(nFullPathname); - sqlite3_mutex *mutexShared; - p->sharable = 1; - if( pSqlite ){ - pSqlite->flags |= SQLITE_SharedCache; - } - if( !zFullPathname ){ - sqlite3_free(p); - return SQLITE_NOMEM; - } - sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); - mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); - sqlite3_mutex_enter(mutexShared); - for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){ - assert( pBt->nRef>0 ); - if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager)) - && sqlite3PagerVfs(pBt->pPager)==pVfs ){ - p->pBt = pBt; - pBt->nRef++; - break; - } - } - sqlite3_mutex_leave(mutexShared); - sqlite3_free(zFullPathname); - } -#ifdef SQLITE_DEBUG - else{ - /* In debug mode, we mark all persistent databases as sharable - ** even when they are not. This exercises the locking code and - ** gives more opportunity for asserts(sqlite3_mutex_held()) - ** statements to find locking problems. - */ - p->sharable = 1; - } -#endif - } -#endif - if( pBt==0 ){ - /* - ** The following asserts make sure that structures used by the btree are - ** the right size. This is to guard against size changes that result - ** when compiling on a different architecture. - */ - assert( sizeof(i64)==8 || sizeof(i64)==4 ); - assert( sizeof(u64)==8 || sizeof(u64)==4 ); - assert( sizeof(u32)==4 ); - assert( sizeof(u16)==2 ); - assert( sizeof(Pgno)==4 ); - - pBt = sqlite3MallocZero( sizeof(*pBt) ); - if( pBt==0 ){ - rc = SQLITE_NOMEM; - goto btree_open_out; - } - rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, - EXTRA_SIZE, flags, vfsFlags); - if( rc==SQLITE_OK ){ - rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); - } - if( rc!=SQLITE_OK ){ - goto btree_open_out; - } - p->pBt = pBt; - - sqlite3PagerSetDestructor(pBt->pPager, pageDestructor); - sqlite3PagerSetReiniter(pBt->pPager, pageReinit); - pBt->pCursor = 0; - pBt->pPage1 = 0; - pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager); - pBt->pageSize = get2byte(&zDbHeader[16]); - if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE - || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ - pBt->pageSize = 0; - sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); - pBt->maxEmbedFrac = 64; /* 25% */ - pBt->minEmbedFrac = 32; /* 12.5% */ - pBt->minLeafFrac = 32; /* 12.5% */ -#ifndef SQLITE_OMIT_AUTOVACUUM - /* If the magic name ":memory:" will create an in-memory database, then - ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if - ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if - ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a - ** regular file-name. In this case the auto-vacuum applies as per normal. - */ - if( zFilename && !isMemdb ){ - pBt->autoVacuum = (SQLITE_DEFAULT_AUTOVACUUM ? 1 : 0); - pBt->incrVacuum = (SQLITE_DEFAULT_AUTOVACUUM==2 ? 1 : 0); - } -#endif - nReserve = 0; - }else{ - nReserve = zDbHeader[20]; - pBt->maxEmbedFrac = zDbHeader[21]; - pBt->minEmbedFrac = zDbHeader[22]; - pBt->minLeafFrac = zDbHeader[23]; - pBt->pageSizeFixed = 1; -#ifndef SQLITE_OMIT_AUTOVACUUM - pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); - pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0); -#endif - } - pBt->usableSize = pBt->pageSize - nReserve; - assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ - sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); - -#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) - /* Add the new BtShared object to the linked list sharable BtShareds. - */ - if( p->sharable ){ - sqlite3_mutex *mutexShared; - pBt->nRef = 1; - mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); - if( SQLITE_THREADSAFE ){ - pBt->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - if( pBt->mutex==0 ){ - rc = SQLITE_NOMEM; - pSqlite->mallocFailed = 0; - goto btree_open_out; - } - } - sqlite3_mutex_enter(mutexShared); - pBt->pNext = sqlite3SharedCacheList; - sqlite3SharedCacheList = pBt; - sqlite3_mutex_leave(mutexShared); - } -#endif - } - -#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) - /* If the new Btree uses a sharable pBtShared, then link the new - ** Btree into the list of all sharable Btrees for the same connection. - ** The list is kept in ascending order by pBt address. - */ - if( p->sharable ){ - int i; - Btree *pSib; - for(i=0; inDb; i++){ - if( (pSib = pSqlite->aDb[i].pBt)!=0 && pSib->sharable ){ - while( pSib->pPrev ){ pSib = pSib->pPrev; } - if( p->pBtpBt ){ - p->pNext = pSib; - p->pPrev = 0; - pSib->pPrev = p; - }else{ - while( pSib->pNext && pSib->pNext->pBtpBt ){ - pSib = pSib->pNext; - } - p->pNext = pSib->pNext; - p->pPrev = pSib; - if( p->pNext ){ - p->pNext->pPrev = p; - } - pSib->pNext = p; - } - break; - } - } - } -#endif - *ppBtree = p; - -btree_open_out: - if( rc!=SQLITE_OK ){ - if( pBt && pBt->pPager ){ - sqlite3PagerClose(pBt->pPager); - } - sqlite3_free(pBt); - sqlite3_free(p); - *ppBtree = 0; - } - return rc; -} - -/* -** Decrement the BtShared.nRef counter. When it reaches zero, -** remove the BtShared structure from the sharing list. Return -** true if the BtShared.nRef counter reaches zero and return -** false if it is still positive. -*/ -static int removeFromSharingList(BtShared *pBt){ -#ifndef SQLITE_OMIT_SHARED_CACHE - sqlite3_mutex *pMaster; - BtShared *pList; - int removed = 0; - - assert( sqlite3_mutex_notheld(pBt->mutex) ); - pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); - sqlite3_mutex_enter(pMaster); - pBt->nRef--; - if( pBt->nRef<=0 ){ - if( sqlite3SharedCacheList==pBt ){ - sqlite3SharedCacheList = pBt->pNext; - }else{ - pList = sqlite3SharedCacheList; - while( pList && pList->pNext!=pBt ){ - pList=pList->pNext; - } - if( pList ){ - pList->pNext = pBt->pNext; - } - } - if( SQLITE_THREADSAFE ){ - sqlite3_mutex_free(pBt->mutex); - } - removed = 1; - } - sqlite3_mutex_leave(pMaster); - return removed; -#else - return 1; -#endif -} - -/* -** Close an open database and invalidate all cursors. -*/ -int sqlite3BtreeClose(Btree *p){ - BtShared *pBt = p->pBt; - BtCursor *pCur; - - /* Close all cursors opened via this handle. */ - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - sqlite3BtreeEnter(p); - pCur = pBt->pCursor; - while( pCur ){ - BtCursor *pTmp = pCur; - pCur = pCur->pNext; - if( pTmp->pBtree==p ){ - sqlite3BtreeCloseCursor(pTmp); - } - } - - /* Rollback any active transaction and free the handle structure. - ** The call to sqlite3BtreeRollback() drops any table-locks held by - ** this handle. - */ - sqlite3BtreeRollback(p); - sqlite3BtreeLeave(p); - - /* If there are still other outstanding references to the shared-btree - ** structure, return now. The remainder of this procedure cleans - ** up the shared-btree. - */ - assert( p->wantToLock==0 && p->locked==0 ); - if( !p->sharable || removeFromSharingList(pBt) ){ - /* The pBt is no longer on the sharing list, so we can access - ** it without having to hold the mutex. - ** - ** Clean out and delete the BtShared object. - */ - assert( !pBt->pCursor ); - sqlite3PagerClose(pBt->pPager); - if( pBt->xFreeSchema && pBt->pSchema ){ - pBt->xFreeSchema(pBt->pSchema); - } - sqlite3_free(pBt->pSchema); - sqlite3_free(pBt); - } - -#ifndef SQLITE_OMIT_SHARED_CACHE - assert( p->wantToLock==0 ); - assert( p->locked==0 ); - if( p->pPrev ) p->pPrev->pNext = p->pNext; - if( p->pNext ) p->pNext->pPrev = p->pPrev; -#endif - - sqlite3_free(p); - return SQLITE_OK; -} - -/* -** Change the busy handler callback function. -*/ -int sqlite3BtreeSetBusyHandler(Btree *p, BusyHandler *pHandler){ - BtShared *pBt = p->pBt; - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - sqlite3BtreeEnter(p); - pBt->pBusyHandler = pHandler; - sqlite3PagerSetBusyhandler(pBt->pPager, pHandler); - sqlite3BtreeLeave(p); - return SQLITE_OK; -} - -/* -** Change the limit on the number of pages allowed in the cache. -** -** The maximum number of cache pages is set to the absolute -** value of mxPage. If mxPage is negative, the pager will -** operate asynchronously - it will not stop to do fsync()s -** to insure data is written to the disk surface before -** continuing. Transactions still work if synchronous is off, -** and the database cannot be corrupted if this program -** crashes. But if the operating system crashes or there is -** an abrupt power failure when synchronous is off, the database -** could be left in an inconsistent and unrecoverable state. -** Synchronous is on by default so database corruption is not -** normally a worry. -*/ -int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){ - BtShared *pBt = p->pBt; - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - sqlite3BtreeEnter(p); - sqlite3PagerSetCachesize(pBt->pPager, mxPage); - sqlite3BtreeLeave(p); - return SQLITE_OK; -} - -/* -** Change the way data is synced to disk in order to increase or decrease -** how well the database resists damage due to OS crashes and power -** failures. Level 1 is the same as asynchronous (no syncs() occur and -** there is a high probability of damage) Level 2 is the default. There -** is a very low but non-zero probability of damage. Level 3 reduces the -** probability of damage to near zero but with a write performance reduction. -*/ -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){ - BtShared *pBt = p->pBt; - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - sqlite3BtreeEnter(p); - sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync); - sqlite3BtreeLeave(p); - return SQLITE_OK; -} -#endif - -/* -** Return TRUE if the given btree is set to safety level 1. In other -** words, return TRUE if no sync() occurs on the disk files. -*/ -int sqlite3BtreeSyncDisabled(Btree *p){ - BtShared *pBt = p->pBt; - int rc; - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - sqlite3BtreeEnter(p); - assert( pBt && pBt->pPager ); - rc = sqlite3PagerNosync(pBt->pPager); - sqlite3BtreeLeave(p); - return rc; -} - -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) -/* -** Change the default pages size and the number of reserved bytes per page. -** -** The page size must be a power of 2 between 512 and 65536. If the page -** size supplied does not meet this constraint then the page size is not -** changed. -** -** Page sizes are constrained to be a power of two so that the region -** of the database file used for locking (beginning at PENDING_BYTE, -** the first byte past the 1GB boundary, 0x40000000) needs to occur -** at the beginning of a page. -** -** If parameter nReserve is less than zero, then the number of reserved -** bytes per page is left unchanged. -*/ -int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve){ - int rc = SQLITE_OK; - BtShared *pBt = p->pBt; - sqlite3BtreeEnter(p); - if( pBt->pageSizeFixed ){ - sqlite3BtreeLeave(p); - return SQLITE_READONLY; - } - if( nReserve<0 ){ - nReserve = pBt->pageSize - pBt->usableSize; - } - if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE && - ((pageSize-1)&pageSize)==0 ){ - assert( (pageSize & 7)==0 ); - assert( !pBt->pPage1 && !pBt->pCursor ); - pBt->pageSize = pageSize; - rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); - } - pBt->usableSize = pBt->pageSize - nReserve; - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Return the currently defined page size -*/ -int sqlite3BtreeGetPageSize(Btree *p){ - return p->pBt->pageSize; -} -int sqlite3BtreeGetReserve(Btree *p){ - int n; - sqlite3BtreeEnter(p); - n = p->pBt->pageSize - p->pBt->usableSize; - sqlite3BtreeLeave(p); - return n; -} - -/* -** Set the maximum page count for a database if mxPage is positive. -** No changes are made if mxPage is 0 or negative. -** Regardless of the value of mxPage, return the maximum page count. -*/ -int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){ - int n; - sqlite3BtreeEnter(p); - n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage); - sqlite3BtreeLeave(p); - return n; -} -#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */ - -/* -** Change the 'auto-vacuum' property of the database. If the 'autoVacuum' -** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it -** is disabled. The default value for the auto-vacuum property is -** determined by the SQLITE_DEFAULT_AUTOVACUUM macro. -*/ -int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ -#ifdef SQLITE_OMIT_AUTOVACUUM - return SQLITE_READONLY; -#else - BtShared *pBt = p->pBt; - int rc = SQLITE_OK; - int av = (autoVacuum?1:0); - - sqlite3BtreeEnter(p); - if( pBt->pageSizeFixed && av!=pBt->autoVacuum ){ - rc = SQLITE_READONLY; - }else{ - pBt->autoVacuum = av; - } - sqlite3BtreeLeave(p); - return rc; -#endif -} - -/* -** Return the value of the 'auto-vacuum' property. If auto-vacuum is -** enabled 1 is returned. Otherwise 0. -*/ -int sqlite3BtreeGetAutoVacuum(Btree *p){ -#ifdef SQLITE_OMIT_AUTOVACUUM - return BTREE_AUTOVACUUM_NONE; -#else - int rc; - sqlite3BtreeEnter(p); - rc = ( - (!p->pBt->autoVacuum)?BTREE_AUTOVACUUM_NONE: - (!p->pBt->incrVacuum)?BTREE_AUTOVACUUM_FULL: - BTREE_AUTOVACUUM_INCR - ); - sqlite3BtreeLeave(p); - return rc; -#endif -} - - -/* -** Get a reference to pPage1 of the database file. This will -** also acquire a readlock on that file. -** -** SQLITE_OK is returned on success. If the file is not a -** well-formed database file, then SQLITE_CORRUPT is returned. -** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM -** is returned if we run out of memory. -*/ -static int lockBtree(BtShared *pBt){ - int rc, pageSize; - MemPage *pPage1; - - assert( sqlite3_mutex_held(pBt->mutex) ); - if( pBt->pPage1 ) return SQLITE_OK; - rc = sqlite3BtreeGetPage(pBt, 1, &pPage1, 0); - if( rc!=SQLITE_OK ) return rc; - - - /* Do some checking to help insure the file we opened really is - ** a valid database file. - */ - rc = SQLITE_NOTADB; - if( sqlite3PagerPagecount(pBt->pPager)>0 ){ - u8 *page1 = pPage1->aData; - if( memcmp(page1, zMagicHeader, 16)!=0 ){ - goto page1_init_failed; - } - if( page1[18]>1 ){ - pBt->readOnly = 1; - } - if( page1[19]>1 ){ - goto page1_init_failed; - } - pageSize = get2byte(&page1[16]); - if( ((pageSize-1)&pageSize)!=0 || pageSize<512 || - (SQLITE_MAX_PAGE_SIZE<32768 && pageSize>SQLITE_MAX_PAGE_SIZE) - ){ - goto page1_init_failed; - } - assert( (pageSize & 7)==0 ); - pBt->pageSize = pageSize; - pBt->usableSize = pageSize - page1[20]; - if( pBt->usableSize<500 ){ - goto page1_init_failed; - } - pBt->maxEmbedFrac = page1[21]; - pBt->minEmbedFrac = page1[22]; - pBt->minLeafFrac = page1[23]; -#ifndef SQLITE_OMIT_AUTOVACUUM - pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); - pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0); -#endif - } - - /* maxLocal is the maximum amount of payload to store locally for - ** a cell. Make sure it is small enough so that at least minFanout - ** cells can will fit on one page. We assume a 10-byte page header. - ** Besides the payload, the cell must store: - ** 2-byte pointer to the cell - ** 4-byte child pointer - ** 9-byte nKey value - ** 4-byte nData value - ** 4-byte overflow page pointer - ** So a cell consists of a 2-byte poiner, a header which is as much as - ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow - ** page pointer. - */ - pBt->maxLocal = (pBt->usableSize-12)*pBt->maxEmbedFrac/255 - 23; - pBt->minLocal = (pBt->usableSize-12)*pBt->minEmbedFrac/255 - 23; - pBt->maxLeaf = pBt->usableSize - 35; - pBt->minLeaf = (pBt->usableSize-12)*pBt->minLeafFrac/255 - 23; - if( pBt->minLocal>pBt->maxLocal || pBt->maxLocal<0 ){ - goto page1_init_failed; - } - assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); - pBt->pPage1 = pPage1; - return SQLITE_OK; - -page1_init_failed: - releasePage(pPage1); - pBt->pPage1 = 0; - return rc; -} - -/* -** This routine works like lockBtree() except that it also invokes the -** busy callback if there is lock contention. -*/ -static int lockBtreeWithRetry(Btree *pRef){ - int rc = SQLITE_OK; - - assert( sqlite3BtreeHoldsMutex(pRef) ); - if( pRef->inTrans==TRANS_NONE ){ - u8 inTransaction = pRef->pBt->inTransaction; - btreeIntegrity(pRef); - rc = sqlite3BtreeBeginTrans(pRef, 0); - pRef->pBt->inTransaction = inTransaction; - pRef->inTrans = TRANS_NONE; - if( rc==SQLITE_OK ){ - pRef->pBt->nTransaction--; - } - btreeIntegrity(pRef); - } - return rc; -} - - -/* -** If there are no outstanding cursors and we are not in the middle -** of a transaction but there is a read lock on the database, then -** this routine unrefs the first page of the database file which -** has the effect of releasing the read lock. -** -** If there are any outstanding cursors, this routine is a no-op. -** -** If there is a transaction in progress, this routine is a no-op. -*/ -static void unlockBtreeIfUnused(BtShared *pBt){ - assert( sqlite3_mutex_held(pBt->mutex) ); - if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){ - if( sqlite3PagerRefcount(pBt->pPager)>=1 ){ - if( pBt->pPage1->aData==0 ){ - MemPage *pPage = pBt->pPage1; - pPage->aData = sqlite3PagerGetData(pPage->pDbPage); - pPage->pBt = pBt; - pPage->pgno = 1; - } - releasePage(pBt->pPage1); - } - pBt->pPage1 = 0; - pBt->inStmt = 0; - } -} - -/* -** Create a new database by initializing the first page of the -** file. -*/ -static int newDatabase(BtShared *pBt){ - MemPage *pP1; - unsigned char *data; - int rc; - - assert( sqlite3_mutex_held(pBt->mutex) ); - if( sqlite3PagerPagecount(pBt->pPager)>0 ) return SQLITE_OK; - pP1 = pBt->pPage1; - assert( pP1!=0 ); - data = pP1->aData; - rc = sqlite3PagerWrite(pP1->pDbPage); - if( rc ) return rc; - memcpy(data, zMagicHeader, sizeof(zMagicHeader)); - assert( sizeof(zMagicHeader)==16 ); - put2byte(&data[16], pBt->pageSize); - data[18] = 1; - data[19] = 1; - data[20] = pBt->pageSize - pBt->usableSize; - data[21] = pBt->maxEmbedFrac; - data[22] = pBt->minEmbedFrac; - data[23] = pBt->minLeafFrac; - memset(&data[24], 0, 100-24); - zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA ); - pBt->pageSizeFixed = 1; -#ifndef SQLITE_OMIT_AUTOVACUUM - assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 ); - assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 ); - put4byte(&data[36 + 4*4], pBt->autoVacuum); - put4byte(&data[36 + 7*4], pBt->incrVacuum); -#endif - return SQLITE_OK; -} - -/* -** Attempt to start a new transaction. A write-transaction -** is started if the second argument is nonzero, otherwise a read- -** transaction. If the second argument is 2 or more and exclusive -** transaction is started, meaning that no other process is allowed -** to access the database. A preexisting transaction may not be -** upgraded to exclusive by calling this routine a second time - the -** exclusivity flag only works for a new transaction. -** -** A write-transaction must be started before attempting any -** changes to the database. None of the following routines -** will work unless a transaction is started first: -** -** sqlite3BtreeCreateTable() -** sqlite3BtreeCreateIndex() -** sqlite3BtreeClearTable() -** sqlite3BtreeDropTable() -** sqlite3BtreeInsert() -** sqlite3BtreeDelete() -** sqlite3BtreeUpdateMeta() -** -** If an initial attempt to acquire the lock fails because of lock contention -** and the database was previously unlocked, then invoke the busy handler -** if there is one. But if there was previously a read-lock, do not -** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is -** returned when there is already a read-lock in order to avoid a deadlock. -** -** Suppose there are two processes A and B. A has a read lock and B has -** a reserved lock. B tries to promote to exclusive but is blocked because -** of A's read lock. A tries to promote to reserved but is blocked by B. -** One or the other of the two processes must give way or there can be -** no progress. By returning SQLITE_BUSY and not invoking the busy callback -** when A already has a read lock, we encourage A to give up and let B -** proceed. -*/ -int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ - BtShared *pBt = p->pBt; - int rc = SQLITE_OK; - - sqlite3BtreeEnter(p); - btreeIntegrity(p); - - /* If the btree is already in a write-transaction, or it - ** is already in a read-transaction and a read-transaction - ** is requested, this is a no-op. - */ - if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){ - goto trans_begun; - } - - /* Write transactions are not possible on a read-only database */ - if( pBt->readOnly && wrflag ){ - rc = SQLITE_READONLY; - goto trans_begun; - } - - /* If another database handle has already opened a write transaction - ** on this shared-btree structure and a second write transaction is - ** requested, return SQLITE_BUSY. - */ - if( pBt->inTransaction==TRANS_WRITE && wrflag ){ - rc = SQLITE_BUSY; - goto trans_begun; - } - - do { - if( pBt->pPage1==0 ){ - rc = lockBtree(pBt); - } - - if( rc==SQLITE_OK && wrflag ){ - if( pBt->readOnly ){ - rc = SQLITE_READONLY; - }else{ - rc = sqlite3PagerBegin(pBt->pPage1->pDbPage, wrflag>1); - if( rc==SQLITE_OK ){ - rc = newDatabase(pBt); - } - } - } - - if( rc==SQLITE_OK ){ - if( wrflag ) pBt->inStmt = 0; - }else{ - unlockBtreeIfUnused(pBt); - } - }while( rc==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && - sqlite3InvokeBusyHandler(pBt->pBusyHandler) ); - - if( rc==SQLITE_OK ){ - if( p->inTrans==TRANS_NONE ){ - pBt->nTransaction++; - } - p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ); - if( p->inTrans>pBt->inTransaction ){ - pBt->inTransaction = p->inTrans; - } - } - - -trans_begun: - btreeIntegrity(p); - sqlite3BtreeLeave(p); - return rc; -} - -#ifndef SQLITE_OMIT_AUTOVACUUM - -/* -** Set the pointer-map entries for all children of page pPage. Also, if -** pPage contains cells that point to overflow pages, set the pointer -** map entries for the overflow pages as well. -*/ -static int setChildPtrmaps(MemPage *pPage){ - int i; /* Counter variable */ - int nCell; /* Number of cells in page pPage */ - int rc; /* Return code */ - BtShared *pBt = pPage->pBt; - int isInitOrig = pPage->isInit; - Pgno pgno = pPage->pgno; - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - rc = sqlite3BtreeInitPage(pPage, pPage->pParent); - if( rc!=SQLITE_OK ){ - goto set_child_ptrmaps_out; - } - nCell = pPage->nCell; - - for(i=0; ileaf ){ - Pgno childPgno = get4byte(pCell); - rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno); - if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out; - } - } - - if( !pPage->leaf ){ - Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); - rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno); - } - -set_child_ptrmaps_out: - pPage->isInit = isInitOrig; - return rc; -} - -/* -** Somewhere on pPage, which is guarenteed to be a btree page, not an overflow -** page, is a pointer to page iFrom. Modify this pointer so that it points to -** iTo. Parameter eType describes the type of pointer to be modified, as -** follows: -** -** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child -** page of pPage. -** -** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow -** page pointed to by one of the cells on pPage. -** -** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next -** overflow page in the list. -*/ -static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - if( eType==PTRMAP_OVERFLOW2 ){ - /* The pointer is always the first 4 bytes of the page in this case. */ - if( get4byte(pPage->aData)!=iFrom ){ - return SQLITE_CORRUPT_BKPT; - } - put4byte(pPage->aData, iTo); - }else{ - int isInitOrig = pPage->isInit; - int i; - int nCell; - - sqlite3BtreeInitPage(pPage, 0); - nCell = pPage->nCell; - - for(i=0; iaData[pPage->hdrOffset+8])!=iFrom ){ - return SQLITE_CORRUPT_BKPT; - } - put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); - } - - pPage->isInit = isInitOrig; - } - return SQLITE_OK; -} - - -/* -** Move the open database page pDbPage to location iFreePage in the -** database. The pDbPage reference remains valid. -*/ -static int relocatePage( - BtShared *pBt, /* Btree */ - MemPage *pDbPage, /* Open page to move */ - u8 eType, /* Pointer map 'type' entry for pDbPage */ - Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */ - Pgno iFreePage /* The location to move pDbPage to */ -){ - MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */ - Pgno iDbPage = pDbPage->pgno; - Pager *pPager = pBt->pPager; - int rc; - - assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || - eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pDbPage->pBt==pBt ); - - /* Move page iDbPage from it's current location to page number iFreePage */ - TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", - iDbPage, iFreePage, iPtrPage, eType)); - rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage); - if( rc!=SQLITE_OK ){ - return rc; - } - pDbPage->pgno = iFreePage; - - /* If pDbPage was a btree-page, then it may have child pages and/or cells - ** that point to overflow pages. The pointer map entries for all these - ** pages need to be changed. - ** - ** If pDbPage is an overflow page, then the first 4 bytes may store a - ** pointer to a subsequent overflow page. If this is the case, then - ** the pointer map needs to be updated for the subsequent overflow page. - */ - if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){ - rc = setChildPtrmaps(pDbPage); - if( rc!=SQLITE_OK ){ - return rc; - } - }else{ - Pgno nextOvfl = get4byte(pDbPage->aData); - if( nextOvfl!=0 ){ - rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage); - if( rc!=SQLITE_OK ){ - return rc; - } - } - } - - /* Fix the database pointer on page iPtrPage that pointed at iDbPage so - ** that it points at iFreePage. Also fix the pointer map entry for - ** iPtrPage. - */ - if( eType!=PTRMAP_ROOTPAGE ){ - rc = sqlite3BtreeGetPage(pBt, iPtrPage, &pPtrPage, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = sqlite3PagerWrite(pPtrPage->pDbPage); - if( rc!=SQLITE_OK ){ - releasePage(pPtrPage); - return rc; - } - rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType); - releasePage(pPtrPage); - if( rc==SQLITE_OK ){ - rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage); - } - } - return rc; -} - -/* Forward declaration required by incrVacuumStep(). */ -static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8); - -/* -** Perform a single step of an incremental-vacuum. If successful, -** return SQLITE_OK. If there is no work to do (and therefore no -** point in calling this function again), return SQLITE_DONE. -** -** More specificly, this function attempts to re-organize the -** database so that the last page of the file currently in use -** is no longer in use. -** -** If the nFin parameter is non-zero, the implementation assumes -** that the caller will keep calling incrVacuumStep() until -** it returns SQLITE_DONE or an error, and that nFin is the -** number of pages the database file will contain after this -** process is complete. -*/ -static int incrVacuumStep(BtShared *pBt, Pgno nFin){ - Pgno iLastPg; /* Last page in the database */ - Pgno nFreeList; /* Number of pages still on the free-list */ - - assert( sqlite3_mutex_held(pBt->mutex) ); - iLastPg = pBt->nTrunc; - if( iLastPg==0 ){ - iLastPg = sqlite3PagerPagecount(pBt->pPager); - } - - if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){ - int rc; - u8 eType; - Pgno iPtrPage; - - nFreeList = get4byte(&pBt->pPage1->aData[36]); - if( nFreeList==0 || nFin==iLastPg ){ - return SQLITE_DONE; - } - - rc = ptrmapGet(pBt, iLastPg, &eType, &iPtrPage); - if( rc!=SQLITE_OK ){ - return rc; - } - if( eType==PTRMAP_ROOTPAGE ){ - return SQLITE_CORRUPT_BKPT; - } - - if( eType==PTRMAP_FREEPAGE ){ - if( nFin==0 ){ - /* Remove the page from the files free-list. This is not required - ** if nFin is non-zero. In that case, the free-list will be - ** truncated to zero after this function returns, so it doesn't - ** matter if it still contains some garbage entries. - */ - Pgno iFreePg; - MemPage *pFreePg; - rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, 1); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( iFreePg==iLastPg ); - releasePage(pFreePg); - } - } else { - Pgno iFreePg; /* Index of free page to move pLastPg to */ - MemPage *pLastPg; - - rc = sqlite3BtreeGetPage(pBt, iLastPg, &pLastPg, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - - /* If nFin is zero, this loop runs exactly once and page pLastPg - ** is swapped with the first free page pulled off the free list. - ** - ** On the other hand, if nFin is greater than zero, then keep - ** looping until a free-page located within the first nFin pages - ** of the file is found. - */ - do { - MemPage *pFreePg; - rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, 0, 0); - if( rc!=SQLITE_OK ){ - releasePage(pLastPg); - return rc; - } - releasePage(pFreePg); - }while( nFin!=0 && iFreePg>nFin ); - assert( iFreePgpDbPage); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg); - releasePage(pLastPg); - if( rc!=SQLITE_OK ){ - return rc; - } - } - } - - pBt->nTrunc = iLastPg - 1; - while( pBt->nTrunc==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, pBt->nTrunc) ){ - pBt->nTrunc--; - } - return SQLITE_OK; -} - -/* -** A write-transaction must be opened before calling this function. -** It performs a single unit of work towards an incremental vacuum. -** -** If the incremental vacuum is finished after this function has run, -** SQLITE_DONE is returned. If it is not finished, but no error occured, -** SQLITE_OK is returned. Otherwise an SQLite error code. -*/ -int sqlite3BtreeIncrVacuum(Btree *p){ - int rc; - BtShared *pBt = p->pBt; - - sqlite3BtreeEnter(p); - assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE ); - if( !pBt->autoVacuum ){ - rc = SQLITE_DONE; - }else{ - invalidateAllOverflowCache(pBt); - rc = incrVacuumStep(pBt, 0); - } - sqlite3BtreeLeave(p); - return rc; -} - -/* -** This routine is called prior to sqlite3PagerCommit when a transaction -** is commited for an auto-vacuum database. -** -** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages -** the database file should be truncated to during the commit process. -** i.e. the database has been reorganized so that only the first *pnTrunc -** pages are in use. -*/ -static int autoVacuumCommit(BtShared *pBt, Pgno *pnTrunc){ - int rc = SQLITE_OK; - Pager *pPager = pBt->pPager; -#ifndef NDEBUG - int nRef = sqlite3PagerRefcount(pPager); -#endif - - assert( sqlite3_mutex_held(pBt->mutex) ); - invalidateAllOverflowCache(pBt); - assert(pBt->autoVacuum); - if( !pBt->incrVacuum ){ - Pgno nFin = 0; - - if( pBt->nTrunc==0 ){ - Pgno nFree; - Pgno nPtrmap; - const int pgsz = pBt->pageSize; - Pgno nOrig = sqlite3PagerPagecount(pBt->pPager); - - if( PTRMAP_ISPAGE(pBt, nOrig) ){ - return SQLITE_CORRUPT_BKPT; - } - if( nOrig==PENDING_BYTE_PAGE(pBt) ){ - nOrig--; - } - nFree = get4byte(&pBt->pPage1->aData[36]); - nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+pgsz/5)/(pgsz/5); - nFin = nOrig - nFree - nPtrmap; - if( nOrig>PENDING_BYTE_PAGE(pBt) && nFin<=PENDING_BYTE_PAGE(pBt) ){ - nFin--; - } - while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){ - nFin--; - } - } - - while( rc==SQLITE_OK ){ - rc = incrVacuumStep(pBt, nFin); - } - if( rc==SQLITE_DONE ){ - assert(nFin==0 || pBt->nTrunc==0 || nFin<=pBt->nTrunc); - rc = SQLITE_OK; - if( pBt->nTrunc ){ - rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); - put4byte(&pBt->pPage1->aData[32], 0); - put4byte(&pBt->pPage1->aData[36], 0); - pBt->nTrunc = nFin; - } - } - if( rc!=SQLITE_OK ){ - sqlite3PagerRollback(pPager); - } - } - - if( rc==SQLITE_OK ){ - *pnTrunc = pBt->nTrunc; - pBt->nTrunc = 0; - } - assert( nRef==sqlite3PagerRefcount(pPager) ); - return rc; -} - -#endif - -/* -** This routine does the first phase of a two-phase commit. This routine -** causes a rollback journal to be created (if it does not already exist) -** and populated with enough information so that if a power loss occurs -** the database can be restored to its original state by playing back -** the journal. Then the contents of the journal are flushed out to -** the disk. After the journal is safely on oxide, the changes to the -** database are written into the database file and flushed to oxide. -** At the end of this call, the rollback journal still exists on the -** disk and we are still holding all locks, so the transaction has not -** committed. See sqlite3BtreeCommit() for the second phase of the -** commit process. -** -** This call is a no-op if no write-transaction is currently active on pBt. -** -** Otherwise, sync the database file for the btree pBt. zMaster points to -** the name of a master journal file that should be written into the -** individual journal file, or is NULL, indicating no master journal file -** (single database transaction). -** -** When this is called, the master journal should already have been -** created, populated with this journal pointer and synced to disk. -** -** Once this is routine has returned, the only thing required to commit -** the write-transaction for this database file is to delete the journal. -*/ -int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){ - int rc = SQLITE_OK; - if( p->inTrans==TRANS_WRITE ){ - BtShared *pBt = p->pBt; - Pgno nTrunc = 0; - sqlite3BtreeEnter(p); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - rc = autoVacuumCommit(pBt, &nTrunc); - if( rc!=SQLITE_OK ){ - sqlite3BtreeLeave(p); - return rc; - } - } -#endif - rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, nTrunc); - sqlite3BtreeLeave(p); - } - return rc; -} - -/* -** Commit the transaction currently in progress. -** -** This routine implements the second phase of a 2-phase commit. The -** sqlite3BtreeSync() routine does the first phase and should be invoked -** prior to calling this routine. The sqlite3BtreeSync() routine did -** all the work of writing information out to disk and flushing the -** contents so that they are written onto the disk platter. All this -** routine has to do is delete or truncate the rollback journal -** (which causes the transaction to commit) and drop locks. -** -** This will release the write lock on the database file. If there -** are no active cursors, it also releases the read lock. -*/ -int sqlite3BtreeCommitPhaseTwo(Btree *p){ - BtShared *pBt = p->pBt; - - sqlite3BtreeEnter(p); - btreeIntegrity(p); - - /* If the handle has a write-transaction open, commit the shared-btrees - ** transaction and set the shared state to TRANS_READ. - */ - if( p->inTrans==TRANS_WRITE ){ - int rc; - assert( pBt->inTransaction==TRANS_WRITE ); - assert( pBt->nTransaction>0 ); - rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); - if( rc!=SQLITE_OK ){ - sqlite3BtreeLeave(p); - return rc; - } - pBt->inTransaction = TRANS_READ; - pBt->inStmt = 0; - } - unlockAllTables(p); - - /* If the handle has any kind of transaction open, decrement the transaction - ** count of the shared btree. If the transaction count reaches 0, set - ** the shared state to TRANS_NONE. The unlockBtreeIfUnused() call below - ** will unlock the pager. - */ - if( p->inTrans!=TRANS_NONE ){ - pBt->nTransaction--; - if( 0==pBt->nTransaction ){ - pBt->inTransaction = TRANS_NONE; - } - } - - /* Set the handles current transaction state to TRANS_NONE and unlock - ** the pager if this call closed the only read or write transaction. - */ - p->inTrans = TRANS_NONE; - unlockBtreeIfUnused(pBt); - - btreeIntegrity(p); - sqlite3BtreeLeave(p); - return SQLITE_OK; -} - -/* -** Do both phases of a commit. -*/ -int sqlite3BtreeCommit(Btree *p){ - int rc; - sqlite3BtreeEnter(p); - rc = sqlite3BtreeCommitPhaseOne(p, 0); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeCommitPhaseTwo(p); - } - sqlite3BtreeLeave(p); - return rc; -} - -#ifndef NDEBUG -/* -** Return the number of write-cursors open on this handle. This is for use -** in assert() expressions, so it is only compiled if NDEBUG is not -** defined. -** -** For the purposes of this routine, a write-cursor is any cursor that -** is capable of writing to the databse. That means the cursor was -** originally opened for writing and the cursor has not be disabled -** by having its state changed to CURSOR_FAULT. -*/ -static int countWriteCursors(BtShared *pBt){ - BtCursor *pCur; - int r = 0; - for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ - if( pCur->wrFlag && pCur->eState!=CURSOR_FAULT ) r++; - } - return r; -} -#endif - -/* -** This routine sets the state to CURSOR_FAULT and the error -** code to errCode for every cursor on BtShared that pBtree -** references. -** -** Every cursor is tripped, including cursors that belong -** to other database connections that happen to be sharing -** the cache with pBtree. -** -** This routine gets called when a rollback occurs. -** All cursors using the same cache must be tripped -** to prevent them from trying to use the btree after -** the rollback. The rollback may have deleted tables -** or moved root pages, so it is not sufficient to -** save the state of the cursor. The cursor must be -** invalidated. -*/ -void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){ - BtCursor *p; - sqlite3BtreeEnter(pBtree); - for(p=pBtree->pBt->pCursor; p; p=p->pNext){ - clearCursorPosition(p); - p->eState = CURSOR_FAULT; - p->skip = errCode; - } - sqlite3BtreeLeave(pBtree); -} - -/* -** Rollback the transaction in progress. All cursors will be -** invalided by this operation. Any attempt to use a cursor -** that was open at the beginning of this operation will result -** in an error. -** -** This will release the write lock on the database file. If there -** are no active cursors, it also releases the read lock. -*/ -int sqlite3BtreeRollback(Btree *p){ - int rc; - BtShared *pBt = p->pBt; - MemPage *pPage1; - - sqlite3BtreeEnter(p); - rc = saveAllCursors(pBt, 0, 0); -#ifndef SQLITE_OMIT_SHARED_CACHE - if( rc!=SQLITE_OK ){ - /* This is a horrible situation. An IO or malloc() error occured whilst - ** trying to save cursor positions. If this is an automatic rollback (as - ** the result of a constraint, malloc() failure or IO error) then - ** the cache may be internally inconsistent (not contain valid trees) so - ** we cannot simply return the error to the caller. Instead, abort - ** all queries that may be using any of the cursors that failed to save. - */ - sqlite3BtreeTripAllCursors(p, rc); - } -#endif - btreeIntegrity(p); - unlockAllTables(p); - - if( p->inTrans==TRANS_WRITE ){ - int rc2; - -#ifndef SQLITE_OMIT_AUTOVACUUM - pBt->nTrunc = 0; -#endif - - assert( TRANS_WRITE==pBt->inTransaction ); - rc2 = sqlite3PagerRollback(pBt->pPager); - if( rc2!=SQLITE_OK ){ - rc = rc2; - } - - /* The rollback may have destroyed the pPage1->aData value. So - ** call sqlite3BtreeGetPage() on page 1 again to make - ** sure pPage1->aData is set correctly. */ - if( sqlite3BtreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){ - releasePage(pPage1); - } - assert( countWriteCursors(pBt)==0 ); - pBt->inTransaction = TRANS_READ; - } - - if( p->inTrans!=TRANS_NONE ){ - assert( pBt->nTransaction>0 ); - pBt->nTransaction--; - if( 0==pBt->nTransaction ){ - pBt->inTransaction = TRANS_NONE; - } - } - - p->inTrans = TRANS_NONE; - pBt->inStmt = 0; - unlockBtreeIfUnused(pBt); - - btreeIntegrity(p); - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Start a statement subtransaction. The subtransaction can -** can be rolled back independently of the main transaction. -** You must start a transaction before starting a subtransaction. -** The subtransaction is ended automatically if the main transaction -** commits or rolls back. -** -** Only one subtransaction may be active at a time. It is an error to try -** to start a new subtransaction if another subtransaction is already active. -** -** Statement subtransactions are used around individual SQL statements -** that are contained within a BEGIN...COMMIT block. If a constraint -** error occurs within the statement, the effect of that one statement -** can be rolled back without having to rollback the entire transaction. -*/ -int sqlite3BtreeBeginStmt(Btree *p){ - int rc; - BtShared *pBt = p->pBt; - sqlite3BtreeEnter(p); - if( (p->inTrans!=TRANS_WRITE) || pBt->inStmt ){ - rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; - }else{ - assert( pBt->inTransaction==TRANS_WRITE ); - rc = pBt->readOnly ? SQLITE_OK : sqlite3PagerStmtBegin(pBt->pPager); - pBt->inStmt = 1; - } - sqlite3BtreeLeave(p); - return rc; -} - - -/* -** Commit the statment subtransaction currently in progress. If no -** subtransaction is active, this is a no-op. -*/ -int sqlite3BtreeCommitStmt(Btree *p){ - int rc; - BtShared *pBt = p->pBt; - sqlite3BtreeEnter(p); - if( pBt->inStmt && !pBt->readOnly ){ - rc = sqlite3PagerStmtCommit(pBt->pPager); - }else{ - rc = SQLITE_OK; - } - pBt->inStmt = 0; - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Rollback the active statement subtransaction. If no subtransaction -** is active this routine is a no-op. -** -** All cursors will be invalidated by this operation. Any attempt -** to use a cursor that was open at the beginning of this operation -** will result in an error. -*/ -int sqlite3BtreeRollbackStmt(Btree *p){ - int rc = SQLITE_OK; - BtShared *pBt = p->pBt; - sqlite3BtreeEnter(p); - if( pBt->inStmt && !pBt->readOnly ){ - rc = sqlite3PagerStmtRollback(pBt->pPager); - assert( countWriteCursors(pBt)==0 ); - pBt->inStmt = 0; - } - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Default key comparison function to be used if no comparison function -** is specified on the sqlite3BtreeCursor() call. -*/ -static int dfltCompare( - void *NotUsed, /* User data is not used */ - int n1, const void *p1, /* First key to compare */ - int n2, const void *p2 /* Second key to compare */ -){ - int c; - c = memcmp(p1, p2, n1pBt; - - assert( sqlite3BtreeHoldsMutex(p) ); - *ppCur = 0; - if( wrFlag ){ - if( pBt->readOnly ){ - return SQLITE_READONLY; - } - if( checkReadLocks(p, iTable, 0) ){ - return SQLITE_LOCKED; - } - } - - if( pBt->pPage1==0 ){ - rc = lockBtreeWithRetry(p); - if( rc!=SQLITE_OK ){ - return rc; - } - if( pBt->readOnly && wrFlag ){ - return SQLITE_READONLY; - } - } - pCur = sqlite3MallocZero( sizeof(*pCur) ); - if( pCur==0 ){ - rc = SQLITE_NOMEM; - goto create_cursor_exception; - } - pCur->pgnoRoot = (Pgno)iTable; - if( iTable==1 && sqlite3PagerPagecount(pBt->pPager)==0 ){ - rc = SQLITE_EMPTY; - goto create_cursor_exception; - } - rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->pPage, 0); - if( rc!=SQLITE_OK ){ - goto create_cursor_exception; - } - - /* Now that no other errors can occur, finish filling in the BtCursor - ** variables, link the cursor into the BtShared list and set *ppCur (the - ** output argument to this function). - */ - pCur->xCompare = xCmp ? xCmp : dfltCompare; - pCur->pArg = pArg; - pCur->pBtree = p; - pCur->pBt = pBt; - pCur->wrFlag = wrFlag; - pCur->pNext = pBt->pCursor; - if( pCur->pNext ){ - pCur->pNext->pPrev = pCur; - } - pBt->pCursor = pCur; - pCur->eState = CURSOR_INVALID; - *ppCur = pCur; - - return SQLITE_OK; - -create_cursor_exception: - if( pCur ){ - releasePage(pCur->pPage); - sqlite3_free(pCur); - } - unlockBtreeIfUnused(pBt); - return rc; -} -int sqlite3BtreeCursor( - Btree *p, /* The btree */ - int iTable, /* Root page of table to open */ - int wrFlag, /* 1 to write. 0 read-only */ - int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */ - void *pArg, /* First arg to xCompare() */ - BtCursor **ppCur /* Write new cursor here */ -){ - int rc; - sqlite3BtreeEnter(p); - rc = btreeCursor(p, iTable, wrFlag, xCmp, pArg, ppCur); - sqlite3BtreeLeave(p); - return rc; -} - - -/* -** Close a cursor. The read lock on the database file is released -** when the last cursor is closed. -*/ -int sqlite3BtreeCloseCursor(BtCursor *pCur){ - BtShared *pBt = pCur->pBt; - Btree *pBtree = pCur->pBtree; - - sqlite3BtreeEnter(pBtree); - clearCursorPosition(pCur); - if( pCur->pPrev ){ - pCur->pPrev->pNext = pCur->pNext; - }else{ - pBt->pCursor = pCur->pNext; - } - if( pCur->pNext ){ - pCur->pNext->pPrev = pCur->pPrev; - } - releasePage(pCur->pPage); - unlockBtreeIfUnused(pBt); - invalidateOverflowCache(pCur); - sqlite3_free(pCur); - sqlite3BtreeLeave(pBtree); - return SQLITE_OK; -} - -/* -** Make a temporary cursor by filling in the fields of pTempCur. -** The temporary cursor is not on the cursor list for the Btree. -*/ -void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur){ - assert( cursorHoldsMutex(pCur) ); - memcpy(pTempCur, pCur, sizeof(*pCur)); - pTempCur->pNext = 0; - pTempCur->pPrev = 0; - if( pTempCur->pPage ){ - sqlite3PagerRef(pTempCur->pPage->pDbPage); - } -} - -/* -** Delete a temporary cursor such as was made by the CreateTemporaryCursor() -** function above. -*/ -void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){ - assert( cursorHoldsMutex(pCur) ); - if( pCur->pPage ){ - sqlite3PagerUnref(pCur->pPage->pDbPage); - } -} - -/* -** Make sure the BtCursor* given in the argument has a valid -** BtCursor.info structure. If it is not already valid, call -** sqlite3BtreeParseCell() to fill it in. -** -** BtCursor.info is a cache of the information in the current cell. -** Using this cache reduces the number of calls to sqlite3BtreeParseCell(). -** -** 2007-06-25: There is a bug in some versions of MSVC that cause the -** compiler to crash when getCellInfo() is implemented as a macro. -** But there is a measureable speed advantage to using the macro on gcc -** (when less compiler optimizations like -Os or -O0 are used and the -** compiler is not doing agressive inlining.) So we use a real function -** for MSVC and a macro for everything else. Ticket #2457. -*/ -#ifndef NDEBUG - static void assertCellInfo(BtCursor *pCur){ - CellInfo info; - memset(&info, 0, sizeof(info)); - sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &info); - assert( memcmp(&info, &pCur->info, sizeof(info))==0 ); - } -#else - #define assertCellInfo(x) -#endif -#ifdef _MSC_VER - /* Use a real function in MSVC to work around bugs in that compiler. */ - static void getCellInfo(BtCursor *pCur){ - if( pCur->info.nSize==0 ){ - sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &pCur->info); - }else{ - assertCellInfo(pCur); - } - } -#else /* if not _MSC_VER */ - /* Use a macro in all other compilers so that the function is inlined */ -#define getCellInfo(pCur) \ - if( pCur->info.nSize==0 ){ \ - sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &pCur->info); \ - }else{ \ - assertCellInfo(pCur); \ - } -#endif /* _MSC_VER */ - -/* -** Set *pSize to the size of the buffer needed to hold the value of -** the key for the current entry. If the cursor is not pointing -** to a valid entry, *pSize is set to 0. -** -** For a table with the INTKEY flag set, this routine returns the key -** itself, not the number of bytes in the key. -*/ -int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){ - int rc; - - assert( cursorHoldsMutex(pCur) ); - rc = restoreOrClearCursorPosition(pCur); - if( rc==SQLITE_OK ){ - assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID ); - if( pCur->eState==CURSOR_INVALID ){ - *pSize = 0; - }else{ - getCellInfo(pCur); - *pSize = pCur->info.nKey; - } - } - return rc; -} - -/* -** Set *pSize to the number of bytes of data in the entry the -** cursor currently points to. Always return SQLITE_OK. -** Failure is not possible. If the cursor is not currently -** pointing to an entry (which can happen, for example, if -** the database is empty) then *pSize is set to 0. -*/ -int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){ - int rc; - - assert( cursorHoldsMutex(pCur) ); - rc = restoreOrClearCursorPosition(pCur); - if( rc==SQLITE_OK ){ - assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID ); - if( pCur->eState==CURSOR_INVALID ){ - /* Not pointing at a valid entry - set *pSize to 0. */ - *pSize = 0; - }else{ - getCellInfo(pCur); - *pSize = pCur->info.nData; - } - } - return rc; -} - -/* -** Given the page number of an overflow page in the database (parameter -** ovfl), this function finds the page number of the next page in the -** linked list of overflow pages. If possible, it uses the auto-vacuum -** pointer-map data instead of reading the content of page ovfl to do so. -** -** If an error occurs an SQLite error code is returned. Otherwise: -** -** Unless pPgnoNext is NULL, the page number of the next overflow -** page in the linked list is written to *pPgnoNext. If page ovfl -** is the last page in it's linked list, *pPgnoNext is set to zero. -** -** If ppPage is not NULL, *ppPage is set to the MemPage* handle -** for page ovfl. The underlying pager page may have been requested -** with the noContent flag set, so the page data accessable via -** this handle may not be trusted. -*/ -static int getOverflowPage( - BtShared *pBt, - Pgno ovfl, /* Overflow page */ - MemPage **ppPage, /* OUT: MemPage handle */ - Pgno *pPgnoNext /* OUT: Next overflow page number */ -){ - Pgno next = 0; - int rc; - - assert( sqlite3_mutex_held(pBt->mutex) ); - /* One of these must not be NULL. Otherwise, why call this function? */ - assert(ppPage || pPgnoNext); - - /* If pPgnoNext is NULL, then this function is being called to obtain - ** a MemPage* reference only. No page-data is required in this case. - */ - if( !pPgnoNext ){ - return sqlite3BtreeGetPage(pBt, ovfl, ppPage, 1); - } - -#ifndef SQLITE_OMIT_AUTOVACUUM - /* Try to find the next page in the overflow list using the - ** autovacuum pointer-map pages. Guess that the next page in - ** the overflow list is page number (ovfl+1). If that guess turns - ** out to be wrong, fall back to loading the data of page - ** number ovfl to determine the next page number. - */ - if( pBt->autoVacuum ){ - Pgno pgno; - Pgno iGuess = ovfl+1; - u8 eType; - - while( PTRMAP_ISPAGE(pBt, iGuess) || iGuess==PENDING_BYTE_PAGE(pBt) ){ - iGuess++; - } - - if( iGuess<=sqlite3PagerPagecount(pBt->pPager) ){ - rc = ptrmapGet(pBt, iGuess, &eType, &pgno); - if( rc!=SQLITE_OK ){ - return rc; - } - if( eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){ - next = iGuess; - } - } - } -#endif - - if( next==0 || ppPage ){ - MemPage *pPage = 0; - - rc = sqlite3BtreeGetPage(pBt, ovfl, &pPage, next!=0); - assert(rc==SQLITE_OK || pPage==0); - if( next==0 && rc==SQLITE_OK ){ - next = get4byte(pPage->aData); - } - - if( ppPage ){ - *ppPage = pPage; - }else{ - releasePage(pPage); - } - } - *pPgnoNext = next; - - return rc; -} - -/* -** Copy data from a buffer to a page, or from a page to a buffer. -** -** pPayload is a pointer to data stored on database page pDbPage. -** If argument eOp is false, then nByte bytes of data are copied -** from pPayload to the buffer pointed at by pBuf. If eOp is true, -** then sqlite3PagerWrite() is called on pDbPage and nByte bytes -** of data are copied from the buffer pBuf to pPayload. -** -** SQLITE_OK is returned on success, otherwise an error code. -*/ -static int copyPayload( - void *pPayload, /* Pointer to page data */ - void *pBuf, /* Pointer to buffer */ - int nByte, /* Number of bytes to copy */ - int eOp, /* 0 -> copy from page, 1 -> copy to page */ - DbPage *pDbPage /* Page containing pPayload */ -){ - if( eOp ){ - /* Copy data from buffer to page (a write operation) */ - int rc = sqlite3PagerWrite(pDbPage); - if( rc!=SQLITE_OK ){ - return rc; - } - memcpy(pPayload, pBuf, nByte); - }else{ - /* Copy data from page to buffer (a read operation) */ - memcpy(pBuf, pPayload, nByte); - } - return SQLITE_OK; -} - -/* -** This function is used to read or overwrite payload information -** for the entry that the pCur cursor is pointing to. If the eOp -** parameter is 0, this is a read operation (data copied into -** buffer pBuf). If it is non-zero, a write (data copied from -** buffer pBuf). -** -** A total of "amt" bytes are read or written beginning at "offset". -** Data is read to or from the buffer pBuf. -** -** This routine does not make a distinction between key and data. -** It just reads or writes bytes from the payload area. Data might -** appear on the main page or be scattered out on multiple overflow -** pages. -** -** If the BtCursor.isIncrblobHandle flag is set, and the current -** cursor entry uses one or more overflow pages, this function -** allocates space for and lazily popluates the overflow page-list -** cache array (BtCursor.aOverflow). Subsequent calls use this -** cache to make seeking to the supplied offset more efficient. -** -** Once an overflow page-list cache has been allocated, it may be -** invalidated if some other cursor writes to the same table, or if -** the cursor is moved to a different row. Additionally, in auto-vacuum -** mode, the following events may invalidate an overflow page-list cache. -** -** * An incremental vacuum, -** * A commit in auto_vacuum="full" mode, -** * Creating a table (may require moving an overflow page). -*/ -static int accessPayload( - BtCursor *pCur, /* Cursor pointing to entry to read from */ - int offset, /* Begin reading this far into payload */ - int amt, /* Read this many bytes */ - unsigned char *pBuf, /* Write the bytes into this buffer */ - int skipKey, /* offset begins at data if this is true */ - int eOp /* zero to read. non-zero to write. */ -){ - unsigned char *aPayload; - int rc = SQLITE_OK; - u32 nKey; - int iIdx = 0; - MemPage *pPage = pCur->pPage; /* Btree page of current cursor entry */ - BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ - - assert( pPage ); - assert( pCur->eState==CURSOR_VALID ); - assert( pCur->idx>=0 && pCur->idxnCell ); - assert( offset>=0 ); - assert( cursorHoldsMutex(pCur) ); - - getCellInfo(pCur); - aPayload = pCur->info.pCell + pCur->info.nHeader; - nKey = (pPage->intKey ? 0 : pCur->info.nKey); - - if( skipKey ){ - offset += nKey; - } - if( offset+amt > nKey+pCur->info.nData ){ - /* Trying to read or write past the end of the data is an error */ - return SQLITE_ERROR; - } - - /* Check if data must be read/written to/from the btree page itself. */ - if( offsetinfo.nLocal ){ - int a = amt; - if( a+offset>pCur->info.nLocal ){ - a = pCur->info.nLocal - offset; - } - rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage); - offset = 0; - pBuf += a; - amt -= a; - }else{ - offset -= pCur->info.nLocal; - } - - if( rc==SQLITE_OK && amt>0 ){ - const int ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */ - Pgno nextPage; - - nextPage = get4byte(&aPayload[pCur->info.nLocal]); - -#ifndef SQLITE_OMIT_INCRBLOB - /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[] - ** has not been allocated, allocate it now. The array is sized at - ** one entry for each overflow page in the overflow chain. The - ** page number of the first overflow page is stored in aOverflow[0], - ** etc. A value of 0 in the aOverflow[] array means "not yet known" - ** (the cache is lazily populated). - */ - if( pCur->isIncrblobHandle && !pCur->aOverflow ){ - int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; - pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl); - if( nOvfl && !pCur->aOverflow ){ - rc = SQLITE_NOMEM; - } - } - - /* If the overflow page-list cache has been allocated and the - ** entry for the first required overflow page is valid, skip - ** directly to it. - */ - if( pCur->aOverflow && pCur->aOverflow[offset/ovflSize] ){ - iIdx = (offset/ovflSize); - nextPage = pCur->aOverflow[iIdx]; - offset = (offset%ovflSize); - } -#endif - - for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){ - -#ifndef SQLITE_OMIT_INCRBLOB - /* If required, populate the overflow page-list cache. */ - if( pCur->aOverflow ){ - assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage); - pCur->aOverflow[iIdx] = nextPage; - } -#endif - - if( offset>=ovflSize ){ - /* The only reason to read this page is to obtain the page - ** number for the next page in the overflow chain. The page - ** data is not required. So first try to lookup the overflow - ** page-list cache, if any, then fall back to the getOverflowPage() - ** function. - */ -#ifndef SQLITE_OMIT_INCRBLOB - if( pCur->aOverflow && pCur->aOverflow[iIdx+1] ){ - nextPage = pCur->aOverflow[iIdx+1]; - } else -#endif - rc = getOverflowPage(pBt, nextPage, 0, &nextPage); - offset -= ovflSize; - }else{ - /* Need to read this page properly. It contains some of the - ** range of data that is being read (eOp==0) or written (eOp!=0). - */ - DbPage *pDbPage; - int a = amt; - rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage); - if( rc==SQLITE_OK ){ - aPayload = sqlite3PagerGetData(pDbPage); - nextPage = get4byte(aPayload); - if( a + offset > ovflSize ){ - a = ovflSize - offset; - } - rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); - sqlite3PagerUnref(pDbPage); - offset = 0; - amt -= a; - pBuf += a; - } - } - } - } - - if( rc==SQLITE_OK && amt>0 ){ - return SQLITE_CORRUPT_BKPT; - } - return rc; -} - -/* -** Read part of the key associated with cursor pCur. Exactly -** "amt" bytes will be transfered into pBuf[]. The transfer -** begins at "offset". -** -** Return SQLITE_OK on success or an error code if anything goes -** wrong. An error is returned if "offset+amt" is larger than -** the available payload. -*/ -int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - int rc; - - assert( cursorHoldsMutex(pCur) ); - rc = restoreOrClearCursorPosition(pCur); - if( rc==SQLITE_OK ){ - assert( pCur->eState==CURSOR_VALID ); - assert( pCur->pPage!=0 ); - if( pCur->pPage->intKey ){ - return SQLITE_CORRUPT_BKPT; - } - assert( pCur->pPage->intKey==0 ); - assert( pCur->idx>=0 && pCur->idxpPage->nCell ); - rc = accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0, 0); - } - return rc; -} - -/* -** Read part of the data associated with cursor pCur. Exactly -** "amt" bytes will be transfered into pBuf[]. The transfer -** begins at "offset". -** -** Return SQLITE_OK on success or an error code if anything goes -** wrong. An error is returned if "offset+amt" is larger than -** the available payload. -*/ -int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - int rc; - - assert( cursorHoldsMutex(pCur) ); - rc = restoreOrClearCursorPosition(pCur); - if( rc==SQLITE_OK ){ - assert( pCur->eState==CURSOR_VALID ); - assert( pCur->pPage!=0 ); - assert( pCur->idx>=0 && pCur->idxpPage->nCell ); - rc = accessPayload(pCur, offset, amt, pBuf, 1, 0); - } - return rc; -} - -/* -** Return a pointer to payload information from the entry that the -** pCur cursor is pointing to. The pointer is to the beginning of -** the key if skipKey==0 and it points to the beginning of data if -** skipKey==1. The number of bytes of available key/data is written -** into *pAmt. If *pAmt==0, then the value returned will not be -** a valid pointer. -** -** This routine is an optimization. It is common for the entire key -** and data to fit on the local page and for there to be no overflow -** pages. When that is so, this routine can be used to access the -** key and data without making a copy. If the key and/or data spills -** onto overflow pages, then accessPayload() must be used to reassembly -** the key/data and copy it into a preallocated buffer. -** -** The pointer returned by this routine looks directly into the cached -** page of the database. The data might change or move the next time -** any btree routine is called. -*/ -static const unsigned char *fetchPayload( - BtCursor *pCur, /* Cursor pointing to entry to read from */ - int *pAmt, /* Write the number of available bytes here */ - int skipKey /* read beginning at data if this is true */ -){ - unsigned char *aPayload; - MemPage *pPage; - u32 nKey; - int nLocal; - - assert( pCur!=0 && pCur->pPage!=0 ); - assert( pCur->eState==CURSOR_VALID ); - assert( cursorHoldsMutex(pCur) ); - pPage = pCur->pPage; - assert( pCur->idx>=0 && pCur->idxnCell ); - getCellInfo(pCur); - aPayload = pCur->info.pCell; - aPayload += pCur->info.nHeader; - if( pPage->intKey ){ - nKey = 0; - }else{ - nKey = pCur->info.nKey; - } - if( skipKey ){ - aPayload += nKey; - nLocal = pCur->info.nLocal - nKey; - }else{ - nLocal = pCur->info.nLocal; - if( nLocal>nKey ){ - nLocal = nKey; - } - } - *pAmt = nLocal; - return aPayload; -} - - -/* -** For the entry that cursor pCur is point to, return as -** many bytes of the key or data as are available on the local -** b-tree page. Write the number of available bytes into *pAmt. -** -** The pointer returned is ephemeral. The key/data may move -** or be destroyed on the next call to any Btree routine, -** including calls from other threads against the same cache. -** Hence, a mutex on the BtShared should be held prior to calling -** this routine. -** -** These routines is used to get quick access to key and data -** in the common case where no overflow pages are used. -*/ -const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){ - assert( cursorHoldsMutex(pCur) ); - if( pCur->eState==CURSOR_VALID ){ - return (const void*)fetchPayload(pCur, pAmt, 0); - } - return 0; -} -const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){ - assert( cursorHoldsMutex(pCur) ); - if( pCur->eState==CURSOR_VALID ){ - return (const void*)fetchPayload(pCur, pAmt, 1); - } - return 0; -} - - -/* -** Move the cursor down to a new child page. The newPgno argument is the -** page number of the child page to move to. -*/ -static int moveToChild(BtCursor *pCur, u32 newPgno){ - int rc; - MemPage *pNewPage; - MemPage *pOldPage; - BtShared *pBt = pCur->pBt; - - assert( cursorHoldsMutex(pCur) ); - assert( pCur->eState==CURSOR_VALID ); - rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage); - if( rc ) return rc; - pNewPage->idxParent = pCur->idx; - pOldPage = pCur->pPage; - pOldPage->idxShift = 0; - releasePage(pOldPage); - pCur->pPage = pNewPage; - pCur->idx = 0; - pCur->info.nSize = 0; - if( pNewPage->nCell<1 ){ - return SQLITE_CORRUPT_BKPT; - } - return SQLITE_OK; -} - -/* -** Return true if the page is the virtual root of its table. -** -** The virtual root page is the root page for most tables. But -** for the table rooted on page 1, sometime the real root page -** is empty except for the right-pointer. In such cases the -** virtual root page is the page that the right-pointer of page -** 1 is pointing to. -*/ -int sqlite3BtreeIsRootPage(MemPage *pPage){ - MemPage *pParent; - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pParent = pPage->pParent; - if( pParent==0 ) return 1; - if( pParent->pgno>1 ) return 0; - if( get2byte(&pParent->aData[pParent->hdrOffset+3])==0 ) return 1; - return 0; -} - -/* -** Move the cursor up to the parent page. -** -** pCur->idx is set to the cell index that contains the pointer -** to the page we are coming from. If we are coming from the -** right-most child page then pCur->idx is set to one more than -** the largest cell index. -*/ -void sqlite3BtreeMoveToParent(BtCursor *pCur){ - MemPage *pParent; - MemPage *pPage; - int idxParent; - - assert( cursorHoldsMutex(pCur) ); - assert( pCur->eState==CURSOR_VALID ); - pPage = pCur->pPage; - assert( pPage!=0 ); - assert( !sqlite3BtreeIsRootPage(pPage) ); - pParent = pPage->pParent; - assert( pParent!=0 ); - idxParent = pPage->idxParent; - sqlite3PagerRef(pParent->pDbPage); - releasePage(pPage); - pCur->pPage = pParent; - pCur->info.nSize = 0; - assert( pParent->idxShift==0 ); - pCur->idx = idxParent; -} - -/* -** Move the cursor to the root page -*/ -static int moveToRoot(BtCursor *pCur){ - MemPage *pRoot; - int rc = SQLITE_OK; - Btree *p = pCur->pBtree; - BtShared *pBt = p->pBt; - - assert( cursorHoldsMutex(pCur) ); - assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); - assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); - assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); - if( pCur->eState>=CURSOR_REQUIRESEEK ){ - if( pCur->eState==CURSOR_FAULT ){ - return pCur->skip; - } - clearCursorPosition(pCur); - } - pRoot = pCur->pPage; - if( pRoot && pRoot->pgno==pCur->pgnoRoot ){ - assert( pRoot->isInit ); - }else{ - if( - SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0)) - ){ - pCur->eState = CURSOR_INVALID; - return rc; - } - releasePage(pCur->pPage); - pCur->pPage = pRoot; - } - pCur->idx = 0; - pCur->info.nSize = 0; - if( pRoot->nCell==0 && !pRoot->leaf ){ - Pgno subpage; - assert( pRoot->pgno==1 ); - subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); - assert( subpage>0 ); - pCur->eState = CURSOR_VALID; - rc = moveToChild(pCur, subpage); - } - pCur->eState = ((pCur->pPage->nCell>0)?CURSOR_VALID:CURSOR_INVALID); - return rc; -} - -/* -** Move the cursor down to the left-most leaf entry beneath the -** entry to which it is currently pointing. -** -** The left-most leaf is the one with the smallest key - the first -** in ascending order. -*/ -static int moveToLeftmost(BtCursor *pCur){ - Pgno pgno; - int rc = SQLITE_OK; - MemPage *pPage; - - assert( cursorHoldsMutex(pCur) ); - assert( pCur->eState==CURSOR_VALID ); - while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){ - assert( pCur->idx>=0 && pCur->idxnCell ); - pgno = get4byte(findCell(pPage, pCur->idx)); - rc = moveToChild(pCur, pgno); - } - return rc; -} - -/* -** Move the cursor down to the right-most leaf entry beneath the -** page to which it is currently pointing. Notice the difference -** between moveToLeftmost() and moveToRightmost(). moveToLeftmost() -** finds the left-most entry beneath the *entry* whereas moveToRightmost() -** finds the right-most entry beneath the *page*. -** -** The right-most entry is the one with the largest key - the last -** key in ascending order. -*/ -static int moveToRightmost(BtCursor *pCur){ - Pgno pgno; - int rc = SQLITE_OK; - MemPage *pPage; - - assert( cursorHoldsMutex(pCur) ); - assert( pCur->eState==CURSOR_VALID ); - while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){ - pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); - pCur->idx = pPage->nCell; - rc = moveToChild(pCur, pgno); - } - if( rc==SQLITE_OK ){ - pCur->idx = pPage->nCell - 1; - pCur->info.nSize = 0; - } - return SQLITE_OK; -} - -/* Move the cursor to the first entry in the table. Return SQLITE_OK -** on success. Set *pRes to 0 if the cursor actually points to something -** or set *pRes to 1 if the table is empty. -*/ -int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ - int rc; - - assert( cursorHoldsMutex(pCur) ); - assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) ); - rc = moveToRoot(pCur); - if( rc==SQLITE_OK ){ - if( pCur->eState==CURSOR_INVALID ){ - assert( pCur->pPage->nCell==0 ); - *pRes = 1; - rc = SQLITE_OK; - }else{ - assert( pCur->pPage->nCell>0 ); - *pRes = 0; - rc = moveToLeftmost(pCur); - } - } - return rc; -} - -/* Move the cursor to the last entry in the table. Return SQLITE_OK -** on success. Set *pRes to 0 if the cursor actually points to something -** or set *pRes to 1 if the table is empty. -*/ -int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ - int rc; - - assert( cursorHoldsMutex(pCur) ); - assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) ); - rc = moveToRoot(pCur); - if( rc==SQLITE_OK ){ - if( CURSOR_INVALID==pCur->eState ){ - assert( pCur->pPage->nCell==0 ); - *pRes = 1; - }else{ - assert( pCur->eState==CURSOR_VALID ); - *pRes = 0; - rc = moveToRightmost(pCur); - } - } - return rc; -} - -/* Move the cursor so that it points to an entry near pKey/nKey. -** Return a success code. -** -** For INTKEY tables, only the nKey parameter is used. pKey is -** ignored. For other tables, nKey is the number of bytes of data -** in pKey. The comparison function specified when the cursor was -** created is used to compare keys. -** -** If an exact match is not found, then the cursor is always -** left pointing at a leaf page which would hold the entry if it -** were present. The cursor might point to an entry that comes -** before or after the key. -** -** The result of comparing the key with the entry to which the -** cursor is written to *pRes if pRes!=NULL. The meaning of -** this value is as follows: -** -** *pRes<0 The cursor is left pointing at an entry that -** is smaller than pKey or if the table is empty -** and the cursor is therefore left point to nothing. -** -** *pRes==0 The cursor is left pointing at an entry that -** exactly matches pKey. -** -** *pRes>0 The cursor is left pointing at an entry that -** is larger than pKey. -** -*/ -int sqlite3BtreeMoveto( - BtCursor *pCur, /* The cursor to be moved */ - const void *pKey, /* The key content for indices. Not used by tables */ - i64 nKey, /* Size of pKey. Or the key for tables */ - int biasRight, /* If true, bias the search to the high end */ - int *pRes /* Search result flag */ -){ - int rc; - - assert( cursorHoldsMutex(pCur) ); - assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) ); - rc = moveToRoot(pCur); - if( rc ){ - return rc; - } - assert( pCur->pPage ); - assert( pCur->pPage->isInit ); - if( pCur->eState==CURSOR_INVALID ){ - *pRes = -1; - assert( pCur->pPage->nCell==0 ); - return SQLITE_OK; - } - for(;;){ - int lwr, upr; - Pgno chldPg; - MemPage *pPage = pCur->pPage; - int c = -1; /* pRes return if table is empty must be -1 */ - lwr = 0; - upr = pPage->nCell-1; - if( !pPage->intKey && pKey==0 ){ - return SQLITE_CORRUPT_BKPT; - } - if( biasRight ){ - pCur->idx = upr; - }else{ - pCur->idx = (upr+lwr)/2; - } - if( lwr<=upr ) for(;;){ - void *pCellKey; - i64 nCellKey; - pCur->info.nSize = 0; - if( pPage->intKey ){ - u8 *pCell; - pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize; - if( pPage->hasData ){ - u32 dummy; - pCell += getVarint32(pCell, &dummy); - } - getVarint(pCell, (u64 *)&nCellKey); - if( nCellKeynKey ){ - c = +1; - }else{ - c = 0; - } - }else{ - int available; - pCellKey = (void *)fetchPayload(pCur, &available, 0); - nCellKey = pCur->info.nKey; - if( available>=nCellKey ){ - c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey); - }else{ - pCellKey = sqlite3_malloc( nCellKey ); - if( pCellKey==0 ) return SQLITE_NOMEM; - rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey); - c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey); - sqlite3_free(pCellKey); - if( rc ){ - return rc; - } - } - } - if( c==0 ){ - if( pPage->leafData && !pPage->leaf ){ - lwr = pCur->idx; - upr = lwr - 1; - break; - }else{ - if( pRes ) *pRes = 0; - return SQLITE_OK; - } - } - if( c<0 ){ - lwr = pCur->idx+1; - }else{ - upr = pCur->idx-1; - } - if( lwr>upr ){ - break; - } - pCur->idx = (lwr+upr)/2; - } - assert( lwr==upr+1 ); - assert( pPage->isInit ); - if( pPage->leaf ){ - chldPg = 0; - }else if( lwr>=pPage->nCell ){ - chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); - }else{ - chldPg = get4byte(findCell(pPage, lwr)); - } - if( chldPg==0 ){ - assert( pCur->idx>=0 && pCur->idxpPage->nCell ); - if( pRes ) *pRes = c; - return SQLITE_OK; - } - pCur->idx = lwr; - pCur->info.nSize = 0; - rc = moveToChild(pCur, chldPg); - if( rc ){ - return rc; - } - } - /* NOT REACHED */ -} - - -/* -** Return TRUE if the cursor is not pointing at an entry of the table. -** -** TRUE will be returned after a call to sqlite3BtreeNext() moves -** past the last entry in the table or sqlite3BtreePrev() moves past -** the first entry. TRUE is also returned if the table is empty. -*/ -int sqlite3BtreeEof(BtCursor *pCur){ - /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries - ** have been deleted? This API will need to change to return an error code - ** as well as the boolean result value. - */ - return (CURSOR_VALID!=pCur->eState); -} - -/* -** Return the database connection handle for a cursor. -*/ -sqlite3 *sqlite3BtreeCursorDb(const BtCursor *pCur){ - assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) ); - return pCur->pBtree->pSqlite; -} - -/* -** Advance the cursor to the next entry in the database. If -** successful then set *pRes=0. If the cursor -** was already pointing to the last entry in the database before -** this routine was called, then set *pRes=1. -*/ -static int btreeNext(BtCursor *pCur, int *pRes){ - int rc; - MemPage *pPage; - - assert( cursorHoldsMutex(pCur) ); - rc = restoreOrClearCursorPosition(pCur); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( pRes!=0 ); - pPage = pCur->pPage; - if( CURSOR_INVALID==pCur->eState ){ - *pRes = 1; - return SQLITE_OK; - } - if( pCur->skip>0 ){ - pCur->skip = 0; - *pRes = 0; - return SQLITE_OK; - } - pCur->skip = 0; - - assert( pPage->isInit ); - assert( pCur->idxnCell ); - - pCur->idx++; - pCur->info.nSize = 0; - if( pCur->idx>=pPage->nCell ){ - if( !pPage->leaf ){ - rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); - if( rc ) return rc; - rc = moveToLeftmost(pCur); - *pRes = 0; - return rc; - } - do{ - if( sqlite3BtreeIsRootPage(pPage) ){ - *pRes = 1; - pCur->eState = CURSOR_INVALID; - return SQLITE_OK; - } - sqlite3BtreeMoveToParent(pCur); - pPage = pCur->pPage; - }while( pCur->idx>=pPage->nCell ); - *pRes = 0; - if( pPage->leafData ){ - rc = sqlite3BtreeNext(pCur, pRes); - }else{ - rc = SQLITE_OK; - } - return rc; - } - *pRes = 0; - if( pPage->leaf ){ - return SQLITE_OK; - } - rc = moveToLeftmost(pCur); - return rc; -} -int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ - int rc; - assert( cursorHoldsMutex(pCur) ); - rc = btreeNext(pCur, pRes); - return rc; -} - - -/* -** Step the cursor to the back to the previous entry in the database. If -** successful then set *pRes=0. If the cursor -** was already pointing to the first entry in the database before -** this routine was called, then set *pRes=1. -*/ -static int btreePrevious(BtCursor *pCur, int *pRes){ - int rc; - Pgno pgno; - MemPage *pPage; - - assert( cursorHoldsMutex(pCur) ); - rc = restoreOrClearCursorPosition(pCur); - if( rc!=SQLITE_OK ){ - return rc; - } - if( CURSOR_INVALID==pCur->eState ){ - *pRes = 1; - return SQLITE_OK; - } - if( pCur->skip<0 ){ - pCur->skip = 0; - *pRes = 0; - return SQLITE_OK; - } - pCur->skip = 0; - - pPage = pCur->pPage; - assert( pPage->isInit ); - assert( pCur->idx>=0 ); - if( !pPage->leaf ){ - pgno = get4byte( findCell(pPage, pCur->idx) ); - rc = moveToChild(pCur, pgno); - if( rc ){ - return rc; - } - rc = moveToRightmost(pCur); - }else{ - while( pCur->idx==0 ){ - if( sqlite3BtreeIsRootPage(pPage) ){ - pCur->eState = CURSOR_INVALID; - *pRes = 1; - return SQLITE_OK; - } - sqlite3BtreeMoveToParent(pCur); - pPage = pCur->pPage; - } - pCur->idx--; - pCur->info.nSize = 0; - if( pPage->leafData && !pPage->leaf ){ - rc = sqlite3BtreePrevious(pCur, pRes); - }else{ - rc = SQLITE_OK; - } - } - *pRes = 0; - return rc; -} -int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ - int rc; - assert( cursorHoldsMutex(pCur) ); - rc = btreePrevious(pCur, pRes); - return rc; -} - -/* -** Allocate a new page from the database file. -** -** The new page is marked as dirty. (In other words, sqlite3PagerWrite() -** has already been called on the new page.) The new page has also -** been referenced and the calling routine is responsible for calling -** sqlite3PagerUnref() on the new page when it is done. -** -** SQLITE_OK is returned on success. Any other return value indicates -** an error. *ppPage and *pPgno are undefined in the event of an error. -** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned. -** -** If the "nearby" parameter is not 0, then a (feeble) effort is made to -** locate a page close to the page number "nearby". This can be used in an -** attempt to keep related pages close to each other in the database file, -** which in turn can make database access faster. -** -** If the "exact" parameter is not 0, and the page-number nearby exists -** anywhere on the free-list, then it is guarenteed to be returned. This -** is only used by auto-vacuum databases when allocating a new table. -*/ -static int allocateBtreePage( - BtShared *pBt, - MemPage **ppPage, - Pgno *pPgno, - Pgno nearby, - u8 exact -){ - MemPage *pPage1; - int rc; - int n; /* Number of pages on the freelist */ - int k; /* Number of leaves on the trunk of the freelist */ - MemPage *pTrunk = 0; - MemPage *pPrevTrunk = 0; - - assert( sqlite3_mutex_held(pBt->mutex) ); - pPage1 = pBt->pPage1; - n = get4byte(&pPage1->aData[36]); - if( n>0 ){ - /* There are pages on the freelist. Reuse one of those pages. */ - Pgno iTrunk; - u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ - - /* If the 'exact' parameter was true and a query of the pointer-map - ** shows that the page 'nearby' is somewhere on the free-list, then - ** the entire-list will be searched for that page. - */ -#ifndef SQLITE_OMIT_AUTOVACUUM - if( exact && nearby<=sqlite3PagerPagecount(pBt->pPager) ){ - u8 eType; - assert( nearby>0 ); - assert( pBt->autoVacuum ); - rc = ptrmapGet(pBt, nearby, &eType, 0); - if( rc ) return rc; - if( eType==PTRMAP_FREEPAGE ){ - searchList = 1; - } - *pPgno = nearby; - } -#endif - - /* Decrement the free-list count by 1. Set iTrunk to the index of the - ** first free-list trunk page. iPrevTrunk is initially 1. - */ - rc = sqlite3PagerWrite(pPage1->pDbPage); - if( rc ) return rc; - put4byte(&pPage1->aData[36], n-1); - - /* The code within this loop is run only once if the 'searchList' variable - ** is not true. Otherwise, it runs once for each trunk-page on the - ** free-list until the page 'nearby' is located. - */ - do { - pPrevTrunk = pTrunk; - if( pPrevTrunk ){ - iTrunk = get4byte(&pPrevTrunk->aData[0]); - }else{ - iTrunk = get4byte(&pPage1->aData[32]); - } - rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0); - if( rc ){ - pTrunk = 0; - goto end_allocate_page; - } - - k = get4byte(&pTrunk->aData[4]); - if( k==0 && !searchList ){ - /* The trunk has no leaves and the list is not being searched. - ** So extract the trunk page itself and use it as the newly - ** allocated page */ - assert( pPrevTrunk==0 ); - rc = sqlite3PagerWrite(pTrunk->pDbPage); - if( rc ){ - goto end_allocate_page; - } - *pPgno = iTrunk; - memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); - *ppPage = pTrunk; - pTrunk = 0; - TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); - }else if( k>pBt->usableSize/4 - 8 ){ - /* Value of k is out of range. Database corruption */ - rc = SQLITE_CORRUPT_BKPT; - goto end_allocate_page; -#ifndef SQLITE_OMIT_AUTOVACUUM - }else if( searchList && nearby==iTrunk ){ - /* The list is being searched and this trunk page is the page - ** to allocate, regardless of whether it has leaves. - */ - assert( *pPgno==iTrunk ); - *ppPage = pTrunk; - searchList = 0; - rc = sqlite3PagerWrite(pTrunk->pDbPage); - if( rc ){ - goto end_allocate_page; - } - if( k==0 ){ - if( !pPrevTrunk ){ - memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); - }else{ - memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4); - } - }else{ - /* The trunk page is required by the caller but it contains - ** pointers to free-list leaves. The first leaf becomes a trunk - ** page in this case. - */ - MemPage *pNewTrunk; - Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); - rc = sqlite3BtreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0); - if( rc!=SQLITE_OK ){ - goto end_allocate_page; - } - rc = sqlite3PagerWrite(pNewTrunk->pDbPage); - if( rc!=SQLITE_OK ){ - releasePage(pNewTrunk); - goto end_allocate_page; - } - memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4); - put4byte(&pNewTrunk->aData[4], k-1); - memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4); - releasePage(pNewTrunk); - if( !pPrevTrunk ){ - put4byte(&pPage1->aData[32], iNewTrunk); - }else{ - rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); - if( rc ){ - goto end_allocate_page; - } - put4byte(&pPrevTrunk->aData[0], iNewTrunk); - } - } - pTrunk = 0; - TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); -#endif - }else{ - /* Extract a leaf from the trunk */ - int closest; - Pgno iPage; - unsigned char *aData = pTrunk->aData; - rc = sqlite3PagerWrite(pTrunk->pDbPage); - if( rc ){ - goto end_allocate_page; - } - if( nearby>0 ){ - int i, dist; - closest = 0; - dist = get4byte(&aData[8]) - nearby; - if( dist<0 ) dist = -dist; - for(i=1; isqlite3PagerPagecount(pBt->pPager) ){ - /* Free page off the end of the file */ - return SQLITE_CORRUPT_BKPT; - } - TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" - ": %d more free pages\n", - *pPgno, closest+1, k, pTrunk->pgno, n-1)); - if( closestpDbPage); - rc = sqlite3PagerWrite((*ppPage)->pDbPage); - if( rc!=SQLITE_OK ){ - releasePage(*ppPage); - } - } - searchList = 0; - } - } - releasePage(pPrevTrunk); - pPrevTrunk = 0; - }while( searchList ); - }else{ - /* There are no pages on the freelist, so create a new page at the - ** end of the file */ - *pPgno = sqlite3PagerPagecount(pBt->pPager) + 1; - -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->nTrunc ){ - /* An incr-vacuum has already run within this transaction. So the - ** page to allocate is not from the physical end of the file, but - ** at pBt->nTrunc. - */ - *pPgno = pBt->nTrunc+1; - if( *pPgno==PENDING_BYTE_PAGE(pBt) ){ - (*pPgno)++; - } - } - if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){ - /* If *pPgno refers to a pointer-map page, allocate two new pages - ** at the end of the file instead of one. The first allocated page - ** becomes a new pointer-map page, the second is used by the caller. - */ - TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno)); - assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); - (*pPgno)++; - } - if( pBt->nTrunc ){ - pBt->nTrunc = *pPgno; - } -#endif - - assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); - rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 0); - if( rc ) return rc; - rc = sqlite3PagerWrite((*ppPage)->pDbPage); - if( rc!=SQLITE_OK ){ - releasePage(*ppPage); - } - TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); - } - - assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); - -end_allocate_page: - releasePage(pTrunk); - releasePage(pPrevTrunk); - return rc; -} - -/* -** Add a page of the database file to the freelist. -** -** sqlite3PagerUnref() is NOT called for pPage. -*/ -static int freePage(MemPage *pPage){ - BtShared *pBt = pPage->pBt; - MemPage *pPage1 = pBt->pPage1; - int rc, n, k; - - /* Prepare the page for freeing */ - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( pPage->pgno>1 ); - pPage->isInit = 0; - releasePage(pPage->pParent); - pPage->pParent = 0; - - /* Increment the free page count on pPage1 */ - rc = sqlite3PagerWrite(pPage1->pDbPage); - if( rc ) return rc; - n = get4byte(&pPage1->aData[36]); - put4byte(&pPage1->aData[36], n+1); - -#ifdef SQLITE_SECURE_DELETE - /* If the SQLITE_SECURE_DELETE compile-time option is enabled, then - ** always fully overwrite deleted information with zeros. - */ - rc = sqlite3PagerWrite(pPage->pDbPage); - if( rc ) return rc; - memset(pPage->aData, 0, pPage->pBt->pageSize); -#endif - -#ifndef SQLITE_OMIT_AUTOVACUUM - /* If the database supports auto-vacuum, write an entry in the pointer-map - ** to indicate that the page is free. - */ - if( pBt->autoVacuum ){ - rc = ptrmapPut(pBt, pPage->pgno, PTRMAP_FREEPAGE, 0); - if( rc ) return rc; - } -#endif - - if( n==0 ){ - /* This is the first free page */ - rc = sqlite3PagerWrite(pPage->pDbPage); - if( rc ) return rc; - memset(pPage->aData, 0, 8); - put4byte(&pPage1->aData[32], pPage->pgno); - TRACE(("FREE-PAGE: %d first\n", pPage->pgno)); - }else{ - /* Other free pages already exist. Retrive the first trunk page - ** of the freelist and find out how many leaves it has. */ - MemPage *pTrunk; - rc = sqlite3BtreeGetPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk, 0); - if( rc ) return rc; - k = get4byte(&pTrunk->aData[4]); - if( k>=pBt->usableSize/4 - 8 ){ - /* The trunk is full. Turn the page being freed into a new - ** trunk page with no leaves. */ - rc = sqlite3PagerWrite(pPage->pDbPage); - if( rc==SQLITE_OK ){ - put4byte(pPage->aData, pTrunk->pgno); - put4byte(&pPage->aData[4], 0); - put4byte(&pPage1->aData[32], pPage->pgno); - TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", - pPage->pgno, pTrunk->pgno)); - } - }else if( k<0 ){ - rc = SQLITE_CORRUPT; - }else{ - /* Add the newly freed page as a leaf on the current trunk */ - rc = sqlite3PagerWrite(pTrunk->pDbPage); - if( rc==SQLITE_OK ){ - put4byte(&pTrunk->aData[4], k+1); - put4byte(&pTrunk->aData[8+k*4], pPage->pgno); -#ifndef SQLITE_SECURE_DELETE - sqlite3PagerDontWrite(pPage->pDbPage); -#endif - } - TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno)); - } - releasePage(pTrunk); - } - return rc; -} - -/* -** Free any overflow pages associated with the given Cell. -*/ -static int clearCell(MemPage *pPage, unsigned char *pCell){ - BtShared *pBt = pPage->pBt; - CellInfo info; - Pgno ovflPgno; - int rc; - int nOvfl; - int ovflPageSize; - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - sqlite3BtreeParseCellPtr(pPage, pCell, &info); - if( info.iOverflow==0 ){ - return SQLITE_OK; /* No overflow pages. Return without doing anything */ - } - ovflPgno = get4byte(&pCell[info.iOverflow]); - ovflPageSize = pBt->usableSize - 4; - nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize; - assert( ovflPgno==0 || nOvfl>0 ); - while( nOvfl-- ){ - MemPage *pOvfl; - if( ovflPgno==0 || ovflPgno>sqlite3PagerPagecount(pBt->pPager) ){ - return SQLITE_CORRUPT_BKPT; - } - - rc = getOverflowPage(pBt, ovflPgno, &pOvfl, (nOvfl==0)?0:&ovflPgno); - if( rc ) return rc; - rc = freePage(pOvfl); - sqlite3PagerUnref(pOvfl->pDbPage); - if( rc ) return rc; - } - return SQLITE_OK; -} - -/* -** Create the byte sequence used to represent a cell on page pPage -** and write that byte sequence into pCell[]. Overflow pages are -** allocated and filled in as necessary. The calling procedure -** is responsible for making sure sufficient space has been allocated -** for pCell[]. -** -** Note that pCell does not necessary need to point to the pPage->aData -** area. pCell might point to some temporary storage. The cell will -** be constructed in this temporary area then copied into pPage->aData -** later. -*/ -static int fillInCell( - MemPage *pPage, /* The page that contains the cell */ - unsigned char *pCell, /* Complete text of the cell */ - const void *pKey, i64 nKey, /* The key */ - const void *pData,int nData, /* The data */ - int nZero, /* Extra zero bytes to append to pData */ - int *pnSize /* Write cell size here */ -){ - int nPayload; - const u8 *pSrc; - int nSrc, n, rc; - int spaceLeft; - MemPage *pOvfl = 0; - MemPage *pToRelease = 0; - unsigned char *pPrior; - unsigned char *pPayload; - BtShared *pBt = pPage->pBt; - Pgno pgnoOvfl = 0; - int nHeader; - CellInfo info; - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - - /* Fill in the header. */ - nHeader = 0; - if( !pPage->leaf ){ - nHeader += 4; - } - if( pPage->hasData ){ - nHeader += putVarint(&pCell[nHeader], nData+nZero); - }else{ - nData = nZero = 0; - } - nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey); - sqlite3BtreeParseCellPtr(pPage, pCell, &info); - assert( info.nHeader==nHeader ); - assert( info.nKey==nKey ); - assert( info.nData==nData+nZero ); - - /* Fill in the payload */ - nPayload = nData + nZero; - if( pPage->intKey ){ - pSrc = pData; - nSrc = nData; - nData = 0; - }else{ - nPayload += nKey; - pSrc = pKey; - nSrc = nKey; - } - *pnSize = info.nSize; - spaceLeft = info.nLocal; - pPayload = &pCell[nHeader]; - pPrior = &pCell[info.iOverflow]; - - while( nPayload>0 ){ - if( spaceLeft==0 ){ - int isExact = 0; -#ifndef SQLITE_OMIT_AUTOVACUUM - Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */ - if( pBt->autoVacuum ){ - do{ - pgnoOvfl++; - } while( - PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) - ); - if( pgnoOvfl>1 ){ - /* isExact = 1; */ - } - } -#endif - rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, isExact); -#ifndef SQLITE_OMIT_AUTOVACUUM - /* If the database supports auto-vacuum, and the second or subsequent - ** overflow page is being allocated, add an entry to the pointer-map - ** for that page now. - ** - ** If this is the first overflow page, then write a partial entry - ** to the pointer-map. If we write nothing to this pointer-map slot, - ** then the optimistic overflow chain processing in clearCell() - ** may misinterpret the uninitialised values and delete the - ** wrong pages from the database. - */ - if( pBt->autoVacuum && rc==SQLITE_OK ){ - u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1); - rc = ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap); - if( rc ){ - releasePage(pOvfl); - } - } -#endif - if( rc ){ - releasePage(pToRelease); - return rc; - } - put4byte(pPrior, pgnoOvfl); - releasePage(pToRelease); - pToRelease = pOvfl; - pPrior = pOvfl->aData; - put4byte(pPrior, 0); - pPayload = &pOvfl->aData[4]; - spaceLeft = pBt->usableSize - 4; - } - n = nPayload; - if( n>spaceLeft ) n = spaceLeft; - if( nSrc>0 ){ - if( n>nSrc ) n = nSrc; - assert( pSrc ); - memcpy(pPayload, pSrc, n); - }else{ - memset(pPayload, 0, n); - } - nPayload -= n; - pPayload += n; - pSrc += n; - nSrc -= n; - spaceLeft -= n; - if( nSrc==0 ){ - nSrc = nData; - pSrc = pData; - } - } - releasePage(pToRelease); - return SQLITE_OK; -} - -/* -** Change the MemPage.pParent pointer on the page whose number is -** given in the second argument so that MemPage.pParent holds the -** pointer in the third argument. -*/ -static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){ - MemPage *pThis; - DbPage *pDbPage; - - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pNewParent!=0 ); - if( pgno==0 ) return SQLITE_OK; - assert( pBt->pPager!=0 ); - pDbPage = sqlite3PagerLookup(pBt->pPager, pgno); - if( pDbPage ){ - pThis = (MemPage *)sqlite3PagerGetExtra(pDbPage); - if( pThis->isInit ){ - assert( pThis->aData==sqlite3PagerGetData(pDbPage) ); - if( pThis->pParent!=pNewParent ){ - if( pThis->pParent ) sqlite3PagerUnref(pThis->pParent->pDbPage); - pThis->pParent = pNewParent; - sqlite3PagerRef(pNewParent->pDbPage); - } - pThis->idxParent = idx; - } - sqlite3PagerUnref(pDbPage); - } - -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - return ptrmapPut(pBt, pgno, PTRMAP_BTREE, pNewParent->pgno); - } -#endif - return SQLITE_OK; -} - - - -/* -** Change the pParent pointer of all children of pPage to point back -** to pPage. -** -** In other words, for every child of pPage, invoke reparentPage() -** to make sure that each child knows that pPage is its parent. -** -** This routine gets called after you memcpy() one page into -** another. -*/ -static int reparentChildPages(MemPage *pPage){ - int i; - BtShared *pBt = pPage->pBt; - int rc = SQLITE_OK; - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - if( pPage->leaf ) return SQLITE_OK; - - for(i=0; inCell; i++){ - u8 *pCell = findCell(pPage, i); - if( !pPage->leaf ){ - rc = reparentPage(pBt, get4byte(pCell), pPage, i); - if( rc!=SQLITE_OK ) return rc; - } - } - if( !pPage->leaf ){ - rc = reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]), - pPage, i); - pPage->idxShift = 0; - } - return rc; -} - -/* -** Remove the i-th cell from pPage. This routine effects pPage only. -** The cell content is not freed or deallocated. It is assumed that -** the cell content has been copied someplace else. This routine just -** removes the reference to the cell from pPage. -** -** "sz" must be the number of bytes in the cell. -*/ -static void dropCell(MemPage *pPage, int idx, int sz){ - int i; /* Loop counter */ - int pc; /* Offset to cell content of cell being deleted */ - u8 *data; /* pPage->aData */ - u8 *ptr; /* Used to move bytes around within data[] */ - - assert( idx>=0 && idxnCell ); - assert( sz==cellSize(pPage, idx) ); - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - data = pPage->aData; - ptr = &data[pPage->cellOffset + 2*idx]; - pc = get2byte(ptr); - assert( pc>10 && pc+sz<=pPage->pBt->usableSize ); - freeSpace(pPage, pc, sz); - for(i=idx+1; inCell; i++, ptr+=2){ - ptr[0] = ptr[2]; - ptr[1] = ptr[3]; - } - pPage->nCell--; - put2byte(&data[pPage->hdrOffset+3], pPage->nCell); - pPage->nFree += 2; - pPage->idxShift = 1; -} - -/* -** Insert a new cell on pPage at cell index "i". pCell points to the -** content of the cell. -** -** If the cell content will fit on the page, then put it there. If it -** will not fit, then make a copy of the cell content into pTemp if -** pTemp is not null. Regardless of pTemp, allocate a new entry -** in pPage->aOvfl[] and make it point to the cell content (either -** in pTemp or the original pCell) and also record its index. -** Allocating a new entry in pPage->aCell[] implies that -** pPage->nOverflow is incremented. -** -** If nSkip is non-zero, then do not copy the first nSkip bytes of the -** cell. The caller will overwrite them after this function returns. If -** nSkip is non-zero, then pCell may not point to an invalid memory location -** (but pCell+nSkip is always valid). -*/ -static int insertCell( - MemPage *pPage, /* Page into which we are copying */ - int i, /* New cell becomes the i-th cell of the page */ - u8 *pCell, /* Content of the new cell */ - int sz, /* Bytes of content in pCell */ - u8 *pTemp, /* Temp storage space for pCell, if needed */ - u8 nSkip /* Do not write the first nSkip bytes of the cell */ -){ - int idx; /* Where to write new cell content in data[] */ - int j; /* Loop counter */ - int top; /* First byte of content for any cell in data[] */ - int end; /* First byte past the last cell pointer in data[] */ - int ins; /* Index in data[] where new cell pointer is inserted */ - int hdr; /* Offset into data[] of the page header */ - int cellOffset; /* Address of first cell pointer in data[] */ - u8 *data; /* The content of the whole page */ - u8 *ptr; /* Used for moving information around in data[] */ - - assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); - assert( sz==cellSizePtr(pPage, pCell) ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - if( pPage->nOverflow || sz+2>pPage->nFree ){ - if( pTemp ){ - memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip); - pCell = pTemp; - } - j = pPage->nOverflow++; - assert( jaOvfl)/sizeof(pPage->aOvfl[0]) ); - pPage->aOvfl[j].pCell = pCell; - pPage->aOvfl[j].idx = i; - pPage->nFree = 0; - }else{ - int rc = sqlite3PagerWrite(pPage->pDbPage); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - data = pPage->aData; - hdr = pPage->hdrOffset; - top = get2byte(&data[hdr+5]); - cellOffset = pPage->cellOffset; - end = cellOffset + 2*pPage->nCell + 2; - ins = cellOffset + 2*i; - if( end > top - sz ){ - rc = defragmentPage(pPage); - if( rc!=SQLITE_OK ) return rc; - top = get2byte(&data[hdr+5]); - assert( end + sz <= top ); - } - idx = allocateSpace(pPage, sz); - assert( idx>0 ); - assert( end <= get2byte(&data[hdr+5]) ); - pPage->nCell++; - pPage->nFree -= 2; - memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip); - for(j=end-2, ptr=&data[j]; j>ins; j-=2, ptr-=2){ - ptr[0] = ptr[-2]; - ptr[1] = ptr[-1]; - } - put2byte(&data[ins], idx); - put2byte(&data[hdr+3], pPage->nCell); - pPage->idxShift = 1; -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pPage->pBt->autoVacuum ){ - /* The cell may contain a pointer to an overflow page. If so, write - ** the entry for the overflow page into the pointer map. - */ - CellInfo info; - sqlite3BtreeParseCellPtr(pPage, pCell, &info); - assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload ); - if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){ - Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]); - rc = ptrmapPut(pPage->pBt, pgnoOvfl, PTRMAP_OVERFLOW1, pPage->pgno); - if( rc!=SQLITE_OK ) return rc; - } - } -#endif - } - - return SQLITE_OK; -} - -/* -** Add a list of cells to a page. The page should be initially empty. -** The cells are guaranteed to fit on the page. -*/ -static void assemblePage( - MemPage *pPage, /* The page to be assemblied */ - int nCell, /* The number of cells to add to this page */ - u8 **apCell, /* Pointers to cell bodies */ - int *aSize /* Sizes of the cells */ -){ - int i; /* Loop counter */ - int totalSize; /* Total size of all cells */ - int hdr; /* Index of page header */ - int cellptr; /* Address of next cell pointer */ - int cellbody; /* Address of next cell body */ - u8 *data; /* Data for the page */ - - assert( pPage->nOverflow==0 ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - totalSize = 0; - for(i=0; inFree ); - assert( pPage->nCell==0 ); - cellptr = pPage->cellOffset; - data = pPage->aData; - hdr = pPage->hdrOffset; - put2byte(&data[hdr+3], nCell); - if( nCell ){ - cellbody = allocateSpace(pPage, totalSize); - assert( cellbody>0 ); - assert( pPage->nFree >= 2*nCell ); - pPage->nFree -= 2*nCell; - for(i=0; ipBt->usableSize ); - } - pPage->nCell = nCell; -} - -/* -** The following parameters determine how many adjacent pages get involved -** in a balancing operation. NN is the number of neighbors on either side -** of the page that participate in the balancing operation. NB is the -** total number of pages that participate, including the target page and -** NN neighbors on either side. -** -** The minimum value of NN is 1 (of course). Increasing NN above 1 -** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance -** in exchange for a larger degradation in INSERT and UPDATE performance. -** The value of NN appears to give the best results overall. -*/ -#define NN 1 /* Number of neighbors on either side of pPage */ -#define NB (NN*2+1) /* Total pages involved in the balance */ - -/* Forward reference */ -static int balance(MemPage*, int); - -#ifndef SQLITE_OMIT_QUICKBALANCE -/* -** This version of balance() handles the common special case where -** a new entry is being inserted on the extreme right-end of the -** tree, in other words, when the new entry will become the largest -** entry in the tree. -** -** Instead of trying balance the 3 right-most leaf pages, just add -** a new page to the right-hand side and put the one new entry in -** that page. This leaves the right side of the tree somewhat -** unbalanced. But odds are that we will be inserting new entries -** at the end soon afterwards so the nearly empty page will quickly -** fill up. On average. -** -** pPage is the leaf page which is the right-most page in the tree. -** pParent is its parent. pPage must have a single overflow entry -** which is also the right-most entry on the page. -*/ -static int balance_quick(MemPage *pPage, MemPage *pParent){ - int rc; - MemPage *pNew; - Pgno pgnoNew; - u8 *pCell; - int szCell; - CellInfo info; - BtShared *pBt = pPage->pBt; - int parentIdx = pParent->nCell; /* pParent new divider cell index */ - int parentSize; /* Size of new divider cell */ - u8 parentCell[64]; /* Space for the new divider cell */ - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - - /* Allocate a new page. Insert the overflow cell from pPage - ** into it. Then remove the overflow cell from pPage. - */ - rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - pCell = pPage->aOvfl[0].pCell; - szCell = cellSizePtr(pPage, pCell); - zeroPage(pNew, pPage->aData[0]); - assemblePage(pNew, 1, &pCell, &szCell); - pPage->nOverflow = 0; - - /* Set the parent of the newly allocated page to pParent. */ - pNew->pParent = pParent; - sqlite3PagerRef(pParent->pDbPage); - - /* pPage is currently the right-child of pParent. Change this - ** so that the right-child is the new page allocated above and - ** pPage is the next-to-right child. - */ - assert( pPage->nCell>0 ); - pCell = findCell(pPage, pPage->nCell-1); - sqlite3BtreeParseCellPtr(pPage, pCell, &info); - rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, 0, &parentSize); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( parentSize<64 ); - rc = insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4); - if( rc!=SQLITE_OK ){ - return rc; - } - put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno); - put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); - -#ifndef SQLITE_OMIT_AUTOVACUUM - /* If this is an auto-vacuum database, update the pointer map - ** with entries for the new page, and any pointer from the - ** cell on the page to an overflow page. - */ - if( pBt->autoVacuum ){ - rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno); - if( rc==SQLITE_OK ){ - rc = ptrmapPutOvfl(pNew, 0); - } - if( rc!=SQLITE_OK ){ - releasePage(pNew); - return rc; - } - } -#endif - - /* Release the reference to the new page and balance the parent page, - ** in case the divider cell inserted caused it to become overfull. - */ - releasePage(pNew); - return balance(pParent, 0); -} -#endif /* SQLITE_OMIT_QUICKBALANCE */ - -/* -** This routine redistributes Cells on pPage and up to NN*2 siblings -** of pPage so that all pages have about the same amount of free space. -** Usually NN siblings on either side of pPage is used in the balancing, -** though more siblings might come from one side if pPage is the first -** or last child of its parent. If pPage has fewer than 2*NN siblings -** (something which can only happen if pPage is the root page or a -** child of root) then all available siblings participate in the balancing. -** -** The number of siblings of pPage might be increased or decreased by one or -** two in an effort to keep pages nearly full but not over full. The root page -** is special and is allowed to be nearly empty. If pPage is -** the root page, then the depth of the tree might be increased -** or decreased by one, as necessary, to keep the root page from being -** overfull or completely empty. -** -** Note that when this routine is called, some of the Cells on pPage -** might not actually be stored in pPage->aData[]. This can happen -** if the page is overfull. Part of the job of this routine is to -** make sure all Cells for pPage once again fit in pPage->aData[]. -** -** In the course of balancing the siblings of pPage, the parent of pPage -** might become overfull or underfull. If that happens, then this routine -** is called recursively on the parent. -** -** If this routine fails for any reason, it might leave the database -** in a corrupted state. So if this routine fails, the database should -** be rolled back. -*/ -static int balance_nonroot(MemPage *pPage){ - MemPage *pParent; /* The parent of pPage */ - BtShared *pBt; /* The whole database */ - int nCell = 0; /* Number of cells in apCell[] */ - int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */ - int nOld; /* Number of pages in apOld[] */ - int nNew; /* Number of pages in apNew[] */ - int nDiv; /* Number of cells in apDiv[] */ - int i, j, k; /* Loop counters */ - int idx; /* Index of pPage in pParent->aCell[] */ - int nxDiv; /* Next divider slot in pParent->aCell[] */ - int rc; /* The return code */ - int leafCorrection; /* 4 if pPage is a leaf. 0 if not */ - int leafData; /* True if pPage is a leaf of a LEAFDATA tree */ - int usableSpace; /* Bytes in pPage beyond the header */ - int pageFlags; /* Value of pPage->aData[0] */ - int subtotal; /* Subtotal of bytes in cells on one page */ - int iSpace = 0; /* First unused byte of aSpace[] */ - MemPage *apOld[NB]; /* pPage and up to two siblings */ - Pgno pgnoOld[NB]; /* Page numbers for each page in apOld[] */ - MemPage *apCopy[NB]; /* Private copies of apOld[] pages */ - MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */ - Pgno pgnoNew[NB+2]; /* Page numbers for each page in apNew[] */ - u8 *apDiv[NB]; /* Divider cells in pParent */ - int cntNew[NB+2]; /* Index in aCell[] of cell after i-th page */ - int szNew[NB+2]; /* Combined size of cells place on i-th page */ - u8 **apCell = 0; /* All cells begin balanced */ - int *szCell; /* Local size of all cells in apCell[] */ - u8 *aCopy[NB]; /* Space for holding data of apCopy[] */ - u8 *aSpace; /* Space to hold copies of dividers cells */ -#ifndef SQLITE_OMIT_AUTOVACUUM - u8 *aFrom = 0; -#endif - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - - /* - ** Find the parent page. - */ - assert( pPage->isInit ); - assert( sqlite3PagerIswriteable(pPage->pDbPage) || pPage->nOverflow==1 ); - pBt = pPage->pBt; - pParent = pPage->pParent; - assert( pParent ); - if( SQLITE_OK!=(rc = sqlite3PagerWrite(pParent->pDbPage)) ){ - return rc; - } - TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno)); - -#ifndef SQLITE_OMIT_QUICKBALANCE - /* - ** A special case: If a new entry has just been inserted into a - ** table (that is, a btree with integer keys and all data at the leaves) - ** and the new entry is the right-most entry in the tree (it has the - ** largest key) then use the special balance_quick() routine for - ** balancing. balance_quick() is much faster and results in a tighter - ** packing of data in the common case. - */ - if( pPage->leaf && - pPage->intKey && - pPage->leafData && - pPage->nOverflow==1 && - pPage->aOvfl[0].idx==pPage->nCell && - pPage->pParent->pgno!=1 && - get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno - ){ - /* - ** TODO: Check the siblings to the left of pPage. It may be that - ** they are not full and no new page is required. - */ - return balance_quick(pPage, pParent); - } -#endif - - if( SQLITE_OK!=(rc = sqlite3PagerWrite(pPage->pDbPage)) ){ - return rc; - } - - /* - ** Find the cell in the parent page whose left child points back - ** to pPage. The "idx" variable is the index of that cell. If pPage - ** is the rightmost child of pParent then set idx to pParent->nCell - */ - if( pParent->idxShift ){ - Pgno pgno; - pgno = pPage->pgno; - assert( pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); - for(idx=0; idxnCell; idx++){ - if( get4byte(findCell(pParent, idx))==pgno ){ - break; - } - } - assert( idxnCell - || get4byte(&pParent->aData[pParent->hdrOffset+8])==pgno ); - }else{ - idx = pPage->idxParent; - } - - /* - ** Initialize variables so that it will be safe to jump - ** directly to balance_cleanup at any moment. - */ - nOld = nNew = 0; - sqlite3PagerRef(pParent->pDbPage); - - /* - ** Find sibling pages to pPage and the cells in pParent that divide - ** the siblings. An attempt is made to find NN siblings on either - ** side of pPage. More siblings are taken from one side, however, if - ** pPage there are fewer than NN siblings on the other side. If pParent - ** has NB or fewer children then all children of pParent are taken. - */ - nxDiv = idx - NN; - if( nxDiv + NB > pParent->nCell ){ - nxDiv = pParent->nCell - NB + 1; - } - if( nxDiv<0 ){ - nxDiv = 0; - } - nDiv = 0; - for(i=0, k=nxDiv; inCell ){ - apDiv[i] = findCell(pParent, k); - nDiv++; - assert( !pParent->leaf ); - pgnoOld[i] = get4byte(apDiv[i]); - }else if( k==pParent->nCell ){ - pgnoOld[i] = get4byte(&pParent->aData[pParent->hdrOffset+8]); - }else{ - break; - } - rc = getAndInitPage(pBt, pgnoOld[i], &apOld[i], pParent); - if( rc ) goto balance_cleanup; - apOld[i]->idxParent = k; - apCopy[i] = 0; - assert( i==nOld ); - nOld++; - nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; - } - - /* Make nMaxCells a multiple of 2 in order to preserve 8-byte - ** alignment */ - nMaxCells = (nMaxCells + 1)&~1; - - /* - ** Allocate space for memory structures - */ - apCell = sqlite3_malloc( - nMaxCells*sizeof(u8*) /* apCell */ - + nMaxCells*sizeof(int) /* szCell */ - + ROUND8(sizeof(MemPage))*NB /* aCopy */ - + pBt->pageSize*(5+NB) /* aSpace */ - + (ISAUTOVACUUM ? nMaxCells : 0) /* aFrom */ - ); - if( apCell==0 ){ - rc = SQLITE_NOMEM; - goto balance_cleanup; - } - szCell = (int*)&apCell[nMaxCells]; - aCopy[0] = (u8*)&szCell[nMaxCells]; - assert( ((aCopy[0] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ - for(i=1; ipageSize+ROUND8(sizeof(MemPage))]; - assert( ((aCopy[i] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ - } - aSpace = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))]; - assert( ((aSpace - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - aFrom = &aSpace[5*pBt->pageSize]; - } -#endif - - /* - ** Make copies of the content of pPage and its siblings into aOld[]. - ** The rest of this function will use data from the copies rather - ** that the original pages since the original pages will be in the - ** process of being overwritten. - */ - for(i=0; iaData = (void*)&p[1]; - memcpy(p->aData, apOld[i]->aData, pBt->pageSize); - } - - /* - ** Load pointers to all cells on sibling pages and the divider cells - ** into the local apCell[] array. Make copies of the divider cells - ** into space obtained form aSpace[] and remove the the divider Cells - ** from pParent. - ** - ** If the siblings are on leaf pages, then the child pointers of the - ** divider cells are stripped from the cells before they are copied - ** into aSpace[]. In this way, all cells in apCell[] are without - ** child pointers. If siblings are not leaves, then all cell in - ** apCell[] include child pointers. Either way, all cells in apCell[] - ** are alike. - ** - ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf. - ** leafData: 1 if pPage holds key+data and pParent holds only keys. - */ - nCell = 0; - leafCorrection = pPage->leaf*4; - leafData = pPage->leafData && pPage->leaf; - for(i=0; inCell+pOld->nOverflow; - for(j=0; jautoVacuum ){ - int a; - aFrom[nCell] = i; - for(a=0; anOverflow; a++){ - if( pOld->aOvfl[a].pCell==apCell[nCell] ){ - aFrom[nCell] = 0xFF; - break; - } - } - } -#endif - nCell++; - } - if( ipageSize*5 ); - memcpy(pTemp, apDiv[i], sz); - apCell[nCell] = pTemp+leafCorrection; -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - aFrom[nCell] = 0xFF; - } -#endif - dropCell(pParent, nxDiv, sz); - szCell[nCell] -= leafCorrection; - assert( get4byte(pTemp)==pgnoOld[i] ); - if( !pOld->leaf ){ - assert( leafCorrection==0 ); - /* The right pointer of the child page pOld becomes the left - ** pointer of the divider cell */ - memcpy(apCell[nCell], &pOld->aData[pOld->hdrOffset+8], 4); - }else{ - assert( leafCorrection==4 ); - if( szCell[nCell]<4 ){ - /* Do not allow any cells smaller than 4 bytes. */ - szCell[nCell] = 4; - } - } - nCell++; - } - } - } - - /* - ** Figure out the number of pages needed to hold all nCell cells. - ** Store this number in "k". Also compute szNew[] which is the total - ** size of all cells on the i-th page and cntNew[] which is the index - ** in apCell[] of the cell that divides page i from page i+1. - ** cntNew[k] should equal nCell. - ** - ** Values computed by this block: - ** - ** k: The total number of sibling pages - ** szNew[i]: Spaced used on the i-th sibling page. - ** cntNew[i]: Index in apCell[] and szCell[] for the first cell to - ** the right of the i-th sibling page. - ** usableSpace: Number of bytes of space available on each sibling. - ** - */ - usableSpace = pBt->usableSize - 12 + leafCorrection; - for(subtotal=k=i=0; i usableSpace ){ - szNew[k] = subtotal - szCell[i]; - cntNew[k] = i; - if( leafData ){ i--; } - subtotal = 0; - k++; - } - } - szNew[k] = subtotal; - cntNew[k] = nCell; - k++; - - /* - ** The packing computed by the previous block is biased toward the siblings - ** on the left side. The left siblings are always nearly full, while the - ** right-most sibling might be nearly empty. This block of code attempts - ** to adjust the packing of siblings to get a better balance. - ** - ** This adjustment is more than an optimization. The packing above might - ** be so out of balance as to be illegal. For example, the right-most - ** sibling might be completely empty. This adjustment is not optional. - */ - for(i=k-1; i>0; i--){ - int szRight = szNew[i]; /* Size of sibling on the right */ - int szLeft = szNew[i-1]; /* Size of sibling on the left */ - int r; /* Index of right-most cell in left sibling */ - int d; /* Index of first cell to the left of right sibling */ - - r = cntNew[i-1] - 1; - d = r + 1 - leafData; - assert( d0) or we are the - ** a virtual root page. A virtual root page is when the real root - ** page is page 1 and we are the only child of that page. - */ - assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) ); - - /* - ** Allocate k new pages. Reuse old pages where possible. - */ - assert( pPage->pgno>1 ); - pageFlags = pPage->aData[0]; - for(i=0; ipDbPage); - nNew++; - if( rc ) goto balance_cleanup; - }else{ - assert( i>0 ); - rc = allocateBtreePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0); - if( rc ) goto balance_cleanup; - apNew[i] = pNew; - nNew++; - } - zeroPage(pNew, pageFlags); - } - - /* Free any old pages that were not reused as new pages. - */ - while( ii ){ - int t; - MemPage *pT; - t = pgnoNew[i]; - pT = apNew[i]; - pgnoNew[i] = pgnoNew[minI]; - apNew[i] = apNew[minI]; - pgnoNew[minI] = t; - apNew[minI] = pT; - } - } - TRACE(("BALANCE: old: %d %d %d new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n", - pgnoOld[0], - nOld>=2 ? pgnoOld[1] : 0, - nOld>=3 ? pgnoOld[2] : 0, - pgnoNew[0], szNew[0], - nNew>=2 ? pgnoNew[1] : 0, nNew>=2 ? szNew[1] : 0, - nNew>=3 ? pgnoNew[2] : 0, nNew>=3 ? szNew[2] : 0, - nNew>=4 ? pgnoNew[3] : 0, nNew>=4 ? szNew[3] : 0, - nNew>=5 ? pgnoNew[4] : 0, nNew>=5 ? szNew[4] : 0)); - - /* - ** Evenly distribute the data in apCell[] across the new pages. - ** Insert divider cells into pParent as necessary. - */ - j = 0; - for(i=0; ipgno==pgnoNew[i] ); - assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]); - assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) ); - assert( pNew->nOverflow==0 ); - -#ifndef SQLITE_OMIT_AUTOVACUUM - /* If this is an auto-vacuum database, update the pointer map entries - ** that point to the siblings that were rearranged. These can be: left - ** children of cells, the right-child of the page, or overflow pages - ** pointed to by cells. - */ - if( pBt->autoVacuum ){ - for(k=j; kpgno!=pNew->pgno ){ - rc = ptrmapPutOvfl(pNew, k-j); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } - } - } - } -#endif - - j = cntNew[i]; - - /* If the sibling page assembled above was not the right-most sibling, - ** insert a divider cell into the parent page. - */ - if( ileaf ){ - memcpy(&pNew->aData[8], pCell, 4); - pTemp = 0; - }else if( leafData ){ - /* If the tree is a leaf-data tree, and the siblings are leaves, - ** then there is no divider cell in apCell[]. Instead, the divider - ** cell consists of the integer key for the right-most cell of - ** the sibling-page assembled above only. - */ - CellInfo info; - j--; - sqlite3BtreeParseCellPtr(pNew, apCell[j], &info); - pCell = &aSpace[iSpace]; - fillInCell(pParent, pCell, 0, info.nKey, 0, 0, 0, &sz); - iSpace += sz; - assert( iSpace<=pBt->pageSize*5 ); - pTemp = 0; - }else{ - pCell -= 4; - pTemp = &aSpace[iSpace]; - iSpace += sz; - assert( iSpace<=pBt->pageSize*5 ); - /* Obscure case for non-leaf-data trees: If the cell at pCell was - ** previously stored on a leaf node, and it's reported size was 4 - ** bytes, then it may actually be smaller than this - ** (see sqlite3BtreeParseCellPtr(), 4 bytes is the minimum size of - ** any cell). But it's important to pass the correct size to - ** insertCell(), so reparse the cell now. - ** - ** Note that this can never happen in an SQLite data file, as all - ** cells are at least 4 bytes. It only happens in b-trees used - ** to evaluate "IN (SELECT ...)" and similar clauses. - */ - if( szCell[j]==4 ){ - assert(leafCorrection==4); - sz = cellSizePtr(pParent, pCell); - } - } - rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4); - if( rc!=SQLITE_OK ) goto balance_cleanup; - put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno); -#ifndef SQLITE_OMIT_AUTOVACUUM - /* If this is an auto-vacuum database, and not a leaf-data tree, - ** then update the pointer map with an entry for the overflow page - ** that the cell just inserted points to (if any). - */ - if( pBt->autoVacuum && !leafData ){ - rc = ptrmapPutOvfl(pParent, nxDiv); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } - } -#endif - j++; - nxDiv++; - } - } - assert( j==nCell ); - assert( nOld>0 ); - assert( nNew>0 ); - if( (pageFlags & PTF_LEAF)==0 ){ - memcpy(&apNew[nNew-1]->aData[8], &apCopy[nOld-1]->aData[8], 4); - } - if( nxDiv==pParent->nCell+pParent->nOverflow ){ - /* Right-most sibling is the right-most child of pParent */ - put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew[nNew-1]); - }else{ - /* Right-most sibling is the left child of the first entry in pParent - ** past the right-most divider entry */ - put4byte(findOverflowCell(pParent, nxDiv), pgnoNew[nNew-1]); - } - - /* - ** Reparent children of all cells. - */ - for(i=0; iisInit ); - rc = balance(pParent, 0); - - /* - ** Cleanup before returning. - */ -balance_cleanup: - sqlite3_free(apCell); - for(i=0; ipgno, nOld, nNew, nCell)); - return rc; -} - -/* -** This routine is called for the root page of a btree when the root -** page contains no cells. This is an opportunity to make the tree -** shallower by one level. -*/ -static int balance_shallower(MemPage *pPage){ - MemPage *pChild; /* The only child page of pPage */ - Pgno pgnoChild; /* Page number for pChild */ - int rc = SQLITE_OK; /* Return code from subprocedures */ - BtShared *pBt; /* The main BTree structure */ - int mxCellPerPage; /* Maximum number of cells per page */ - u8 **apCell; /* All cells from pages being balanced */ - int *szCell; /* Local size of all cells */ - - assert( pPage->pParent==0 ); - assert( pPage->nCell==0 ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pBt = pPage->pBt; - mxCellPerPage = MX_CELL(pBt); - apCell = sqlite3_malloc( mxCellPerPage*(sizeof(u8*)+sizeof(int)) ); - if( apCell==0 ) return SQLITE_NOMEM; - szCell = (int*)&apCell[mxCellPerPage]; - if( pPage->leaf ){ - /* The table is completely empty */ - TRACE(("BALANCE: empty table %d\n", pPage->pgno)); - }else{ - /* The root page is empty but has one child. Transfer the - ** information from that one child into the root page if it - ** will fit. This reduces the depth of the tree by one. - ** - ** If the root page is page 1, it has less space available than - ** its child (due to the 100 byte header that occurs at the beginning - ** of the database fle), so it might not be able to hold all of the - ** information currently contained in the child. If this is the - ** case, then do not do the transfer. Leave page 1 empty except - ** for the right-pointer to the child page. The child page becomes - ** the virtual root of the tree. - */ - pgnoChild = get4byte(&pPage->aData[pPage->hdrOffset+8]); - assert( pgnoChild>0 ); - assert( pgnoChild<=sqlite3PagerPagecount(pPage->pBt->pPager) ); - rc = sqlite3BtreeGetPage(pPage->pBt, pgnoChild, &pChild, 0); - if( rc ) goto end_shallow_balance; - if( pPage->pgno==1 ){ - rc = sqlite3BtreeInitPage(pChild, pPage); - if( rc ) goto end_shallow_balance; - assert( pChild->nOverflow==0 ); - if( pChild->nFree>=100 ){ - /* The child information will fit on the root page, so do the - ** copy */ - int i; - zeroPage(pPage, pChild->aData[0]); - for(i=0; inCell; i++){ - apCell[i] = findCell(pChild,i); - szCell[i] = cellSizePtr(pChild, apCell[i]); - } - assemblePage(pPage, pChild->nCell, apCell, szCell); - /* Copy the right-pointer of the child to the parent. */ - put4byte(&pPage->aData[pPage->hdrOffset+8], - get4byte(&pChild->aData[pChild->hdrOffset+8])); - freePage(pChild); - TRACE(("BALANCE: child %d transfer to page 1\n", pChild->pgno)); - }else{ - /* The child has more information that will fit on the root. - ** The tree is already balanced. Do nothing. */ - TRACE(("BALANCE: child %d will not fit on page 1\n", pChild->pgno)); - } - }else{ - memcpy(pPage->aData, pChild->aData, pPage->pBt->usableSize); - pPage->isInit = 0; - pPage->pParent = 0; - rc = sqlite3BtreeInitPage(pPage, 0); - assert( rc==SQLITE_OK ); - freePage(pChild); - TRACE(("BALANCE: transfer child %d into root %d\n", - pChild->pgno, pPage->pgno)); - } - rc = reparentChildPages(pPage); - assert( pPage->nOverflow==0 ); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - int i; - for(i=0; inCell; i++){ - rc = ptrmapPutOvfl(pPage, i); - if( rc!=SQLITE_OK ){ - goto end_shallow_balance; - } - } - } -#endif - releasePage(pChild); - } -end_shallow_balance: - sqlite3_free(apCell); - return rc; -} - - -/* -** The root page is overfull -** -** When this happens, Create a new child page and copy the -** contents of the root into the child. Then make the root -** page an empty page with rightChild pointing to the new -** child. Finally, call balance_internal() on the new child -** to cause it to split. -*/ -static int balance_deeper(MemPage *pPage){ - int rc; /* Return value from subprocedures */ - MemPage *pChild; /* Pointer to a new child page */ - Pgno pgnoChild; /* Page number of the new child page */ - BtShared *pBt; /* The BTree */ - int usableSize; /* Total usable size of a page */ - u8 *data; /* Content of the parent page */ - u8 *cdata; /* Content of the child page */ - int hdr; /* Offset to page header in parent */ - int brk; /* Offset to content of first cell in parent */ - - assert( pPage->pParent==0 ); - assert( pPage->nOverflow>0 ); - pBt = pPage->pBt; - assert( sqlite3_mutex_held(pBt->mutex) ); - rc = allocateBtreePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0); - if( rc ) return rc; - assert( sqlite3PagerIswriteable(pChild->pDbPage) ); - usableSize = pBt->usableSize; - data = pPage->aData; - hdr = pPage->hdrOffset; - brk = get2byte(&data[hdr+5]); - cdata = pChild->aData; - memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr); - memcpy(&cdata[brk], &data[brk], usableSize-brk); - assert( pChild->isInit==0 ); - rc = sqlite3BtreeInitPage(pChild, pPage); - if( rc ) goto balancedeeper_out; - memcpy(pChild->aOvfl, pPage->aOvfl, pPage->nOverflow*sizeof(pPage->aOvfl[0])); - pChild->nOverflow = pPage->nOverflow; - if( pChild->nOverflow ){ - pChild->nFree = 0; - } - assert( pChild->nCell==pPage->nCell ); - zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF); - put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild); - TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno)); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - int i; - rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno); - if( rc ) goto balancedeeper_out; - for(i=0; inCell; i++){ - rc = ptrmapPutOvfl(pChild, i); - if( rc!=SQLITE_OK ){ - return rc; - } - } - } -#endif - rc = balance_nonroot(pChild); - -balancedeeper_out: - releasePage(pChild); - return rc; -} - -/* -** Decide if the page pPage needs to be balanced. If balancing is -** required, call the appropriate balancing routine. -*/ -static int balance(MemPage *pPage, int insert){ - int rc = SQLITE_OK; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - if( pPage->pParent==0 ){ - rc = sqlite3PagerWrite(pPage->pDbPage); - if( rc==SQLITE_OK && pPage->nOverflow>0 ){ - rc = balance_deeper(pPage); - } - if( rc==SQLITE_OK && pPage->nCell==0 ){ - rc = balance_shallower(pPage); - } - }else{ - if( pPage->nOverflow>0 || - (!insert && pPage->nFree>pPage->pBt->usableSize*2/3) ){ - rc = balance_nonroot(pPage); - } - } - return rc; -} - -/* -** This routine checks all cursors that point to table pgnoRoot. -** If any of those cursors were opened with wrFlag==0 in a different -** database connection (a database connection that shares the pager -** cache with the current connection) and that other connection -** is not in the ReadUncommmitted state, then this routine returns -** SQLITE_LOCKED. -** -** In addition to checking for read-locks (where a read-lock -** means a cursor opened with wrFlag==0) this routine also moves -** all write cursors so that they are pointing to the -** first Cell on the root page. This is necessary because an insert -** or delete might change the number of cells on a page or delete -** a page entirely and we do not want to leave any cursors -** pointing to non-existant pages or cells. -*/ -static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){ - BtCursor *p; - BtShared *pBt = pBtree->pBt; - sqlite3 *db = pBtree->pSqlite; - assert( sqlite3BtreeHoldsMutex(pBtree) ); - for(p=pBt->pCursor; p; p=p->pNext){ - if( p==pExclude ) continue; - if( p->eState!=CURSOR_VALID ) continue; - if( p->pgnoRoot!=pgnoRoot ) continue; - if( p->wrFlag==0 ){ - sqlite3 *dbOther = p->pBtree->pSqlite; - if( dbOther==0 || - (dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0) ){ - return SQLITE_LOCKED; - } - }else if( p->pPage->pgno!=p->pgnoRoot ){ - moveToRoot(p); - } - } - return SQLITE_OK; -} - -/* -** Insert a new record into the BTree. The key is given by (pKey,nKey) -** and the data is given by (pData,nData). The cursor is used only to -** define what table the record should be inserted into. The cursor -** is left pointing at a random location. -** -** For an INTKEY table, only the nKey value of the key is used. pKey is -** ignored. For a ZERODATA table, the pData and nData are both ignored. -*/ -int sqlite3BtreeInsert( - BtCursor *pCur, /* Insert data into the table of this cursor */ - const void *pKey, i64 nKey, /* The key of the new record */ - const void *pData, int nData, /* The data of the new record */ - int nZero, /* Number of extra 0 bytes to append to data */ - int appendBias /* True if this is likely an append */ -){ - int rc; - int loc; - int szNew; - MemPage *pPage; - Btree *p = pCur->pBtree; - BtShared *pBt = p->pBt; - unsigned char *oldCell; - unsigned char *newCell = 0; - - assert( cursorHoldsMutex(pCur) ); - if( pBt->inTransaction!=TRANS_WRITE ){ - /* Must start a transaction before doing an insert */ - rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; - return rc; - } - assert( !pBt->readOnly ); - if( !pCur->wrFlag ){ - return SQLITE_PERM; /* Cursor not open for writing */ - } - if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){ - return SQLITE_LOCKED; /* The table pCur points to has a read lock */ - } - if( pCur->eState==CURSOR_FAULT ){ - return pCur->skip; - } - - /* Save the positions of any other cursors open on this table */ - clearCursorPosition(pCur); - if( - SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) || - SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc)) - ){ - return rc; - } - - pPage = pCur->pPage; - assert( pPage->intKey || nKey>=0 ); - assert( pPage->leaf || !pPage->leafData ); - TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", - pCur->pgnoRoot, nKey, nData, pPage->pgno, - loc==0 ? "overwrite" : "new entry")); - assert( pPage->isInit ); - newCell = sqlite3_malloc( MX_CELL_SIZE(pBt) ); - if( newCell==0 ) return SQLITE_NOMEM; - rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew); - if( rc ) goto end_insert; - assert( szNew==cellSizePtr(pPage, newCell) ); - assert( szNew<=MX_CELL_SIZE(pBt) ); - if( loc==0 && CURSOR_VALID==pCur->eState ){ - int szOld; - assert( pCur->idx>=0 && pCur->idxnCell ); - rc = sqlite3PagerWrite(pPage->pDbPage); - if( rc ){ - goto end_insert; - } - oldCell = findCell(pPage, pCur->idx); - if( !pPage->leaf ){ - memcpy(newCell, oldCell, 4); - } - szOld = cellSizePtr(pPage, oldCell); - rc = clearCell(pPage, oldCell); - if( rc ) goto end_insert; - dropCell(pPage, pCur->idx, szOld); - }else if( loc<0 && pPage->nCell>0 ){ - assert( pPage->leaf ); - pCur->idx++; - pCur->info.nSize = 0; - }else{ - assert( pPage->leaf ); - } - rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0); - if( rc!=SQLITE_OK ) goto end_insert; - rc = balance(pPage, 1); - /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */ - /* fflush(stdout); */ - if( rc==SQLITE_OK ){ - moveToRoot(pCur); - } -end_insert: - sqlite3_free(newCell); - return rc; -} - -/* -** Delete the entry that the cursor is pointing to. The cursor -** is left pointing at a random location. -*/ -int sqlite3BtreeDelete(BtCursor *pCur){ - MemPage *pPage = pCur->pPage; - unsigned char *pCell; - int rc; - Pgno pgnoChild = 0; - Btree *p = pCur->pBtree; - BtShared *pBt = p->pBt; - - assert( cursorHoldsMutex(pCur) ); - assert( pPage->isInit ); - if( pBt->inTransaction!=TRANS_WRITE ){ - /* Must start a transaction before doing a delete */ - rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; - return rc; - } - assert( !pBt->readOnly ); - if( pCur->eState==CURSOR_FAULT ){ - return pCur->skip; - } - if( pCur->idx >= pPage->nCell ){ - return SQLITE_ERROR; /* The cursor is not pointing to anything */ - } - if( !pCur->wrFlag ){ - return SQLITE_PERM; /* Did not open this cursor for writing */ - } - if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){ - return SQLITE_LOCKED; /* The table pCur points to has a read lock */ - } - - /* Restore the current cursor position (a no-op if the cursor is not in - ** CURSOR_REQUIRESEEK state) and save the positions of any other cursors - ** open on the same table. Then call sqlite3PagerWrite() on the page - ** that the entry will be deleted from. - */ - if( - (rc = restoreOrClearCursorPosition(pCur))!=0 || - (rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur))!=0 || - (rc = sqlite3PagerWrite(pPage->pDbPage))!=0 - ){ - return rc; - } - - /* Locate the cell within it's page and leave pCell pointing to the - ** data. The clearCell() call frees any overflow pages associated with the - ** cell. The cell itself is still intact. - */ - pCell = findCell(pPage, pCur->idx); - if( !pPage->leaf ){ - pgnoChild = get4byte(pCell); - } - rc = clearCell(pPage, pCell); - if( rc ){ - return rc; - } - - if( !pPage->leaf ){ - /* - ** The entry we are about to delete is not a leaf so if we do not - ** do something we will leave a hole on an internal page. - ** We have to fill the hole by moving in a cell from a leaf. The - ** next Cell after the one to be deleted is guaranteed to exist and - ** to be a leaf so we can use it. - */ - BtCursor leafCur; - unsigned char *pNext; - int szNext; /* The compiler warning is wrong: szNext is always - ** initialized before use. Adding an extra initialization - ** to silence the compiler slows down the code. */ - int notUsed; - unsigned char *tempCell = 0; - assert( !pPage->leafData ); - sqlite3BtreeGetTempCursor(pCur, &leafCur); - rc = sqlite3BtreeNext(&leafCur, ¬Used); - if( rc==SQLITE_OK ){ - rc = sqlite3PagerWrite(leafCur.pPage->pDbPage); - } - if( rc==SQLITE_OK ){ - TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n", - pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno)); - dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); - pNext = findCell(leafCur.pPage, leafCur.idx); - szNext = cellSizePtr(leafCur.pPage, pNext); - assert( MX_CELL_SIZE(pBt)>=szNext+4 ); - tempCell = sqlite3_malloc( MX_CELL_SIZE(pBt) ); - if( tempCell==0 ){ - rc = SQLITE_NOMEM; - } - } - if( rc==SQLITE_OK ){ - rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell, 0); - } - if( rc==SQLITE_OK ){ - put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild); - rc = balance(pPage, 0); - } - if( rc==SQLITE_OK ){ - dropCell(leafCur.pPage, leafCur.idx, szNext); - rc = balance(leafCur.pPage, 0); - } - sqlite3_free(tempCell); - sqlite3BtreeReleaseTempCursor(&leafCur); - }else{ - TRACE(("DELETE: table=%d delete from leaf %d\n", - pCur->pgnoRoot, pPage->pgno)); - dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); - rc = balance(pPage, 0); - } - if( rc==SQLITE_OK ){ - moveToRoot(pCur); - } - return rc; -} - -/* -** Create a new BTree table. Write into *piTable the page -** number for the root page of the new table. -** -** The type of type is determined by the flags parameter. Only the -** following values of flags are currently in use. Other values for -** flags might not work: -** -** BTREE_INTKEY|BTREE_LEAFDATA Used for SQL tables with rowid keys -** BTREE_ZERODATA Used for SQL indices -*/ -static int btreeCreateTable(Btree *p, int *piTable, int flags){ - BtShared *pBt = p->pBt; - MemPage *pRoot; - Pgno pgnoRoot; - int rc; - - assert( sqlite3BtreeHoldsMutex(p) ); - if( pBt->inTransaction!=TRANS_WRITE ){ - /* Must start a transaction first */ - rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; - return rc; - } - assert( !pBt->readOnly ); - -#ifdef SQLITE_OMIT_AUTOVACUUM - rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); - if( rc ){ - return rc; - } -#else - if( pBt->autoVacuum ){ - Pgno pgnoMove; /* Move a page here to make room for the root-page */ - MemPage *pPageMove; /* The page to move to. */ - - /* Creating a new table may probably require moving an existing database - ** to make room for the new tables root page. In case this page turns - ** out to be an overflow page, delete all overflow page-map caches - ** held by open cursors. - */ - invalidateAllOverflowCache(pBt); - - /* Read the value of meta[3] from the database to determine where the - ** root page of the new table should go. meta[3] is the largest root-page - ** created so far, so the new root-page is (meta[3]+1). - */ - rc = sqlite3BtreeGetMeta(p, 4, &pgnoRoot); - if( rc!=SQLITE_OK ){ - return rc; - } - pgnoRoot++; - - /* The new root-page may not be allocated on a pointer-map page, or the - ** PENDING_BYTE page. - */ - if( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) || - pgnoRoot==PENDING_BYTE_PAGE(pBt) ){ - pgnoRoot++; - } - assert( pgnoRoot>=3 ); - - /* Allocate a page. The page that currently resides at pgnoRoot will - ** be moved to the allocated page (unless the allocated page happens - ** to reside at pgnoRoot). - */ - rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1); - if( rc!=SQLITE_OK ){ - return rc; - } - - if( pgnoMove!=pgnoRoot ){ - /* pgnoRoot is the page that will be used for the root-page of - ** the new table (assuming an error did not occur). But we were - ** allocated pgnoMove. If required (i.e. if it was not allocated - ** by extending the file), the current page at position pgnoMove - ** is already journaled. - */ - u8 eType; - Pgno iPtrPage; - - releasePage(pPageMove); - - /* Move the page currently at pgnoRoot to pgnoMove. */ - rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); - if( rc!=SQLITE_OK || eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ - releasePage(pRoot); - return rc; - } - assert( eType!=PTRMAP_ROOTPAGE ); - assert( eType!=PTRMAP_FREEPAGE ); - rc = sqlite3PagerWrite(pRoot->pDbPage); - if( rc!=SQLITE_OK ){ - releasePage(pRoot); - return rc; - } - rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove); - releasePage(pRoot); - - /* Obtain the page at pgnoRoot */ - if( rc!=SQLITE_OK ){ - return rc; - } - rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = sqlite3PagerWrite(pRoot->pDbPage); - if( rc!=SQLITE_OK ){ - releasePage(pRoot); - return rc; - } - }else{ - pRoot = pPageMove; - } - - /* Update the pointer-map and meta-data with the new root-page number. */ - rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0); - if( rc ){ - releasePage(pRoot); - return rc; - } - rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot); - if( rc ){ - releasePage(pRoot); - return rc; - } - - }else{ - rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); - if( rc ) return rc; - } -#endif - assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); - zeroPage(pRoot, flags | PTF_LEAF); - sqlite3PagerUnref(pRoot->pDbPage); - *piTable = (int)pgnoRoot; - return SQLITE_OK; -} -int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){ - int rc; - sqlite3BtreeEnter(p); - rc = btreeCreateTable(p, piTable, flags); - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Erase the given database page and all its children. Return -** the page to the freelist. -*/ -static int clearDatabasePage( - BtShared *pBt, /* The BTree that contains the table */ - Pgno pgno, /* Page number to clear */ - MemPage *pParent, /* Parent page. NULL for the root */ - int freePageFlag /* Deallocate page if true */ -){ - MemPage *pPage = 0; - int rc; - unsigned char *pCell; - int i; - - assert( sqlite3_mutex_held(pBt->mutex) ); - if( pgno>sqlite3PagerPagecount(pBt->pPager) ){ - return SQLITE_CORRUPT_BKPT; - } - - rc = getAndInitPage(pBt, pgno, &pPage, pParent); - if( rc ) goto cleardatabasepage_out; - for(i=0; inCell; i++){ - pCell = findCell(pPage, i); - if( !pPage->leaf ){ - rc = clearDatabasePage(pBt, get4byte(pCell), pPage->pParent, 1); - if( rc ) goto cleardatabasepage_out; - } - rc = clearCell(pPage, pCell); - if( rc ) goto cleardatabasepage_out; - } - if( !pPage->leaf ){ - rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), pPage->pParent, 1); - if( rc ) goto cleardatabasepage_out; - } - if( freePageFlag ){ - rc = freePage(pPage); - }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){ - zeroPage(pPage, pPage->aData[0] | PTF_LEAF); - } - -cleardatabasepage_out: - releasePage(pPage); - return rc; -} - -/* -** Delete all information from a single table in the database. iTable is -** the page number of the root of the table. After this routine returns, -** the root page is empty, but still exists. -** -** This routine will fail with SQLITE_LOCKED if there are any open -** read cursors on the table. Open write cursors are moved to the -** root of the table. -*/ -int sqlite3BtreeClearTable(Btree *p, int iTable){ - int rc; - BtShared *pBt = p->pBt; - sqlite3BtreeEnter(p); - if( p->inTrans!=TRANS_WRITE ){ - rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; - }else if( (rc = checkReadLocks(p, iTable, 0))!=SQLITE_OK ){ - /* nothing to do */ - }else if( SQLITE_OK!=(rc = saveAllCursors(pBt, iTable, 0)) ){ - /* nothing to do */ - }else{ - rc = clearDatabasePage(pBt, (Pgno)iTable, 0, 0); - } - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Erase all information in a table and add the root of the table to -** the freelist. Except, the root of the principle table (the one on -** page 1) is never added to the freelist. -** -** This routine will fail with SQLITE_LOCKED if there are any open -** cursors on the table. -** -** If AUTOVACUUM is enabled and the page at iTable is not the last -** root page in the database file, then the last root page -** in the database file is moved into the slot formerly occupied by -** iTable and that last slot formerly occupied by the last root page -** is added to the freelist instead of iTable. In this say, all -** root pages are kept at the beginning of the database file, which -** is necessary for AUTOVACUUM to work right. *piMoved is set to the -** page number that used to be the last root page in the file before -** the move. If no page gets moved, *piMoved is set to 0. -** The last root page is recorded in meta[3] and the value of -** meta[3] is updated by this procedure. -*/ -static int btreeDropTable(Btree *p, int iTable, int *piMoved){ - int rc; - MemPage *pPage = 0; - BtShared *pBt = p->pBt; - - assert( sqlite3BtreeHoldsMutex(p) ); - if( p->inTrans!=TRANS_WRITE ){ - return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; - } - - /* It is illegal to drop a table if any cursors are open on the - ** database. This is because in auto-vacuum mode the backend may - ** need to move another root-page to fill a gap left by the deleted - ** root page. If an open cursor was using this page a problem would - ** occur. - */ - if( pBt->pCursor ){ - return SQLITE_LOCKED; - } - - rc = sqlite3BtreeGetPage(pBt, (Pgno)iTable, &pPage, 0); - if( rc ) return rc; - rc = sqlite3BtreeClearTable(p, iTable); - if( rc ){ - releasePage(pPage); - return rc; - } - - *piMoved = 0; - - if( iTable>1 ){ -#ifdef SQLITE_OMIT_AUTOVACUUM - rc = freePage(pPage); - releasePage(pPage); -#else - if( pBt->autoVacuum ){ - Pgno maxRootPgno; - rc = sqlite3BtreeGetMeta(p, 4, &maxRootPgno); - if( rc!=SQLITE_OK ){ - releasePage(pPage); - return rc; - } - - if( iTable==maxRootPgno ){ - /* If the table being dropped is the table with the largest root-page - ** number in the database, put the root page on the free list. - */ - rc = freePage(pPage); - releasePage(pPage); - if( rc!=SQLITE_OK ){ - return rc; - } - }else{ - /* The table being dropped does not have the largest root-page - ** number in the database. So move the page that does into the - ** gap left by the deleted root-page. - */ - MemPage *pMove; - releasePage(pPage); - rc = sqlite3BtreeGetPage(pBt, maxRootPgno, &pMove, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable); - releasePage(pMove); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = sqlite3BtreeGetPage(pBt, maxRootPgno, &pMove, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = freePage(pMove); - releasePage(pMove); - if( rc!=SQLITE_OK ){ - return rc; - } - *piMoved = maxRootPgno; - } - - /* Set the new 'max-root-page' value in the database header. This - ** is the old value less one, less one more if that happens to - ** be a root-page number, less one again if that is the - ** PENDING_BYTE_PAGE. - */ - maxRootPgno--; - if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){ - maxRootPgno--; - } - if( maxRootPgno==PTRMAP_PAGENO(pBt, maxRootPgno) ){ - maxRootPgno--; - } - assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) ); - - rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno); - }else{ - rc = freePage(pPage); - releasePage(pPage); - } -#endif - }else{ - /* If sqlite3BtreeDropTable was called on page 1. */ - zeroPage(pPage, PTF_INTKEY|PTF_LEAF ); - releasePage(pPage); - } - return rc; -} -int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ - int rc; - sqlite3BtreeEnter(p); - rc = btreeDropTable(p, iTable, piMoved); - sqlite3BtreeLeave(p); - return rc; -} - - -/* -** Read the meta-information out of a database file. Meta[0] -** is the number of free pages currently in the database. Meta[1] -** through meta[15] are available for use by higher layers. Meta[0] -** is read-only, the others are read/write. -** -** The schema layer numbers meta values differently. At the schema -** layer (and the SetCookie and ReadCookie opcodes) the number of -** free pages is not visible. So Cookie[0] is the same as Meta[1]. -*/ -int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ - DbPage *pDbPage; - int rc; - unsigned char *pP1; - BtShared *pBt = p->pBt; - - sqlite3BtreeEnter(p); - - /* Reading a meta-data value requires a read-lock on page 1 (and hence - ** the sqlite_master table. We grab this lock regardless of whether or - ** not the SQLITE_ReadUncommitted flag is set (the table rooted at page - ** 1 is treated as a special case by queryTableLock() and lockTable()). - */ - rc = queryTableLock(p, 1, READ_LOCK); - if( rc!=SQLITE_OK ){ - sqlite3BtreeLeave(p); - return rc; - } - - assert( idx>=0 && idx<=15 ); - rc = sqlite3PagerGet(pBt->pPager, 1, &pDbPage); - if( rc ){ - sqlite3BtreeLeave(p); - return rc; - } - pP1 = (unsigned char *)sqlite3PagerGetData(pDbPage); - *pMeta = get4byte(&pP1[36 + idx*4]); - sqlite3PagerUnref(pDbPage); - - /* If autovacuumed is disabled in this build but we are trying to - ** access an autovacuumed database, then make the database readonly. - */ -#ifdef SQLITE_OMIT_AUTOVACUUM - if( idx==4 && *pMeta>0 ) pBt->readOnly = 1; -#endif - - /* Grab the read-lock on page 1. */ - rc = lockTable(p, 1, READ_LOCK); - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Write meta-information back into the database. Meta[0] is -** read-only and may not be written. -*/ -int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ - BtShared *pBt = p->pBt; - unsigned char *pP1; - int rc; - assert( idx>=1 && idx<=15 ); - sqlite3BtreeEnter(p); - if( p->inTrans!=TRANS_WRITE ){ - rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; - }else{ - assert( pBt->pPage1!=0 ); - pP1 = pBt->pPage1->aData; - rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); - if( rc==SQLITE_OK ){ - put4byte(&pP1[36 + idx*4], iMeta); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( idx==7 ){ - assert( pBt->autoVacuum || iMeta==0 ); - assert( iMeta==0 || iMeta==1 ); - pBt->incrVacuum = iMeta; - } -#endif - } - } - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Return the flag byte at the beginning of the page that the cursor -** is currently pointing to. -*/ -int sqlite3BtreeFlags(BtCursor *pCur){ - /* TODO: What about CURSOR_REQUIRESEEK state? Probably need to call - ** restoreOrClearCursorPosition() here. - */ - MemPage *pPage = pCur->pPage; - assert( cursorHoldsMutex(pCur) ); - assert( pPage->pBt==pCur->pBt ); - return pPage ? pPage->aData[pPage->hdrOffset] : 0; -} - - -/* -** Return the pager associated with a BTree. This routine is used for -** testing and debugging only. -*/ -Pager *sqlite3BtreePager(Btree *p){ - return p->pBt->pPager; -} - -#ifndef SQLITE_OMIT_INTEGRITY_CHECK -/* -** Append a message to the error message string. -*/ -static void checkAppendMsg( - IntegrityCk *pCheck, - char *zMsg1, - const char *zFormat, - ... -){ - va_list ap; - char *zMsg2; - if( !pCheck->mxErr ) return; - pCheck->mxErr--; - pCheck->nErr++; - va_start(ap, zFormat); - zMsg2 = sqlite3VMPrintf(0, zFormat, ap); - va_end(ap); - if( zMsg1==0 ) zMsg1 = ""; - if( pCheck->zErrMsg ){ - char *zOld = pCheck->zErrMsg; - pCheck->zErrMsg = 0; - sqlite3SetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, (char*)0); - sqlite3_free(zOld); - }else{ - sqlite3SetString(&pCheck->zErrMsg, zMsg1, zMsg2, (char*)0); - } - sqlite3_free(zMsg2); -} -#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -#ifndef SQLITE_OMIT_INTEGRITY_CHECK -/* -** Add 1 to the reference count for page iPage. If this is the second -** reference to the page, add an error message to pCheck->zErrMsg. -** Return 1 if there are 2 ore more references to the page and 0 if -** if this is the first reference to the page. -** -** Also check that the page number is in bounds. -*/ -static int checkRef(IntegrityCk *pCheck, int iPage, char *zContext){ - if( iPage==0 ) return 1; - if( iPage>pCheck->nPage || iPage<0 ){ - checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage); - return 1; - } - if( pCheck->anRef[iPage]==1 ){ - checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage); - return 1; - } - return (pCheck->anRef[iPage]++)>1; -} - -#ifndef SQLITE_OMIT_AUTOVACUUM -/* -** Check that the entry in the pointer-map for page iChild maps to -** page iParent, pointer type ptrType. If not, append an error message -** to pCheck. -*/ -static void checkPtrmap( - IntegrityCk *pCheck, /* Integrity check context */ - Pgno iChild, /* Child page number */ - u8 eType, /* Expected pointer map type */ - Pgno iParent, /* Expected pointer map parent page number */ - char *zContext /* Context description (used for error msg) */ -){ - int rc; - u8 ePtrmapType; - Pgno iPtrmapParent; - - rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); - if( rc!=SQLITE_OK ){ - checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild); - return; - } - - if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ - checkAppendMsg(pCheck, zContext, - "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", - iChild, eType, iParent, ePtrmapType, iPtrmapParent); - } -} -#endif - -/* -** Check the integrity of the freelist or of an overflow page list. -** Verify that the number of pages on the list is N. -*/ -static void checkList( - IntegrityCk *pCheck, /* Integrity checking context */ - int isFreeList, /* True for a freelist. False for overflow page list */ - int iPage, /* Page number for first page in the list */ - int N, /* Expected number of pages in the list */ - char *zContext /* Context for error messages */ -){ - int i; - int expected = N; - int iFirst = iPage; - while( N-- > 0 && pCheck->mxErr ){ - DbPage *pOvflPage; - unsigned char *pOvflData; - if( iPage<1 ){ - checkAppendMsg(pCheck, zContext, - "%d of %d pages missing from overflow list starting at %d", - N+1, expected, iFirst); - break; - } - if( checkRef(pCheck, iPage, zContext) ) break; - if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){ - checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage); - break; - } - pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); - if( isFreeList ){ - int n = get4byte(&pOvflData[4]); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pCheck->pBt->autoVacuum ){ - checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext); - } -#endif - if( n>pCheck->pBt->usableSize/4-8 ){ - checkAppendMsg(pCheck, zContext, - "freelist leaf count too big on page %d", iPage); - N--; - }else{ - for(i=0; ipBt->autoVacuum ){ - checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext); - } -#endif - checkRef(pCheck, iFreePage, zContext); - } - N -= n; - } - } -#ifndef SQLITE_OMIT_AUTOVACUUM - else{ - /* If this database supports auto-vacuum and iPage is not the last - ** page in this overflow list, check that the pointer-map entry for - ** the following page matches iPage. - */ - if( pCheck->pBt->autoVacuum && N>0 ){ - i = get4byte(pOvflData); - checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext); - } - } -#endif - iPage = get4byte(pOvflData); - sqlite3PagerUnref(pOvflPage); - } -} -#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -#ifndef SQLITE_OMIT_INTEGRITY_CHECK -/* -** Do various sanity checks on a single page of a tree. Return -** the tree depth. Root pages return 0. Parents of root pages -** return 1, and so forth. -** -** These checks are done: -** -** 1. Make sure that cells and freeblocks do not overlap -** but combine to completely cover the page. -** NO 2. Make sure cell keys are in order. -** NO 3. Make sure no key is less than or equal to zLowerBound. -** NO 4. Make sure no key is greater than or equal to zUpperBound. -** 5. Check the integrity of overflow pages. -** 6. Recursively call checkTreePage on all children. -** 7. Verify that the depth of all children is the same. -** 8. Make sure this page is at least 33% full or else it is -** the root of the tree. -*/ -static int checkTreePage( - IntegrityCk *pCheck, /* Context for the sanity check */ - int iPage, /* Page number of the page to check */ - MemPage *pParent, /* Parent page */ - char *zParentContext /* Parent context */ -){ - MemPage *pPage; - int i, rc, depth, d2, pgno, cnt; - int hdr, cellStart; - int nCell; - u8 *data; - BtShared *pBt; - int usableSize; - char zContext[100]; - char *hit; - - sqlite3_snprintf(sizeof(zContext), zContext, "Page %d: ", iPage); - - /* Check that the page exists - */ - pBt = pCheck->pBt; - usableSize = pBt->usableSize; - if( iPage==0 ) return 0; - if( checkRef(pCheck, iPage, zParentContext) ) return 0; - if( (rc = sqlite3BtreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){ - checkAppendMsg(pCheck, zContext, - "unable to get the page. error code=%d", rc); - return 0; - } - if( (rc = sqlite3BtreeInitPage(pPage, pParent))!=0 ){ - checkAppendMsg(pCheck, zContext, - "sqlite3BtreeInitPage() returns error code %d", rc); - releasePage(pPage); - return 0; - } - - /* Check out all the cells. - */ - depth = 0; - for(i=0; inCell && pCheck->mxErr; i++){ - u8 *pCell; - int sz; - CellInfo info; - - /* Check payload overflow pages - */ - sqlite3_snprintf(sizeof(zContext), zContext, - "On tree page %d cell %d: ", iPage, i); - pCell = findCell(pPage,i); - sqlite3BtreeParseCellPtr(pPage, pCell, &info); - sz = info.nData; - if( !pPage->intKey ) sz += info.nKey; - assert( sz==info.nPayload ); - if( sz>info.nLocal ){ - int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4); - Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext); - } -#endif - checkList(pCheck, 0, pgnoOvfl, nPage, zContext); - } - - /* Check sanity of left child page. - */ - if( !pPage->leaf ){ - pgno = get4byte(pCell); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext); - } -#endif - d2 = checkTreePage(pCheck,pgno,pPage,zContext); - if( i>0 && d2!=depth ){ - checkAppendMsg(pCheck, zContext, "Child page depth differs"); - } - depth = d2; - } - } - if( !pPage->leaf ){ - pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); - sqlite3_snprintf(sizeof(zContext), zContext, - "On page %d at right child: ", iPage); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, 0); - } -#endif - checkTreePage(pCheck, pgno, pPage, zContext); - } - - /* Check for complete coverage of the page - */ - data = pPage->aData; - hdr = pPage->hdrOffset; - hit = sqlite3MallocZero( usableSize ); - if( hit ){ - memset(hit, 1, get2byte(&data[hdr+5])); - nCell = get2byte(&data[hdr+3]); - cellStart = hdr + 12 - 4*pPage->leaf; - for(i=0; i=usableSize || pc<0 ){ - checkAppendMsg(pCheck, 0, - "Corruption detected in cell %d on page %d",i,iPage,0); - }else{ - for(j=pc+size-1; j>=pc; j--) hit[j]++; - } - } - for(cnt=0, i=get2byte(&data[hdr+1]); i>0 && i=usableSize || i<0 ){ - checkAppendMsg(pCheck, 0, - "Corruption detected in cell %d on page %d",i,iPage,0); - }else{ - for(j=i+size-1; j>=i; j--) hit[j]++; - } - i = get2byte(&data[i]); - } - for(i=cnt=0; i1 ){ - checkAppendMsg(pCheck, 0, - "Multiple uses for byte %d of page %d", i, iPage); - break; - } - } - if( cnt!=data[hdr+7] ){ - checkAppendMsg(pCheck, 0, - "Fragmented space is %d byte reported as %d on page %d", - cnt, data[hdr+7], iPage); - } - } - sqlite3_free(hit); - - releasePage(pPage); - return depth+1; -} -#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -#ifndef SQLITE_OMIT_INTEGRITY_CHECK -/* -** This routine does a complete check of the given BTree file. aRoot[] is -** an array of pages numbers were each page number is the root page of -** a table. nRoot is the number of entries in aRoot. -** -** If everything checks out, this routine returns NULL. If something is -** amiss, an error message is written into memory obtained from malloc() -** and a pointer to that error message is returned. The calling function -** is responsible for freeing the error message when it is done. -*/ -char *sqlite3BtreeIntegrityCheck( - Btree *p, /* The btree to be checked */ - int *aRoot, /* An array of root pages numbers for individual trees */ - int nRoot, /* Number of entries in aRoot[] */ - int mxErr, /* Stop reporting errors after this many */ - int *pnErr /* Write number of errors seen to this variable */ -){ - int i; - int nRef; - IntegrityCk sCheck; - BtShared *pBt = p->pBt; - - sqlite3BtreeEnter(p); - nRef = sqlite3PagerRefcount(pBt->pPager); - if( lockBtreeWithRetry(p)!=SQLITE_OK ){ - sqlite3BtreeLeave(p); - return sqlite3StrDup("Unable to acquire a read lock on the database"); - } - sCheck.pBt = pBt; - sCheck.pPager = pBt->pPager; - sCheck.nPage = sqlite3PagerPagecount(sCheck.pPager); - sCheck.mxErr = mxErr; - sCheck.nErr = 0; - *pnErr = 0; -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->nTrunc!=0 ){ - sCheck.nPage = pBt->nTrunc; - } -#endif - if( sCheck.nPage==0 ){ - unlockBtreeIfUnused(pBt); - sqlite3BtreeLeave(p); - return 0; - } - sCheck.anRef = sqlite3_malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); - if( !sCheck.anRef ){ - unlockBtreeIfUnused(pBt); - *pnErr = 1; - sqlite3BtreeLeave(p); - return sqlite3MPrintf(p->pSqlite, "Unable to malloc %d bytes", - (sCheck.nPage+1)*sizeof(sCheck.anRef[0])); - } - for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; } - i = PENDING_BYTE_PAGE(pBt); - if( i<=sCheck.nPage ){ - sCheck.anRef[i] = 1; - } - sCheck.zErrMsg = 0; - - /* Check the integrity of the freelist - */ - checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]), - get4byte(&pBt->pPage1->aData[36]), "Main freelist: "); - - /* Check all the tables. - */ - for(i=0; iautoVacuum && aRoot[i]>1 ){ - checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0); - } -#endif - checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: "); - } - - /* Make sure every page in the file is referenced - */ - for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ -#ifdef SQLITE_OMIT_AUTOVACUUM - if( sCheck.anRef[i]==0 ){ - checkAppendMsg(&sCheck, 0, "Page %d is never used", i); - } -#else - /* If the database supports auto-vacuum, make sure no tables contain - ** references to pointer-map pages. - */ - if( sCheck.anRef[i]==0 && - (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ - checkAppendMsg(&sCheck, 0, "Page %d is never used", i); - } - if( sCheck.anRef[i]!=0 && - (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ - checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i); - } -#endif - } - - /* Make sure this analysis did not leave any unref() pages - */ - unlockBtreeIfUnused(pBt); - if( nRef != sqlite3PagerRefcount(pBt->pPager) ){ - checkAppendMsg(&sCheck, 0, - "Outstanding page count goes from %d to %d during this analysis", - nRef, sqlite3PagerRefcount(pBt->pPager) - ); - } - - /* Clean up and report errors. - */ - sqlite3BtreeLeave(p); - sqlite3_free(sCheck.anRef); - *pnErr = sCheck.nErr; - return sCheck.zErrMsg; -} -#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -/* -** Return the full pathname of the underlying database file. -** -** The pager filename is invariant as long as the pager is -** open so it is safe to access without the BtShared mutex. -*/ -const char *sqlite3BtreeGetFilename(Btree *p){ - assert( p->pBt->pPager!=0 ); - return sqlite3PagerFilename(p->pBt->pPager); -} - -/* -** Return the pathname of the directory that contains the database file. -** -** The pager directory name is invariant as long as the pager is -** open so it is safe to access without the BtShared mutex. -*/ -const char *sqlite3BtreeGetDirname(Btree *p){ - assert( p->pBt->pPager!=0 ); - return sqlite3PagerDirname(p->pBt->pPager); -} - -/* -** Return the pathname of the journal file for this database. The return -** value of this routine is the same regardless of whether the journal file -** has been created or not. -** -** The pager journal filename is invariant as long as the pager is -** open so it is safe to access without the BtShared mutex. -*/ -const char *sqlite3BtreeGetJournalname(Btree *p){ - assert( p->pBt->pPager!=0 ); - return sqlite3PagerJournalname(p->pBt->pPager); -} - -#ifndef SQLITE_OMIT_VACUUM -/* -** Copy the complete content of pBtFrom into pBtTo. A transaction -** must be active for both files. -** -** The size of file pBtFrom may be reduced by this operation. -** If anything goes wrong, the transaction on pBtFrom is rolled back. -*/ -static int btreeCopyFile(Btree *pTo, Btree *pFrom){ - int rc = SQLITE_OK; - Pgno i, nPage, nToPage, iSkip; - - BtShared *pBtTo = pTo->pBt; - BtShared *pBtFrom = pFrom->pBt; - - if( pTo->inTrans!=TRANS_WRITE || pFrom->inTrans!=TRANS_WRITE ){ - return SQLITE_ERROR; - } - if( pBtTo->pCursor ) return SQLITE_BUSY; - nToPage = sqlite3PagerPagecount(pBtTo->pPager); - nPage = sqlite3PagerPagecount(pBtFrom->pPager); - iSkip = PENDING_BYTE_PAGE(pBtTo); - for(i=1; rc==SQLITE_OK && i<=nPage; i++){ - DbPage *pDbPage; - if( i==iSkip ) continue; - rc = sqlite3PagerGet(pBtFrom->pPager, i, &pDbPage); - if( rc ) break; - rc = sqlite3PagerOverwrite(pBtTo->pPager, i, sqlite3PagerGetData(pDbPage)); - sqlite3PagerUnref(pDbPage); - } - - /* If the file is shrinking, journal the pages that are being truncated - ** so that they can be rolled back if the commit fails. - */ - for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){ - DbPage *pDbPage; - if( i==iSkip ) continue; - rc = sqlite3PagerGet(pBtTo->pPager, i, &pDbPage); - if( rc ) break; - rc = sqlite3PagerWrite(pDbPage); - sqlite3PagerDontWrite(pDbPage); - /* Yeah. It seems wierd to call DontWrite() right after Write(). But - ** that is because the names of those procedures do not exactly - ** represent what they do. Write() really means "put this page in the - ** rollback journal and mark it as dirty so that it will be written - ** to the database file later." DontWrite() undoes the second part of - ** that and prevents the page from being written to the database. The - ** page is still on the rollback journal, though. And that is the whole - ** point of this loop: to put pages on the rollback journal. */ - sqlite3PagerUnref(pDbPage); - } - if( !rc && nPagepPager, nPage); - } - - if( rc ){ - sqlite3BtreeRollback(pTo); - } - return rc; -} -int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ - int rc; - sqlite3BtreeEnter(pTo); - sqlite3BtreeEnter(pFrom); - rc = btreeCopyFile(pTo, pFrom); - sqlite3BtreeLeave(pFrom); - sqlite3BtreeLeave(pTo); - return rc; -} - -#endif /* SQLITE_OMIT_VACUUM */ - -/* -** Return non-zero if a transaction is active. -*/ -int sqlite3BtreeIsInTrans(Btree *p){ - assert( p==0 || sqlite3_mutex_held(p->pSqlite->mutex) ); - return (p && (p->inTrans==TRANS_WRITE)); -} - -/* -** Return non-zero if a statement transaction is active. -*/ -int sqlite3BtreeIsInStmt(Btree *p){ - assert( sqlite3BtreeHoldsMutex(p) ); - return (p->pBt && p->pBt->inStmt); -} - -/* -** Return non-zero if a read (or write) transaction is active. -*/ -int sqlite3BtreeIsInReadTrans(Btree *p){ - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - return (p && (p->inTrans!=TRANS_NONE)); -} - -/* -** This function returns a pointer to a blob of memory associated with -** a single shared-btree. The memory is used by client code for it's own -** purposes (for example, to store a high-level schema associated with -** the shared-btree). The btree layer manages reference counting issues. -** -** The first time this is called on a shared-btree, nBytes bytes of memory -** are allocated, zeroed, and returned to the caller. For each subsequent -** call the nBytes parameter is ignored and a pointer to the same blob -** of memory returned. -** -** Just before the shared-btree is closed, the function passed as the -** xFree argument when the memory allocation was made is invoked on the -** blob of allocated memory. This function should not call sqlite3_free() -** on the memory, the btree layer does that. -*/ -void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ - BtShared *pBt = p->pBt; - sqlite3BtreeEnter(p); - if( !pBt->pSchema ){ - pBt->pSchema = sqlite3MallocZero(nBytes); - pBt->xFreeSchema = xFree; - } - sqlite3BtreeLeave(p); - return pBt->pSchema; -} - -/* -** Return true if another user of the same shared btree as the argument -** handle holds an exclusive lock on the sqlite_master table. -*/ -int sqlite3BtreeSchemaLocked(Btree *p){ - int rc; - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - sqlite3BtreeEnter(p); - rc = (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK); - sqlite3BtreeLeave(p); - return rc; -} - - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** Obtain a lock on the table whose root page is iTab. The -** lock is a write lock if isWritelock is true or a read lock -** if it is false. -*/ -int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ - int rc = SQLITE_OK; - u8 lockType = (isWriteLock?WRITE_LOCK:READ_LOCK); - sqlite3BtreeEnter(p); - rc = queryTableLock(p, iTab, lockType); - if( rc==SQLITE_OK ){ - rc = lockTable(p, iTab, lockType); - } - sqlite3BtreeLeave(p); - return rc; -} -#endif - -#ifndef SQLITE_OMIT_INCRBLOB -/* -** Argument pCsr must be a cursor opened for writing on an -** INTKEY table currently pointing at a valid table entry. -** This function modifies the data stored as part of that entry. -** Only the data content may only be modified, it is not possible -** to change the length of the data stored. -*/ -int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ - assert( cursorHoldsMutex(pCsr) ); - assert( sqlite3_mutex_held(pCsr->pBtree->pSqlite->mutex) ); - assert(pCsr->isIncrblobHandle); - if( pCsr->eState>=CURSOR_REQUIRESEEK ){ - if( pCsr->eState==CURSOR_FAULT ){ - return pCsr->skip; - }else{ - return SQLITE_ABORT; - } - } - - /* Check some preconditions: - ** (a) the cursor is open for writing, - ** (b) there is no read-lock on the table being modified and - ** (c) the cursor points at a valid row of an intKey table. - */ - if( !pCsr->wrFlag ){ - return SQLITE_READONLY; - } - assert( !pCsr->pBt->readOnly - && pCsr->pBt->inTransaction==TRANS_WRITE ); - if( checkReadLocks(pCsr->pBtree, pCsr->pgnoRoot, pCsr) ){ - return SQLITE_LOCKED; /* The table pCur points to has a read lock */ - } - if( pCsr->eState==CURSOR_INVALID || !pCsr->pPage->intKey ){ - return SQLITE_ERROR; - } - - return accessPayload(pCsr, offset, amt, (unsigned char *)z, 0, 1); -} - -/* -** Set a flag on this cursor to cache the locations of pages from the -** overflow list for the current row. This is used by cursors opened -** for incremental blob IO only. -** -** This function sets a flag only. The actual page location cache -** (stored in BtCursor.aOverflow[]) is allocated and used by function -** accessPayload() (the worker function for sqlite3BtreeData() and -** sqlite3BtreePutData()). -*/ -void sqlite3BtreeCacheOverflow(BtCursor *pCur){ - assert( cursorHoldsMutex(pCur) ); - assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) ); - assert(!pCur->isIncrblobHandle); - assert(!pCur->aOverflow); - pCur->isIncrblobHandle = 1; -} -#endif diff --git a/extensions/sqlite/sqlite-source/btree.h b/extensions/sqlite/sqlite-source/btree.h deleted file mode 100644 index 21541fc5..00000000 --- a/extensions/sqlite/sqlite-source/btree.h +++ /dev/null @@ -1,204 +0,0 @@ -/* -** 2001 September 15 -** -** 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 interface that the sqlite B-Tree file -** subsystem. See comments in the source code for a detailed description -** of what each interface routine does. -** -** @(#) $Id$ -*/ -#ifndef _BTREE_H_ -#define _BTREE_H_ - -/* TODO: This definition is just included so other modules compile. It -** needs to be revisited. -*/ -#define SQLITE_N_BTREE_META 10 - -/* -** If defined as non-zero, auto-vacuum is enabled by default. Otherwise -** it must be turned on for each database using "PRAGMA auto_vacuum = 1". -*/ -#ifndef SQLITE_DEFAULT_AUTOVACUUM - #define SQLITE_DEFAULT_AUTOVACUUM 0 -#endif - -#define BTREE_AUTOVACUUM_NONE 0 /* Do not do auto-vacuum */ -#define BTREE_AUTOVACUUM_FULL 1 /* Do full auto-vacuum */ -#define BTREE_AUTOVACUUM_INCR 2 /* Incremental vacuum */ - -/* -** Forward declarations of structure -*/ -typedef struct Btree Btree; -typedef struct BtCursor BtCursor; -typedef struct BtShared BtShared; -typedef struct BtreeMutexArray BtreeMutexArray; - -/* -** This structure records all of the Btrees that need to hold -** a mutex before we enter sqlite3VdbeExec(). The Btrees are -** are placed in aBtree[] in order of aBtree[]->pBt. That way, -** we can always lock and unlock them all quickly. -*/ -struct BtreeMutexArray { - int nMutex; - Btree *aBtree[SQLITE_MAX_ATTACHED+1]; -}; - - -int sqlite3BtreeOpen( - const char *zFilename, /* Name of database file to open */ - sqlite3 *db, /* Associated database connection */ - Btree **, /* Return open Btree* here */ - int flags, /* Flags */ - int vfsFlags /* Flags passed through to VFS open */ -); - -/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the -** following values. -** -** NOTE: These values must match the corresponding PAGER_ values in -** pager.h. -*/ -#define BTREE_OMIT_JOURNAL 1 /* Do not use journal. No argument */ -#define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ -#define BTREE_MEMORY 4 /* In-memory DB. No argument */ -#define BTREE_READONLY 8 /* Open the database in read-only mode */ -#define BTREE_READWRITE 16 /* Open for both reading and writing */ -#define BTREE_CREATE 32 /* Create the database if it does not exist */ - -/* Additional values for the 4th argument of sqlite3BtreeOpen that -** are not associated with PAGER_ values. -*/ -#define BTREE_PRIVATE 64 /* Never share with other connections */ - -int sqlite3BtreeClose(Btree*); -int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*); -int sqlite3BtreeSetCacheSize(Btree*,int); -int sqlite3BtreeSetSafetyLevel(Btree*,int,int); -int sqlite3BtreeSyncDisabled(Btree*); -int sqlite3BtreeSetPageSize(Btree*,int,int); -int sqlite3BtreeGetPageSize(Btree*); -int sqlite3BtreeMaxPageCount(Btree*,int); -int sqlite3BtreeGetReserve(Btree*); -int sqlite3BtreeSetAutoVacuum(Btree *, int); -int sqlite3BtreeGetAutoVacuum(Btree *); -int sqlite3BtreeBeginTrans(Btree*,int); -int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); -int sqlite3BtreeCommitPhaseTwo(Btree*); -int sqlite3BtreeCommit(Btree*); -int sqlite3BtreeRollback(Btree*); -int sqlite3BtreeBeginStmt(Btree*); -int sqlite3BtreeCommitStmt(Btree*); -int sqlite3BtreeRollbackStmt(Btree*); -int sqlite3BtreeCreateTable(Btree*, int*, int flags); -int sqlite3BtreeIsInTrans(Btree*); -int sqlite3BtreeIsInStmt(Btree*); -int sqlite3BtreeIsInReadTrans(Btree*); -void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); -int sqlite3BtreeSchemaLocked(Btree *); -int sqlite3BtreeLockTable(Btree *, int, u8); - -const char *sqlite3BtreeGetFilename(Btree *); -const char *sqlite3BtreeGetDirname(Btree *); -const char *sqlite3BtreeGetJournalname(Btree *); -int sqlite3BtreeCopyFile(Btree *, Btree *); - -int sqlite3BtreeIncrVacuum(Btree *); - -/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR -** of the following flags: -*/ -#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */ -#define BTREE_ZERODATA 2 /* Table has keys only - no data */ -#define BTREE_LEAFDATA 4 /* Data stored in leaves only. Implies INTKEY */ - -int sqlite3BtreeDropTable(Btree*, int, int*); -int sqlite3BtreeClearTable(Btree*, int); -int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue); -int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); -void sqlite3BtreeTripAllCursors(Btree*, int); - -int sqlite3BtreeCursor( - Btree*, /* BTree containing table to open */ - int iTable, /* Index of root page */ - int wrFlag, /* 1 for writing. 0 for read-only */ - int(*)(void*,int,const void*,int,const void*), /* Key comparison function */ - void*, /* First argument to compare function */ - BtCursor **ppCursor /* Returned cursor */ -); - -int sqlite3BtreeCloseCursor(BtCursor*); -int sqlite3BtreeMoveto(BtCursor*,const void *pKey,i64 nKey,int bias,int *pRes); -int sqlite3BtreeDelete(BtCursor*); -int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, - const void *pData, int nData, - int nZero, int bias); -int sqlite3BtreeFirst(BtCursor*, int *pRes); -int sqlite3BtreeLast(BtCursor*, int *pRes); -int sqlite3BtreeNext(BtCursor*, int *pRes); -int sqlite3BtreeEof(BtCursor*); -int sqlite3BtreeFlags(BtCursor*); -int sqlite3BtreePrevious(BtCursor*, int *pRes); -int sqlite3BtreeKeySize(BtCursor*, i64 *pSize); -int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*); -sqlite3 *sqlite3BtreeCursorDb(const BtCursor*); -const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt); -const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt); -int sqlite3BtreeDataSize(BtCursor*, u32 *pSize); -int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); - -char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); -struct Pager *sqlite3BtreePager(Btree*); - -int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); -void sqlite3BtreeCacheOverflow(BtCursor *); - -#ifdef SQLITE_TEST -int sqlite3BtreeCursorInfo(BtCursor*, int*, int); -void sqlite3BtreeCursorList(Btree*); -int sqlite3BtreePageDump(Btree*, int, int recursive); -#endif - -/* -** If we are not using shared cache, then there is no need to -** use mutexes to access the BtShared structures. So make the -** Enter and Leave procedures no-ops. -*/ -#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE - void sqlite3BtreeEnter(Btree*); - void sqlite3BtreeLeave(Btree*); - int sqlite3BtreeHoldsMutex(Btree*); - void sqlite3BtreeEnterCursor(BtCursor*); - void sqlite3BtreeLeaveCursor(BtCursor*); - void sqlite3BtreeEnterAll(sqlite3*); - void sqlite3BtreeLeaveAll(sqlite3*); - int sqlite3BtreeHoldsAllMutexes(sqlite3*); - void sqlite3BtreeMutexArrayEnter(BtreeMutexArray*); - void sqlite3BtreeMutexArrayLeave(BtreeMutexArray*); - void sqlite3BtreeMutexArrayInsert(BtreeMutexArray*, Btree*); -#else -# define sqlite3BtreeEnter(X) -# define sqlite3BtreeLeave(X) -# define sqlite3BtreeHoldsMutex(X) 1 -# define sqlite3BtreeEnterCursor(X) -# define sqlite3BtreeLeaveCursor(X) -# define sqlite3BtreeEnterAll(X) -# define sqlite3BtreeLeaveAll(X) -# define sqlite3BtreeHoldsAllMutexes(X) 1 -# define sqlite3BtreeMutexArrayEnter(X) -# define sqlite3BtreeMutexArrayLeave(X) -# define sqlite3BtreeMutexArrayInsert(X,Y) -#endif - - -#endif /* _BTREE_H_ */ diff --git a/extensions/sqlite/sqlite-source/btreeInt.h b/extensions/sqlite/sqlite-source/btreeInt.h deleted file mode 100644 index 6d290893..00000000 --- a/extensions/sqlite/sqlite-source/btreeInt.h +++ /dev/null @@ -1,648 +0,0 @@ -/* -** 2004 April 6 -** -** 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. -** -************************************************************************* -** $Id$ -** -** This file implements a external (disk-based) database using BTrees. -** For a detailed discussion of BTrees, refer to -** -** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: -** "Sorting And Searching", pages 473-480. Addison-Wesley -** Publishing Company, Reading, Massachusetts. -** -** The basic idea is that each page of the file contains N database -** entries and N+1 pointers to subpages. -** -** ---------------------------------------------------------------- -** | Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) | -** ---------------------------------------------------------------- -** -** All of the keys on the page that Ptr(0) points to have values less -** than Key(0). All of the keys on page Ptr(1) and its subpages have -** values greater than Key(0) and less than Key(1). All of the keys -** on Ptr(N) and its subpages have values greater than Key(N-1). And -** so forth. -** -** Finding a particular key requires reading O(log(M)) pages from the -** disk where M is the number of entries in the tree. -** -** In this implementation, a single file can hold one or more separate -** BTrees. Each BTree is identified by the index of its root page. The -** key and data for any entry are combined to form the "payload". A -** fixed amount of payload can be carried directly on the database -** page. If the payload is larger than the preset amount then surplus -** bytes are stored on overflow pages. The payload for an entry -** and the preceding pointer are combined to form a "Cell". Each -** page has a small header which contains the Ptr(N) pointer and other -** information such as the size of key and data. -** -** FORMAT DETAILS -** -** The file is divided into pages. The first page is called page 1, -** the second is page 2, and so forth. A page number of zero indicates -** "no such page". The page size can be anything between 512 and 65536. -** Each page can be either a btree page, a freelist page or an overflow -** page. -** -** The first page is always a btree page. The first 100 bytes of the first -** page contain a special header (the "file header") that describes the file. -** The format of the file header is as follows: -** -** OFFSET SIZE DESCRIPTION -** 0 16 Header string: "SQLite format 3\000" -** 16 2 Page size in bytes. -** 18 1 File format write version -** 19 1 File format read version -** 20 1 Bytes of unused space at the end of each page -** 21 1 Max embedded payload fraction -** 22 1 Min embedded payload fraction -** 23 1 Min leaf payload fraction -** 24 4 File change counter -** 28 4 Reserved for future use -** 32 4 First freelist page -** 36 4 Number of freelist pages in the file -** 40 60 15 4-byte meta values passed to higher layers -** -** All of the integer values are big-endian (most significant byte first). -** -** The file change counter is incremented when the database is changed -** This counter allows other processes to know when the file has changed -** and thus when they need to flush their cache. -** -** The max embedded payload fraction is the amount of the total usable -** space in a page that can be consumed by a single cell for standard -** B-tree (non-LEAFDATA) tables. A value of 255 means 100%. The default -** is to limit the maximum cell size so that at least 4 cells will fit -** on one page. Thus the default max embedded payload fraction is 64. -** -** If the payload for a cell is larger than the max payload, then extra -** payload is spilled to overflow pages. Once an overflow page is allocated, -** as many bytes as possible are moved into the overflow pages without letting -** the cell size drop below the min embedded payload fraction. -** -** The min leaf payload fraction is like the min embedded payload fraction -** except that it applies to leaf nodes in a LEAFDATA tree. The maximum -** payload fraction for a LEAFDATA tree is always 100% (or 255) and it -** not specified in the header. -** -** Each btree pages is divided into three sections: The header, the -** cell pointer array, and the cell content area. Page 1 also has a 100-byte -** file header that occurs before the page header. -** -** |----------------| -** | file header | 100 bytes. Page 1 only. -** |----------------| -** | page header | 8 bytes for leaves. 12 bytes for interior nodes -** |----------------| -** | cell pointer | | 2 bytes per cell. Sorted order. -** | array | | Grows downward -** | | v -** |----------------| -** | unallocated | -** | space | -** |----------------| ^ Grows upwards -** | cell content | | Arbitrary order interspersed with freeblocks. -** | area | | and free space fragments. -** |----------------| -** -** The page headers looks like this: -** -** OFFSET SIZE DESCRIPTION -** 0 1 Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf -** 1 2 byte offset to the first freeblock -** 3 2 number of cells on this page -** 5 2 first byte of the cell content area -** 7 1 number of fragmented free bytes -** 8 4 Right child (the Ptr(N) value). Omitted on leaves. -** -** The flags define the format of this btree page. The leaf flag means that -** this page has no children. The zerodata flag means that this page carries -** only keys and no data. The intkey flag means that the key is a integer -** which is stored in the key size entry of the cell header rather than in -** the payload area. -** -** The cell pointer array begins on the first byte after the page header. -** The cell pointer array contains zero or more 2-byte numbers which are -** offsets from the beginning of the page to the cell content in the cell -** content area. The cell pointers occur in sorted order. The system strives -** to keep free space after the last cell pointer so that new cells can -** be easily added without having to defragment the page. -** -** Cell content is stored at the very end of the page and grows toward the -** beginning of the page. -** -** Unused space within the cell content area is collected into a linked list of -** freeblocks. Each freeblock is at least 4 bytes in size. The byte offset -** to the first freeblock is given in the header. Freeblocks occur in -** increasing order. Because a freeblock must be at least 4 bytes in size, -** any group of 3 or fewer unused bytes in the cell content area cannot -** exist on the freeblock chain. A group of 3 or fewer free bytes is called -** a fragment. The total number of bytes in all fragments is recorded. -** in the page header at offset 7. -** -** SIZE DESCRIPTION -** 2 Byte offset of the next freeblock -** 2 Bytes in this freeblock -** -** Cells are of variable length. Cells are stored in the cell content area at -** the end of the page. Pointers to the cells are in the cell pointer array -** that immediately follows the page header. Cells is not necessarily -** contiguous or in order, but cell pointers are contiguous and in order. -** -** Cell content makes use of variable length integers. A variable -** length integer is 1 to 9 bytes where the lower 7 bits of each -** byte are used. The integer consists of all bytes that have bit 8 set and -** the first byte with bit 8 clear. The most significant byte of the integer -** appears first. A variable-length integer may not be more than 9 bytes long. -** As a special case, all 8 bytes of the 9th byte are used as data. This -** allows a 64-bit integer to be encoded in 9 bytes. -** -** 0x00 becomes 0x00000000 -** 0x7f becomes 0x0000007f -** 0x81 0x00 becomes 0x00000080 -** 0x82 0x00 becomes 0x00000100 -** 0x80 0x7f becomes 0x0000007f -** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678 -** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081 -** -** Variable length integers are used for rowids and to hold the number of -** bytes of key and data in a btree cell. -** -** The content of a cell looks like this: -** -** SIZE DESCRIPTION -** 4 Page number of the left child. Omitted if leaf flag is set. -** var Number of bytes of data. Omitted if the zerodata flag is set. -** var Number of bytes of key. Or the key itself if intkey flag is set. -** * Payload -** 4 First page of the overflow chain. Omitted if no overflow -** -** Overflow pages form a linked list. Each page except the last is completely -** filled with data (pagesize - 4 bytes). The last page can have as little -** as 1 byte of data. -** -** SIZE DESCRIPTION -** 4 Page number of next overflow page -** * Data -** -** Freelist pages come in two subtypes: trunk pages and leaf pages. The -** file header points to the first in a linked list of trunk page. Each trunk -** page points to multiple leaf pages. The content of a leaf page is -** unspecified. A trunk page looks like this: -** -** SIZE DESCRIPTION -** 4 Page number of next trunk page -** 4 Number of leaf pointers on this page -** * zero or more pages numbers of leaves -*/ -#include "sqliteInt.h" -#include "pager.h" -#include "btree.h" -#include "os.h" -#include - -/* Round up a number to the next larger multiple of 8. This is used -** to force 8-byte alignment on 64-bit architectures. -*/ -#define ROUND8(x) ((x+7)&~7) - - -/* The following value is the maximum cell size assuming a maximum page -** size give above. -*/ -#define MX_CELL_SIZE(pBt) (pBt->pageSize-8) - -/* The maximum number of cells on a single page of the database. This -** assumes a minimum cell size of 3 bytes. Such small cells will be -** exceedingly rare, but they are possible. -*/ -#define MX_CELL(pBt) ((pBt->pageSize-8)/3) - -/* Forward declarations */ -typedef struct MemPage MemPage; -typedef struct BtLock BtLock; - -/* -** This is a magic string that appears at the beginning of every -** SQLite database in order to identify the file as a real database. -** -** You can change this value at compile-time by specifying a -** -DSQLITE_FILE_HEADER="..." on the compiler command-line. The -** header must be exactly 16 bytes including the zero-terminator so -** the string itself should be 15 characters long. If you change -** the header, then your custom library will not be able to read -** databases generated by the standard tools and the standard tools -** will not be able to read databases created by your custom library. -*/ -#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */ -# define SQLITE_FILE_HEADER "SQLite format 3" -#endif - -/* -** Page type flags. An ORed combination of these flags appear as the -** first byte of on-disk image of every BTree page. -*/ -#define PTF_INTKEY 0x01 -#define PTF_ZERODATA 0x02 -#define PTF_LEAFDATA 0x04 -#define PTF_LEAF 0x08 - -/* -** As each page of the file is loaded into memory, an instance of the following -** structure is appended and initialized to zero. This structure stores -** information about the page that is decoded from the raw file page. -** -** The pParent field points back to the parent page. This allows us to -** walk up the BTree from any leaf to the root. Care must be taken to -** unref() the parent page pointer when this page is no longer referenced. -** The pageDestructor() routine handles that chore. -** -** Access to all fields of this structure is controlled by the mutex -** stored in MemPage.pBt->mutex. -*/ -struct MemPage { - u8 isInit; /* True if previously initialized. MUST BE FIRST! */ - u8 idxShift; /* True if Cell indices have changed */ - u8 nOverflow; /* Number of overflow cell bodies in aCell[] */ - u8 intKey; /* True if intkey flag is set */ - u8 leaf; /* True if leaf flag is set */ - u8 zeroData; /* True if table stores keys only */ - u8 leafData; /* True if tables stores data on leaves only */ - u8 hasData; /* True if this page stores data */ - u8 hdrOffset; /* 100 for page 1. 0 otherwise */ - u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */ - u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */ - u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ - u16 cellOffset; /* Index in aData of first cell pointer */ - u16 idxParent; /* Index in parent of this node */ - u16 nFree; /* Number of free bytes on the page */ - u16 nCell; /* Number of cells on this page, local and ovfl */ - struct _OvflCell { /* Cells that will not fit on aData[] */ - u8 *pCell; /* Pointers to the body of the overflow cell */ - u16 idx; /* Insert this cell before idx-th non-overflow cell */ - } aOvfl[5]; - BtShared *pBt; /* Pointer to BtShared that this page is part of */ - u8 *aData; /* Pointer to disk image of the page data */ - DbPage *pDbPage; /* Pager page handle */ - Pgno pgno; /* Page number for this page */ - MemPage *pParent; /* The parent of this page. NULL for root */ -}; - -/* -** The in-memory image of a disk page has the auxiliary information appended -** to the end. EXTRA_SIZE is the number of bytes of space needed to hold -** that extra information. -*/ -#define EXTRA_SIZE sizeof(MemPage) - -/* A Btree handle -** -** A database connection contains a pointer to an instance of -** this object for every database file that it has open. This structure -** is opaque to the database connection. The database connection cannot -** see the internals of this structure and only deals with pointers to -** this structure. -** -** For some database files, the same underlying database cache might be -** shared between multiple connections. In that case, each contection -** has it own pointer to this object. But each instance of this object -** points to the same BtShared object. The database cache and the -** schema associated with the database file are all contained within -** the BtShared object. -** -** All fields in this structure are accessed under sqlite3.mutex. -** The pBt pointer itself may not be changed while there exists cursors -** in the referenced BtShared that point back to this Btree since those -** cursors have to do go through this Btree to find their BtShared and -** they often do so without holding sqlite3.mutex. -*/ -struct Btree { - sqlite3 *pSqlite; /* The database connection holding this btree */ - BtShared *pBt; /* Sharable content of this btree */ - u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */ - u8 sharable; /* True if we can share pBt with other pSqlite */ - u8 locked; /* True if pSqlite currently has pBt locked */ - int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */ - Btree *pNext; /* List of other sharable Btrees from the same pSqlite */ - Btree *pPrev; /* Back pointer of the same list */ -}; - -/* -** Btree.inTrans may take one of the following values. -** -** If the shared-data extension is enabled, there may be multiple users -** of the Btree structure. At most one of these may open a write transaction, -** but any number may have active read transactions. -*/ -#define TRANS_NONE 0 -#define TRANS_READ 1 -#define TRANS_WRITE 2 - -/* -** An instance of this object represents a single database file. -** -** A single database file can be in use as the same time by two -** or more database connections. When two or more connections are -** sharing the same database file, each connection has it own -** private Btree object for the file and each of those Btrees points -** to this one BtShared object. BtShared.nRef is the number of -** connections currently sharing this database file. -** -** Fields in this structure are accessed under the BtShared.mutex -** mutex, except for nRef and pNext which are accessed under the -** global SQLITE_MUTEX_STATIC_MASTER mutex. The pPager field -** may not be modified once it is initially set as long as nRef>0. -** The pSchema field may be set once under BtShared.mutex and -** thereafter is unchanged as long as nRef>0. -*/ -struct BtShared { - Pager *pPager; /* The page cache */ - BtCursor *pCursor; /* A list of all open cursors */ - MemPage *pPage1; /* First page of the database */ - u8 inStmt; /* True if we are in a statement subtransaction */ - u8 readOnly; /* True if the underlying file is readonly */ - u8 maxEmbedFrac; /* Maximum payload as % of total page size */ - u8 minEmbedFrac; /* Minimum payload as % of total page size */ - u8 minLeafFrac; /* Minimum leaf payload as % of total page size */ - u8 pageSizeFixed; /* True if the page size can no longer be changed */ -#ifndef SQLITE_OMIT_AUTOVACUUM - u8 autoVacuum; /* True if auto-vacuum is enabled */ - u8 incrVacuum; /* True if incr-vacuum is enabled */ - Pgno nTrunc; /* Non-zero if the db will be truncated (incr vacuum) */ -#endif - u16 pageSize; /* Total number of bytes on a page */ - u16 usableSize; /* Number of usable bytes on each page */ - int maxLocal; /* Maximum local payload in non-LEAFDATA tables */ - int minLocal; /* Minimum local payload in non-LEAFDATA tables */ - int maxLeaf; /* Maximum local payload in a LEAFDATA table */ - int minLeaf; /* Minimum local payload in a LEAFDATA table */ - BusyHandler *pBusyHandler; /* Callback for when there is lock contention */ - u8 inTransaction; /* Transaction state */ - int nTransaction; /* Number of open transactions (read + write) */ - void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */ - void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */ - sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */ -#ifndef SQLITE_OMIT_SHARED_CACHE - int nRef; /* Number of references to this structure */ - BtShared *pNext; /* Next on a list of sharable BtShared structs */ - BtLock *pLock; /* List of locks held on this shared-btree struct */ -#endif -}; - -/* -** An instance of the following structure is used to hold information -** about a cell. The parseCellPtr() function fills in this structure -** based on information extract from the raw disk page. -*/ -typedef struct CellInfo CellInfo; -struct CellInfo { - u8 *pCell; /* Pointer to the start of cell content */ - i64 nKey; /* The key for INTKEY tables, or number of bytes in key */ - u32 nData; /* Number of bytes of data */ - u32 nPayload; /* Total amount of payload */ - u16 nHeader; /* Size of the cell content header in bytes */ - u16 nLocal; /* Amount of payload held locally */ - u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */ - u16 nSize; /* Size of the cell content on the main b-tree page */ -}; - -/* -** A cursor is a pointer to a particular entry within a particular -** b-tree within a database file. -** -** The entry is identified by its MemPage and the index in -** MemPage.aCell[] of the entry. -** -** When a single database file can shared by two more database connections, -** but cursors cannot be shared. Each cursor is associated with a -** particular database connection identified BtCursor.pBtree.pSqlite. -** -** Fields in this structure are accessed under the BtShared.mutex -** found at self->pBt->mutex. -*/ -struct BtCursor { - Btree *pBtree; /* The Btree to which this cursor belongs */ - BtShared *pBt; /* The BtShared this cursor points to */ - BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */ - int (*xCompare)(void*,int,const void*,int,const void*); /* Key comp func */ - void *pArg; /* First arg to xCompare() */ - Pgno pgnoRoot; /* The root page of this tree */ - MemPage *pPage; /* Page that contains the entry */ - int idx; /* Index of the entry in pPage->aCell[] */ - CellInfo info; /* A parse of the cell we are pointing at */ - u8 wrFlag; /* True if writable */ - u8 eState; /* One of the CURSOR_XXX constants (see below) */ - void *pKey; /* Saved key that was cursor's last known position */ - i64 nKey; /* Size of pKey, or last integer key */ - int skip; /* (skip<0) -> Prev() is a no-op. (skip>0) -> Next() is */ -#ifndef SQLITE_OMIT_INCRBLOB - u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ - Pgno *aOverflow; /* Cache of overflow page locations */ -#endif -}; - -/* -** Potential values for BtCursor.eState. -** -** CURSOR_VALID: -** Cursor points to a valid entry. getPayload() etc. may be called. -** -** CURSOR_INVALID: -** Cursor does not point to a valid entry. This can happen (for example) -** because the table is empty or because BtreeCursorFirst() has not been -** called. -** -** CURSOR_REQUIRESEEK: -** The table that this cursor was opened on still exists, but has been -** modified since the cursor was last used. The cursor position is saved -** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in -** this state, restoreOrClearCursorPosition() can be called to attempt to -** seek the cursor to the saved position. -** -** CURSOR_FAULT: -** A unrecoverable error (an I/O error or a malloc failure) has occurred -** on a different connection that shares the BtShared cache with this -** cursor. The error has left the cache in an inconsistent state. -** Do nothing else with this cursor. Any attempt to use the cursor -** should return the error code stored in BtCursor.skip -*/ -#define CURSOR_INVALID 0 -#define CURSOR_VALID 1 -#define CURSOR_REQUIRESEEK 2 -#define CURSOR_FAULT 3 - -/* -** The TRACE macro will print high-level status information about the -** btree operation when the global variable sqlite3_btree_trace is -** enabled. -*/ -#if SQLITE_TEST -# define TRACE(X) if( sqlite3_btree_trace ){ printf X; fflush(stdout); } -#else -# define TRACE(X) -#endif - -/* -** Routines to read and write variable-length integers. These used to -** be defined locally, but now we use the varint routines in the util.c -** file. -*/ -#define getVarint sqlite3GetVarint -#define getVarint32(A,B) ((*B=*(A))<=0x7f?1:sqlite3GetVarint32(A,B)) -#define putVarint sqlite3PutVarint - -/* The database page the PENDING_BYTE occupies. This page is never used. -** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They -** should possibly be consolidated (presumably in pager.h). -** -** If disk I/O is omitted (meaning that the database is stored purely -** in memory) then there is no pending byte. -*/ -#ifdef SQLITE_OMIT_DISKIO -# define PENDING_BYTE_PAGE(pBt) 0x7fffffff -#else -# define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1) -#endif - -/* -** A linked list of the following structures is stored at BtShared.pLock. -** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor -** is opened on the table with root page BtShared.iTable. Locks are removed -** from this list when a transaction is committed or rolled back, or when -** a btree handle is closed. -*/ -struct BtLock { - Btree *pBtree; /* Btree handle holding this lock */ - Pgno iTable; /* Root page of table */ - u8 eLock; /* READ_LOCK or WRITE_LOCK */ - BtLock *pNext; /* Next in BtShared.pLock list */ -}; - -/* Candidate values for BtLock.eLock */ -#define READ_LOCK 1 -#define WRITE_LOCK 2 - -/* -** These macros define the location of the pointer-map entry for a -** database page. The first argument to each is the number of usable -** bytes on each page of the database (often 1024). The second is the -** page number to look up in the pointer map. -** -** PTRMAP_PAGENO returns the database page number of the pointer-map -** page that stores the required pointer. PTRMAP_PTROFFSET returns -** the offset of the requested map entry. -** -** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page, -** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be -** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements -** this test. -*/ -#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno) -#define PTRMAP_PTROFFSET(pBt, pgno) (5*(pgno-ptrmapPageno(pBt, pgno)-1)) -#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno)) - -/* -** The pointer map is a lookup table that identifies the parent page for -** each child page in the database file. The parent page is the page that -** contains a pointer to the child. Every page in the database contains -** 0 or 1 parent pages. (In this context 'database page' refers -** to any page that is not part of the pointer map itself.) Each pointer map -** entry consists of a single byte 'type' and a 4 byte parent page number. -** The PTRMAP_XXX identifiers below are the valid types. -** -** The purpose of the pointer map is to facility moving pages from one -** position in the file to another as part of autovacuum. When a page -** is moved, the pointer in its parent must be updated to point to the -** new location. The pointer map is used to locate the parent page quickly. -** -** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not -** used in this case. -** -** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number -** is not used in this case. -** -** PTRMAP_OVERFLOW1: The database page is the first page in a list of -** overflow pages. The page number identifies the page that -** contains the cell with a pointer to this overflow page. -** -** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of -** overflow pages. The page-number identifies the previous -** page in the overflow page list. -** -** PTRMAP_BTREE: The database page is a non-root btree page. The page number -** identifies the parent page in the btree. -*/ -#define PTRMAP_ROOTPAGE 1 -#define PTRMAP_FREEPAGE 2 -#define PTRMAP_OVERFLOW1 3 -#define PTRMAP_OVERFLOW2 4 -#define PTRMAP_BTREE 5 - -/* A bunch of assert() statements to check the transaction state variables -** of handle p (type Btree*) are internally consistent. -*/ -#define btreeIntegrity(p) \ - assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \ - assert( p->pBt->inTransaction>=p->inTrans ); - - -/* -** The ISAUTOVACUUM macro is used within balance_nonroot() to determine -** if the database supports auto-vacuum or not. Because it is used -** within an expression that is an argument to another macro -** (sqliteMallocRaw), it is not possible to use conditional compilation. -** So, this macro is defined instead. -*/ -#ifndef SQLITE_OMIT_AUTOVACUUM -#define ISAUTOVACUUM (pBt->autoVacuum) -#else -#define ISAUTOVACUUM 0 -#endif - - -/* -** This structure is passed around through all the sanity checking routines -** in order to keep track of some global state information. -*/ -typedef struct IntegrityCk IntegrityCk; -struct IntegrityCk { - BtShared *pBt; /* The tree being checked out */ - Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ - int nPage; /* Number of pages in the database */ - int *anRef; /* Number of times each page is referenced */ - int mxErr; /* Stop accumulating errors when this reaches zero */ - char *zErrMsg; /* An error message. NULL if no errors seen. */ - int nErr; /* Number of messages written to zErrMsg so far */ -}; - -/* -** Read or write a two- and four-byte big-endian integer values. -*/ -#define get2byte(x) ((x)[0]<<8 | (x)[1]) -#define put2byte(p,v) ((p)[0] = (v)>>8, (p)[1] = (v)) -#define get4byte sqlite3Get4byte -#define put4byte sqlite3Put4byte - -/* -** Internal routines that should be accessed by the btree layer only. -*/ -int sqlite3BtreeGetPage(BtShared*, Pgno, MemPage**, int); -int sqlite3BtreeInitPage(MemPage *pPage, MemPage *pParent); -void sqlite3BtreeParseCellPtr(MemPage*, u8*, CellInfo*); -void sqlite3BtreeParseCell(MemPage*, int, CellInfo*); -#ifdef SQLITE_TEST -u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell); -#endif -int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur); -void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur); -void sqlite3BtreeReleaseTempCursor(BtCursor *pCur); -int sqlite3BtreeIsRootPage(MemPage *pPage); -void sqlite3BtreeMoveToParent(BtCursor *pCur); diff --git a/extensions/sqlite/sqlite-source/build.c b/extensions/sqlite/sqlite-source/build.c deleted file mode 100644 index 2323f2a4..00000000 --- a/extensions/sqlite/sqlite-source/build.c +++ /dev/null @@ -1,3409 +0,0 @@ -/* -** 2001 September 15 -** -** 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 file contains C code routines that are called by the SQLite parser -** when syntax rules are reduced. The routines in this file handle the -** following kinds of SQL syntax: -** -** CREATE TABLE -** DROP TABLE -** CREATE INDEX -** DROP INDEX -** creating ID lists -** BEGIN TRANSACTION -** COMMIT -** ROLLBACK -** -** $Id$ -*/ -#include "sqliteInt.h" -#include - -/* -** This routine is called when a new SQL statement is beginning to -** be parsed. Initialize the pParse structure as needed. -*/ -void sqlite3BeginParse(Parse *pParse, int explainFlag){ - pParse->explain = explainFlag; - pParse->nVar = 0; -} - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** The TableLock structure is only used by the sqlite3TableLock() and -** codeTableLocks() functions. -*/ -struct TableLock { - int iDb; /* The database containing the table to be locked */ - int iTab; /* The root page of the table to be locked */ - u8 isWriteLock; /* True for write lock. False for a read lock */ - const char *zName; /* Name of the table */ -}; - -/* -** Record the fact that we want to lock a table at run-time. -** -** The table to be locked has root page iTab and is found in database iDb. -** A read or a write lock can be taken depending on isWritelock. -** -** This routine just records the fact that the lock is desired. The -** code to make the lock occur is generated by a later call to -** codeTableLocks() which occurs during sqlite3FinishCoding(). -*/ -void sqlite3TableLock( - Parse *pParse, /* Parsing context */ - int iDb, /* Index of the database containing the table to lock */ - int iTab, /* Root page number of the table to be locked */ - u8 isWriteLock, /* True for a write lock */ - const char *zName /* Name of the table to be locked */ -){ - int i; - int nBytes; - TableLock *p; - - if( iDb<0 ){ - return; - } - - for(i=0; inTableLock; i++){ - p = &pParse->aTableLock[i]; - if( p->iDb==iDb && p->iTab==iTab ){ - p->isWriteLock = (p->isWriteLock || isWriteLock); - return; - } - } - - nBytes = sizeof(TableLock) * (pParse->nTableLock+1); - pParse->aTableLock = - sqlite3DbReallocOrFree(pParse->db, pParse->aTableLock, nBytes); - if( pParse->aTableLock ){ - p = &pParse->aTableLock[pParse->nTableLock++]; - p->iDb = iDb; - p->iTab = iTab; - p->isWriteLock = isWriteLock; - p->zName = zName; - }else{ - pParse->nTableLock = 0; - pParse->db->mallocFailed = 1; - } -} - -/* -** Code an OP_TableLock instruction for each table locked by the -** statement (configured by calls to sqlite3TableLock()). -*/ -static void codeTableLocks(Parse *pParse){ - int i; - Vdbe *pVdbe; - - if( 0==(pVdbe = sqlite3GetVdbe(pParse)) ){ - return; - } - - for(i=0; inTableLock; i++){ - TableLock *p = &pParse->aTableLock[i]; - int p1 = p->iDb; - if( p->isWriteLock ){ - p1 = -1*(p1+1); - } - sqlite3VdbeOp3(pVdbe, OP_TableLock, p1, p->iTab, p->zName, P3_STATIC); - } -} -#else - #define codeTableLocks(x) -#endif - -/* -** This routine is called after a single SQL statement has been -** parsed and a VDBE program to execute that statement has been -** prepared. This routine puts the finishing touches on the -** VDBE program and resets the pParse structure for the next -** parse. -** -** Note that if an error occurred, it might be the case that -** no VDBE code was generated. -*/ -void sqlite3FinishCoding(Parse *pParse){ - sqlite3 *db; - Vdbe *v; - - db = pParse->db; - if( db->mallocFailed ) return; - if( pParse->nested ) return; - if( !pParse->pVdbe ){ - if( pParse->rc==SQLITE_OK && pParse->nErr ){ - pParse->rc = SQLITE_ERROR; - return; - } - } - - /* Begin by generating some termination code at the end of the - ** vdbe program - */ - v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3VdbeAddOp(v, OP_Halt, 0, 0); - - /* The cookie mask contains one bit for each database file open. - ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are - ** set for each database that is used. Generate code to start a - ** transaction on each used database and to verify the schema cookie - ** on each used database. - */ - if( pParse->cookieGoto>0 ){ - u32 mask; - int iDb; - sqlite3VdbeJumpHere(v, pParse->cookieGoto-1); - for(iDb=0, mask=1; iDbnDb; mask<<=1, iDb++){ - if( (mask & pParse->cookieMask)==0 ) continue; - sqlite3VdbeUsesBtree(v, iDb); - sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0); - sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]); - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( pParse->pVirtualLock ){ - char *vtab = (char *)pParse->pVirtualLock->pVtab; - sqlite3VdbeOp3(v, OP_VBegin, 0, 0, vtab, P3_VTAB); - } -#endif - - /* Once all the cookies have been verified and transactions opened, - ** obtain the required table-locks. This is a no-op unless the - ** shared-cache feature is enabled. - */ - codeTableLocks(pParse); - sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto); - } - -#ifndef SQLITE_OMIT_TRACE - /* Add a No-op that contains the complete text of the compiled SQL - ** statement as its P3 argument. This does not change the functionality - ** of the program. - ** - ** This is used to implement sqlite3_trace(). - */ - sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql); -#endif /* SQLITE_OMIT_TRACE */ - } - - - /* Get the VDBE program ready for execution - */ - if( v && pParse->nErr==0 && !db->mallocFailed ){ -#ifdef SQLITE_DEBUG - FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; - sqlite3VdbeTrace(v, trace); -#endif - sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3, - pParse->nTab+3, pParse->explain); - pParse->rc = SQLITE_DONE; - pParse->colNamesSet = 0; - }else if( pParse->rc==SQLITE_OK ){ - pParse->rc = SQLITE_ERROR; - } - pParse->nTab = 0; - pParse->nMem = 0; - pParse->nSet = 0; - pParse->nVar = 0; - pParse->cookieMask = 0; - pParse->cookieGoto = 0; -} - -/* -** Run the parser and code generator recursively in order to generate -** code for the SQL statement given onto the end of the pParse context -** currently under construction. When the parser is run recursively -** this way, the final OP_Halt is not appended and other initialization -** and finalization steps are omitted because those are handling by the -** outermost parser. -** -** Not everything is nestable. This facility is designed to permit -** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use -** care if you decide to try to use this routine for some other purposes. -*/ -void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ - va_list ap; - char *zSql; -# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar)) - char saveBuf[SAVE_SZ]; - - if( pParse->nErr ) return; - assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ - va_start(ap, zFormat); - zSql = sqlite3VMPrintf(pParse->db, zFormat, ap); - va_end(ap); - if( zSql==0 ){ - pParse->db->mallocFailed = 1; - return; /* A malloc must have failed */ - } - pParse->nested++; - memcpy(saveBuf, &pParse->nVar, SAVE_SZ); - memset(&pParse->nVar, 0, SAVE_SZ); - sqlite3RunParser(pParse, zSql, 0); - sqlite3_free(zSql); - memcpy(&pParse->nVar, saveBuf, SAVE_SZ); - pParse->nested--; -} - -/* -** Locate the in-memory structure that describes a particular database -** table given the name of that table and (optionally) the name of the -** database containing the table. Return NULL if not found. -** -** If zDatabase is 0, all databases are searched for the table and the -** first matching table is returned. (No checking for duplicate table -** names is done.) The search order is TEMP first, then MAIN, then any -** auxiliary databases added using the ATTACH command. -** -** See also sqlite3LocateTable(). -*/ -Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ - Table *p = 0; - int i; - assert( zName!=0 ); - for(i=OMIT_TEMPDB; inDb; i++){ - int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue; - p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, strlen(zName)+1); - if( p ) break; - } - return p; -} - -/* -** Locate the in-memory structure that describes a particular database -** table given the name of that table and (optionally) the name of the -** database containing the table. Return NULL if not found. Also leave an -** error message in pParse->zErrMsg. -** -** The difference between this routine and sqlite3FindTable() is that this -** routine leaves an error message in pParse->zErrMsg where -** sqlite3FindTable() does not. -*/ -Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){ - Table *p; - - /* Read the database schema. If an error occurs, leave an error message - ** and code in pParse and return NULL. */ - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - return 0; - } - - p = sqlite3FindTable(pParse->db, zName, zDbase); - if( p==0 ){ - if( zDbase ){ - sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName); - }else{ - sqlite3ErrorMsg(pParse, "no such table: %s", zName); - } - pParse->checkSchema = 1; - } - return p; -} - -/* -** Locate the in-memory structure that describes -** a particular index given the name of that index -** and the name of the database that contains the index. -** Return NULL if not found. -** -** If zDatabase is 0, all databases are searched for the -** table and the first matching index is returned. (No checking -** for duplicate index names is done.) The search order is -** TEMP first, then MAIN, then any auxiliary databases added -** using the ATTACH command. -*/ -Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ - Index *p = 0; - int i; - for(i=OMIT_TEMPDB; inDb; i++){ - int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - Schema *pSchema = db->aDb[j].pSchema; - if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue; - assert( pSchema || (j==1 && !db->aDb[1].pBt) ); - if( pSchema ){ - p = sqlite3HashFind(&pSchema->idxHash, zName, strlen(zName)+1); - } - if( p ) break; - } - return p; -} - -/* -** Reclaim the memory used by an index -*/ -static void freeIndex(Index *p){ - sqlite3_free(p->zColAff); - sqlite3_free(p); -} - -/* -** Remove the given index from the index hash table, and free -** its memory structures. -** -** The index is removed from the database hash tables but -** it is not unlinked from the Table that it indexes. -** Unlinking from the Table must be done by the calling function. -*/ -static void sqliteDeleteIndex(Index *p){ - Index *pOld; - const char *zName = p->zName; - - pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName, strlen( zName)+1, 0); - assert( pOld==0 || pOld==p ); - freeIndex(p); -} - -/* -** For the index called zIdxName which is found in the database iDb, -** unlike that index from its Table then remove the index from -** the index hash table and free all memory structures associated -** with the index. -*/ -void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ - Index *pIndex; - int len; - Hash *pHash = &db->aDb[iDb].pSchema->idxHash; - - len = strlen(zIdxName); - pIndex = sqlite3HashInsert(pHash, zIdxName, len+1, 0); - if( pIndex ){ - if( pIndex->pTable->pIndex==pIndex ){ - pIndex->pTable->pIndex = pIndex->pNext; - }else{ - Index *p; - for(p=pIndex->pTable->pIndex; p && p->pNext!=pIndex; p=p->pNext){} - if( p && p->pNext==pIndex ){ - p->pNext = pIndex->pNext; - } - } - freeIndex(pIndex); - } - db->flags |= SQLITE_InternChanges; -} - -/* -** Erase all schema information from the in-memory hash tables of -** a single database. This routine is called to reclaim memory -** before the database closes. It is also called during a rollback -** if there were schema changes during the transaction or if a -** schema-cookie mismatch occurs. -** -** If iDb<=0 then reset the internal schema tables for all database -** files. If iDb>=2 then reset the internal schema for only the -** single file indicated. -*/ -void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ - int i, j; - - assert( iDb>=0 && iDbnDb ); - for(i=iDb; inDb; i++){ - Db *pDb = &db->aDb[i]; - if( pDb->pSchema ){ - sqlite3SchemaFree(pDb->pSchema); - } - if( iDb>0 ) return; - } - assert( iDb==0 ); - db->flags &= ~SQLITE_InternChanges; - - /* If one or more of the auxiliary database files has been closed, - ** then remove them from the auxiliary database list. We take the - ** opportunity to do this here since we have just deleted all of the - ** schema hash tables and therefore do not have to make any changes - ** to any of those tables. - */ - for(i=0; inDb; i++){ - struct Db *pDb = &db->aDb[i]; - if( pDb->pBt==0 ){ - if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux); - pDb->pAux = 0; - } - } - for(i=j=2; inDb; i++){ - struct Db *pDb = &db->aDb[i]; - if( pDb->pBt==0 ){ - sqlite3_free(pDb->zName); - pDb->zName = 0; - continue; - } - if( jaDb[j] = db->aDb[i]; - } - j++; - } - memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j])); - db->nDb = j; - if( db->nDb<=2 && db->aDb!=db->aDbStatic ){ - memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0])); - sqlite3_free(db->aDb); - db->aDb = db->aDbStatic; - } -} - -/* -** This routine is called when a commit occurs. -*/ -void sqlite3CommitInternalChanges(sqlite3 *db){ - db->flags &= ~SQLITE_InternChanges; -} - -/* -** Clear the column names from a table or view. -*/ -static void sqliteResetColumnNames(Table *pTable){ - int i; - Column *pCol; - assert( pTable!=0 ); - if( (pCol = pTable->aCol)!=0 ){ - for(i=0; inCol; i++, pCol++){ - sqlite3_free(pCol->zName); - sqlite3ExprDelete(pCol->pDflt); - sqlite3_free(pCol->zType); - sqlite3_free(pCol->zColl); - } - sqlite3_free(pTable->aCol); - } - pTable->aCol = 0; - pTable->nCol = 0; -} - -/* -** Remove the memory data structures associated with the given -** Table. No changes are made to disk by this routine. -** -** This routine just deletes the data structure. It does not unlink -** the table data structure from the hash table. Nor does it remove -** foreign keys from the sqlite.aFKey hash table. But it does destroy -** memory structures of the indices and foreign keys associated with -** the table. -*/ -void sqlite3DeleteTable(Table *pTable){ - Index *pIndex, *pNext; - FKey *pFKey, *pNextFKey; - - if( pTable==0 ) return; - - /* Do not delete the table until the reference count reaches zero. */ - pTable->nRef--; - if( pTable->nRef>0 ){ - return; - } - assert( pTable->nRef==0 ); - - /* Delete all indices associated with this table - */ - for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ - pNext = pIndex->pNext; - assert( pIndex->pSchema==pTable->pSchema ); - sqliteDeleteIndex(pIndex); - } - -#ifndef SQLITE_OMIT_FOREIGN_KEY - /* Delete all foreign keys associated with this table. The keys - ** should have already been unlinked from the pSchema->aFKey hash table - */ - for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){ - pNextFKey = pFKey->pNextFrom; - assert( sqlite3HashFind(&pTable->pSchema->aFKey, - pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey ); - sqlite3_free(pFKey); - } -#endif - - /* Delete the Table structure itself. - */ - sqliteResetColumnNames(pTable); - sqlite3_free(pTable->zName); - sqlite3_free(pTable->zColAff); - sqlite3SelectDelete(pTable->pSelect); -#ifndef SQLITE_OMIT_CHECK - sqlite3ExprDelete(pTable->pCheck); -#endif - sqlite3VtabClear(pTable); - sqlite3_free(pTable); -} - -/* -** Unlink the given table from the hash tables and the delete the -** table structure with all its indices and foreign keys. -*/ -void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ - Table *p; - FKey *pF1, *pF2; - Db *pDb; - - assert( db!=0 ); - assert( iDb>=0 && iDbnDb ); - assert( zTabName && zTabName[0] ); - pDb = &db->aDb[iDb]; - p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, strlen(zTabName)+1,0); - if( p ){ -#ifndef SQLITE_OMIT_FOREIGN_KEY - for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){ - int nTo = strlen(pF1->zTo) + 1; - pF2 = sqlite3HashFind(&pDb->pSchema->aFKey, pF1->zTo, nTo); - if( pF2==pF1 ){ - sqlite3HashInsert(&pDb->pSchema->aFKey, pF1->zTo, nTo, pF1->pNextTo); - }else{ - while( pF2 && pF2->pNextTo!=pF1 ){ pF2=pF2->pNextTo; } - if( pF2 ){ - pF2->pNextTo = pF1->pNextTo; - } - } - } -#endif - sqlite3DeleteTable(p); - } - db->flags |= SQLITE_InternChanges; -} - -/* -** Given a token, return a string that consists of the text of that -** token with any quotations removed. Space to hold the returned string -** is obtained from sqliteMalloc() and must be freed by the calling -** function. -** -** Tokens are often just pointers into the original SQL text and so -** are not \000 terminated and are not persistent. The returned string -** is \000 terminated and is persistent. -*/ -char *sqlite3NameFromToken(sqlite3 *db, Token *pName){ - char *zName; - if( pName ){ - zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n); - sqlite3Dequote(zName); - }else{ - zName = 0; - } - return zName; -} - -/* -** Open the sqlite_master table stored in database number iDb for -** writing. The table is opened using cursor 0. -*/ -void sqlite3OpenMasterTable(Parse *p, int iDb){ - Vdbe *v = sqlite3GetVdbe(p); - sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb)); - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenWrite, 0, MASTER_ROOT); - sqlite3VdbeAddOp(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */ -} - -/* -** The token *pName contains the name of a database (either "main" or -** "temp" or the name of an attached db). This routine returns the -** index of the named database in db->aDb[], or -1 if the named db -** does not exist. -*/ -int sqlite3FindDb(sqlite3 *db, Token *pName){ - int i = -1; /* Database number */ - int n; /* Number of characters in the name */ - Db *pDb; /* A database whose name space is being searched */ - char *zName; /* Name we are searching for */ - - zName = sqlite3NameFromToken(db, pName); - if( zName ){ - n = strlen(zName); - for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ - if( (!OMIT_TEMPDB || i!=1 ) && n==strlen(pDb->zName) && - 0==sqlite3StrICmp(pDb->zName, zName) ){ - break; - } - } - sqlite3_free(zName); - } - return i; -} - -/* The table or view or trigger name is passed to this routine via tokens -** pName1 and pName2. If the table name was fully qualified, for example: -** -** CREATE TABLE xxx.yyy (...); -** -** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if -** the table name is not fully qualified, i.e.: -** -** CREATE TABLE yyy(...); -** -** Then pName1 is set to "yyy" and pName2 is "". -** -** This routine sets the *ppUnqual pointer to point at the token (pName1 or -** pName2) that stores the unqualified table name. The index of the -** database "xxx" is returned. -*/ -int sqlite3TwoPartName( - Parse *pParse, /* Parsing and code generating context */ - Token *pName1, /* The "xxx" in the name "xxx.yyy" or "xxx" */ - Token *pName2, /* The "yyy" in the name "xxx.yyy" */ - Token **pUnqual /* Write the unqualified object name here */ -){ - int iDb; /* Database holding the object */ - sqlite3 *db = pParse->db; - - if( pName2 && pName2->n>0 ){ - assert( !db->init.busy ); - *pUnqual = pName2; - iDb = sqlite3FindDb(db, pName1); - if( iDb<0 ){ - sqlite3ErrorMsg(pParse, "unknown database %T", pName1); - pParse->nErr++; - return -1; - } - }else{ - assert( db->init.iDb==0 || db->init.busy ); - iDb = db->init.iDb; - *pUnqual = pName1; - } - return iDb; -} - -/* -** This routine is used to check if the UTF-8 string zName is a legal -** unqualified name for a new schema object (table, index, view or -** trigger). All names are legal except those that begin with the string -** "sqlite_" (in upper, lower or mixed case). This portion of the namespace -** is reserved for internal use. -*/ -int sqlite3CheckObjectName(Parse *pParse, const char *zName){ - if( !pParse->db->init.busy && pParse->nested==0 - && (pParse->db->flags & SQLITE_WriteSchema)==0 - && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ - sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); - return SQLITE_ERROR; - } - return SQLITE_OK; -} - -/* -** Begin constructing a new table representation in memory. This is -** the first of several action routines that get called in response -** to a CREATE TABLE statement. In particular, this routine is called -** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp -** flag is true if the table should be stored in the auxiliary database -** file instead of in the main database file. This is normally the case -** when the "TEMP" or "TEMPORARY" keyword occurs in between -** CREATE and TABLE. -** -** The new table record is initialized and put in pParse->pNewTable. -** As more of the CREATE TABLE statement is parsed, additional action -** routines will be called to add more information to this record. -** At the end of the CREATE TABLE statement, the sqlite3EndTable() routine -** is called to complete the construction of the new table record. -*/ -void sqlite3StartTable( - Parse *pParse, /* Parser context */ - Token *pName1, /* First part of the name of the table or view */ - Token *pName2, /* Second part of the name of the table or view */ - int isTemp, /* True if this is a TEMP table */ - int isView, /* True if this is a VIEW */ - int isVirtual, /* True if this is a VIRTUAL table */ - int noErr /* Do nothing if table already exists */ -){ - Table *pTable; - char *zName = 0; /* The name of the new table */ - sqlite3 *db = pParse->db; - Vdbe *v; - int iDb; /* Database number to create the table in */ - Token *pName; /* Unqualified name of the table to create */ - - /* The table or view name to create is passed to this routine via tokens - ** pName1 and pName2. If the table name was fully qualified, for example: - ** - ** CREATE TABLE xxx.yyy (...); - ** - ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if - ** the table name is not fully qualified, i.e.: - ** - ** CREATE TABLE yyy(...); - ** - ** Then pName1 is set to "yyy" and pName2 is "". - ** - ** The call below sets the pName pointer to point at the token (pName1 or - ** pName2) that stores the unqualified table name. The variable iDb is - ** set to the index of the database that the table or view is to be - ** created in. - */ - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); - if( iDb<0 ) return; - if( !OMIT_TEMPDB && isTemp && iDb>1 ){ - /* If creating a temp table, the name may not be qualified */ - sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); - return; - } - if( !OMIT_TEMPDB && isTemp ) iDb = 1; - - pParse->sNameToken = *pName; - zName = sqlite3NameFromToken(db, pName); - if( zName==0 ) return; - if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ - goto begin_table_error; - } - if( db->init.iDb==1 ) isTemp = 1; -#ifndef SQLITE_OMIT_AUTHORIZATION - assert( (isTemp & 1)==isTemp ); - { - int code; - char *zDb = db->aDb[iDb].zName; - if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ - goto begin_table_error; - } - if( isView ){ - if( !OMIT_TEMPDB && isTemp ){ - code = SQLITE_CREATE_TEMP_VIEW; - }else{ - code = SQLITE_CREATE_VIEW; - } - }else{ - if( !OMIT_TEMPDB && isTemp ){ - code = SQLITE_CREATE_TEMP_TABLE; - }else{ - code = SQLITE_CREATE_TABLE; - } - } - if( !isVirtual && sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){ - goto begin_table_error; - } - } -#endif - - /* Make sure the new table name does not collide with an existing - ** index or table name in the same database. Issue an error message if - ** it does. The exception is if the statement being parsed was passed - ** to an sqlite3_declare_vtab() call. In that case only the column names - ** and types will be used, so there is no need to test for namespace - ** collisions. - */ - if( !IN_DECLARE_VTAB ){ - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - goto begin_table_error; - } - pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName); - if( pTable ){ - if( !noErr ){ - sqlite3ErrorMsg(pParse, "table %T already exists", pName); - } - goto begin_table_error; - } - if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){ - sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); - goto begin_table_error; - } - } - - pTable = sqlite3DbMallocZero(db, sizeof(Table)); - if( pTable==0 ){ - db->mallocFailed = 1; - pParse->rc = SQLITE_NOMEM; - pParse->nErr++; - goto begin_table_error; - } - pTable->zName = zName; - pTable->iPKey = -1; - pTable->pSchema = db->aDb[iDb].pSchema; - pTable->nRef = 1; - if( pParse->pNewTable ) sqlite3DeleteTable(pParse->pNewTable); - pParse->pNewTable = pTable; - - /* If this is the magic sqlite_sequence table used by autoincrement, - ** then record a pointer to this table in the main database structure - ** so that INSERT can find the table easily. - */ -#ifndef SQLITE_OMIT_AUTOINCREMENT - if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){ - pTable->pSchema->pSeqTab = pTable; - } -#endif - - /* Begin generating the code that will insert the table record into - ** the SQLITE_MASTER table. Note in particular that we must go ahead - ** and allocate the record number for the table entry now. Before any - ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause - ** indices to be created and the table record must come before the - ** indices. Hence, the record number for the table must be allocated - ** now. - */ - if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){ - int lbl; - int fileFormat; - sqlite3BeginWriteOperation(pParse, 0, iDb); - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( isVirtual ){ - sqlite3VdbeAddOp(v, OP_VBegin, 0, 0); - } -#endif - - /* If the file format and encoding in the database have not been set, - ** set them now. - */ - sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); /* file_format */ - sqlite3VdbeUsesBtree(v, iDb); - lbl = sqlite3VdbeMakeLabel(v); - sqlite3VdbeAddOp(v, OP_If, 0, lbl); - fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? - 1 : SQLITE_MAX_FILE_FORMAT; - sqlite3VdbeAddOp(v, OP_Integer, fileFormat, 0); - sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1); - sqlite3VdbeAddOp(v, OP_Integer, ENC(db), 0); - sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4); - sqlite3VdbeResolveLabel(v, lbl); - - /* This just creates a place-holder record in the sqlite_master table. - ** The record created does not contain anything yet. It will be replaced - ** by the real entry in code generated at sqlite3EndTable(). - ** - ** The rowid for the new entry is left on the top of the stack. - ** The rowid value is needed by the code that sqlite3EndTable will - ** generate. - */ -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) - if( isView || isVirtual ){ - sqlite3VdbeAddOp(v, OP_Integer, 0, 0); - }else -#endif - { - sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0); - } - sqlite3OpenMasterTable(pParse, iDb); - sqlite3VdbeAddOp(v, OP_NewRowid, 0, 0); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3VdbeAddOp(v, OP_Null, 0, 0); - sqlite3VdbeAddOp(v, OP_Insert, 0, OPFLAG_APPEND); - sqlite3VdbeAddOp(v, OP_Close, 0, 0); - sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - } - - /* Normal (non-error) return. */ - return; - - /* If an error occurs, we jump here */ -begin_table_error: - sqlite3_free(zName); - return; -} - -/* -** This macro is used to compare two strings in a case-insensitive manner. -** It is slightly faster than calling sqlite3StrICmp() directly, but -** produces larger code. -** -** WARNING: This macro is not compatible with the strcmp() family. It -** returns true if the two strings are equal, otherwise false. -*/ -#define STRICMP(x, y) (\ -sqlite3UpperToLower[*(unsigned char *)(x)]== \ -sqlite3UpperToLower[*(unsigned char *)(y)] \ -&& sqlite3StrICmp((x)+1,(y)+1)==0 ) - -/* -** Add a new column to the table currently being constructed. -** -** The parser calls this routine once for each column declaration -** in a CREATE TABLE statement. sqlite3StartTable() gets called -** first to get things going. Then this routine is called for each -** column. -*/ -void sqlite3AddColumn(Parse *pParse, Token *pName){ - Table *p; - int i; - char *z; - Column *pCol; - if( (p = pParse->pNewTable)==0 ) return; - if( p->nCol+1>SQLITE_MAX_COLUMN ){ - sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); - return; - } - z = sqlite3NameFromToken(pParse->db, pName); - if( z==0 ) return; - for(i=0; inCol; i++){ - if( STRICMP(z, p->aCol[i].zName) ){ - sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); - sqlite3_free(z); - return; - } - } - if( (p->nCol & 0x7)==0 ){ - Column *aNew; - aNew = sqlite3DbRealloc(pParse->db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0])); - if( aNew==0 ){ - sqlite3_free(z); - return; - } - p->aCol = aNew; - } - pCol = &p->aCol[p->nCol]; - memset(pCol, 0, sizeof(p->aCol[0])); - pCol->zName = z; - - /* If there is no type specified, columns have the default affinity - ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will - ** be called next to set pCol->affinity correctly. - */ - pCol->affinity = SQLITE_AFF_NONE; - p->nCol++; -} - -/* -** This routine is called by the parser while in the middle of -** parsing a CREATE TABLE statement. A "NOT NULL" constraint has -** been seen on a column. This routine sets the notNull flag on -** the column currently under construction. -*/ -void sqlite3AddNotNull(Parse *pParse, int onError){ - Table *p; - int i; - if( (p = pParse->pNewTable)==0 ) return; - i = p->nCol-1; - if( i>=0 ) p->aCol[i].notNull = onError; -} - -/* -** Scan the column type name zType (length nType) and return the -** associated affinity type. -** -** This routine does a case-independent search of zType for the -** substrings in the following table. If one of the substrings is -** found, the corresponding affinity is returned. If zType contains -** more than one of the substrings, entries toward the top of -** the table take priority. For example, if zType is 'BLOBINT', -** SQLITE_AFF_INTEGER is returned. -** -** Substring | Affinity -** -------------------------------- -** 'INT' | SQLITE_AFF_INTEGER -** 'CHAR' | SQLITE_AFF_TEXT -** 'CLOB' | SQLITE_AFF_TEXT -** 'TEXT' | SQLITE_AFF_TEXT -** 'BLOB' | SQLITE_AFF_NONE -** 'REAL' | SQLITE_AFF_REAL -** 'FLOA' | SQLITE_AFF_REAL -** 'DOUB' | SQLITE_AFF_REAL -** -** If none of the substrings in the above table are found, -** SQLITE_AFF_NUMERIC is returned. -*/ -char sqlite3AffinityType(const Token *pType){ - u32 h = 0; - char aff = SQLITE_AFF_NUMERIC; - const unsigned char *zIn = pType->z; - const unsigned char *zEnd = &pType->z[pType->n]; - - while( zIn!=zEnd ){ - h = (h<<8) + sqlite3UpperToLower[*zIn]; - zIn++; - if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ - aff = SQLITE_AFF_TEXT; - }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */ - aff = SQLITE_AFF_TEXT; - }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */ - aff = SQLITE_AFF_TEXT; - }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */ - && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){ - aff = SQLITE_AFF_NONE; -#ifndef SQLITE_OMIT_FLOATING_POINT - }else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l') /* REAL */ - && aff==SQLITE_AFF_NUMERIC ){ - aff = SQLITE_AFF_REAL; - }else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a') /* FLOA */ - && aff==SQLITE_AFF_NUMERIC ){ - aff = SQLITE_AFF_REAL; - }else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b') /* DOUB */ - && aff==SQLITE_AFF_NUMERIC ){ - aff = SQLITE_AFF_REAL; -#endif - }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */ - aff = SQLITE_AFF_INTEGER; - break; - } - } - - return aff; -} - -/* -** This routine is called by the parser while in the middle of -** parsing a CREATE TABLE statement. The pFirst token is the first -** token in the sequence of tokens that describe the type of the -** column currently under construction. pLast is the last token -** in the sequence. Use this information to construct a string -** that contains the typename of the column and store that string -** in zType. -*/ -void sqlite3AddColumnType(Parse *pParse, Token *pType){ - Table *p; - int i; - Column *pCol; - - if( (p = pParse->pNewTable)==0 ) return; - i = p->nCol-1; - if( i<0 ) return; - pCol = &p->aCol[i]; - sqlite3_free(pCol->zType); - pCol->zType = sqlite3NameFromToken(pParse->db, pType); - pCol->affinity = sqlite3AffinityType(pType); -} - -/* -** The expression is the default value for the most recently added column -** of the table currently under construction. -** -** Default value expressions must be constant. Raise an exception if this -** is not the case. -** -** This routine is called by the parser while in the middle of -** parsing a CREATE TABLE statement. -*/ -void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){ - Table *p; - Column *pCol; - if( (p = pParse->pNewTable)!=0 ){ - pCol = &(p->aCol[p->nCol-1]); - if( !sqlite3ExprIsConstantOrFunction(pExpr) ){ - sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", - pCol->zName); - }else{ - Expr *pCopy; - sqlite3 *db = pParse->db; - sqlite3ExprDelete(pCol->pDflt); - pCol->pDflt = pCopy = sqlite3ExprDup(db, pExpr); - if( pCopy ){ - sqlite3TokenCopy(db, &pCopy->span, &pExpr->span); - } - } - } - sqlite3ExprDelete(pExpr); -} - -/* -** Designate the PRIMARY KEY for the table. pList is a list of names -** of columns that form the primary key. If pList is NULL, then the -** most recently added column of the table is the primary key. -** -** A table can have at most one primary key. If the table already has -** a primary key (and this is the second primary key) then create an -** error. -** -** If the PRIMARY KEY is on a single column whose datatype is INTEGER, -** then we will try to use that column as the rowid. Set the Table.iPKey -** field of the table under construction to be the index of the -** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is -** no INTEGER PRIMARY KEY. -** -** If the key is not an INTEGER PRIMARY KEY, then create a unique -** index for the key. No index is created for INTEGER PRIMARY KEYs. -*/ -void sqlite3AddPrimaryKey( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* List of field names to be indexed */ - int onError, /* What to do with a uniqueness conflict */ - int autoInc, /* True if the AUTOINCREMENT keyword is present */ - int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */ -){ - Table *pTab = pParse->pNewTable; - char *zType = 0; - int iCol = -1, i; - if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit; - if( pTab->hasPrimKey ){ - sqlite3ErrorMsg(pParse, - "table \"%s\" has more than one primary key", pTab->zName); - goto primary_key_exit; - } - pTab->hasPrimKey = 1; - if( pList==0 ){ - iCol = pTab->nCol - 1; - pTab->aCol[iCol].isPrimKey = 1; - }else{ - for(i=0; inExpr; i++){ - for(iCol=0; iColnCol; iCol++){ - if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){ - break; - } - } - if( iColnCol ){ - pTab->aCol[iCol].isPrimKey = 1; - } - } - if( pList->nExpr>1 ) iCol = -1; - } - if( iCol>=0 && iColnCol ){ - zType = pTab->aCol[iCol].zType; - } - if( zType && sqlite3StrICmp(zType, "INTEGER")==0 - && sortOrder==SQLITE_SO_ASC ){ - pTab->iPKey = iCol; - pTab->keyConf = onError; - pTab->autoInc = autoInc; - }else if( autoInc ){ -#ifndef SQLITE_OMIT_AUTOINCREMENT - sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " - "INTEGER PRIMARY KEY"); -#endif - }else{ - sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0); - pList = 0; - } - -primary_key_exit: - sqlite3ExprListDelete(pList); - return; -} - -/* -** Add a new CHECK constraint to the table currently under construction. -*/ -void sqlite3AddCheckConstraint( - Parse *pParse, /* Parsing context */ - Expr *pCheckExpr /* The check expression */ -){ -#ifndef SQLITE_OMIT_CHECK - Table *pTab = pParse->pNewTable; - sqlite3 *db = pParse->db; - if( pTab && !IN_DECLARE_VTAB ){ - /* The CHECK expression must be duplicated so that tokens refer - ** to malloced space and not the (ephemeral) text of the CREATE TABLE - ** statement */ - pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck, - sqlite3ExprDup(db, pCheckExpr)); - } -#endif - sqlite3ExprDelete(pCheckExpr); -} - -/* -** Set the collation function of the most recently parsed table column -** to the CollSeq given. -*/ -void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){ - Table *p; - int i; - - if( (p = pParse->pNewTable)==0 ) return; - i = p->nCol-1; - - if( sqlite3LocateCollSeq(pParse, zType, nType) ){ - Index *pIdx; - p->aCol[i].zColl = sqlite3DbStrNDup(pParse->db, zType, nType); - - /* If the column is declared as " PRIMARY KEY COLLATE ", - ** then an index may have been created on this column before the - ** collation type was added. Correct this if it is the case. - */ - for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ - assert( pIdx->nColumn==1 ); - if( pIdx->aiColumn[0]==i ){ - pIdx->azColl[0] = p->aCol[i].zColl; - } - } - } -} - -/* -** This function returns the collation sequence for database native text -** encoding identified by the string zName, length nName. -** -** If the requested collation sequence is not available, or not available -** in the database native encoding, the collation factory is invoked to -** request it. If the collation factory does not supply such a sequence, -** and the sequence is available in another text encoding, then that is -** returned instead. -** -** If no versions of the requested collations sequence are available, or -** another error occurs, NULL is returned and an error message written into -** pParse. -** -** This routine is a wrapper around sqlite3FindCollSeq(). This routine -** invokes the collation factory if the named collation cannot be found -** and generates an error message. -*/ -CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){ - sqlite3 *db = pParse->db; - u8 enc = ENC(db); - u8 initbusy = db->init.busy; - CollSeq *pColl; - - pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy); - if( !initbusy && (!pColl || !pColl->xCmp) ){ - pColl = sqlite3GetCollSeq(db, pColl, zName, nName); - if( !pColl ){ - if( nName<0 ){ - nName = strlen(zName); - } - sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName); - pColl = 0; - } - } - - return pColl; -} - - -/* -** Generate code that will increment the schema cookie. -** -** The schema cookie is used to determine when the schema for the -** database changes. After each schema change, the cookie value -** changes. When a process first reads the schema it records the -** cookie. Thereafter, whenever it goes to access the database, -** it checks the cookie to make sure the schema has not changed -** since it was last read. -** -** This plan is not completely bullet-proof. It is possible for -** the schema to change multiple times and for the cookie to be -** set back to prior value. But schema changes are infrequent -** and the probability of hitting the same cookie value is only -** 1 chance in 2^32. So we're safe enough. -*/ -void sqlite3ChangeCookie(sqlite3 *db, Vdbe *v, int iDb){ - sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, 0); - sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0); -} - -/* -** Measure the number of characters needed to output the given -** identifier. The number returned includes any quotes used -** but does not include the null terminator. -** -** The estimate is conservative. It might be larger that what is -** really needed. -*/ -static int identLength(const char *z){ - int n; - for(n=0; *z; n++, z++){ - if( *z=='"' ){ n++; } - } - return n + 2; -} - -/* -** Write an identifier onto the end of the given string. Add -** quote characters as needed. -*/ -static void identPut(char *z, int *pIdx, char *zSignedIdent){ - unsigned char *zIdent = (unsigned char*)zSignedIdent; - int i, j, needQuote; - i = *pIdx; - for(j=0; zIdent[j]; j++){ - if( !isalnum(zIdent[j]) && zIdent[j]!='_' ) break; - } - needQuote = zIdent[j]!=0 || isdigit(zIdent[0]) - || sqlite3KeywordCode(zIdent, j)!=TK_ID; - if( needQuote ) z[i++] = '"'; - for(j=0; zIdent[j]; j++){ - z[i++] = zIdent[j]; - if( zIdent[j]=='"' ) z[i++] = '"'; - } - if( needQuote ) z[i++] = '"'; - z[i] = 0; - *pIdx = i; -} - -/* -** Generate a CREATE TABLE statement appropriate for the given -** table. Memory to hold the text of the statement is obtained -** from sqliteMalloc() and must be freed by the calling function. -*/ -static char *createTableStmt(Table *p, int isTemp){ - int i, k, n; - char *zStmt; - char *zSep, *zSep2, *zEnd, *z; - Column *pCol; - n = 0; - for(pCol = p->aCol, i=0; inCol; i++, pCol++){ - n += identLength(pCol->zName); - z = pCol->zType; - if( z ){ - n += (strlen(z) + 1); - } - } - n += identLength(p->zName); - if( n<50 ){ - zSep = ""; - zSep2 = ","; - zEnd = ")"; - }else{ - zSep = "\n "; - zSep2 = ",\n "; - zEnd = "\n)"; - } - n += 35 + 6*p->nCol; - zStmt = sqlite3_malloc( n ); - if( zStmt==0 ) return 0; - sqlite3_snprintf(n, zStmt, - !OMIT_TEMPDB&&isTemp ? "CREATE TEMP TABLE ":"CREATE TABLE "); - k = strlen(zStmt); - identPut(zStmt, &k, p->zName); - zStmt[k++] = '('; - for(pCol=p->aCol, i=0; inCol; i++, pCol++){ - sqlite3_snprintf(n-k, &zStmt[k], zSep); - k += strlen(&zStmt[k]); - zSep = zSep2; - identPut(zStmt, &k, pCol->zName); - if( (z = pCol->zType)!=0 ){ - zStmt[k++] = ' '; - assert( strlen(z)+k+1<=n ); - sqlite3_snprintf(n-k, &zStmt[k], "%s", z); - k += strlen(z); - } - } - sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd); - return zStmt; -} - -/* -** This routine is called to report the final ")" that terminates -** a CREATE TABLE statement. -** -** The table structure that other action routines have been building -** is added to the internal hash tables, assuming no errors have -** occurred. -** -** An entry for the table is made in the master table on disk, unless -** this is a temporary table or db->init.busy==1. When db->init.busy==1 -** it means we are reading the sqlite_master table because we just -** connected to the database or because the sqlite_master table has -** recently changed, so the entry for this table already exists in -** the sqlite_master table. We do not want to create it again. -** -** If the pSelect argument is not NULL, it means that this routine -** was called to create a table generated from a -** "CREATE TABLE ... AS SELECT ..." statement. The column names of -** the new table will match the result set of the SELECT. -*/ -void sqlite3EndTable( - Parse *pParse, /* Parse context */ - Token *pCons, /* The ',' token after the last column defn. */ - Token *pEnd, /* The final ')' token in the CREATE TABLE */ - Select *pSelect /* Select from a "CREATE ... AS SELECT" */ -){ - Table *p; - sqlite3 *db = pParse->db; - int iDb; - - if( (pEnd==0 && pSelect==0) || pParse->nErr || db->mallocFailed ) { - return; - } - p = pParse->pNewTable; - if( p==0 ) return; - - assert( !db->init.busy || !pSelect ); - - iDb = sqlite3SchemaToIndex(db, p->pSchema); - -#ifndef SQLITE_OMIT_CHECK - /* Resolve names in all CHECK constraint expressions. - */ - if( p->pCheck ){ - SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ - NameContext sNC; /* Name context for pParse->pNewTable */ - - memset(&sNC, 0, sizeof(sNC)); - memset(&sSrc, 0, sizeof(sSrc)); - sSrc.nSrc = 1; - sSrc.a[0].zName = p->zName; - sSrc.a[0].pTab = p; - sSrc.a[0].iCursor = -1; - sNC.pParse = pParse; - sNC.pSrcList = &sSrc; - sNC.isCheck = 1; - if( sqlite3ExprResolveNames(&sNC, p->pCheck) ){ - return; - } - } -#endif /* !defined(SQLITE_OMIT_CHECK) */ - - /* If the db->init.busy is 1 it means we are reading the SQL off the - ** "sqlite_master" or "sqlite_temp_master" table on the disk. - ** So do not write to the disk again. Extract the root page number - ** for the table from the db->init.newTnum field. (The page number - ** should have been put there by the sqliteOpenCb routine.) - */ - if( db->init.busy ){ - p->tnum = db->init.newTnum; - } - - /* If not initializing, then create a record for the new table - ** in the SQLITE_MASTER table of the database. The record number - ** for the new table entry should already be on the stack. - ** - ** If this is a TEMPORARY table, write the entry into the auxiliary - ** file instead of into the main database file. - */ - if( !db->init.busy ){ - int n; - Vdbe *v; - char *zType; /* "view" or "table" */ - char *zType2; /* "VIEW" or "TABLE" */ - char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */ - - v = sqlite3GetVdbe(pParse); - if( v==0 ) return; - - sqlite3VdbeAddOp(v, OP_Close, 0, 0); - - /* Create the rootpage for the new table and push it onto the stack. - ** A view has no rootpage, so just push a zero onto the stack for - ** views. Initialize zType at the same time. - */ - if( p->pSelect==0 ){ - /* A regular table */ - zType = "table"; - zType2 = "TABLE"; -#ifndef SQLITE_OMIT_VIEW - }else{ - /* A view */ - zType = "view"; - zType2 = "VIEW"; -#endif - } - - /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT - ** statement to populate the new table. The root-page number for the - ** new table is on the top of the vdbe stack. - ** - ** Once the SELECT has been coded by sqlite3Select(), it is in a - ** suitable state to query for the column names and types to be used - ** by the new table. - ** - ** A shared-cache write-lock is not required to write to the new table, - ** as a schema-lock must have already been obtained to create it. Since - ** a schema-lock excludes all other database users, the write-lock would - ** be redundant. - */ - if( pSelect ){ - Table *pSelTab; - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenWrite, 1, 0); - pParse->nTab = 2; - sqlite3Select(pParse, pSelect, SRT_Table, 1, 0, 0, 0, 0); - sqlite3VdbeAddOp(v, OP_Close, 1, 0); - if( pParse->nErr==0 ){ - pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSelect); - if( pSelTab==0 ) return; - assert( p->aCol==0 ); - p->nCol = pSelTab->nCol; - p->aCol = pSelTab->aCol; - pSelTab->nCol = 0; - pSelTab->aCol = 0; - sqlite3DeleteTable(pSelTab); - } - } - - /* Compute the complete text of the CREATE statement */ - if( pSelect ){ - zStmt = createTableStmt(p, p->pSchema==db->aDb[1].pSchema); - }else{ - n = pEnd->z - pParse->sNameToken.z + 1; - zStmt = sqlite3MPrintf(db, - "CREATE %s %.*s", zType2, n, pParse->sNameToken.z - ); - } - - /* A slot for the record has already been allocated in the - ** SQLITE_MASTER table. We just need to update that slot with all - ** the information we've collected. The rowid for the preallocated - ** slot is the 2nd item on the stack. The top of the stack is the - ** root page for the new table (or a 0 if this is a view). - */ - sqlite3NestedParse(pParse, - "UPDATE %Q.%s " - "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#0, sql=%Q " - "WHERE rowid=#1", - db->aDb[iDb].zName, SCHEMA_TABLE(iDb), - zType, - p->zName, - p->zName, - zStmt - ); - sqlite3_free(zStmt); - sqlite3ChangeCookie(db, v, iDb); - -#ifndef SQLITE_OMIT_AUTOINCREMENT - /* Check to see if we need to create an sqlite_sequence table for - ** keeping track of autoincrement keys. - */ - if( p->autoInc ){ - Db *pDb = &db->aDb[iDb]; - if( pDb->pSchema->pSeqTab==0 ){ - sqlite3NestedParse(pParse, - "CREATE TABLE %Q.sqlite_sequence(name,seq)", - pDb->zName - ); - } - } -#endif - - /* Reparse everything to update our internal data structures */ - sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, - sqlite3MPrintf(db, "tbl_name='%q'",p->zName), P3_DYNAMIC); - } - - - /* Add the table to the in-memory representation of the database. - */ - if( db->init.busy && pParse->nErr==0 ){ - Table *pOld; - FKey *pFKey; - Schema *pSchema = p->pSchema; - pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, strlen(p->zName)+1,p); - if( pOld ){ - assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ - db->mallocFailed = 1; - return; - } -#ifndef SQLITE_OMIT_FOREIGN_KEY - for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){ - void *data; - int nTo = strlen(pFKey->zTo) + 1; - pFKey->pNextTo = sqlite3HashFind(&pSchema->aFKey, pFKey->zTo, nTo); - data = sqlite3HashInsert(&pSchema->aFKey, pFKey->zTo, nTo, pFKey); - if( data==(void *)pFKey ){ - db->mallocFailed = 1; - } - } -#endif - pParse->pNewTable = 0; - db->nTable++; - db->flags |= SQLITE_InternChanges; - -#ifndef SQLITE_OMIT_ALTERTABLE - if( !p->pSelect ){ - const char *zName = (const char *)pParse->sNameToken.z; - int nName; - assert( !pSelect && pCons && pEnd ); - if( pCons->z==0 ){ - pCons = pEnd; - } - nName = (const char *)pCons->z - zName; - p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName); - } -#endif - } -} - -#ifndef SQLITE_OMIT_VIEW -/* -** The parser calls this routine in order to create a new VIEW -*/ -void sqlite3CreateView( - Parse *pParse, /* The parsing context */ - Token *pBegin, /* The CREATE token that begins the statement */ - Token *pName1, /* The token that holds the name of the view */ - Token *pName2, /* The token that holds the name of the view */ - Select *pSelect, /* A SELECT statement that will become the new view */ - int isTemp, /* TRUE for a TEMPORARY view */ - int noErr /* Suppress error messages if VIEW already exists */ -){ - Table *p; - int n; - const unsigned char *z; - Token sEnd; - DbFixer sFix; - Token *pName; - int iDb; - sqlite3 *db = pParse->db; - - if( pParse->nVar>0 ){ - sqlite3ErrorMsg(pParse, "parameters are not allowed in views"); - sqlite3SelectDelete(pSelect); - return; - } - sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); - p = pParse->pNewTable; - if( p==0 || pParse->nErr ){ - sqlite3SelectDelete(pSelect); - return; - } - sqlite3TwoPartName(pParse, pName1, pName2, &pName); - iDb = sqlite3SchemaToIndex(db, p->pSchema); - if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName) - && sqlite3FixSelect(&sFix, pSelect) - ){ - sqlite3SelectDelete(pSelect); - return; - } - - /* Make a copy of the entire SELECT statement that defines the view. - ** This will force all the Expr.token.z values to be dynamically - ** allocated rather than point to the input string - which means that - ** they will persist after the current sqlite3_exec() call returns. - */ - p->pSelect = sqlite3SelectDup(db, pSelect); - sqlite3SelectDelete(pSelect); - if( db->mallocFailed ){ - return; - } - if( !db->init.busy ){ - sqlite3ViewGetColumnNames(pParse, p); - } - - /* Locate the end of the CREATE VIEW statement. Make sEnd point to - ** the end. - */ - sEnd = pParse->sLastToken; - if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){ - sEnd.z += sEnd.n; - } - sEnd.n = 0; - n = sEnd.z - pBegin->z; - z = (const unsigned char*)pBegin->z; - while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; } - sEnd.z = &z[n-1]; - sEnd.n = 1; - - /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */ - sqlite3EndTable(pParse, 0, &sEnd, 0); - return; -} -#endif /* SQLITE_OMIT_VIEW */ - -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) -/* -** The Table structure pTable is really a VIEW. Fill in the names of -** the columns of the view in the pTable structure. Return the number -** of errors. If an error is seen leave an error message in pParse->zErrMsg. -*/ -int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ - Table *pSelTab; /* A fake table from which we get the result set */ - Select *pSel; /* Copy of the SELECT that implements the view */ - int nErr = 0; /* Number of errors encountered */ - int n; /* Temporarily holds the number of cursors assigned */ - sqlite3 *db = pParse->db; /* Database connection for malloc errors */ - - assert( pTable ); - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( sqlite3VtabCallConnect(pParse, pTable) ){ - return SQLITE_ERROR; - } - if( IsVirtual(pTable) ) return 0; -#endif - -#ifndef SQLITE_OMIT_VIEW - /* A positive nCol means the columns names for this view are - ** already known. - */ - if( pTable->nCol>0 ) return 0; - - /* A negative nCol is a special marker meaning that we are currently - ** trying to compute the column names. If we enter this routine with - ** a negative nCol, it means two or more views form a loop, like this: - ** - ** CREATE VIEW one AS SELECT * FROM two; - ** CREATE VIEW two AS SELECT * FROM one; - ** - ** Actually, this error is caught previously and so the following test - ** should always fail. But we will leave it in place just to be safe. - */ - if( pTable->nCol<0 ){ - sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName); - return 1; - } - assert( pTable->nCol>=0 ); - - /* If we get this far, it means we need to compute the table names. - ** Note that the call to sqlite3ResultSetOfSelect() will expand any - ** "*" elements in the results set of the view and will assign cursors - ** to the elements of the FROM clause. But we do not want these changes - ** to be permanent. So the computation is done on a copy of the SELECT - ** statement that defines the view. - */ - assert( pTable->pSelect ); - pSel = sqlite3SelectDup(db, pTable->pSelect); - if( pSel ){ - n = pParse->nTab; - sqlite3SrcListAssignCursors(pParse, pSel->pSrc); - pTable->nCol = -1; - pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel); - pParse->nTab = n; - if( pSelTab ){ - assert( pTable->aCol==0 ); - pTable->nCol = pSelTab->nCol; - pTable->aCol = pSelTab->aCol; - pSelTab->nCol = 0; - pSelTab->aCol = 0; - sqlite3DeleteTable(pSelTab); - pTable->pSchema->flags |= DB_UnresetViews; - }else{ - pTable->nCol = 0; - nErr++; - } - sqlite3SelectDelete(pSel); - } else { - nErr++; - } -#endif /* SQLITE_OMIT_VIEW */ - return nErr; -} -#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ - -#ifndef SQLITE_OMIT_VIEW -/* -** Clear the column names from every VIEW in database idx. -*/ -static void sqliteViewResetAll(sqlite3 *db, int idx){ - HashElem *i; - if( !DbHasProperty(db, idx, DB_UnresetViews) ) return; - for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){ - Table *pTab = sqliteHashData(i); - if( pTab->pSelect ){ - sqliteResetColumnNames(pTab); - } - } - DbClearProperty(db, idx, DB_UnresetViews); -} -#else -# define sqliteViewResetAll(A,B) -#endif /* SQLITE_OMIT_VIEW */ - -/* -** This function is called by the VDBE to adjust the internal schema -** used by SQLite when the btree layer moves a table root page. The -** root-page of a table or index in database iDb has changed from iFrom -** to iTo. -** -** Ticket #1728: The symbol table might still contain information -** on tables and/or indices that are the process of being deleted. -** If you are unlucky, one of those deleted indices or tables might -** have the same rootpage number as the real table or index that is -** being moved. So we cannot stop searching after the first match -** because the first match might be for one of the deleted indices -** or tables and not the table/index that is actually being moved. -** We must continue looping until all tables and indices with -** rootpage==iFrom have been converted to have a rootpage of iTo -** in order to be certain that we got the right one. -*/ -#ifndef SQLITE_OMIT_AUTOVACUUM -void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){ - HashElem *pElem; - Hash *pHash; - - pHash = &pDb->pSchema->tblHash; - for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ - Table *pTab = sqliteHashData(pElem); - if( pTab->tnum==iFrom ){ - pTab->tnum = iTo; - } - } - pHash = &pDb->pSchema->idxHash; - for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ - Index *pIdx = sqliteHashData(pElem); - if( pIdx->tnum==iFrom ){ - pIdx->tnum = iTo; - } - } -} -#endif - -/* -** Write code to erase the table with root-page iTable from database iDb. -** Also write code to modify the sqlite_master table and internal schema -** if a root-page of another table is moved by the btree-layer whilst -** erasing iTable (this can happen with an auto-vacuum database). -*/ -static void destroyRootPage(Parse *pParse, int iTable, int iDb){ - Vdbe *v = sqlite3GetVdbe(pParse); - sqlite3VdbeAddOp(v, OP_Destroy, iTable, iDb); -#ifndef SQLITE_OMIT_AUTOVACUUM - /* OP_Destroy pushes an integer onto the stack. If this integer - ** is non-zero, then it is the root page number of a table moved to - ** location iTable. The following code modifies the sqlite_master table to - ** reflect this. - ** - ** The "#0" in the SQL is a special constant that means whatever value - ** is on the top of the stack. See sqlite3RegisterExpr(). - */ - sqlite3NestedParse(pParse, - "UPDATE %Q.%s SET rootpage=%d WHERE #0 AND rootpage=#0", - pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable); -#endif -} - -/* -** Write VDBE code to erase table pTab and all associated indices on disk. -** Code to update the sqlite_master tables and internal schema definitions -** in case a root-page belonging to another table is moved by the btree layer -** is also added (this can happen with an auto-vacuum database). -*/ -static void destroyTable(Parse *pParse, Table *pTab){ -#ifdef SQLITE_OMIT_AUTOVACUUM - Index *pIdx; - int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - destroyRootPage(pParse, pTab->tnum, iDb); - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - destroyRootPage(pParse, pIdx->tnum, iDb); - } -#else - /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM - ** is not defined), then it is important to call OP_Destroy on the - ** table and index root-pages in order, starting with the numerically - ** largest root-page number. This guarantees that none of the root-pages - ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the - ** following were coded: - ** - ** OP_Destroy 4 0 - ** ... - ** OP_Destroy 5 0 - ** - ** and root page 5 happened to be the largest root-page number in the - ** database, then root page 5 would be moved to page 4 by the - ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit - ** a free-list page. - */ - int iTab = pTab->tnum; - int iDestroyed = 0; - - while( 1 ){ - Index *pIdx; - int iLargest = 0; - - if( iDestroyed==0 || iTabpIndex; pIdx; pIdx=pIdx->pNext){ - int iIdx = pIdx->tnum; - assert( pIdx->pSchema==pTab->pSchema ); - if( (iDestroyed==0 || (iIdxiLargest ){ - iLargest = iIdx; - } - } - if( iLargest==0 ){ - return; - }else{ - int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - destroyRootPage(pParse, iLargest, iDb); - iDestroyed = iLargest; - } - } -#endif -} - -/* -** This routine is called to do the work of a DROP TABLE statement. -** pName is the name of the table to be dropped. -*/ -void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ - Table *pTab; - Vdbe *v; - sqlite3 *db = pParse->db; - int iDb; - - if( pParse->nErr || db->mallocFailed ){ - goto exit_drop_table; - } - assert( pName->nSrc==1 ); - pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase); - - if( pTab==0 ){ - if( noErr ){ - sqlite3ErrorClear(pParse); - } - goto exit_drop_table; - } - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDb>=0 && iDbnDb ); -#ifndef SQLITE_OMIT_AUTHORIZATION - { - int code; - const char *zTab = SCHEMA_TABLE(iDb); - const char *zDb = db->aDb[iDb].zName; - const char *zArg2 = 0; - if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){ - goto exit_drop_table; - } - if( isView ){ - if( !OMIT_TEMPDB && iDb==1 ){ - code = SQLITE_DROP_TEMP_VIEW; - }else{ - code = SQLITE_DROP_VIEW; - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - }else if( IsVirtual(pTab) ){ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto exit_drop_table; - } - code = SQLITE_DROP_VTABLE; - zArg2 = pTab->pMod->zName; -#endif - }else{ - if( !OMIT_TEMPDB && iDb==1 ){ - code = SQLITE_DROP_TEMP_TABLE; - }else{ - code = SQLITE_DROP_TABLE; - } - } - if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){ - goto exit_drop_table; - } - if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ - goto exit_drop_table; - } - } -#endif - if( pTab->readOnly || pTab==db->aDb[iDb].pSchema->pSeqTab ){ - sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); - goto exit_drop_table; - } - -#ifndef SQLITE_OMIT_VIEW - /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used - ** on a table. - */ - if( isView && pTab->pSelect==0 ){ - sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); - goto exit_drop_table; - } - if( !isView && pTab->pSelect ){ - sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); - goto exit_drop_table; - } -#endif - - /* Generate code to remove the table from the master table - ** on disk. - */ - v = sqlite3GetVdbe(pParse); - if( v ){ - Trigger *pTrigger; - Db *pDb = &db->aDb[iDb]; - sqlite3BeginWriteOperation(pParse, 0, iDb); - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - Vdbe *v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3VdbeAddOp(v, OP_VBegin, 0, 0); - } - } -#endif - - /* Drop all triggers associated with the table being dropped. Code - ** is generated to remove entries from sqlite_master and/or - ** sqlite_temp_master if required. - */ - pTrigger = pTab->pTrigger; - while( pTrigger ){ - assert( pTrigger->pSchema==pTab->pSchema || - pTrigger->pSchema==db->aDb[1].pSchema ); - sqlite3DropTriggerPtr(pParse, pTrigger); - pTrigger = pTrigger->pNext; - } - -#ifndef SQLITE_OMIT_AUTOINCREMENT - /* Remove any entries of the sqlite_sequence table associated with - ** the table being dropped. This is done before the table is dropped - ** at the btree level, in case the sqlite_sequence table needs to - ** move as a result of the drop (can happen in auto-vacuum mode). - */ - if( pTab->autoInc ){ - sqlite3NestedParse(pParse, - "DELETE FROM %s.sqlite_sequence WHERE name=%Q", - pDb->zName, pTab->zName - ); - } -#endif - - /* Drop all SQLITE_MASTER table and index entries that refer to the - ** table. The program name loops through the master table and deletes - ** every row that refers to a table of the same name as the one being - ** dropped. Triggers are handled seperately because a trigger can be - ** created in the temp database that refers to a table in another - ** database. - */ - sqlite3NestedParse(pParse, - "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", - pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); - if( !isView && !IsVirtual(pTab) ){ - destroyTable(pParse, pTab); - } - - /* Remove the table entry from SQLite's internal schema and modify - ** the schema cookie. - */ - if( IsVirtual(pTab) ){ - sqlite3VdbeOp3(v, OP_VDestroy, iDb, 0, pTab->zName, 0); - } - sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0); - sqlite3ChangeCookie(db, v, iDb); - } - sqliteViewResetAll(db, iDb); - -exit_drop_table: - sqlite3SrcListDelete(pName); -} - -/* -** This routine is called to create a new foreign key on the table -** currently under construction. pFromCol determines which columns -** in the current table point to the foreign key. If pFromCol==0 then -** connect the key to the last column inserted. pTo is the name of -** the table referred to. pToCol is a list of tables in the other -** pTo table that the foreign key points to. flags contains all -** information about the conflict resolution algorithms specified -** in the ON DELETE, ON UPDATE and ON INSERT clauses. -** -** An FKey structure is created and added to the table currently -** under construction in the pParse->pNewTable field. The new FKey -** is not linked into db->aFKey at this point - that does not happen -** until sqlite3EndTable(). -** -** The foreign key is set for IMMEDIATE processing. A subsequent call -** to sqlite3DeferForeignKey() might change this to DEFERRED. -*/ -void sqlite3CreateForeignKey( - Parse *pParse, /* Parsing context */ - ExprList *pFromCol, /* Columns in this table that point to other table */ - Token *pTo, /* Name of the other table */ - ExprList *pToCol, /* Columns in the other table */ - int flags /* Conflict resolution algorithms. */ -){ -#ifndef SQLITE_OMIT_FOREIGN_KEY - FKey *pFKey = 0; - Table *p = pParse->pNewTable; - int nByte; - int i; - int nCol; - char *z; - - assert( pTo!=0 ); - if( p==0 || pParse->nErr || IN_DECLARE_VTAB ) goto fk_end; - if( pFromCol==0 ){ - int iCol = p->nCol-1; - if( iCol<0 ) goto fk_end; - if( pToCol && pToCol->nExpr!=1 ){ - sqlite3ErrorMsg(pParse, "foreign key on %s" - " should reference only one column of table %T", - p->aCol[iCol].zName, pTo); - goto fk_end; - } - nCol = 1; - }else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){ - sqlite3ErrorMsg(pParse, - "number of columns in foreign key does not match the number of " - "columns in the referenced table"); - goto fk_end; - }else{ - nCol = pFromCol->nExpr; - } - nByte = sizeof(*pFKey) + nCol*sizeof(pFKey->aCol[0]) + pTo->n + 1; - if( pToCol ){ - for(i=0; inExpr; i++){ - nByte += strlen(pToCol->a[i].zName) + 1; - } - } - pFKey = sqlite3DbMallocZero(pParse->db, nByte ); - if( pFKey==0 ){ - goto fk_end; - } - pFKey->pFrom = p; - pFKey->pNextFrom = p->pFKey; - z = (char*)&pFKey[1]; - pFKey->aCol = (struct sColMap*)z; - z += sizeof(struct sColMap)*nCol; - pFKey->zTo = z; - memcpy(z, pTo->z, pTo->n); - z[pTo->n] = 0; - z += pTo->n+1; - pFKey->pNextTo = 0; - pFKey->nCol = nCol; - if( pFromCol==0 ){ - pFKey->aCol[0].iFrom = p->nCol-1; - }else{ - for(i=0; inCol; j++){ - if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){ - pFKey->aCol[i].iFrom = j; - break; - } - } - if( j>=p->nCol ){ - sqlite3ErrorMsg(pParse, - "unknown column \"%s\" in foreign key definition", - pFromCol->a[i].zName); - goto fk_end; - } - } - } - if( pToCol ){ - for(i=0; ia[i].zName); - pFKey->aCol[i].zCol = z; - memcpy(z, pToCol->a[i].zName, n); - z[n] = 0; - z += n+1; - } - } - pFKey->isDeferred = 0; - pFKey->deleteConf = flags & 0xff; - pFKey->updateConf = (flags >> 8 ) & 0xff; - pFKey->insertConf = (flags >> 16 ) & 0xff; - - /* Link the foreign key to the table as the last step. - */ - p->pFKey = pFKey; - pFKey = 0; - -fk_end: - sqlite3_free(pFKey); -#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ - sqlite3ExprListDelete(pFromCol); - sqlite3ExprListDelete(pToCol); -} - -/* -** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED -** clause is seen as part of a foreign key definition. The isDeferred -** parameter is 1 for INITIALLY DEFERRED and 0 for INITIALLY IMMEDIATE. -** The behavior of the most recently created foreign key is adjusted -** accordingly. -*/ -void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ -#ifndef SQLITE_OMIT_FOREIGN_KEY - Table *pTab; - FKey *pFKey; - if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return; - pFKey->isDeferred = isDeferred; -#endif -} - -/* -** Generate code that will erase and refill index *pIdx. This is -** used to initialize a newly created index or to recompute the -** content of an index in response to a REINDEX command. -** -** if memRootPage is not negative, it means that the index is newly -** created. The memory cell specified by memRootPage contains the -** root page number of the index. If memRootPage is negative, then -** the index already exists and must be cleared before being refilled and -** the root page number of the index is taken from pIndex->tnum. -*/ -static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ - Table *pTab = pIndex->pTable; /* The table that is indexed */ - int iTab = pParse->nTab; /* Btree cursor used for pTab */ - int iIdx = pParse->nTab+1; /* Btree cursor used for pIndex */ - int addr1; /* Address of top of loop */ - int tnum; /* Root page of index */ - Vdbe *v; /* Generate code into this virtual machine */ - KeyInfo *pKey; /* KeyInfo for index */ - sqlite3 *db = pParse->db; /* The database connection */ - int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); - -#ifndef SQLITE_OMIT_AUTHORIZATION - if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, - db->aDb[iDb].zName ) ){ - return; - } -#endif - - /* Require a write-lock on the table to perform this operation */ - sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); - - v = sqlite3GetVdbe(pParse); - if( v==0 ) return; - if( memRootPage>=0 ){ - sqlite3VdbeAddOp(v, OP_MemLoad, memRootPage, 0); - tnum = 0; - }else{ - tnum = pIndex->tnum; - sqlite3VdbeAddOp(v, OP_Clear, tnum, iDb); - } - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); - pKey = sqlite3IndexKeyinfo(pParse, pIndex); - sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum, (char *)pKey, P3_KEYINFO_HANDOFF); - sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); - addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0); - sqlite3GenerateIndexKey(v, pIndex, iTab); - if( pIndex->onError!=OE_None ){ - int curaddr = sqlite3VdbeCurrentAddr(v); - int addr2 = curaddr+4; - sqlite3VdbeChangeP2(v, curaddr-1, addr2); - sqlite3VdbeAddOp(v, OP_Rowid, iTab, 0); - sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); - sqlite3VdbeAddOp(v, OP_IsUnique, iIdx, addr2); - sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort, - "indexed columns are not unique", P3_STATIC); - assert( db->mallocFailed || addr2==sqlite3VdbeCurrentAddr(v) ); - } - sqlite3VdbeAddOp(v, OP_IdxInsert, iIdx, 0); - sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1); - sqlite3VdbeJumpHere(v, addr1); - sqlite3VdbeAddOp(v, OP_Close, iTab, 0); - sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); -} - -/* -** Create a new index for an SQL table. pName1.pName2 is the name of the index -** and pTblList is the name of the table that is to be indexed. Both will -** be NULL for a primary key or an index that is created to satisfy a -** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable -** as the table to be indexed. pParse->pNewTable is a table that is -** currently being constructed by a CREATE TABLE statement. -** -** pList is a list of columns to be indexed. pList will be NULL if this -** is a primary key or unique-constraint on the most recent column added -** to the table currently under construction. -*/ -void sqlite3CreateIndex( - Parse *pParse, /* All information about this parse */ - Token *pName1, /* First part of index name. May be NULL */ - Token *pName2, /* Second part of index name. May be NULL */ - SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ - ExprList *pList, /* A list of columns to be indexed */ - int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ - Token *pStart, /* The CREATE token that begins this statement */ - Token *pEnd, /* The ")" that closes the CREATE INDEX statement */ - int sortOrder, /* Sort order of primary key when pList==NULL */ - int ifNotExist /* Omit error if index already exists */ -){ - Table *pTab = 0; /* Table to be indexed */ - Index *pIndex = 0; /* The index to be created */ - char *zName = 0; /* Name of the index */ - int nName; /* Number of characters in zName */ - int i, j; - Token nullId; /* Fake token for an empty ID list */ - DbFixer sFix; /* For assigning database names to pTable */ - int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */ - sqlite3 *db = pParse->db; - Db *pDb; /* The specific table containing the indexed database */ - int iDb; /* Index of the database that is being written */ - Token *pName = 0; /* Unqualified name of the index to create */ - struct ExprList_item *pListItem; /* For looping over pList */ - int nCol; - int nExtra = 0; - char *zExtra; - - if( pParse->nErr || db->mallocFailed || IN_DECLARE_VTAB ){ - goto exit_create_index; - } - - /* - ** Find the table that is to be indexed. Return early if not found. - */ - if( pTblName!=0 ){ - - /* Use the two-part index name to determine the database - ** to search for the table. 'Fix' the table name to this db - ** before looking up the table. - */ - assert( pName1 && pName2 ); - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); - if( iDb<0 ) goto exit_create_index; - -#ifndef SQLITE_OMIT_TEMPDB - /* If the index name was unqualified, check if the the table - ** is a temp table. If so, set the database to 1. - */ - pTab = sqlite3SrcListLookup(pParse, pTblName); - if( pName2 && pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ - iDb = 1; - } -#endif - - if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) && - sqlite3FixSrcList(&sFix, pTblName) - ){ - /* Because the parser constructs pTblName from a single identifier, - ** sqlite3FixSrcList can never fail. */ - assert(0); - } - pTab = sqlite3LocateTable(pParse, pTblName->a[0].zName, - pTblName->a[0].zDatabase); - if( !pTab ) goto exit_create_index; - assert( db->aDb[iDb].pSchema==pTab->pSchema ); - }else{ - assert( pName==0 ); - pTab = pParse->pNewTable; - if( !pTab ) goto exit_create_index; - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - } - pDb = &db->aDb[iDb]; - - if( pTab==0 || pParse->nErr ) goto exit_create_index; - if( pTab->readOnly ){ - sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); - goto exit_create_index; - } -#ifndef SQLITE_OMIT_VIEW - if( pTab->pSelect ){ - sqlite3ErrorMsg(pParse, "views may not be indexed"); - goto exit_create_index; - } -#endif -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - sqlite3ErrorMsg(pParse, "virtual tables may not be indexed"); - goto exit_create_index; - } -#endif - - /* - ** Find the name of the index. Make sure there is not already another - ** index or table with the same name. - ** - ** Exception: If we are reading the names of permanent indices from the - ** sqlite_master table (because some other process changed the schema) and - ** one of the index names collides with the name of a temporary table or - ** index, then we will continue to process this index. - ** - ** If pName==0 it means that we are - ** dealing with a primary key or UNIQUE constraint. We have to invent our - ** own name. - */ - if( pName ){ - zName = sqlite3NameFromToken(db, pName); - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index; - if( zName==0 ) goto exit_create_index; - if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ - goto exit_create_index; - } - if( !db->init.busy ){ - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index; - if( sqlite3FindTable(db, zName, 0)!=0 ){ - sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); - goto exit_create_index; - } - } - if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){ - if( !ifNotExist ){ - sqlite3ErrorMsg(pParse, "index %s already exists", zName); - } - goto exit_create_index; - } - }else{ - char zBuf[30]; - int n; - Index *pLoop; - for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){} - sqlite3_snprintf(sizeof(zBuf),zBuf,"_%d",n); - zName = 0; - sqlite3SetString(&zName, "sqlite_autoindex_", pTab->zName, zBuf, (char*)0); - if( zName==0 ){ - db->mallocFailed = 1; - goto exit_create_index; - } - } - - /* Check for authorization to create an index. - */ -#ifndef SQLITE_OMIT_AUTHORIZATION - { - const char *zDb = pDb->zName; - if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){ - goto exit_create_index; - } - i = SQLITE_CREATE_INDEX; - if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX; - if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){ - goto exit_create_index; - } - } -#endif - - /* If pList==0, it means this routine was called to make a primary - ** key out of the last column added to the table under construction. - ** So create a fake list to simulate this. - */ - if( pList==0 ){ - nullId.z = (u8*)pTab->aCol[pTab->nCol-1].zName; - nullId.n = strlen((char*)nullId.z); - pList = sqlite3ExprListAppend(pParse, 0, 0, &nullId); - if( pList==0 ) goto exit_create_index; - pList->a[0].sortOrder = sortOrder; - } - - /* Figure out how many bytes of space are required to store explicitly - ** specified collation sequence names. - */ - for(i=0; inExpr; i++){ - Expr *pExpr = pList->a[i].pExpr; - if( pExpr ){ - nExtra += (1 + strlen(pExpr->pColl->zName)); - } - } - - /* - ** Allocate the index structure. - */ - nName = strlen(zName); - nCol = pList->nExpr; - pIndex = sqlite3DbMallocZero(db, - sizeof(Index) + /* Index structure */ - sizeof(int)*nCol + /* Index.aiColumn */ - sizeof(int)*(nCol+1) + /* Index.aiRowEst */ - sizeof(char *)*nCol + /* Index.azColl */ - sizeof(u8)*nCol + /* Index.aSortOrder */ - nName + 1 + /* Index.zName */ - nExtra /* Collation sequence names */ - ); - if( db->mallocFailed ){ - goto exit_create_index; - } - pIndex->azColl = (char**)(&pIndex[1]); - pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]); - pIndex->aiRowEst = (unsigned *)(&pIndex->aiColumn[nCol]); - pIndex->aSortOrder = (u8 *)(&pIndex->aiRowEst[nCol+1]); - pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]); - zExtra = (char *)(&pIndex->zName[nName+1]); - memcpy(pIndex->zName, zName, nName+1); - pIndex->pTable = pTab; - pIndex->nColumn = pList->nExpr; - pIndex->onError = onError; - pIndex->autoIndex = pName==0; - pIndex->pSchema = db->aDb[iDb].pSchema; - - /* Check to see if we should honor DESC requests on index columns - */ - if( pDb->pSchema->file_format>=4 ){ - sortOrderMask = -1; /* Honor DESC */ - }else{ - sortOrderMask = 0; /* Ignore DESC */ - } - - /* Scan the names of the columns of the table to be indexed and - ** load the column indices into the Index structure. Report an error - ** if any column is not found. - */ - for(i=0, pListItem=pList->a; inExpr; i++, pListItem++){ - const char *zColName = pListItem->zName; - Column *pTabCol; - int requestedSortOrder; - char *zColl; /* Collation sequence name */ - - for(j=0, pTabCol=pTab->aCol; jnCol; j++, pTabCol++){ - if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; - } - if( j>=pTab->nCol ){ - sqlite3ErrorMsg(pParse, "table %s has no column named %s", - pTab->zName, zColName); - goto exit_create_index; - } - /* TODO: Add a test to make sure that the same column is not named - ** more than once within the same index. Only the first instance of - ** the column will ever be used by the optimizer. Note that using the - ** same column more than once cannot be an error because that would - ** break backwards compatibility - it needs to be a warning. - */ - pIndex->aiColumn[i] = j; - if( pListItem->pExpr ){ - assert( pListItem->pExpr->pColl ); - zColl = zExtra; - sqlite3_snprintf(nExtra, zExtra, "%s", pListItem->pExpr->pColl->zName); - zExtra += (strlen(zColl) + 1); - }else{ - zColl = pTab->aCol[j].zColl; - if( !zColl ){ - zColl = db->pDfltColl->zName; - } - } - if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl, -1) ){ - goto exit_create_index; - } - pIndex->azColl[i] = zColl; - requestedSortOrder = pListItem->sortOrder & sortOrderMask; - pIndex->aSortOrder[i] = requestedSortOrder; - } - sqlite3DefaultRowEst(pIndex); - - if( pTab==pParse->pNewTable ){ - /* This routine has been called to create an automatic index as a - ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or - ** a PRIMARY KEY or UNIQUE clause following the column definitions. - ** i.e. one of: - ** - ** CREATE TABLE t(x PRIMARY KEY, y); - ** CREATE TABLE t(x, y, UNIQUE(x, y)); - ** - ** Either way, check to see if the table already has such an index. If - ** so, don't bother creating this one. This only applies to - ** automatically created indices. Users can do as they wish with - ** explicit indices. - */ - Index *pIdx; - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - int k; - assert( pIdx->onError!=OE_None ); - assert( pIdx->autoIndex ); - assert( pIndex->onError!=OE_None ); - - if( pIdx->nColumn!=pIndex->nColumn ) continue; - for(k=0; knColumn; k++){ - const char *z1 = pIdx->azColl[k]; - const char *z2 = pIndex->azColl[k]; - if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break; - if( pIdx->aSortOrder[k]!=pIndex->aSortOrder[k] ) break; - if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break; - } - if( k==pIdx->nColumn ){ - if( pIdx->onError!=pIndex->onError ){ - /* This constraint creates the same index as a previous - ** constraint specified somewhere in the CREATE TABLE statement. - ** However the ON CONFLICT clauses are different. If both this - ** constraint and the previous equivalent constraint have explicit - ** ON CONFLICT clauses this is an error. Otherwise, use the - ** explicitly specified behaviour for the index. - */ - if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){ - sqlite3ErrorMsg(pParse, - "conflicting ON CONFLICT clauses specified", 0); - } - if( pIdx->onError==OE_Default ){ - pIdx->onError = pIndex->onError; - } - } - goto exit_create_index; - } - } - } - - /* Link the new Index structure to its table and to the other - ** in-memory database structures. - */ - if( db->init.busy ){ - Index *p; - p = sqlite3HashInsert(&pIndex->pSchema->idxHash, - pIndex->zName, strlen(pIndex->zName)+1, pIndex); - if( p ){ - assert( p==pIndex ); /* Malloc must have failed */ - db->mallocFailed = 1; - goto exit_create_index; - } - db->flags |= SQLITE_InternChanges; - if( pTblName!=0 ){ - pIndex->tnum = db->init.newTnum; - } - } - - /* If the db->init.busy is 0 then create the index on disk. This - ** involves writing the index into the master table and filling in the - ** index with the current table contents. - ** - ** The db->init.busy is 0 when the user first enters a CREATE INDEX - ** command. db->init.busy is 1 when a database is opened and - ** CREATE INDEX statements are read out of the master table. In - ** the latter case the index already exists on disk, which is why - ** we don't want to recreate it. - ** - ** If pTblName==0 it means this index is generated as a primary key - ** or UNIQUE constraint of a CREATE TABLE statement. Since the table - ** has just been created, it contains no data and the index initialization - ** step can be skipped. - */ - else if( db->init.busy==0 ){ - Vdbe *v; - char *zStmt; - int iMem = pParse->nMem++; - - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto exit_create_index; - - - /* Create the rootpage for the index - */ - sqlite3BeginWriteOperation(pParse, 1, iDb); - sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0); - sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0); - - /* Gather the complete text of the CREATE INDEX statement into - ** the zStmt variable - */ - if( pStart && pEnd ){ - /* A named index with an explicit CREATE INDEX statement */ - zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", - onError==OE_None ? "" : " UNIQUE", - pEnd->z - pName->z + 1, - pName->z); - }else{ - /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ - /* zStmt = sqlite3MPrintf(""); */ - zStmt = 0; - } - - /* Add an entry in sqlite_master for this index - */ - sqlite3NestedParse(pParse, - "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#0,%Q);", - db->aDb[iDb].zName, SCHEMA_TABLE(iDb), - pIndex->zName, - pTab->zName, - zStmt - ); - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3_free(zStmt); - - /* Fill the index with data and reparse the schema. Code an OP_Expire - ** to invalidate all pre-compiled statements. - */ - if( pTblName ){ - sqlite3RefillIndex(pParse, pIndex, iMem); - sqlite3ChangeCookie(db, v, iDb); - sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, - sqlite3MPrintf(db, "name='%q'", pIndex->zName), P3_DYNAMIC); - sqlite3VdbeAddOp(v, OP_Expire, 0, 0); - } - } - - /* When adding an index to the list of indices for a table, make - ** sure all indices labeled OE_Replace come after all those labeled - ** OE_Ignore. This is necessary for the correct operation of UPDATE - ** and INSERT. - */ - if( db->init.busy || pTblName==0 ){ - if( onError!=OE_Replace || pTab->pIndex==0 - || pTab->pIndex->onError==OE_Replace){ - pIndex->pNext = pTab->pIndex; - pTab->pIndex = pIndex; - }else{ - Index *pOther = pTab->pIndex; - while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){ - pOther = pOther->pNext; - } - pIndex->pNext = pOther->pNext; - pOther->pNext = pIndex; - } - pIndex = 0; - } - - /* Clean up before exiting */ -exit_create_index: - if( pIndex ){ - freeIndex(pIndex); - } - sqlite3ExprListDelete(pList); - sqlite3SrcListDelete(pTblName); - sqlite3_free(zName); - return; -} - -/* -** Generate code to make sure the file format number is at least minFormat. -** The generated code will increase the file format number if necessary. -*/ -void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){ - Vdbe *v; - v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); - sqlite3VdbeUsesBtree(v, iDb); - sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0); - sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0); - sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1); - } -} - -/* -** Fill the Index.aiRowEst[] array with default information - information -** to be used when we have not run the ANALYZE command. -** -** aiRowEst[0] is suppose to contain the number of elements in the index. -** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the -** number of rows in the table that match any particular value of the -** first column of the index. aiRowEst[2] is an estimate of the number -** of rows that match any particular combiniation of the first 2 columns -** of the index. And so forth. It must always be the case that -* -** aiRowEst[N]<=aiRowEst[N-1] -** aiRowEst[N]>=1 -** -** Apart from that, we have little to go on besides intuition as to -** how aiRowEst[] should be initialized. The numbers generated here -** are based on typical values found in actual indices. -*/ -void sqlite3DefaultRowEst(Index *pIdx){ - unsigned *a = pIdx->aiRowEst; - int i; - assert( a!=0 ); - a[0] = 1000000; - for(i=pIdx->nColumn; i>=5; i--){ - a[i] = 5; - } - while( i>=1 ){ - a[i] = 11 - i; - i--; - } - if( pIdx->onError!=OE_None ){ - a[pIdx->nColumn] = 1; - } -} - -/* -** This routine will drop an existing named index. This routine -** implements the DROP INDEX statement. -*/ -void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ - Index *pIndex; - Vdbe *v; - sqlite3 *db = pParse->db; - int iDb; - - if( pParse->nErr || db->mallocFailed ){ - goto exit_drop_index; - } - assert( pName->nSrc==1 ); - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - goto exit_drop_index; - } - pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); - if( pIndex==0 ){ - if( !ifExists ){ - sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); - } - pParse->checkSchema = 1; - goto exit_drop_index; - } - if( pIndex->autoIndex ){ - sqlite3ErrorMsg(pParse, "index associated with UNIQUE " - "or PRIMARY KEY constraint cannot be dropped", 0); - goto exit_drop_index; - } - iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); -#ifndef SQLITE_OMIT_AUTHORIZATION - { - int code = SQLITE_DROP_INDEX; - Table *pTab = pIndex->pTable; - const char *zDb = db->aDb[iDb].zName; - const char *zTab = SCHEMA_TABLE(iDb); - if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ - goto exit_drop_index; - } - if( !OMIT_TEMPDB && iDb ) code = SQLITE_DROP_TEMP_INDEX; - if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){ - goto exit_drop_index; - } - } -#endif - - /* Generate code to remove the index and from the master table */ - v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3NestedParse(pParse, - "DELETE FROM %Q.%s WHERE name=%Q", - db->aDb[iDb].zName, SCHEMA_TABLE(iDb), - pIndex->zName - ); - sqlite3ChangeCookie(db, v, iDb); - destroyRootPage(pParse, pIndex->tnum, iDb); - sqlite3VdbeOp3(v, OP_DropIndex, iDb, 0, pIndex->zName, 0); - } - -exit_drop_index: - sqlite3SrcListDelete(pName); -} - -/* -** pArray is a pointer to an array of objects. Each object in the -** array is szEntry bytes in size. This routine allocates a new -** object on the end of the array. -** -** *pnEntry is the number of entries already in use. *pnAlloc is -** the previously allocated size of the array. initSize is the -** suggested initial array size allocation. -** -** The index of the new entry is returned in *pIdx. -** -** This routine returns a pointer to the array of objects. This -** might be the same as the pArray parameter or it might be a different -** pointer if the array was resized. -*/ -void *sqlite3ArrayAllocate( - sqlite3 *db, /* Connection to notify of malloc failures */ - void *pArray, /* Array of objects. Might be reallocated */ - int szEntry, /* Size of each object in the array */ - int initSize, /* Suggested initial allocation, in elements */ - int *pnEntry, /* Number of objects currently in use */ - int *pnAlloc, /* Current size of the allocation, in elements */ - int *pIdx /* Write the index of a new slot here */ -){ - char *z; - if( *pnEntry >= *pnAlloc ){ - void *pNew; - int newSize; - newSize = (*pnAlloc)*2 + initSize; - pNew = sqlite3DbRealloc(db, pArray, newSize*szEntry); - if( pNew==0 ){ - *pIdx = -1; - return pArray; - } - *pnAlloc = newSize; - pArray = pNew; - } - z = (char*)pArray; - memset(&z[*pnEntry * szEntry], 0, szEntry); - *pIdx = *pnEntry; - ++*pnEntry; - return pArray; -} - -/* -** Append a new element to the given IdList. Create a new IdList if -** need be. -** -** A new IdList is returned, or NULL if malloc() fails. -*/ -IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){ - int i; - if( pList==0 ){ - pList = sqlite3DbMallocZero(db, sizeof(IdList) ); - if( pList==0 ) return 0; - pList->nAlloc = 0; - } - pList->a = sqlite3ArrayAllocate( - db, - pList->a, - sizeof(pList->a[0]), - 5, - &pList->nId, - &pList->nAlloc, - &i - ); - if( i<0 ){ - sqlite3IdListDelete(pList); - return 0; - } - pList->a[i].zName = sqlite3NameFromToken(db, pToken); - return pList; -} - -/* -** Delete an IdList. -*/ -void sqlite3IdListDelete(IdList *pList){ - int i; - if( pList==0 ) return; - for(i=0; inId; i++){ - sqlite3_free(pList->a[i].zName); - } - sqlite3_free(pList->a); - sqlite3_free(pList); -} - -/* -** Return the index in pList of the identifier named zId. Return -1 -** if not found. -*/ -int sqlite3IdListIndex(IdList *pList, const char *zName){ - int i; - if( pList==0 ) return -1; - for(i=0; inId; i++){ - if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; - } - return -1; -} - -/* -** Append a new table name to the given SrcList. Create a new SrcList if -** need be. A new entry is created in the SrcList even if pToken is NULL. -** -** A new SrcList is returned, or NULL if malloc() fails. -** -** If pDatabase is not null, it means that the table has an optional -** database name prefix. Like this: "database.table". The pDatabase -** points to the table name and the pTable points to the database name. -** The SrcList.a[].zName field is filled with the table name which might -** come from pTable (if pDatabase is NULL) or from pDatabase. -** SrcList.a[].zDatabase is filled with the database name from pTable, -** or with NULL if no database is specified. -** -** In other words, if call like this: -** -** sqlite3SrcListAppend(D,A,B,0); -** -** Then B is a table name and the database name is unspecified. If called -** like this: -** -** sqlite3SrcListAppend(D,A,B,C); -** -** Then C is the table name and B is the database name. -*/ -SrcList *sqlite3SrcListAppend( - sqlite3 *db, /* Connection to notify of malloc failures */ - SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */ - Token *pTable, /* Table to append */ - Token *pDatabase /* Database of the table */ -){ - struct SrcList_item *pItem; - if( pList==0 ){ - pList = sqlite3DbMallocZero(db, sizeof(SrcList) ); - if( pList==0 ) return 0; - pList->nAlloc = 1; - } - if( pList->nSrc>=pList->nAlloc ){ - SrcList *pNew; - pList->nAlloc *= 2; - pNew = sqlite3DbRealloc(db, pList, - sizeof(*pList) + (pList->nAlloc-1)*sizeof(pList->a[0]) ); - if( pNew==0 ){ - sqlite3SrcListDelete(pList); - return 0; - } - pList = pNew; - } - pItem = &pList->a[pList->nSrc]; - memset(pItem, 0, sizeof(pList->a[0])); - if( pDatabase && pDatabase->z==0 ){ - pDatabase = 0; - } - if( pDatabase && pTable ){ - Token *pTemp = pDatabase; - pDatabase = pTable; - pTable = pTemp; - } - pItem->zName = sqlite3NameFromToken(db, pTable); - pItem->zDatabase = sqlite3NameFromToken(db, pDatabase); - pItem->iCursor = -1; - pItem->isPopulated = 0; - pList->nSrc++; - return pList; -} - -/* -** Assign cursors to all tables in a SrcList -*/ -void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ - int i; - struct SrcList_item *pItem; - assert(pList || pParse->db->mallocFailed ); - if( pList ){ - for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pItem->iCursor>=0 ) break; - pItem->iCursor = pParse->nTab++; - if( pItem->pSelect ){ - sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); - } - } - } -} - -/* -** Delete an entire SrcList including all its substructure. -*/ -void sqlite3SrcListDelete(SrcList *pList){ - int i; - struct SrcList_item *pItem; - if( pList==0 ) return; - for(pItem=pList->a, i=0; inSrc; i++, pItem++){ - sqlite3_free(pItem->zDatabase); - sqlite3_free(pItem->zName); - sqlite3_free(pItem->zAlias); - sqlite3DeleteTable(pItem->pTab); - sqlite3SelectDelete(pItem->pSelect); - sqlite3ExprDelete(pItem->pOn); - sqlite3IdListDelete(pItem->pUsing); - } - sqlite3_free(pList); -} - -/* -** This routine is called by the parser to add a new term to the -** end of a growing FROM clause. The "p" parameter is the part of -** the FROM clause that has already been constructed. "p" is NULL -** if this is the first term of the FROM clause. pTable and pDatabase -** are the name of the table and database named in the FROM clause term. -** pDatabase is NULL if the database name qualifier is missing - the -** usual case. If the term has a alias, then pAlias points to the -** alias token. If the term is a subquery, then pSubquery is the -** SELECT statement that the subquery encodes. The pTable and -** pDatabase parameters are NULL for subqueries. The pOn and pUsing -** parameters are the content of the ON and USING clauses. -** -** Return a new SrcList which encodes is the FROM with the new -** term added. -*/ -SrcList *sqlite3SrcListAppendFromTerm( - Parse *pParse, /* Parsing context */ - SrcList *p, /* The left part of the FROM clause already seen */ - Token *pTable, /* Name of the table to add to the FROM clause */ - Token *pDatabase, /* Name of the database containing pTable */ - Token *pAlias, /* The right-hand side of the AS subexpression */ - Select *pSubquery, /* A subquery used in place of a table name */ - Expr *pOn, /* The ON clause of a join */ - IdList *pUsing /* The USING clause of a join */ -){ - struct SrcList_item *pItem; - sqlite3 *db = pParse->db; - p = sqlite3SrcListAppend(db, p, pTable, pDatabase); - if( p==0 || p->nSrc==0 ){ - sqlite3ExprDelete(pOn); - sqlite3IdListDelete(pUsing); - sqlite3SelectDelete(pSubquery); - return p; - } - pItem = &p->a[p->nSrc-1]; - if( pAlias && pAlias->n ){ - pItem->zAlias = sqlite3NameFromToken(db, pAlias); - } - pItem->pSelect = pSubquery; - pItem->pOn = pOn; - pItem->pUsing = pUsing; - return p; -} - -/* -** When building up a FROM clause in the parser, the join operator -** is initially attached to the left operand. But the code generator -** expects the join operator to be on the right operand. This routine -** Shifts all join operators from left to right for an entire FROM -** clause. -** -** Example: Suppose the join is like this: -** -** A natural cross join B -** -** The operator is "natural cross join". The A and B operands are stored -** in p->a[0] and p->a[1], respectively. The parser initially stores the -** operator with A. This routine shifts that operator over to B. -*/ -void sqlite3SrcListShiftJoinType(SrcList *p){ - if( p && p->a ){ - int i; - for(i=p->nSrc-1; i>0; i--){ - p->a[i].jointype = p->a[i-1].jointype; - } - p->a[0].jointype = 0; - } -} - -/* -** Begin a transaction -*/ -void sqlite3BeginTransaction(Parse *pParse, int type){ - sqlite3 *db; - Vdbe *v; - int i; - - if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; - if( pParse->nErr || db->mallocFailed ) return; - if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return; - - v = sqlite3GetVdbe(pParse); - if( !v ) return; - if( type!=TK_DEFERRED ){ - for(i=0; inDb; i++){ - sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); - sqlite3VdbeUsesBtree(v, i); - } - } - sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0); -} - -/* -** Commit a transaction -*/ -void sqlite3CommitTransaction(Parse *pParse){ - sqlite3 *db; - Vdbe *v; - - if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; - if( pParse->nErr || db->mallocFailed ) return; - if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return; - - v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0); - } -} - -/* -** Rollback a transaction -*/ -void sqlite3RollbackTransaction(Parse *pParse){ - sqlite3 *db; - Vdbe *v; - - if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; - if( pParse->nErr || db->mallocFailed ) return; - if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return; - - v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1); - } -} - -/* -** Make sure the TEMP database is open and available for use. Return -** the number of errors. Leave any error messages in the pParse structure. -*/ -int sqlite3OpenTempDatabase(Parse *pParse){ - sqlite3 *db = pParse->db; - if( db->aDb[1].pBt==0 && !pParse->explain ){ - int rc; - static const int flags = - SQLITE_OPEN_READWRITE | - SQLITE_OPEN_CREATE | - SQLITE_OPEN_EXCLUSIVE | - SQLITE_OPEN_DELETEONCLOSE | - SQLITE_OPEN_TEMP_DB; - - rc = sqlite3BtreeFactory(db, 0, 0, SQLITE_DEFAULT_CACHE_SIZE, flags, - &db->aDb[1].pBt); - if( rc!=SQLITE_OK ){ - sqlite3ErrorMsg(pParse, "unable to open a temporary database " - "file for storing temporary tables"); - pParse->rc = rc; - return 1; - } - if( db->flags & !db->autoCommit ){ - rc = sqlite3BtreeBeginTrans(db->aDb[1].pBt, 1); - if( rc!=SQLITE_OK ){ - sqlite3ErrorMsg(pParse, "unable to get a write lock on " - "the temporary database file"); - pParse->rc = rc; - return 1; - } - } - assert( db->aDb[1].pSchema ); - } - return 0; -} - -/* -** Generate VDBE code that will verify the schema cookie and start -** a read-transaction for all named database files. -** -** It is important that all schema cookies be verified and all -** read transactions be started before anything else happens in -** the VDBE program. But this routine can be called after much other -** code has been generated. So here is what we do: -** -** The first time this routine is called, we code an OP_Goto that -** will jump to a subroutine at the end of the program. Then we -** record every database that needs its schema verified in the -** pParse->cookieMask field. Later, after all other code has been -** generated, the subroutine that does the cookie verifications and -** starts the transactions will be coded and the OP_Goto P2 value -** will be made to point to that subroutine. The generation of the -** cookie verification subroutine code happens in sqlite3FinishCoding(). -** -** If iDb<0 then code the OP_Goto only - don't set flag to verify the -** schema on any databases. This can be used to position the OP_Goto -** early in the code, before we know if any database tables will be used. -*/ -void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ - sqlite3 *db; - Vdbe *v; - int mask; - - v = sqlite3GetVdbe(pParse); - if( v==0 ) return; /* This only happens if there was a prior error */ - db = pParse->db; - if( pParse->cookieGoto==0 ){ - pParse->cookieGoto = sqlite3VdbeAddOp(v, OP_Goto, 0, 0)+1; - } - if( iDb>=0 ){ - assert( iDbnDb ); - assert( db->aDb[iDb].pBt!=0 || iDb==1 ); - assert( iDbcookieMask & mask)==0 ){ - pParse->cookieMask |= mask; - pParse->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; - if( !OMIT_TEMPDB && iDb==1 ){ - sqlite3OpenTempDatabase(pParse); - } - } - } -} - -/* -** Generate VDBE code that prepares for doing an operation that -** might change the database. -** -** This routine starts a new transaction if we are not already within -** a transaction. If we are already within a transaction, then a checkpoint -** is set if the setStatement parameter is true. A checkpoint should -** be set for operations that might fail (due to a constraint) part of -** the way through and which will need to undo some writes without having to -** rollback the whole transaction. For operations where all constraints -** can be checked before any changes are made to the database, it is never -** necessary to undo a write and the checkpoint should not be set. -** -** Only database iDb and the temp database are made writable by this call. -** If iDb==0, then the main and temp databases are made writable. If -** iDb==1 then only the temp database is made writable. If iDb>1 then the -** specified auxiliary database and the temp database are made writable. -*/ -void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ - Vdbe *v = sqlite3GetVdbe(pParse); - if( v==0 ) return; - sqlite3CodeVerifySchema(pParse, iDb); - pParse->writeMask |= 1<nested==0 ){ - sqlite3VdbeAddOp(v, OP_Statement, iDb, 0); - } - if( (OMIT_TEMPDB || iDb!=1) && pParse->db->aDb[1].pBt!=0 ){ - sqlite3BeginWriteOperation(pParse, setStatement, 1); - } -} - -/* -** Check to see if pIndex uses the collating sequence pColl. Return -** true if it does and false if it does not. -*/ -#ifndef SQLITE_OMIT_REINDEX -static int collationMatch(const char *zColl, Index *pIndex){ - int i; - for(i=0; inColumn; i++){ - const char *z = pIndex->azColl[i]; - if( z==zColl || (z && zColl && 0==sqlite3StrICmp(z, zColl)) ){ - return 1; - } - } - return 0; -} -#endif - -/* -** Recompute all indices of pTab that use the collating sequence pColl. -** If pColl==0 then recompute all indices of pTab. -*/ -#ifndef SQLITE_OMIT_REINDEX -static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){ - Index *pIndex; /* An index associated with pTab */ - - for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ - if( zColl==0 || collationMatch(zColl, pIndex) ){ - int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3RefillIndex(pParse, pIndex, -1); - } - } -} -#endif - -/* -** Recompute all indices of all tables in all databases where the -** indices use the collating sequence pColl. If pColl==0 then recompute -** all indices everywhere. -*/ -#ifndef SQLITE_OMIT_REINDEX -static void reindexDatabases(Parse *pParse, char const *zColl){ - Db *pDb; /* A single database */ - int iDb; /* The database index number */ - sqlite3 *db = pParse->db; /* The database connection */ - HashElem *k; /* For looping over tables in pDb */ - Table *pTab; /* A table in the database */ - - for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ - assert( pDb!=0 ); - for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){ - pTab = (Table*)sqliteHashData(k); - reindexTable(pParse, pTab, zColl); - } - } -} -#endif - -/* -** Generate code for the REINDEX command. -** -** REINDEX -- 1 -** REINDEX -- 2 -** REINDEX ?.? -- 3 -** REINDEX ?.? -- 4 -** -** Form 1 causes all indices in all attached databases to be rebuilt. -** Form 2 rebuilds all indices in all databases that use the named -** collating function. Forms 3 and 4 rebuild the named index or all -** indices associated with the named table. -*/ -#ifndef SQLITE_OMIT_REINDEX -void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ - CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */ - char *z; /* Name of a table or index */ - const char *zDb; /* Name of the database */ - Table *pTab; /* A table in the database */ - Index *pIndex; /* An index associated with pTab */ - int iDb; /* The database index number */ - sqlite3 *db = pParse->db; /* The database connection */ - Token *pObjName; /* Name of the table or index to be reindexed */ - - /* Read the database schema. If an error occurs, leave an error message - ** and code in pParse and return NULL. */ - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - return; - } - - if( pName1==0 || pName1->z==0 ){ - reindexDatabases(pParse, 0); - return; - }else if( pName2==0 || pName2->z==0 ){ - assert( pName1->z ); - pColl = sqlite3FindCollSeq(db, ENC(db), (char*)pName1->z, pName1->n, 0); - if( pColl ){ - char *zColl = sqlite3DbStrNDup(db, (const char *)pName1->z, pName1->n); - if( zColl ){ - reindexDatabases(pParse, zColl); - sqlite3_free(zColl); - } - return; - } - } - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); - if( iDb<0 ) return; - z = sqlite3NameFromToken(db, pObjName); - if( z==0 ) return; - zDb = db->aDb[iDb].zName; - pTab = sqlite3FindTable(db, z, zDb); - if( pTab ){ - reindexTable(pParse, pTab, 0); - sqlite3_free(z); - return; - } - pIndex = sqlite3FindIndex(db, z, zDb); - sqlite3_free(z); - if( pIndex ){ - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3RefillIndex(pParse, pIndex, -1); - return; - } - sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); -} -#endif - -/* -** Return a dynamicly allocated KeyInfo structure that can be used -** with OP_OpenRead or OP_OpenWrite to access database index pIdx. -** -** If successful, a pointer to the new structure is returned. In this case -** the caller is responsible for calling sqlite3_free() on the returned -** pointer. If an error occurs (out of memory or missing collation -** sequence), NULL is returned and the state of pParse updated to reflect -** the error. -*/ -KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){ - int i; - int nCol = pIdx->nColumn; - int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol; - KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(pParse->db, nBytes); - - if( pKey ){ - pKey->db = pParse->db; - pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]); - assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) ); - for(i=0; iazColl[i]; - assert( zColl ); - pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl, -1); - pKey->aSortOrder[i] = pIdx->aSortOrder[i]; - } - pKey->nField = nCol; - } - - if( pParse->nErr ){ - sqlite3_free(pKey); - pKey = 0; - } - return pKey; -} diff --git a/extensions/sqlite/sqlite-source/callback.c b/extensions/sqlite/sqlite-source/callback.c deleted file mode 100644 index e5a41c72..00000000 --- a/extensions/sqlite/sqlite-source/callback.c +++ /dev/null @@ -1,378 +0,0 @@ -/* -** 2005 May 23 -** -** 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 file contains functions used to access the internal hash tables -** of user defined functions and collation sequences. -** -** $Id$ -*/ - -#include "sqliteInt.h" - -/* -** Invoke the 'collation needed' callback to request a collation sequence -** in the database text encoding of name zName, length nName. -** If the collation sequence -*/ -static void callCollNeeded(sqlite3 *db, const char *zName, int nName){ - assert( !db->xCollNeeded || !db->xCollNeeded16 ); - if( nName<0 ) nName = strlen(zName); - if( db->xCollNeeded ){ - char *zExternal = sqlite3DbStrNDup(db, zName, nName); - if( !zExternal ) return; - db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal); - sqlite3_free(zExternal); - } -#ifndef SQLITE_OMIT_UTF16 - if( db->xCollNeeded16 ){ - char const *zExternal; - sqlite3_value *pTmp = sqlite3ValueNew(db); - sqlite3ValueSetStr(pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC); - zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); - if( zExternal ){ - db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal); - } - sqlite3ValueFree(pTmp); - } -#endif -} - -/* -** This routine is called if the collation factory fails to deliver a -** collation function in the best encoding but there may be other versions -** of this collation function (for other text encodings) available. Use one -** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if -** possible. -*/ -static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ - CollSeq *pColl2; - char *z = pColl->zName; - int n = strlen(z); - int i; - static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; - for(i=0; i<3; i++){ - pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0); - if( pColl2->xCmp!=0 ){ - memcpy(pColl, pColl2, sizeof(CollSeq)); - pColl->xDel = 0; /* Do not copy the destructor */ - return SQLITE_OK; - } - } - return SQLITE_ERROR; -} - -/* -** This function is responsible for invoking the collation factory callback -** or substituting a collation sequence of a different encoding when the -** requested collation sequence is not available in the database native -** encoding. -** -** If it is not NULL, then pColl must point to the database native encoding -** collation sequence with name zName, length nName. -** -** The return value is either the collation sequence to be used in database -** db for collation type name zName, length nName, or NULL, if no collation -** sequence can be found. -*/ -CollSeq *sqlite3GetCollSeq( - sqlite3* db, - CollSeq *pColl, - const char *zName, - int nName -){ - CollSeq *p; - - p = pColl; - if( !p ){ - p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0); - } - if( !p || !p->xCmp ){ - /* No collation sequence of this type for this encoding is registered. - ** Call the collation factory to see if it can supply us with one. - */ - callCollNeeded(db, zName, nName); - p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0); - } - if( p && !p->xCmp && synthCollSeq(db, p) ){ - p = 0; - } - assert( !p || p->xCmp ); - return p; -} - -/* -** This routine is called on a collation sequence before it is used to -** check that it is defined. An undefined collation sequence exists when -** a database is loaded that contains references to collation sequences -** that have not been defined by sqlite3_create_collation() etc. -** -** If required, this routine calls the 'collation needed' callback to -** request a definition of the collating sequence. If this doesn't work, -** an equivalent collating sequence that uses a text encoding different -** from the main database is substituted, if one is available. -*/ -int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ - if( pColl ){ - const char *zName = pColl->zName; - CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1); - if( !p ){ - if( pParse->nErr==0 ){ - sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); - } - pParse->nErr++; - return SQLITE_ERROR; - } - assert( p==pColl ); - } - return SQLITE_OK; -} - - - -/* -** Locate and return an entry from the db.aCollSeq hash table. If the entry -** specified by zName and nName is not found and parameter 'create' is -** true, then create a new entry. Otherwise return NULL. -** -** Each pointer stored in the sqlite3.aCollSeq hash table contains an -** array of three CollSeq structures. The first is the collation sequence -** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be. -** -** Stored immediately after the three collation sequences is a copy of -** the collation sequence name. A pointer to this string is stored in -** each collation sequence structure. -*/ -static CollSeq *findCollSeqEntry( - sqlite3 *db, - const char *zName, - int nName, - int create -){ - CollSeq *pColl; - if( nName<0 ) nName = strlen(zName); - pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); - - if( 0==pColl && create ){ - pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 ); - if( pColl ){ - CollSeq *pDel = 0; - pColl[0].zName = (char*)&pColl[3]; - pColl[0].enc = SQLITE_UTF8; - pColl[1].zName = (char*)&pColl[3]; - pColl[1].enc = SQLITE_UTF16LE; - pColl[2].zName = (char*)&pColl[3]; - pColl[2].enc = SQLITE_UTF16BE; - memcpy(pColl[0].zName, zName, nName); - pColl[0].zName[nName] = 0; - pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); - - /* If a malloc() failure occured in sqlite3HashInsert(), it will - ** return the pColl pointer to be deleted (because it wasn't added - ** to the hash table). - */ - assert( pDel==0 || pDel==pColl ); - if( pDel!=0 ){ - db->mallocFailed = 1; - sqlite3_free(pDel); - pColl = 0; - } - } - } - return pColl; -} - -/* -** Parameter zName points to a UTF-8 encoded string nName bytes long. -** Return the CollSeq* pointer for the collation sequence named zName -** for the encoding 'enc' from the database 'db'. -** -** If the entry specified is not found and 'create' is true, then create a -** new entry. Otherwise return NULL. -** -** A separate function sqlite3LocateCollSeq() is a wrapper around -** this routine. sqlite3LocateCollSeq() invokes the collation factory -** if necessary and generates an error message if the collating sequence -** cannot be found. -*/ -CollSeq *sqlite3FindCollSeq( - sqlite3 *db, - u8 enc, - const char *zName, - int nName, - int create -){ - CollSeq *pColl; - if( zName ){ - pColl = findCollSeqEntry(db, zName, nName, create); - }else{ - pColl = db->pDfltColl; - } - assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); - assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); - if( pColl ) pColl += enc-1; - return pColl; -} - -/* -** Locate a user function given a name, a number of arguments and a flag -** indicating whether the function prefers UTF-16 over UTF-8. Return a -** pointer to the FuncDef structure that defines that function, or return -** NULL if the function does not exist. -** -** If the createFlag argument is true, then a new (blank) FuncDef -** structure is created and liked into the "db" structure if a -** no matching function previously existed. When createFlag is true -** and the nArg parameter is -1, then only a function that accepts -** any number of arguments will be returned. -** -** If createFlag is false and nArg is -1, then the first valid -** function found is returned. A function is valid if either xFunc -** or xStep is non-zero. -** -** If createFlag is false, then a function with the required name and -** number of arguments may be returned even if the eTextRep flag does not -** match that requested. -*/ -FuncDef *sqlite3FindFunction( - sqlite3 *db, /* An open database */ - const char *zName, /* Name of the function. Not null-terminated */ - int nName, /* Number of characters in the name */ - int nArg, /* Number of arguments. -1 means any number */ - u8 enc, /* Preferred text encoding */ - int createFlag /* Create new entry if true and does not otherwise exist */ -){ - FuncDef *p; /* Iterator variable */ - FuncDef *pFirst; /* First function with this name */ - FuncDef *pBest = 0; /* Best match found so far */ - int bestmatch = 0; - - - assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); - if( nArg<-1 ) nArg = -1; - - pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName); - for(p=pFirst; p; p=p->pNext){ - /* During the search for the best function definition, bestmatch is set - ** as follows to indicate the quality of the match with the definition - ** pointed to by pBest: - ** - ** 0: pBest is NULL. No match has been found. - ** 1: A variable arguments function that prefers UTF-8 when a UTF-16 - ** encoding is requested, or vice versa. - ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is - ** requested, or vice versa. - ** 3: A variable arguments function using the same text encoding. - ** 4: A function with the exact number of arguments requested that - ** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa. - ** 5: A function with the exact number of arguments requested that - ** prefers UTF-16LE when UTF-16BE is requested, or vice versa. - ** 6: An exact match. - ** - ** A larger value of 'matchqual' indicates a more desirable match. - */ - if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){ - int match = 1; /* Quality of this match */ - if( p->nArg==nArg || nArg==-1 ){ - match = 4; - } - if( enc==p->iPrefEnc ){ - match += 2; - } - else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) || - (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){ - match += 1; - } - - if( match>bestmatch ){ - pBest = p; - bestmatch = match; - } - } - } - - /* If the createFlag parameter is true, and the seach did not reveal an - ** exact match for the name, number of arguments and encoding, then add a - ** new entry to the hash table and return it. - */ - if( createFlag && bestmatch<6 && - (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName))!=0 ){ - pBest->nArg = nArg; - pBest->pNext = pFirst; - pBest->iPrefEnc = enc; - memcpy(pBest->zName, zName, nName); - pBest->zName[nName] = 0; - if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){ - db->mallocFailed = 1; - sqlite3_free(pBest); - return 0; - } - } - - if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){ - return pBest; - } - return 0; -} - -/* -** Free all resources held by the schema structure. The void* argument points -** at a Schema struct. This function does not call sqlite3_free() on the -** pointer itself, it just cleans up subsiduary resources (i.e. the contents -** of the schema hash tables). -*/ -void sqlite3SchemaFree(void *p){ - Hash temp1; - Hash temp2; - HashElem *pElem; - Schema *pSchema = (Schema *)p; - - temp1 = pSchema->tblHash; - temp2 = pSchema->trigHash; - sqlite3HashInit(&pSchema->trigHash, SQLITE_HASH_STRING, 0); - sqlite3HashClear(&pSchema->aFKey); - sqlite3HashClear(&pSchema->idxHash); - for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ - sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem)); - } - sqlite3HashClear(&temp2); - sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0); - for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ - Table *pTab = sqliteHashData(pElem); - sqlite3DeleteTable(pTab); - } - sqlite3HashClear(&temp1); - pSchema->pSeqTab = 0; - pSchema->flags &= ~DB_SchemaLoaded; -} - -/* -** Find and return the schema associated with a BTree. Create -** a new one if necessary. -*/ -Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ - Schema * p; - if( pBt ){ - p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaFree); - }else{ - p = (Schema *)sqlite3MallocZero(sizeof(Schema)); - } - if( !p ){ - db->mallocFailed = 1; - }else if ( 0==p->file_format ){ - sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0); - sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0); - sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0); - sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1); - p->enc = SQLITE_UTF8; - } - return p; -} diff --git a/extensions/sqlite/sqlite-source/complete.c b/extensions/sqlite/sqlite-source/complete.c deleted file mode 100644 index f35ca864..00000000 --- a/extensions/sqlite/sqlite-source/complete.c +++ /dev/null @@ -1,271 +0,0 @@ -/* -** 2001 September 15 -** -** 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. -** -************************************************************************* -** An tokenizer for SQL -** -** This file contains C code that implements the sqlite3_complete() API. -** This code used to be part of the tokenizer.c source file. But by -** separating it out, the code will be automatically omitted from -** static links that do not use it. -** -** $Id$ -*/ -#include "sqliteInt.h" -#ifndef SQLITE_OMIT_COMPLETE - -/* -** This is defined in tokenize.c. We just have to import the definition. -*/ -#ifndef SQLITE_AMALGAMATION -#ifdef SQLITE_ASCII -extern const char sqlite3IsAsciiIdChar[]; -#define IdChar(C) (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsAsciiIdChar[c-0x20])) -#endif -#ifdef SQLITE_EBCDIC -extern const char sqlite3IsEbcdicIdChar[]; -#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) -#endif -#endif /* SQLITE_AMALGAMATION */ - - -/* -** Token types used by the sqlite3_complete() routine. See the header -** comments on that procedure for additional information. -*/ -#define tkSEMI 0 -#define tkWS 1 -#define tkOTHER 2 -#define tkEXPLAIN 3 -#define tkCREATE 4 -#define tkTEMP 5 -#define tkTRIGGER 6 -#define tkEND 7 - -/* -** Return TRUE if the given SQL string ends in a semicolon. -** -** Special handling is require for CREATE TRIGGER statements. -** Whenever the CREATE TRIGGER keywords are seen, the statement -** must end with ";END;". -** -** This implementation uses a state machine with 7 states: -** -** (0) START At the beginning or end of an SQL statement. This routine -** returns 1 if it ends in the START state and 0 if it ends -** in any other state. -** -** (1) NORMAL We are in the middle of statement which ends with a single -** semicolon. -** -** (2) EXPLAIN The keyword EXPLAIN has been seen at the beginning of -** a statement. -** -** (3) CREATE The keyword CREATE has been seen at the beginning of a -** statement, possibly preceeded by EXPLAIN and/or followed by -** TEMP or TEMPORARY -** -** (4) TRIGGER We are in the middle of a trigger definition that must be -** ended by a semicolon, the keyword END, and another semicolon. -** -** (5) SEMI We've seen the first semicolon in the ";END;" that occurs at -** the end of a trigger definition. -** -** (6) END We've seen the ";END" of the ";END;" that occurs at the end -** of a trigger difinition. -** -** Transitions between states above are determined by tokens extracted -** from the input. The following tokens are significant: -** -** (0) tkSEMI A semicolon. -** (1) tkWS Whitespace -** (2) tkOTHER Any other SQL token. -** (3) tkEXPLAIN The "explain" keyword. -** (4) tkCREATE The "create" keyword. -** (5) tkTEMP The "temp" or "temporary" keyword. -** (6) tkTRIGGER The "trigger" keyword. -** (7) tkEND The "end" keyword. -** -** Whitespace never causes a state transition and is always ignored. -** -** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed -** to recognize the end of a trigger can be omitted. All we have to do -** is look for a semicolon that is not part of an string or comment. -*/ -int sqlite3_complete(const char *zSql){ - u8 state = 0; /* Current state, using numbers defined in header comment */ - u8 token; /* Value of the next token */ - -#ifndef SQLITE_OMIT_TRIGGER - /* A complex statement machine used to detect the end of a CREATE TRIGGER - ** statement. This is the normal case. - */ - static const u8 trans[7][8] = { - /* Token: */ - /* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */ - /* 0 START: */ { 0, 0, 1, 2, 3, 1, 1, 1, }, - /* 1 NORMAL: */ { 0, 1, 1, 1, 1, 1, 1, 1, }, - /* 2 EXPLAIN: */ { 0, 2, 1, 1, 3, 1, 1, 1, }, - /* 3 CREATE: */ { 0, 3, 1, 1, 1, 3, 4, 1, }, - /* 4 TRIGGER: */ { 5, 4, 4, 4, 4, 4, 4, 4, }, - /* 5 SEMI: */ { 5, 5, 4, 4, 4, 4, 4, 6, }, - /* 6 END: */ { 0, 6, 4, 4, 4, 4, 4, 4, }, - }; -#else - /* If triggers are not suppored by this compile then the statement machine - ** used to detect the end of a statement is much simplier - */ - static const u8 trans[2][3] = { - /* Token: */ - /* State: ** SEMI WS OTHER */ - /* 0 START: */ { 0, 0, 1, }, - /* 1 NORMAL: */ { 0, 1, 1, }, - }; -#endif /* SQLITE_OMIT_TRIGGER */ - - while( *zSql ){ - switch( *zSql ){ - case ';': { /* A semicolon */ - token = tkSEMI; - break; - } - case ' ': - case '\r': - case '\t': - case '\n': - case '\f': { /* White space is ignored */ - token = tkWS; - break; - } - case '/': { /* C-style comments */ - if( zSql[1]!='*' ){ - token = tkOTHER; - break; - } - zSql += 2; - while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; } - if( zSql[0]==0 ) return 0; - zSql++; - token = tkWS; - break; - } - case '-': { /* SQL-style comments from "--" to end of line */ - if( zSql[1]!='-' ){ - token = tkOTHER; - break; - } - while( *zSql && *zSql!='\n' ){ zSql++; } - if( *zSql==0 ) return state==0; - token = tkWS; - break; - } - case '[': { /* Microsoft-style identifiers in [...] */ - zSql++; - while( *zSql && *zSql!=']' ){ zSql++; } - if( *zSql==0 ) return 0; - token = tkOTHER; - break; - } - case '`': /* Grave-accent quoted symbols used by MySQL */ - case '"': /* single- and double-quoted strings */ - case '\'': { - int c = *zSql; - zSql++; - while( *zSql && *zSql!=c ){ zSql++; } - if( *zSql==0 ) return 0; - token = tkOTHER; - break; - } - default: { - int c; - if( IdChar((u8)*zSql) ){ - /* Keywords and unquoted identifiers */ - int nId; - for(nId=1; IdChar(zSql[nId]); nId++){} -#ifdef SQLITE_OMIT_TRIGGER - token = tkOTHER; -#else - switch( *zSql ){ - case 'c': case 'C': { - if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){ - token = tkCREATE; - }else{ - token = tkOTHER; - } - break; - } - case 't': case 'T': { - if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){ - token = tkTRIGGER; - }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){ - token = tkTEMP; - }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){ - token = tkTEMP; - }else{ - token = tkOTHER; - } - break; - } - case 'e': case 'E': { - if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){ - token = tkEND; - }else -#ifndef SQLITE_OMIT_EXPLAIN - if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){ - token = tkEXPLAIN; - }else -#endif - { - token = tkOTHER; - } - break; - } - default: { - token = tkOTHER; - break; - } - } -#endif /* SQLITE_OMIT_TRIGGER */ - zSql += nId-1; - }else{ - /* Operators and special symbols */ - token = tkOTHER; - } - break; - } - } - state = trans[state][token]; - zSql++; - } - return state==0; -} - -#ifndef SQLITE_OMIT_UTF16 -/* -** This routine is the same as the sqlite3_complete() routine described -** above, except that the parameter is required to be UTF-16 encoded, not -** UTF-8. -*/ -int sqlite3_complete16(const void *zSql){ - sqlite3_value *pVal; - char const *zSql8; - int rc = SQLITE_NOMEM; - - pVal = sqlite3ValueNew(0); - sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); - zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8); - if( zSql8 ){ - rc = sqlite3_complete(zSql8); - } - sqlite3ValueFree(pVal); - return sqlite3ApiExit(0, rc); -} -#endif /* SQLITE_OMIT_UTF16 */ -#endif /* SQLITE_OMIT_COMPLETE */ diff --git a/extensions/sqlite/sqlite-source/date.c b/extensions/sqlite/sqlite-source/date.c deleted file mode 100644 index c440db84..00000000 --- a/extensions/sqlite/sqlite-source/date.c +++ /dev/null @@ -1,1045 +0,0 @@ -/* -** 2003 October 31 -** -** 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 file contains the C functions that implement date and time -** functions for SQLite. -** -** There is only one exported symbol in this file - the function -** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. -** All other code has file scope. -** -** $Id$ -** -** SQLite processes all times and dates as Julian Day numbers. The -** dates and times are stored as the number of days since noon -** in Greenwich on November 24, 4714 B.C. according to the Gregorian -** calendar system. -** -** 1970-01-01 00:00:00 is JD 2440587.5 -** 2000-01-01 00:00:00 is JD 2451544.5 -** -** This implemention requires years to be expressed as a 4-digit number -** which means that only dates between 0000-01-01 and 9999-12-31 can -** be represented, even though julian day numbers allow a much wider -** range of dates. -** -** The Gregorian calendar system is used for all dates and times, -** even those that predate the Gregorian calendar. Historians usually -** use the Julian calendar for dates prior to 1582-10-15 and for some -** dates afterwards, depending on locale. Beware of this difference. -** -** The conversion algorithms are implemented based on descriptions -** in the following text: -** -** Jean Meeus -** Astronomical Algorithms, 2nd Edition, 1998 -** ISBM 0-943396-61-1 -** Willmann-Bell, Inc -** Richmond, Virginia (USA) -*/ -#include "sqliteInt.h" -#include -#include -#include -#include - -#ifndef SQLITE_OMIT_DATETIME_FUNCS - -/* -** A structure for holding a single date and time. -*/ -typedef struct DateTime DateTime; -struct DateTime { - double rJD; /* The julian day number */ - int Y, M, D; /* Year, month, and day */ - int h, m; /* Hour and minutes */ - int tz; /* Timezone offset in minutes */ - double s; /* Seconds */ - char validYMD; /* True if Y,M,D are valid */ - char validHMS; /* True if h,m,s are valid */ - char validJD; /* True if rJD is valid */ - char validTZ; /* True if tz is valid */ -}; - - -/* -** Convert zDate into one or more integers. Additional arguments -** come in groups of 5 as follows: -** -** N number of digits in the integer -** min minimum allowed value of the integer -** max maximum allowed value of the integer -** nextC first character after the integer -** pVal where to write the integers value. -** -** Conversions continue until one with nextC==0 is encountered. -** The function returns the number of successful conversions. -*/ -static int getDigits(const char *zDate, ...){ - va_list ap; - int val; - int N; - int min; - int max; - int nextC; - int *pVal; - int cnt = 0; - va_start(ap, zDate); - do{ - N = va_arg(ap, int); - min = va_arg(ap, int); - max = va_arg(ap, int); - nextC = va_arg(ap, int); - pVal = va_arg(ap, int*); - val = 0; - while( N-- ){ - if( !isdigit(*(u8*)zDate) ){ - goto end_getDigits; - } - val = val*10 + *zDate - '0'; - zDate++; - } - if( valmax || (nextC!=0 && nextC!=*zDate) ){ - goto end_getDigits; - } - *pVal = val; - zDate++; - cnt++; - }while( nextC ); -end_getDigits: - va_end(ap); - return cnt; -} - -/* -** Read text from z[] and convert into a floating point number. Return -** the number of digits converted. -*/ -#define getValue sqlite3AtoF - -/* -** Parse a timezone extension on the end of a date-time. -** The extension is of the form: -** -** (+/-)HH:MM -** -** If the parse is successful, write the number of minutes -** of change in *pnMin and return 0. If a parser error occurs, -** return 0. -** -** A missing specifier is not considered an error. -*/ -static int parseTimezone(const char *zDate, DateTime *p){ - int sgn = 0; - int nHr, nMn; - while( isspace(*(u8*)zDate) ){ zDate++; } - p->tz = 0; - if( *zDate=='-' ){ - sgn = -1; - }else if( *zDate=='+' ){ - sgn = +1; - }else{ - return *zDate!=0; - } - zDate++; - if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){ - return 1; - } - zDate += 5; - p->tz = sgn*(nMn + nHr*60); - while( isspace(*(u8*)zDate) ){ zDate++; } - return *zDate!=0; -} - -/* -** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF. -** The HH, MM, and SS must each be exactly 2 digits. The -** fractional seconds FFFF can be one or more digits. -** -** Return 1 if there is a parsing error and 0 on success. -*/ -static int parseHhMmSs(const char *zDate, DateTime *p){ - int h, m, s; - double ms = 0.0; - if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){ - return 1; - } - zDate += 5; - if( *zDate==':' ){ - zDate++; - if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){ - return 1; - } - zDate += 2; - if( *zDate=='.' && isdigit((u8)zDate[1]) ){ - double rScale = 1.0; - zDate++; - while( isdigit(*(u8*)zDate) ){ - ms = ms*10.0 + *zDate - '0'; - rScale *= 10.0; - zDate++; - } - ms /= rScale; - } - }else{ - s = 0; - } - p->validJD = 0; - p->validHMS = 1; - p->h = h; - p->m = m; - p->s = s + ms; - if( parseTimezone(zDate, p) ) return 1; - p->validTZ = p->tz!=0; - return 0; -} - -/* -** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume -** that the YYYY-MM-DD is according to the Gregorian calendar. -** -** Reference: Meeus page 61 -*/ -static void computeJD(DateTime *p){ - int Y, M, D, A, B, X1, X2; - - if( p->validJD ) return; - if( p->validYMD ){ - Y = p->Y; - M = p->M; - D = p->D; - }else{ - Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */ - M = 1; - D = 1; - } - if( M<=2 ){ - Y--; - M += 12; - } - A = Y/100; - B = 2 - A + (A/4); - X1 = 365.25*(Y+4716); - X2 = 30.6001*(M+1); - p->rJD = X1 + X2 + D + B - 1524.5; - p->validJD = 1; - if( p->validHMS ){ - p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0; - if( p->validTZ ){ - p->rJD -= p->tz*60/86400.0; - p->validYMD = 0; - p->validHMS = 0; - p->validTZ = 0; - } - } -} - -/* -** Parse dates of the form -** -** YYYY-MM-DD HH:MM:SS.FFF -** YYYY-MM-DD HH:MM:SS -** YYYY-MM-DD HH:MM -** YYYY-MM-DD -** -** Write the result into the DateTime structure and return 0 -** on success and 1 if the input string is not a well-formed -** date. -*/ -static int parseYyyyMmDd(const char *zDate, DateTime *p){ - int Y, M, D, neg; - - if( zDate[0]=='-' ){ - zDate++; - neg = 1; - }else{ - neg = 0; - } - if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){ - return 1; - } - zDate += 10; - while( isspace(*(u8*)zDate) || 'T'==*(u8*)zDate ){ zDate++; } - if( parseHhMmSs(zDate, p)==0 ){ - /* We got the time */ - }else if( *zDate==0 ){ - p->validHMS = 0; - }else{ - return 1; - } - p->validJD = 0; - p->validYMD = 1; - p->Y = neg ? -Y : Y; - p->M = M; - p->D = D; - if( p->validTZ ){ - computeJD(p); - } - return 0; -} - -/* -** Attempt to parse the given string into a Julian Day Number. Return -** the number of errors. -** -** The following are acceptable forms for the input string: -** -** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM -** DDDD.DD -** now -** -** In the first form, the +/-HH:MM is always optional. The fractional -** seconds extension (the ".FFF") is optional. The seconds portion -** (":SS.FFF") is option. The year and date can be omitted as long -** as there is a time string. The time string can be omitted as long -** as there is a year and date. -*/ -static int parseDateOrTime( - sqlite3_context *context, - const char *zDate, - DateTime *p -){ - memset(p, 0, sizeof(*p)); - if( parseYyyyMmDd(zDate,p)==0 ){ - return 0; - }else if( parseHhMmSs(zDate, p)==0 ){ - return 0; - }else if( sqlite3StrICmp(zDate,"now")==0){ - double r; - sqlite3OsCurrentTime((sqlite3_vfs *)sqlite3_user_data(context), &r); - p->rJD = r; - p->validJD = 1; - return 0; - }else if( sqlite3IsNumber(zDate, 0, SQLITE_UTF8) ){ - getValue(zDate, &p->rJD); - p->validJD = 1; - return 0; - } - return 1; -} - -/* -** Compute the Year, Month, and Day from the julian day number. -*/ -static void computeYMD(DateTime *p){ - int Z, A, B, C, D, E, X1; - if( p->validYMD ) return; - if( !p->validJD ){ - p->Y = 2000; - p->M = 1; - p->D = 1; - }else{ - Z = p->rJD + 0.5; - A = (Z - 1867216.25)/36524.25; - A = Z + 1 + A - (A/4); - B = A + 1524; - C = (B - 122.1)/365.25; - D = 365.25*C; - E = (B-D)/30.6001; - X1 = 30.6001*E; - p->D = B - D - X1; - p->M = E<14 ? E-1 : E-13; - p->Y = p->M>2 ? C - 4716 : C - 4715; - } - p->validYMD = 1; -} - -/* -** Compute the Hour, Minute, and Seconds from the julian day number. -*/ -static void computeHMS(DateTime *p){ - int Z, s; - if( p->validHMS ) return; - computeJD(p); - Z = p->rJD + 0.5; - s = (p->rJD + 0.5 - Z)*86400000.0 + 0.5; - p->s = 0.001*s; - s = p->s; - p->s -= s; - p->h = s/3600; - s -= p->h*3600; - p->m = s/60; - p->s += s - p->m*60; - p->validHMS = 1; -} - -/* -** Compute both YMD and HMS -*/ -static void computeYMD_HMS(DateTime *p){ - computeYMD(p); - computeHMS(p); -} - -/* -** Clear the YMD and HMS and the TZ -*/ -static void clearYMD_HMS_TZ(DateTime *p){ - p->validYMD = 0; - p->validHMS = 0; - p->validTZ = 0; -} - -/* -** Compute the difference (in days) between localtime and UTC (a.k.a. GMT) -** for the time value p where p is in UTC. -*/ -static double localtimeOffset(DateTime *p){ - DateTime x, y; - time_t t; - x = *p; - computeYMD_HMS(&x); - if( x.Y<1971 || x.Y>=2038 ){ - x.Y = 2000; - x.M = 1; - x.D = 1; - x.h = 0; - x.m = 0; - x.s = 0.0; - } else { - int s = x.s + 0.5; - x.s = s; - } - x.tz = 0; - x.validJD = 0; - computeJD(&x); - t = (x.rJD-2440587.5)*86400.0 + 0.5; -#ifdef HAVE_LOCALTIME_R - { - struct tm sLocal; - localtime_r(&t, &sLocal); - y.Y = sLocal.tm_year + 1900; - y.M = sLocal.tm_mon + 1; - y.D = sLocal.tm_mday; - y.h = sLocal.tm_hour; - y.m = sLocal.tm_min; - y.s = sLocal.tm_sec; - } -#else - { - struct tm *pTm; - sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); - pTm = localtime(&t); - y.Y = pTm->tm_year + 1900; - y.M = pTm->tm_mon + 1; - y.D = pTm->tm_mday; - y.h = pTm->tm_hour; - y.m = pTm->tm_min; - y.s = pTm->tm_sec; - sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); - } -#endif - y.validYMD = 1; - y.validHMS = 1; - y.validJD = 0; - y.validTZ = 0; - computeJD(&y); - return y.rJD - x.rJD; -} - -/* -** Process a modifier to a date-time stamp. The modifiers are -** as follows: -** -** NNN days -** NNN hours -** NNN minutes -** NNN.NNNN seconds -** NNN months -** NNN years -** start of month -** start of year -** start of week -** start of day -** weekday N -** unixepoch -** localtime -** utc -** -** Return 0 on success and 1 if there is any kind of error. -*/ -static int parseModifier(const char *zMod, DateTime *p){ - int rc = 1; - int n; - double r; - char *z, zBuf[30]; - z = zBuf; - for(n=0; nrJD += localtimeOffset(p); - clearYMD_HMS_TZ(p); - rc = 0; - } - break; - } - case 'u': { - /* - ** unixepoch - ** - ** Treat the current value of p->rJD as the number of - ** seconds since 1970. Convert to a real julian day number. - */ - if( strcmp(z, "unixepoch")==0 && p->validJD ){ - p->rJD = p->rJD/86400.0 + 2440587.5; - clearYMD_HMS_TZ(p); - rc = 0; - }else if( strcmp(z, "utc")==0 ){ - double c1; - computeJD(p); - c1 = localtimeOffset(p); - p->rJD -= c1; - clearYMD_HMS_TZ(p); - p->rJD += c1 - localtimeOffset(p); - rc = 0; - } - break; - } - case 'w': { - /* - ** weekday N - ** - ** Move the date to the same time on the next occurrence of - ** weekday N where 0==Sunday, 1==Monday, and so forth. If the - ** date is already on the appropriate weekday, this is a no-op. - */ - if( strncmp(z, "weekday ", 8)==0 && getValue(&z[8],&r)>0 - && (n=r)==r && n>=0 && r<7 ){ - int Z; - computeYMD_HMS(p); - p->validTZ = 0; - p->validJD = 0; - computeJD(p); - Z = p->rJD + 1.5; - Z %= 7; - if( Z>n ) Z -= 7; - p->rJD += n - Z; - clearYMD_HMS_TZ(p); - rc = 0; - } - break; - } - case 's': { - /* - ** start of TTTTT - ** - ** Move the date backwards to the beginning of the current day, - ** or month or year. - */ - if( strncmp(z, "start of ", 9)!=0 ) break; - z += 9; - computeYMD(p); - p->validHMS = 1; - p->h = p->m = 0; - p->s = 0.0; - p->validTZ = 0; - p->validJD = 0; - if( strcmp(z,"month")==0 ){ - p->D = 1; - rc = 0; - }else if( strcmp(z,"year")==0 ){ - computeYMD(p); - p->M = 1; - p->D = 1; - rc = 0; - }else if( strcmp(z,"day")==0 ){ - rc = 0; - } - break; - } - case '+': - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': { - n = getValue(z, &r); - assert( n>=1 ); - if( z[n]==':' ){ - /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the - ** specified number of hours, minutes, seconds, and fractional seconds - ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be - ** omitted. - */ - const char *z2 = z; - DateTime tx; - int day; - if( !isdigit(*(u8*)z2) ) z2++; - memset(&tx, 0, sizeof(tx)); - if( parseHhMmSs(z2, &tx) ) break; - computeJD(&tx); - tx.rJD -= 0.5; - day = (int)tx.rJD; - tx.rJD -= day; - if( z[0]=='-' ) tx.rJD = -tx.rJD; - computeJD(p); - clearYMD_HMS_TZ(p); - p->rJD += tx.rJD; - rc = 0; - break; - } - z += n; - while( isspace(*(u8*)z) ) z++; - n = strlen(z); - if( n>10 || n<3 ) break; - if( z[n-1]=='s' ){ z[n-1] = 0; n--; } - computeJD(p); - rc = 0; - if( n==3 && strcmp(z,"day")==0 ){ - p->rJD += r; - }else if( n==4 && strcmp(z,"hour")==0 ){ - p->rJD += r/24.0; - }else if( n==6 && strcmp(z,"minute")==0 ){ - p->rJD += r/(24.0*60.0); - }else if( n==6 && strcmp(z,"second")==0 ){ - p->rJD += r/(24.0*60.0*60.0); - }else if( n==5 && strcmp(z,"month")==0 ){ - int x, y; - computeYMD_HMS(p); - p->M += r; - x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; - p->Y += x; - p->M -= x*12; - p->validJD = 0; - computeJD(p); - y = r; - if( y!=r ){ - p->rJD += (r - y)*30.0; - } - }else if( n==4 && strcmp(z,"year")==0 ){ - computeYMD_HMS(p); - p->Y += r; - p->validJD = 0; - computeJD(p); - }else{ - rc = 1; - } - clearYMD_HMS_TZ(p); - break; - } - default: { - break; - } - } - return rc; -} - -/* -** Process time function arguments. argv[0] is a date-time stamp. -** argv[1] and following are modifiers. Parse them all and write -** the resulting time into the DateTime structure p. Return 0 -** on success and 1 if there are any errors. -*/ -static int isDate( - sqlite3_context *context, - int argc, - sqlite3_value **argv, - DateTime *p -){ - int i; - const unsigned char *z; - if( argc==0 ) return 1; - z = sqlite3_value_text(argv[0]); - if( !z || parseDateOrTime(context, (char*)z, p) ){ - return 1; - } - for(i=1; iSQLITE_MAX_LENGTH ){ - sqlite3_result_error_toobig(context); - return; - }else{ - z = sqlite3_malloc( n ); - if( z==0 ) return; - } - computeJD(&x); - computeYMD_HMS(&x); - for(i=j=0; zFmt[i]; i++){ - if( zFmt[i]!='%' ){ - z[j++] = zFmt[i]; - }else{ - i++; - switch( zFmt[i] ){ - case 'd': sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break; - case 'f': { - double s = x.s; - if( s>59.999 ) s = 59.999; - sqlite3_snprintf(7, &z[j],"%06.3f", s); - j += strlen(&z[j]); - break; - } - case 'H': sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break; - case 'W': /* Fall thru */ - case 'j': { - int nDay; /* Number of days since 1st day of year */ - DateTime y = x; - y.validJD = 0; - y.M = 1; - y.D = 1; - computeJD(&y); - nDay = x.rJD - y.rJD + 0.5; - if( zFmt[i]=='W' ){ - int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ - wd = ((int)(x.rJD+0.5)) % 7; - sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7); - j += 2; - }else{ - sqlite3_snprintf(4, &z[j],"%03d",nDay+1); - j += 3; - } - break; - } - case 'J': { - sqlite3_snprintf(20, &z[j],"%.16g",x.rJD); - j+=strlen(&z[j]); - break; - } - case 'm': sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break; - case 'M': sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break; - case 's': { - sqlite3_snprintf(30,&z[j],"%d", - (int)((x.rJD-2440587.5)*86400.0 + 0.5)); - j += strlen(&z[j]); - break; - } - case 'S': sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break; - case 'w': z[j++] = (((int)(x.rJD+1.5)) % 7) + '0'; break; - case 'Y': sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=strlen(&z[j]);break; - case '%': z[j++] = '%'; break; - } - } - } - z[j] = 0; - sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT); - if( z!=zBuf ){ - sqlite3_free(z); - } -} - -/* -** current_time() -** -** This function returns the same value as time('now'). -*/ -static void ctimeFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - sqlite3_value *pVal = sqlite3ValueNew(0); - if( pVal ){ - sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC); - timeFunc(context, 1, &pVal); - sqlite3ValueFree(pVal); - } -} - -/* -** current_date() -** -** This function returns the same value as date('now'). -*/ -static void cdateFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - sqlite3_value *pVal = sqlite3ValueNew(0); - if( pVal ){ - sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC); - dateFunc(context, 1, &pVal); - sqlite3ValueFree(pVal); - } -} - -/* -** current_timestamp() -** -** This function returns the same value as datetime('now'). -*/ -static void ctimestampFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - sqlite3_value *pVal = sqlite3ValueNew(0); - if( pVal ){ - sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC); - datetimeFunc(context, 1, &pVal); - sqlite3ValueFree(pVal); - } -} -#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */ - -#ifdef SQLITE_OMIT_DATETIME_FUNCS -/* -** If the library is compiled to omit the full-scale date and time -** handling (to get a smaller binary), the following minimal version -** of the functions current_time(), current_date() and current_timestamp() -** are included instead. This is to support column declarations that -** include "DEFAULT CURRENT_TIME" etc. -** -** This function uses the C-library functions time(), gmtime() -** and strftime(). The format string to pass to strftime() is supplied -** as the user-data for the function. -*/ -static void currentTimeFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - time_t t; - char *zFormat = (char *)sqlite3_user_data(context); - char zBuf[20]; - - time(&t); -#ifdef SQLITE_TEST - { - extern int sqlite3_current_time; /* See os_XXX.c */ - if( sqlite3_current_time ){ - t = sqlite3_current_time; - } - } -#endif - -#ifdef HAVE_GMTIME_R - { - struct tm sNow; - gmtime_r(&t, &sNow); - strftime(zBuf, 20, zFormat, &sNow); - } -#else - { - struct tm *pTm; - sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); - pTm = gmtime(&t); - strftime(zBuf, 20, zFormat, pTm); - sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); - } -#endif - - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); -} -#endif - -/* -** This function registered all of the above C functions as SQL -** functions. This should be the only routine in this file with -** external linkage. -*/ -void sqlite3RegisterDateTimeFunctions(sqlite3 *db){ -#ifndef SQLITE_OMIT_DATETIME_FUNCS - static const struct { - char *zName; - int nArg; - void (*xFunc)(sqlite3_context*,int,sqlite3_value**); - } aFuncs[] = { - { "julianday", -1, juliandayFunc }, - { "date", -1, dateFunc }, - { "time", -1, timeFunc }, - { "datetime", -1, datetimeFunc }, - { "strftime", -1, strftimeFunc }, - { "current_time", 0, ctimeFunc }, - { "current_timestamp", 0, ctimestampFunc }, - { "current_date", 0, cdateFunc }, - }; - int i; - - for(i=0; ipVfs), aFuncs[i].xFunc, 0, 0); - } -#else - static const struct { - char *zName; - char *zFormat; - } aFuncs[] = { - { "current_time", "%H:%M:%S" }, - { "current_date", "%Y-%m-%d" }, - { "current_timestamp", "%Y-%m-%d %H:%M:%S" } - }; - int i; - - for(i=0; izErrMsg and return NULL. If all tables -** are found, return a pointer to the last table. -*/ -Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ - Table *pTab = 0; - int i; - struct SrcList_item *pItem; - for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ - pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase); - sqlite3DeleteTable(pItem->pTab); - pItem->pTab = pTab; - if( pTab ){ - pTab->nRef++; - } - } - return pTab; -} - -/* -** Check to make sure the given table is writable. If it is not -** writable, generate an error message and return 1. If it is -** writable return 0; -*/ -int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ - if( (pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0 - && pParse->nested==0) -#ifndef SQLITE_OMIT_VIRTUALTABLE - || (pTab->pMod && pTab->pMod->pModule->xUpdate==0) -#endif - ){ - sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); - return 1; - } -#ifndef SQLITE_OMIT_VIEW - if( !viewOk && pTab->pSelect ){ - sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); - return 1; - } -#endif - return 0; -} - -/* -** Generate code that will open a table for reading. -*/ -void sqlite3OpenTable( - Parse *p, /* Generate code into this VDBE */ - int iCur, /* The cursor number of the table */ - int iDb, /* The database index in sqlite3.aDb[] */ - Table *pTab, /* The table to be opened */ - int opcode /* OP_OpenRead or OP_OpenWrite */ -){ - Vdbe *v; - if( IsVirtual(pTab) ) return; - v = sqlite3GetVdbe(p); - assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); - sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName); - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); - VdbeComment((v, "# %s", pTab->zName)); - sqlite3VdbeAddOp(v, opcode, iCur, pTab->tnum); - sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol); -} - - -/* -** Generate code for a DELETE FROM statement. -** -** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL; -** \________/ \________________/ -** pTabList pWhere -*/ -void sqlite3DeleteFrom( - Parse *pParse, /* The parser context */ - SrcList *pTabList, /* The table from which we should delete things */ - Expr *pWhere /* The WHERE clause. May be null */ -){ - Vdbe *v; /* The virtual database engine */ - Table *pTab; /* The table from which records will be deleted */ - const char *zDb; /* Name of database holding pTab */ - int end, addr = 0; /* A couple addresses of generated code */ - int i; /* Loop counter */ - WhereInfo *pWInfo; /* Information about the WHERE clause */ - Index *pIdx; /* For looping over indices of the table */ - int iCur; /* VDBE Cursor number for pTab */ - sqlite3 *db; /* Main database structure */ - AuthContext sContext; /* Authorization context */ - int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */ - NameContext sNC; /* Name context to resolve expressions in */ - int iDb; /* Database number */ - int memCnt = 0; /* Memory cell used for change counting */ - -#ifndef SQLITE_OMIT_TRIGGER - int isView; /* True if attempting to delete from a view */ - int triggers_exist = 0; /* True if any triggers exist */ -#endif - - sContext.pParse = 0; - db = pParse->db; - if( pParse->nErr || db->mallocFailed ){ - goto delete_from_cleanup; - } - assert( pTabList->nSrc==1 ); - - /* Locate the table which we want to delete. This table has to be - ** put in an SrcList structure because some of the subroutines we - ** will be calling are designed to work with multiple tables and expect - ** an SrcList* parameter instead of just a Table* parameter. - */ - pTab = sqlite3SrcListLookup(pParse, pTabList); - if( pTab==0 ) goto delete_from_cleanup; - - /* Figure out if we have any triggers and if the table being - ** deleted from is a view - */ -#ifndef SQLITE_OMIT_TRIGGER - triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0); - isView = pTab->pSelect!=0; -#else -# define triggers_exist 0 -# define isView 0 -#endif -#ifdef SQLITE_OMIT_VIEW -# undef isView -# define isView 0 -#endif - - if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){ - goto delete_from_cleanup; - } - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDbnDb ); - zDb = db->aDb[iDb].zName; - if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ - goto delete_from_cleanup; - } - - /* If pTab is really a view, make sure it has been initialized. - */ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto delete_from_cleanup; - } - - /* Allocate a cursor used to store the old.* data for a trigger. - */ - if( triggers_exist ){ - oldIdx = pParse->nTab++; - } - - /* Resolve the column names in the WHERE clause. - */ - assert( pTabList->nSrc==1 ); - iCur = pTabList->a[0].iCursor = pParse->nTab++; - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - sNC.pSrcList = pTabList; - if( sqlite3ExprResolveNames(&sNC, pWhere) ){ - goto delete_from_cleanup; - } - - /* Start the view context - */ - if( isView ){ - sqlite3AuthContextPush(pParse, &sContext, pTab->zName); - } - - /* Begin generating code. - */ - v = sqlite3GetVdbe(pParse); - if( v==0 ){ - goto delete_from_cleanup; - } - if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, triggers_exist, iDb); - - /* If we are trying to delete from a view, realize that view into - ** a ephemeral table. - */ - if( isView ){ - Select *pView = sqlite3SelectDup(db, pTab->pSelect); - sqlite3Select(pParse, pView, SRT_EphemTab, iCur, 0, 0, 0, 0); - sqlite3SelectDelete(pView); - } - - /* Initialize the counter of the number of rows deleted, if - ** we are counting rows. - */ - if( db->flags & SQLITE_CountRows ){ - memCnt = pParse->nMem++; - sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt); - } - - /* Special case: A DELETE without a WHERE clause deletes everything. - ** It is easier just to erase the whole table. Note, however, that - ** this means that the row change count will be incorrect. - */ - if( pWhere==0 && !triggers_exist && !IsVirtual(pTab) ){ - if( db->flags & SQLITE_CountRows ){ - /* If counting rows deleted, just count the total number of - ** entries in the table. */ - int endOfLoop = sqlite3VdbeMakeLabel(v); - int addr2; - if( !isView ){ - sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); - } - sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2); - addr2 = sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt); - sqlite3VdbeAddOp(v, OP_Next, iCur, addr2); - sqlite3VdbeResolveLabel(v, endOfLoop); - sqlite3VdbeAddOp(v, OP_Close, iCur, 0); - } - if( !isView ){ - sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, iDb); - if( !pParse->nested ){ - sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC); - } - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - assert( pIdx->pSchema==pTab->pSchema ); - sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, iDb); - } - } - } - /* The usual case: There is a WHERE clause so we have to scan through - ** the table and pick which records to delete. - */ - else{ - /* Begin the database scan - */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0); - if( pWInfo==0 ) goto delete_from_cleanup; - - /* Remember the rowid of every item to be deleted. - */ - sqlite3VdbeAddOp(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0); - sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0); - if( db->flags & SQLITE_CountRows ){ - sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt); - } - - /* End the database scan loop. - */ - sqlite3WhereEnd(pWInfo); - - /* Open the pseudo-table used to store OLD if there are triggers. - */ - if( triggers_exist ){ - sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0); - sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol); - } - - /* Delete every item whose key was written to the list during the - ** database scan. We have to delete items after the scan is complete - ** because deleting an item can change the scan order. - */ - end = sqlite3VdbeMakeLabel(v); - - /* This is the beginning of the delete loop when there are - ** row triggers. - */ - if( triggers_exist ){ - addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end); - if( !isView ){ - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); - } - sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); - sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); - sqlite3VdbeAddOp(v, OP_RowData, iCur, 0); - sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0); - if( !isView ){ - sqlite3VdbeAddOp(v, OP_Close, iCur, 0); - } - - (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab, - -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default, - addr); - } - - if( !isView ){ - /* Open cursors for the table we are deleting from and all its - ** indices. If there are row triggers, this happens inside the - ** OP_FifoRead loop because the cursor have to all be closed - ** before the trigger fires. If there are no row triggers, the - ** cursors are opened only once on the outside the loop. - */ - sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite); - - /* This is the beginning of the delete loop when there are no - ** row triggers */ - if( !triggers_exist ){ - addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end); - } - - /* Delete the row */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - pParse->pVirtualLock = pTab; - sqlite3VdbeOp3(v, OP_VUpdate, 0, 1, (const char*)pTab->pVtab, P3_VTAB); - }else -#endif - { - sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0); - } - } - - /* If there are row triggers, close all cursors then invoke - ** the AFTER triggers - */ - if( triggers_exist ){ - if( !isView ){ - for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ - sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum); - } - sqlite3VdbeAddOp(v, OP_Close, iCur, 0); - } - (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1, - oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default, - addr); - } - - /* End of the delete loop */ - sqlite3VdbeAddOp(v, OP_Goto, 0, addr); - sqlite3VdbeResolveLabel(v, end); - - /* Close the cursors after the loop if there are no row triggers */ - if( !triggers_exist && !IsVirtual(pTab) ){ - for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ - sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum); - } - sqlite3VdbeAddOp(v, OP_Close, iCur, 0); - } - } - - /* - ** Return the number of rows that were deleted. If this routine is - ** generating code because of a call to sqlite3NestedParse(), do not - ** invoke the callback function. - */ - if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){ - sqlite3VdbeAddOp(v, OP_MemLoad, memCnt, 0); - sqlite3VdbeAddOp(v, OP_Callback, 1, 0); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P3_STATIC); - } - -delete_from_cleanup: - sqlite3AuthContextPop(&sContext); - sqlite3SrcListDelete(pTabList); - sqlite3ExprDelete(pWhere); - return; -} - -/* -** This routine generates VDBE code that causes a single row of a -** single table to be deleted. -** -** The VDBE must be in a particular state when this routine is called. -** These are the requirements: -** -** 1. A read/write cursor pointing to pTab, the table containing the row -** to be deleted, must be opened as cursor number "base". -** -** 2. Read/write cursors for all indices of pTab must be open as -** cursor number base+i for the i-th index. -** -** 3. The record number of the row to be deleted must be on the top -** of the stack. -** -** This routine pops the top of the stack to remove the record number -** and then generates code to remove both the table record and all index -** entries that point to that record. -*/ -void sqlite3GenerateRowDelete( - sqlite3 *db, /* The database containing the index */ - Vdbe *v, /* Generate code into this VDBE */ - Table *pTab, /* Table containing the row to be deleted */ - int iCur, /* Cursor number for the table */ - int count /* Increment the row change counter */ -){ - int addr; - addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0); - sqlite3GenerateRowIndexDelete(v, pTab, iCur, 0); - sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0)); - if( count ){ - sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC); - } - sqlite3VdbeJumpHere(v, addr); -} - -/* -** This routine generates VDBE code that causes the deletion of all -** index entries associated with a single row of a single table. -** -** The VDBE must be in a particular state when this routine is called. -** These are the requirements: -** -** 1. A read/write cursor pointing to pTab, the table containing the row -** to be deleted, must be opened as cursor number "iCur". -** -** 2. Read/write cursors for all indices of pTab must be open as -** cursor number iCur+i for the i-th index. -** -** 3. The "iCur" cursor must be pointing to the row that is to be -** deleted. -*/ -void sqlite3GenerateRowIndexDelete( - Vdbe *v, /* Generate code into this VDBE */ - Table *pTab, /* Table containing the row to be deleted */ - int iCur, /* Cursor number for the table */ - char *aIdxUsed /* Only delete if aIdxUsed!=0 && aIdxUsed[i]!=0 */ -){ - int i; - Index *pIdx; - - for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ - if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue; - sqlite3GenerateIndexKey(v, pIdx, iCur); - sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0); - } -} - -/* -** Generate code that will assemble an index key and put it on the top -** of the tack. The key with be for index pIdx which is an index on pTab. -** iCur is the index of a cursor open on the pTab table and pointing to -** the entry that needs indexing. -*/ -void sqlite3GenerateIndexKey( - Vdbe *v, /* Generate code into this VDBE */ - Index *pIdx, /* The index for which to generate a key */ - int iCur /* Cursor number for the pIdx->pTable table */ -){ - int j; - Table *pTab = pIdx->pTable; - - sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); - for(j=0; jnColumn; j++){ - int idx = pIdx->aiColumn[j]; - if( idx==pTab->iPKey ){ - sqlite3VdbeAddOp(v, OP_Dup, j, 0); - }else{ - sqlite3VdbeAddOp(v, OP_Column, iCur, idx); - sqlite3ColumnDefault(v, pTab, idx); - } - } - sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0); - sqlite3IndexAffinityStr(v, pIdx); -} diff --git a/extensions/sqlite/sqlite-source/expr.c b/extensions/sqlite/sqlite-source/expr.c deleted file mode 100644 index a18eeb7c..00000000 --- a/extensions/sqlite/sqlite-source/expr.c +++ /dev/null @@ -1,2617 +0,0 @@ -/* -** 2001 September 15 -** -** 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 file contains routines used for analyzing expressions and -** for generating VDBE code that evaluates expressions in SQLite. -** -** $Id$ -*/ -#include "sqliteInt.h" -#include - -/* -** Return the 'affinity' of the expression pExpr if any. -** -** If pExpr is a column, a reference to a column via an 'AS' alias, -** or a sub-select with a column as the return value, then the -** affinity of that column is returned. Otherwise, 0x00 is returned, -** indicating no affinity for the expression. -** -** i.e. the WHERE clause expresssions in the following statements all -** have an affinity: -** -** CREATE TABLE t1(a); -** SELECT * FROM t1 WHERE a; -** SELECT a AS b FROM t1 WHERE b; -** SELECT * FROM t1 WHERE (select a from t1); -*/ -char sqlite3ExprAffinity(Expr *pExpr){ - int op = pExpr->op; - if( op==TK_SELECT ){ - return sqlite3ExprAffinity(pExpr->pSelect->pEList->a[0].pExpr); - } -#ifndef SQLITE_OMIT_CAST - if( op==TK_CAST ){ - return sqlite3AffinityType(&pExpr->token); - } -#endif - return pExpr->affinity; -} - -/* -** Set the collating sequence for expression pExpr to be the collating -** sequence named by pToken. Return a pointer to the revised expression. -** The collating sequence is marked as "explicit" using the EP_ExpCollate -** flag. An explicit collating sequence will override implicit -** collating sequences. -*/ -Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pName){ - CollSeq *pColl; - if( pExpr==0 ) return 0; - pColl = sqlite3LocateCollSeq(pParse, (char*)pName->z, pName->n); - if( pColl ){ - pExpr->pColl = pColl; - pExpr->flags |= EP_ExpCollate; - } - return pExpr; -} - -/* -** Return the default collation sequence for the expression pExpr. If -** there is no default collation type, return 0. -*/ -CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ - CollSeq *pColl = 0; - if( pExpr ){ - int op; - pColl = pExpr->pColl; - op = pExpr->op; - if( (op==TK_CAST || op==TK_UPLUS) && !pColl ){ - return sqlite3ExprCollSeq(pParse, pExpr->pLeft); - } - } - if( sqlite3CheckCollSeq(pParse, pColl) ){ - pColl = 0; - } - return pColl; -} - -/* -** pExpr is an operand of a comparison operator. aff2 is the -** type affinity of the other operand. This routine returns the -** type affinity that should be used for the comparison operator. -*/ -char sqlite3CompareAffinity(Expr *pExpr, char aff2){ - char aff1 = sqlite3ExprAffinity(pExpr); - if( aff1 && aff2 ){ - /* Both sides of the comparison are columns. If one has numeric - ** affinity, use that. Otherwise use no affinity. - */ - if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){ - return SQLITE_AFF_NUMERIC; - }else{ - return SQLITE_AFF_NONE; - } - }else if( !aff1 && !aff2 ){ - /* Neither side of the comparison is a column. Compare the - ** results directly. - */ - return SQLITE_AFF_NONE; - }else{ - /* One side is a column, the other is not. Use the columns affinity. */ - assert( aff1==0 || aff2==0 ); - return (aff1 + aff2); - } -} - -/* -** pExpr is a comparison operator. Return the type affinity that should -** be applied to both operands prior to doing the comparison. -*/ -static char comparisonAffinity(Expr *pExpr){ - char aff; - assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT || - pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE || - pExpr->op==TK_NE ); - assert( pExpr->pLeft ); - aff = sqlite3ExprAffinity(pExpr->pLeft); - if( pExpr->pRight ){ - aff = sqlite3CompareAffinity(pExpr->pRight, aff); - } - else if( pExpr->pSelect ){ - aff = sqlite3CompareAffinity(pExpr->pSelect->pEList->a[0].pExpr, aff); - } - else if( !aff ){ - aff = SQLITE_AFF_NONE; - } - return aff; -} - -/* -** pExpr is a comparison expression, eg. '=', '<', IN(...) etc. -** idx_affinity is the affinity of an indexed column. Return true -** if the index with affinity idx_affinity may be used to implement -** the comparison in pExpr. -*/ -int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){ - char aff = comparisonAffinity(pExpr); - switch( aff ){ - case SQLITE_AFF_NONE: - return 1; - case SQLITE_AFF_TEXT: - return idx_affinity==SQLITE_AFF_TEXT; - default: - return sqlite3IsNumericAffinity(idx_affinity); - } -} - -/* -** Return the P1 value that should be used for a binary comparison -** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2. -** If jumpIfNull is true, then set the low byte of the returned -** P1 value to tell the opcode to jump if either expression -** evaluates to NULL. -*/ -static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){ - char aff = sqlite3ExprAffinity(pExpr2); - return ((int)sqlite3CompareAffinity(pExpr1, aff))+(jumpIfNull?0x100:0); -} - -/* -** Return a pointer to the collation sequence that should be used by -** a binary comparison operator comparing pLeft and pRight. -** -** If the left hand expression has a collating sequence type, then it is -** used. Otherwise the collation sequence for the right hand expression -** is used, or the default (BINARY) if neither expression has a collating -** type. -** -** Argument pRight (but not pLeft) may be a null pointer. In this case, -** it is not considered. -*/ -CollSeq *sqlite3BinaryCompareCollSeq( - Parse *pParse, - Expr *pLeft, - Expr *pRight -){ - CollSeq *pColl; - assert( pLeft ); - if( pLeft->flags & EP_ExpCollate ){ - assert( pLeft->pColl ); - pColl = pLeft->pColl; - }else if( pRight && pRight->flags & EP_ExpCollate ){ - assert( pRight->pColl ); - pColl = pRight->pColl; - }else{ - pColl = sqlite3ExprCollSeq(pParse, pLeft); - if( !pColl ){ - pColl = sqlite3ExprCollSeq(pParse, pRight); - } - } - return pColl; -} - -/* -** Generate code for a comparison operator. -*/ -static int codeCompare( - Parse *pParse, /* The parsing (and code generating) context */ - Expr *pLeft, /* The left operand */ - Expr *pRight, /* The right operand */ - int opcode, /* The comparison opcode */ - int dest, /* Jump here if true. */ - int jumpIfNull /* If true, jump if either operand is NULL */ -){ - int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull); - CollSeq *p3 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); - return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void*)p3, P3_COLLSEQ); -} - -/* -** Construct a new expression node and return a pointer to it. Memory -** for this node is obtained from sqlite3_malloc(). The calling function -** is responsible for making sure the node eventually gets freed. -*/ -Expr *sqlite3Expr( - sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ - int op, /* Expression opcode */ - Expr *pLeft, /* Left operand */ - Expr *pRight, /* Right operand */ - const Token *pToken /* Argument token */ -){ - Expr *pNew; - pNew = sqlite3DbMallocZero(db, sizeof(Expr)); - if( pNew==0 ){ - /* When malloc fails, delete pLeft and pRight. Expressions passed to - ** this function must always be allocated with sqlite3Expr() for this - ** reason. - */ - sqlite3ExprDelete(pLeft); - sqlite3ExprDelete(pRight); - return 0; - } - pNew->op = op; - pNew->pLeft = pLeft; - pNew->pRight = pRight; - pNew->iAgg = -1; - if( pToken ){ - assert( pToken->dyn==0 ); - pNew->span = pNew->token = *pToken; - }else if( pLeft ){ - if( pRight ){ - sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span); - if( pRight->flags & EP_ExpCollate ){ - pNew->flags |= EP_ExpCollate; - pNew->pColl = pRight->pColl; - } - } - if( pLeft->flags & EP_ExpCollate ){ - pNew->flags |= EP_ExpCollate; - pNew->pColl = pLeft->pColl; - } - } - - sqlite3ExprSetHeight(pNew); - return pNew; -} - -/* -** Works like sqlite3Expr() except that it takes an extra Parse* -** argument and notifies the associated connection object if malloc fails. -*/ -Expr *sqlite3PExpr( - Parse *pParse, /* Parsing context */ - int op, /* Expression opcode */ - Expr *pLeft, /* Left operand */ - Expr *pRight, /* Right operand */ - const Token *pToken /* Argument token */ -){ - return sqlite3Expr(pParse->db, op, pLeft, pRight, pToken); -} - -/* -** When doing a nested parse, you can include terms in an expression -** that look like this: #0 #1 #2 ... These terms refer to elements -** on the stack. "#0" means the top of the stack. -** "#1" means the next down on the stack. And so forth. -** -** This routine is called by the parser to deal with on of those terms. -** It immediately generates code to store the value in a memory location. -** The returns an expression that will code to extract the value from -** that memory location as needed. -*/ -Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){ - Vdbe *v = pParse->pVdbe; - Expr *p; - int depth; - if( pParse->nested==0 ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken); - return sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); - } - if( v==0 ) return 0; - p = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, pToken); - if( p==0 ){ - return 0; /* Malloc failed */ - } - depth = atoi((char*)&pToken->z[1]); - p->iTable = pParse->nMem++; - sqlite3VdbeAddOp(v, OP_Dup, depth, 0); - sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1); - return p; -} - -/* -** Join two expressions using an AND operator. If either expression is -** NULL, then just return the other expression. -*/ -Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){ - if( pLeft==0 ){ - return pRight; - }else if( pRight==0 ){ - return pLeft; - }else{ - return sqlite3Expr(db, TK_AND, pLeft, pRight, 0); - } -} - -/* -** Set the Expr.span field of the given expression to span all -** text between the two given tokens. -*/ -void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){ - assert( pRight!=0 ); - assert( pLeft!=0 ); - if( pExpr && pRight->z && pLeft->z ){ - assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 ); - if( pLeft->dyn==0 && pRight->dyn==0 ){ - pExpr->span.z = pLeft->z; - pExpr->span.n = pRight->n + (pRight->z - pLeft->z); - }else{ - pExpr->span.z = 0; - } - } -} - -/* -** Construct a new expression node for a function with multiple -** arguments. -*/ -Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ - Expr *pNew; - assert( pToken ); - pNew = sqlite3DbMallocZero(pParse->db, sizeof(Expr) ); - if( pNew==0 ){ - sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */ - return 0; - } - pNew->op = TK_FUNCTION; - pNew->pList = pList; - assert( pToken->dyn==0 ); - pNew->token = *pToken; - pNew->span = pNew->token; - - sqlite3ExprSetHeight(pNew); - return pNew; -} - -/* -** Assign a variable number to an expression that encodes a wildcard -** in the original SQL statement. -** -** Wildcards consisting of a single "?" are assigned the next sequential -** variable number. -** -** Wildcards of the form "?nnn" are assigned the number "nnn". We make -** sure "nnn" is not too be to avoid a denial of service attack when -** the SQL statement comes from an external source. -** -** Wildcards of the form ":aaa" or "$aaa" are assigned the same number -** as the previous instance of the same wildcard. Or if this is the first -** instance of the wildcard, the next sequenial variable number is -** assigned. -*/ -void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ - Token *pToken; - sqlite3 *db = pParse->db; - - if( pExpr==0 ) return; - pToken = &pExpr->token; - assert( pToken->n>=1 ); - assert( pToken->z!=0 ); - assert( pToken->z[0]!=0 ); - if( pToken->n==1 ){ - /* Wildcard of the form "?". Assign the next variable number */ - pExpr->iTable = ++pParse->nVar; - }else if( pToken->z[0]=='?' ){ - /* Wildcard of the form "?nnn". Convert "nnn" to an integer and - ** use it as the variable number */ - int i; - pExpr->iTable = i = atoi((char*)&pToken->z[1]); - if( i<1 || i>SQLITE_MAX_VARIABLE_NUMBER ){ - sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", - SQLITE_MAX_VARIABLE_NUMBER); - } - if( i>pParse->nVar ){ - pParse->nVar = i; - } - }else{ - /* Wildcards of the form ":aaa" or "$aaa". Reuse the same variable - ** number as the prior appearance of the same name, or if the name - ** has never appeared before, reuse the same variable number - */ - int i, n; - n = pToken->n; - for(i=0; inVarExpr; i++){ - Expr *pE; - if( (pE = pParse->apVarExpr[i])!=0 - && pE->token.n==n - && memcmp(pE->token.z, pToken->z, n)==0 ){ - pExpr->iTable = pE->iTable; - break; - } - } - if( i>=pParse->nVarExpr ){ - pExpr->iTable = ++pParse->nVar; - if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ - pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; - pParse->apVarExpr = - sqlite3DbReallocOrFree( - db, - pParse->apVarExpr, - pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) - ); - } - if( !db->mallocFailed ){ - assert( pParse->apVarExpr!=0 ); - pParse->apVarExpr[pParse->nVarExpr++] = pExpr; - } - } - } - if( !pParse->nErr && pParse->nVar>SQLITE_MAX_VARIABLE_NUMBER ){ - sqlite3ErrorMsg(pParse, "too many SQL variables"); - } -} - -/* -** Recursively delete an expression tree. -*/ -void sqlite3ExprDelete(Expr *p){ - if( p==0 ) return; - if( p->span.dyn ) sqlite3_free((char*)p->span.z); - if( p->token.dyn ) sqlite3_free((char*)p->token.z); - sqlite3ExprDelete(p->pLeft); - sqlite3ExprDelete(p->pRight); - sqlite3ExprListDelete(p->pList); - sqlite3SelectDelete(p->pSelect); - sqlite3_free(p); -} - -/* -** The Expr.token field might be a string literal that is quoted. -** If so, remove the quotation marks. -*/ -void sqlite3DequoteExpr(sqlite3 *db, Expr *p){ - if( ExprHasAnyProperty(p, EP_Dequoted) ){ - return; - } - ExprSetProperty(p, EP_Dequoted); - if( p->token.dyn==0 ){ - sqlite3TokenCopy(db, &p->token, &p->token); - } - sqlite3Dequote((char*)p->token.z); -} - - -/* -** The following group of routines make deep copies of expressions, -** expression lists, ID lists, and select statements. The copies can -** be deleted (by being passed to their respective ...Delete() routines) -** without effecting the originals. -** -** The expression list, ID, and source lists return by sqlite3ExprListDup(), -** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded -** by subsequent calls to sqlite*ListAppend() routines. -** -** Any tables that the SrcList might point to are not duplicated. -*/ -Expr *sqlite3ExprDup(sqlite3 *db, Expr *p){ - Expr *pNew; - if( p==0 ) return 0; - pNew = sqlite3DbMallocRaw(db, sizeof(*p) ); - if( pNew==0 ) return 0; - memcpy(pNew, p, sizeof(*pNew)); - if( p->token.z!=0 ){ - pNew->token.z = (u8*)sqlite3DbStrNDup(db, (char*)p->token.z, p->token.n); - pNew->token.dyn = 1; - }else{ - assert( pNew->token.z==0 ); - } - pNew->span.z = 0; - pNew->pLeft = sqlite3ExprDup(db, p->pLeft); - pNew->pRight = sqlite3ExprDup(db, p->pRight); - pNew->pList = sqlite3ExprListDup(db, p->pList); - pNew->pSelect = sqlite3SelectDup(db, p->pSelect); - return pNew; -} -void sqlite3TokenCopy(sqlite3 *db, Token *pTo, Token *pFrom){ - if( pTo->dyn ) sqlite3_free((char*)pTo->z); - if( pFrom->z ){ - pTo->n = pFrom->n; - pTo->z = (u8*)sqlite3DbStrNDup(db, (char*)pFrom->z, pFrom->n); - pTo->dyn = 1; - }else{ - pTo->z = 0; - } -} -ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p){ - ExprList *pNew; - struct ExprList_item *pItem, *pOldItem; - int i; - if( p==0 ) return 0; - pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); - if( pNew==0 ) return 0; - pNew->iECursor = 0; - pNew->nExpr = pNew->nAlloc = p->nExpr; - pNew->a = pItem = sqlite3DbMallocRaw(db, p->nExpr*sizeof(p->a[0]) ); - if( pItem==0 ){ - sqlite3_free(pNew); - return 0; - } - pOldItem = p->a; - for(i=0; inExpr; i++, pItem++, pOldItem++){ - Expr *pNewExpr, *pOldExpr; - pItem->pExpr = pNewExpr = sqlite3ExprDup(db, pOldExpr = pOldItem->pExpr); - if( pOldExpr->span.z!=0 && pNewExpr ){ - /* Always make a copy of the span for top-level expressions in the - ** expression list. The logic in SELECT processing that determines - ** the names of columns in the result set needs this information */ - sqlite3TokenCopy(db, &pNewExpr->span, &pOldExpr->span); - } - assert( pNewExpr==0 || pNewExpr->span.z!=0 - || pOldExpr->span.z==0 - || db->mallocFailed ); - pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); - pItem->sortOrder = pOldItem->sortOrder; - pItem->isAgg = pOldItem->isAgg; - pItem->done = 0; - } - return pNew; -} - -/* -** If cursors, triggers, views and subqueries are all omitted from -** the build, then none of the following routines, except for -** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes -** called with a NULL argument. -*/ -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ - || !defined(SQLITE_OMIT_SUBQUERY) -SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p){ - SrcList *pNew; - int i; - int nByte; - if( p==0 ) return 0; - nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); - pNew = sqlite3DbMallocRaw(db, nByte ); - if( pNew==0 ) return 0; - pNew->nSrc = pNew->nAlloc = p->nSrc; - for(i=0; inSrc; i++){ - struct SrcList_item *pNewItem = &pNew->a[i]; - struct SrcList_item *pOldItem = &p->a[i]; - Table *pTab; - pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); - pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); - pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); - pNewItem->jointype = pOldItem->jointype; - pNewItem->iCursor = pOldItem->iCursor; - pNewItem->isPopulated = pOldItem->isPopulated; - pTab = pNewItem->pTab = pOldItem->pTab; - if( pTab ){ - pTab->nRef++; - } - pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect); - pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn); - pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing); - pNewItem->colUsed = pOldItem->colUsed; - } - return pNew; -} -IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ - IdList *pNew; - int i; - if( p==0 ) return 0; - pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); - if( pNew==0 ) return 0; - pNew->nId = pNew->nAlloc = p->nId; - pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) ); - if( pNew->a==0 ){ - sqlite3_free(pNew); - return 0; - } - for(i=0; inId; i++){ - struct IdList_item *pNewItem = &pNew->a[i]; - struct IdList_item *pOldItem = &p->a[i]; - pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); - pNewItem->idx = pOldItem->idx; - } - return pNew; -} -Select *sqlite3SelectDup(sqlite3 *db, Select *p){ - Select *pNew; - if( p==0 ) return 0; - pNew = sqlite3DbMallocRaw(db, sizeof(*p) ); - if( pNew==0 ) return 0; - pNew->isDistinct = p->isDistinct; - pNew->pEList = sqlite3ExprListDup(db, p->pEList); - pNew->pSrc = sqlite3SrcListDup(db, p->pSrc); - pNew->pWhere = sqlite3ExprDup(db, p->pWhere); - pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy); - pNew->pHaving = sqlite3ExprDup(db, p->pHaving); - pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy); - pNew->op = p->op; - pNew->pPrior = sqlite3SelectDup(db, p->pPrior); - pNew->pLimit = sqlite3ExprDup(db, p->pLimit); - pNew->pOffset = sqlite3ExprDup(db, p->pOffset); - pNew->iLimit = -1; - pNew->iOffset = -1; - pNew->isResolved = p->isResolved; - pNew->isAgg = p->isAgg; - pNew->usesEphm = 0; - pNew->disallowOrderBy = 0; - pNew->pRightmost = 0; - pNew->addrOpenEphm[0] = -1; - pNew->addrOpenEphm[1] = -1; - pNew->addrOpenEphm[2] = -1; - return pNew; -} -#else -Select *sqlite3SelectDup(sqlite3 *db, Select *p){ - assert( p==0 ); - return 0; -} -#endif - - -/* -** Add a new element to the end of an expression list. If pList is -** initially NULL, then create a new expression list. -*/ -ExprList *sqlite3ExprListAppend( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* List to which to append. Might be NULL */ - Expr *pExpr, /* Expression to be appended */ - Token *pName /* AS keyword for the expression */ -){ - sqlite3 *db = pParse->db; - if( pList==0 ){ - pList = sqlite3DbMallocZero(db, sizeof(ExprList) ); - if( pList==0 ){ - goto no_mem; - } - assert( pList->nAlloc==0 ); - } - if( pList->nAlloc<=pList->nExpr ){ - struct ExprList_item *a; - int n = pList->nAlloc*2 + 4; - a = sqlite3DbRealloc(db, pList->a, n*sizeof(pList->a[0])); - if( a==0 ){ - goto no_mem; - } - pList->a = a; - pList->nAlloc = n; - } - assert( pList->a!=0 ); - if( pExpr || pName ){ - struct ExprList_item *pItem = &pList->a[pList->nExpr++]; - memset(pItem, 0, sizeof(*pItem)); - pItem->zName = sqlite3NameFromToken(db, pName); - pItem->pExpr = pExpr; - } - return pList; - -no_mem: - /* Avoid leaking memory if malloc has failed. */ - sqlite3ExprDelete(pExpr); - sqlite3ExprListDelete(pList); - return 0; -} - -/* -** If the expression list pEList contains more than iLimit elements, -** leave an error message in pParse. -*/ -void sqlite3ExprListCheckLength( - Parse *pParse, - ExprList *pEList, - int iLimit, - const char *zObject -){ - if( pEList && pEList->nExpr>iLimit ){ - sqlite3ErrorMsg(pParse, "too many columns in %s", zObject); - } -} - - -#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0 -/* The following three functions, heightOfExpr(), heightOfExprList() -** and heightOfSelect(), are used to determine the maximum height -** of any expression tree referenced by the structure passed as the -** first argument. -** -** If this maximum height is greater than the current value pointed -** to by pnHeight, the second parameter, then set *pnHeight to that -** value. -*/ -static void heightOfExpr(Expr *p, int *pnHeight){ - if( p ){ - if( p->nHeight>*pnHeight ){ - *pnHeight = p->nHeight; - } - } -} -static void heightOfExprList(ExprList *p, int *pnHeight){ - if( p ){ - int i; - for(i=0; inExpr; i++){ - heightOfExpr(p->a[i].pExpr, pnHeight); - } - } -} -static void heightOfSelect(Select *p, int *pnHeight){ - if( p ){ - heightOfExpr(p->pWhere, pnHeight); - heightOfExpr(p->pHaving, pnHeight); - heightOfExpr(p->pLimit, pnHeight); - heightOfExpr(p->pOffset, pnHeight); - heightOfExprList(p->pEList, pnHeight); - heightOfExprList(p->pGroupBy, pnHeight); - heightOfExprList(p->pOrderBy, pnHeight); - heightOfSelect(p->pPrior, pnHeight); - } -} - -/* -** Set the Expr.nHeight variable in the structure passed as an -** argument. An expression with no children, Expr.pList or -** Expr.pSelect member has a height of 1. Any other expression -** has a height equal to the maximum height of any other -** referenced Expr plus one. -*/ -void sqlite3ExprSetHeight(Expr *p){ - int nHeight = 0; - heightOfExpr(p->pLeft, &nHeight); - heightOfExpr(p->pRight, &nHeight); - heightOfExprList(p->pList, &nHeight); - heightOfSelect(p->pSelect, &nHeight); - p->nHeight = nHeight + 1; -} - -/* -** Return the maximum height of any expression tree referenced -** by the select statement passed as an argument. -*/ -int sqlite3SelectExprHeight(Select *p){ - int nHeight = 0; - heightOfSelect(p, &nHeight); - return nHeight; -} -#endif - -/* -** Delete an entire expression list. -*/ -void sqlite3ExprListDelete(ExprList *pList){ - int i; - struct ExprList_item *pItem; - if( pList==0 ) return; - assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) ); - assert( pList->nExpr<=pList->nAlloc ); - for(pItem=pList->a, i=0; inExpr; i++, pItem++){ - sqlite3ExprDelete(pItem->pExpr); - sqlite3_free(pItem->zName); - } - sqlite3_free(pList->a); - sqlite3_free(pList); -} - -/* -** Walk an expression tree. Call xFunc for each node visited. -** -** The return value from xFunc determines whether the tree walk continues. -** 0 means continue walking the tree. 1 means do not walk children -** of the current node but continue with siblings. 2 means abandon -** the tree walk completely. -** -** The return value from this routine is 1 to abandon the tree walk -** and 0 to continue. -** -** NOTICE: This routine does *not* descend into subqueries. -*/ -static int walkExprList(ExprList *, int (*)(void *, Expr*), void *); -static int walkExprTree(Expr *pExpr, int (*xFunc)(void*,Expr*), void *pArg){ - int rc; - if( pExpr==0 ) return 0; - rc = (*xFunc)(pArg, pExpr); - if( rc==0 ){ - if( walkExprTree(pExpr->pLeft, xFunc, pArg) ) return 1; - if( walkExprTree(pExpr->pRight, xFunc, pArg) ) return 1; - if( walkExprList(pExpr->pList, xFunc, pArg) ) return 1; - } - return rc>1; -} - -/* -** Call walkExprTree() for every expression in list p. -*/ -static int walkExprList(ExprList *p, int (*xFunc)(void *, Expr*), void *pArg){ - int i; - struct ExprList_item *pItem; - if( !p ) return 0; - for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ - if( walkExprTree(pItem->pExpr, xFunc, pArg) ) return 1; - } - return 0; -} - -/* -** Call walkExprTree() for every expression in Select p, not including -** expressions that are part of sub-selects in any FROM clause or the LIMIT -** or OFFSET expressions.. -*/ -static int walkSelectExpr(Select *p, int (*xFunc)(void *, Expr*), void *pArg){ - walkExprList(p->pEList, xFunc, pArg); - walkExprTree(p->pWhere, xFunc, pArg); - walkExprList(p->pGroupBy, xFunc, pArg); - walkExprTree(p->pHaving, xFunc, pArg); - walkExprList(p->pOrderBy, xFunc, pArg); - if( p->pPrior ){ - walkSelectExpr(p->pPrior, xFunc, pArg); - } - return 0; -} - - -/* -** This routine is designed as an xFunc for walkExprTree(). -** -** pArg is really a pointer to an integer. If we can tell by looking -** at pExpr that the expression that contains pExpr is not a constant -** expression, then set *pArg to 0 and return 2 to abandon the tree walk. -** If pExpr does does not disqualify the expression from being a constant -** then do nothing. -** -** After walking the whole tree, if no nodes are found that disqualify -** the expression as constant, then we assume the whole expression -** is constant. See sqlite3ExprIsConstant() for additional information. -*/ -static int exprNodeIsConstant(void *pArg, Expr *pExpr){ - int *pN = (int*)pArg; - - /* If *pArg is 3 then any term of the expression that comes from - ** the ON or USING clauses of a join disqualifies the expression - ** from being considered constant. */ - if( (*pN)==3 && ExprHasAnyProperty(pExpr, EP_FromJoin) ){ - *pN = 0; - return 2; - } - - switch( pExpr->op ){ - /* Consider functions to be constant if all their arguments are constant - ** and *pArg==2 */ - case TK_FUNCTION: - if( (*pN)==2 ) return 0; - /* Fall through */ - case TK_ID: - case TK_COLUMN: - case TK_DOT: - case TK_AGG_FUNCTION: - case TK_AGG_COLUMN: -#ifndef SQLITE_OMIT_SUBQUERY - case TK_SELECT: - case TK_EXISTS: -#endif - *pN = 0; - return 2; - case TK_IN: - if( pExpr->pSelect ){ - *pN = 0; - return 2; - } - default: - return 0; - } -} - -/* -** Walk an expression tree. Return 1 if the expression is constant -** and 0 if it involves variables or function calls. -** -** For the purposes of this function, a double-quoted string (ex: "abc") -** is considered a variable but a single-quoted string (ex: 'abc') is -** a constant. -*/ -int sqlite3ExprIsConstant(Expr *p){ - int isConst = 1; - walkExprTree(p, exprNodeIsConstant, &isConst); - return isConst; -} - -/* -** Walk an expression tree. Return 1 if the expression is constant -** that does no originate from the ON or USING clauses of a join. -** Return 0 if it involves variables or function calls or terms from -** an ON or USING clause. -*/ -int sqlite3ExprIsConstantNotJoin(Expr *p){ - int isConst = 3; - walkExprTree(p, exprNodeIsConstant, &isConst); - return isConst!=0; -} - -/* -** Walk an expression tree. Return 1 if the expression is constant -** or a function call with constant arguments. Return and 0 if there -** are any variables. -** -** For the purposes of this function, a double-quoted string (ex: "abc") -** is considered a variable but a single-quoted string (ex: 'abc') is -** a constant. -*/ -int sqlite3ExprIsConstantOrFunction(Expr *p){ - int isConst = 2; - walkExprTree(p, exprNodeIsConstant, &isConst); - return isConst!=0; -} - -/* -** If the expression p codes a constant integer that is small enough -** to fit in a 32-bit integer, return 1 and put the value of the integer -** in *pValue. If the expression is not an integer or if it is too big -** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. -*/ -int sqlite3ExprIsInteger(Expr *p, int *pValue){ - switch( p->op ){ - case TK_INTEGER: { - if( sqlite3GetInt32((char*)p->token.z, pValue) ){ - return 1; - } - break; - } - case TK_UPLUS: { - return sqlite3ExprIsInteger(p->pLeft, pValue); - } - case TK_UMINUS: { - int v; - if( sqlite3ExprIsInteger(p->pLeft, &v) ){ - *pValue = -v; - return 1; - } - break; - } - default: break; - } - return 0; -} - -/* -** Return TRUE if the given string is a row-id column name. -*/ -int sqlite3IsRowid(const char *z){ - if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1; - if( sqlite3StrICmp(z, "ROWID")==0 ) return 1; - if( sqlite3StrICmp(z, "OID")==0 ) return 1; - return 0; -} - -/* -** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up -** that name in the set of source tables in pSrcList and make the pExpr -** expression node refer back to that source column. The following changes -** are made to pExpr: -** -** pExpr->iDb Set the index in db->aDb[] of the database holding -** the table. -** pExpr->iTable Set to the cursor number for the table obtained -** from pSrcList. -** pExpr->iColumn Set to the column number within the table. -** pExpr->op Set to TK_COLUMN. -** pExpr->pLeft Any expression this points to is deleted -** pExpr->pRight Any expression this points to is deleted. -** -** The pDbToken is the name of the database (the "X"). This value may be -** NULL meaning that name is of the form Y.Z or Z. Any available database -** can be used. The pTableToken is the name of the table (the "Y"). This -** value can be NULL if pDbToken is also NULL. If pTableToken is NULL it -** means that the form of the name is Z and that columns from any table -** can be used. -** -** If the name cannot be resolved unambiguously, leave an error message -** in pParse and return non-zero. Return zero on success. -*/ -static int lookupName( - Parse *pParse, /* The parsing context */ - Token *pDbToken, /* Name of the database containing table, or NULL */ - Token *pTableToken, /* Name of table containing column, or NULL */ - Token *pColumnToken, /* Name of the column. */ - NameContext *pNC, /* The name context used to resolve the name */ - Expr *pExpr /* Make this EXPR node point to the selected column */ -){ - char *zDb = 0; /* Name of the database. The "X" in X.Y.Z */ - char *zTab = 0; /* Name of the table. The "Y" in X.Y.Z or Y.Z */ - char *zCol = 0; /* Name of the column. The "Z" */ - int i, j; /* Loop counters */ - int cnt = 0; /* Number of matching column names */ - int cntTab = 0; /* Number of matching table names */ - sqlite3 *db = pParse->db; /* The database */ - struct SrcList_item *pItem; /* Use for looping over pSrcList items */ - struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ - NameContext *pTopNC = pNC; /* First namecontext in the list */ - Schema *pSchema = 0; /* Schema of the expression */ - - assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ - zDb = sqlite3NameFromToken(db, pDbToken); - zTab = sqlite3NameFromToken(db, pTableToken); - zCol = sqlite3NameFromToken(db, pColumnToken); - if( db->mallocFailed ){ - goto lookupname_end; - } - - pExpr->iTable = -1; - while( pNC && cnt==0 ){ - ExprList *pEList; - SrcList *pSrcList = pNC->pSrcList; - - if( pSrcList ){ - for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ - Table *pTab; - int iDb; - Column *pCol; - - pTab = pItem->pTab; - assert( pTab!=0 ); - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( pTab->nCol>0 ); - if( zTab ){ - if( pItem->zAlias ){ - char *zTabName = pItem->zAlias; - if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue; - }else{ - char *zTabName = pTab->zName; - if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue; - if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){ - continue; - } - } - } - if( 0==(cntTab++) ){ - pExpr->iTable = pItem->iCursor; - pSchema = pTab->pSchema; - pMatch = pItem; - } - for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ - if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ - const char *zColl = pTab->aCol[j].zColl; - IdList *pUsing; - cnt++; - pExpr->iTable = pItem->iCursor; - pMatch = pItem; - pSchema = pTab->pSchema; - /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ - pExpr->iColumn = j==pTab->iPKey ? -1 : j; - pExpr->affinity = pTab->aCol[j].affinity; - if( (pExpr->flags & EP_ExpCollate)==0 ){ - pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); - } - if( inSrc-1 ){ - if( pItem[1].jointype & JT_NATURAL ){ - /* If this match occurred in the left table of a natural join, - ** then skip the right table to avoid a duplicate match */ - pItem++; - i++; - }else if( (pUsing = pItem[1].pUsing)!=0 ){ - /* If this match occurs on a column that is in the USING clause - ** of a join, skip the search of the right table of the join - ** to avoid a duplicate match there. */ - int k; - for(k=0; knId; k++){ - if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){ - pItem++; - i++; - break; - } - } - } - } - break; - } - } - } - } - -#ifndef SQLITE_OMIT_TRIGGER - /* If we have not already resolved the name, then maybe - ** it is a new.* or old.* trigger argument reference - */ - if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){ - TriggerStack *pTriggerStack = pParse->trigStack; - Table *pTab = 0; - if( pTriggerStack->newIdx != -1 && sqlite3StrICmp("new", zTab) == 0 ){ - pExpr->iTable = pTriggerStack->newIdx; - assert( pTriggerStack->pTab ); - pTab = pTriggerStack->pTab; - }else if( pTriggerStack->oldIdx != -1 && sqlite3StrICmp("old", zTab)==0 ){ - pExpr->iTable = pTriggerStack->oldIdx; - assert( pTriggerStack->pTab ); - pTab = pTriggerStack->pTab; - } - - if( pTab ){ - int iCol; - Column *pCol = pTab->aCol; - - pSchema = pTab->pSchema; - cntTab++; - for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) { - if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ - const char *zColl = pTab->aCol[iCol].zColl; - cnt++; - pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol; - pExpr->affinity = pTab->aCol[iCol].affinity; - if( (pExpr->flags & EP_ExpCollate)==0 ){ - pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); - } - pExpr->pTab = pTab; - break; - } - } - } - } -#endif /* !defined(SQLITE_OMIT_TRIGGER) */ - - /* - ** Perhaps the name is a reference to the ROWID - */ - if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){ - cnt = 1; - pExpr->iColumn = -1; - pExpr->affinity = SQLITE_AFF_INTEGER; - } - - /* - ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z - ** might refer to an result-set alias. This happens, for example, when - ** we are resolving names in the WHERE clause of the following command: - ** - ** SELECT a+b AS x FROM table WHERE x<10; - ** - ** In cases like this, replace pExpr with a copy of the expression that - ** forms the result set entry ("a+b" in the example) and return immediately. - ** Note that the expression in the result set should have already been - ** resolved by the time the WHERE clause is resolved. - */ - if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){ - for(j=0; jnExpr; j++){ - char *zAs = pEList->a[j].zName; - if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ - Expr *pDup, *pOrig; - assert( pExpr->pLeft==0 && pExpr->pRight==0 ); - assert( pExpr->pList==0 ); - assert( pExpr->pSelect==0 ); - pOrig = pEList->a[j].pExpr; - if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){ - sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); - sqlite3_free(zCol); - return 2; - } - pDup = sqlite3ExprDup(db, pOrig); - if( pExpr->flags & EP_ExpCollate ){ - pDup->pColl = pExpr->pColl; - pDup->flags |= EP_ExpCollate; - } - if( pExpr->span.dyn ) sqlite3_free((char*)pExpr->span.z); - if( pExpr->token.dyn ) sqlite3_free((char*)pExpr->token.z); - memcpy(pExpr, pDup, sizeof(*pExpr)); - sqlite3_free(pDup); - cnt = 1; - pMatch = 0; - assert( zTab==0 && zDb==0 ); - goto lookupname_end_2; - } - } - } - - /* Advance to the next name context. The loop will exit when either - ** we have a match (cnt>0) or when we run out of name contexts. - */ - if( cnt==0 ){ - pNC = pNC->pNext; - } - } - - /* - ** If X and Y are NULL (in other words if only the column name Z is - ** supplied) and the value of Z is enclosed in double-quotes, then - ** Z is a string literal if it doesn't match any column names. In that - ** case, we need to return right away and not make any changes to - ** pExpr. - ** - ** Because no reference was made to outer contexts, the pNC->nRef - ** fields are not changed in any context. - */ - if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){ - sqlite3_free(zCol); - return 0; - } - - /* - ** cnt==0 means there was not match. cnt>1 means there were two or - ** more matches. Either way, we have an error. - */ - if( cnt!=1 ){ - char *z = 0; - char *zErr; - zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s"; - if( zDb ){ - sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, (char*)0); - }else if( zTab ){ - sqlite3SetString(&z, zTab, ".", zCol, (char*)0); - }else{ - z = sqlite3StrDup(zCol); - } - if( z ){ - sqlite3ErrorMsg(pParse, zErr, z); - sqlite3_free(z); - pTopNC->nErr++; - }else{ - db->mallocFailed = 1; - } - } - - /* If a column from a table in pSrcList is referenced, then record - ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes - ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the - ** column number is greater than the number of bits in the bitmask - ** then set the high-order bit of the bitmask. - */ - if( pExpr->iColumn>=0 && pMatch!=0 ){ - int n = pExpr->iColumn; - if( n>=sizeof(Bitmask)*8 ){ - n = sizeof(Bitmask)*8-1; - } - assert( pMatch->iCursor==pExpr->iTable ); - pMatch->colUsed |= ((Bitmask)1)<pLeft); - pExpr->pLeft = 0; - sqlite3ExprDelete(pExpr->pRight); - pExpr->pRight = 0; - pExpr->op = TK_COLUMN; -lookupname_end_2: - sqlite3_free(zCol); - if( cnt==1 ){ - assert( pNC!=0 ); - sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); - if( pMatch && !pMatch->pSelect ){ - pExpr->pTab = pMatch->pTab; - } - /* Increment the nRef value on all name contexts from TopNC up to - ** the point where the name matched. */ - for(;;){ - assert( pTopNC!=0 ); - pTopNC->nRef++; - if( pTopNC==pNC ) break; - pTopNC = pTopNC->pNext; - } - return 0; - } else { - return 1; - } -} - -/* -** This routine is designed as an xFunc for walkExprTree(). -** -** Resolve symbolic names into TK_COLUMN operators for the current -** node in the expression tree. Return 0 to continue the search down -** the tree or 2 to abort the tree walk. -** -** This routine also does error checking and name resolution for -** function names. The operator for aggregate functions is changed -** to TK_AGG_FUNCTION. -*/ -static int nameResolverStep(void *pArg, Expr *pExpr){ - NameContext *pNC = (NameContext*)pArg; - Parse *pParse; - - if( pExpr==0 ) return 1; - assert( pNC!=0 ); - pParse = pNC->pParse; - - if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return 1; - ExprSetProperty(pExpr, EP_Resolved); -#ifndef NDEBUG - if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){ - SrcList *pSrcList = pNC->pSrcList; - int i; - for(i=0; ipSrcList->nSrc; i++){ - assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursornTab); - } - } -#endif - switch( pExpr->op ){ - /* Double-quoted strings (ex: "abc") are used as identifiers if - ** possible. Otherwise they remain as strings. Single-quoted - ** strings (ex: 'abc') are always string literals. - */ - case TK_STRING: { - if( pExpr->token.z[0]=='\'' ) break; - /* Fall thru into the TK_ID case if this is a double-quoted string */ - } - /* A lone identifier is the name of a column. - */ - case TK_ID: { - lookupName(pParse, 0, 0, &pExpr->token, pNC, pExpr); - return 1; - } - - /* A table name and column name: ID.ID - ** Or a database, table and column: ID.ID.ID - */ - case TK_DOT: { - Token *pColumn; - Token *pTable; - Token *pDb; - Expr *pRight; - - /* if( pSrcList==0 ) break; */ - pRight = pExpr->pRight; - if( pRight->op==TK_ID ){ - pDb = 0; - pTable = &pExpr->pLeft->token; - pColumn = &pRight->token; - }else{ - assert( pRight->op==TK_DOT ); - pDb = &pExpr->pLeft->token; - pTable = &pRight->pLeft->token; - pColumn = &pRight->pRight->token; - } - lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr); - return 1; - } - - /* Resolve function names - */ - case TK_CONST_FUNC: - case TK_FUNCTION: { - ExprList *pList = pExpr->pList; /* The argument list */ - int n = pList ? pList->nExpr : 0; /* Number of arguments */ - int no_such_func = 0; /* True if no such function exists */ - int wrong_num_args = 0; /* True if wrong number of arguments */ - int is_agg = 0; /* True if is an aggregate function */ - int i; - int auth; /* Authorization to use the function */ - int nId; /* Number of characters in function name */ - const char *zId; /* The function name. */ - FuncDef *pDef; /* Information about the function */ - int enc = ENC(pParse->db); /* The database encoding */ - - zId = (char*)pExpr->token.z; - nId = pExpr->token.n; - pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); - if( pDef==0 ){ - pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0); - if( pDef==0 ){ - no_such_func = 1; - }else{ - wrong_num_args = 1; - } - }else{ - is_agg = pDef->xFunc==0; - } -#ifndef SQLITE_OMIT_AUTHORIZATION - if( pDef ){ - auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0); - if( auth!=SQLITE_OK ){ - if( auth==SQLITE_DENY ){ - sqlite3ErrorMsg(pParse, "not authorized to use function: %s", - pDef->zName); - pNC->nErr++; - } - pExpr->op = TK_NULL; - return 1; - } - } -#endif - if( is_agg && !pNC->allowAgg ){ - sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); - pNC->nErr++; - is_agg = 0; - }else if( no_such_func ){ - sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); - pNC->nErr++; - }else if( wrong_num_args ){ - sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", - nId, zId); - pNC->nErr++; - } - if( is_agg ){ - pExpr->op = TK_AGG_FUNCTION; - pNC->hasAgg = 1; - } - if( is_agg ) pNC->allowAgg = 0; - for(i=0; pNC->nErr==0 && ia[i].pExpr, nameResolverStep, pNC); - } - if( is_agg ) pNC->allowAgg = 1; - /* FIX ME: Compute pExpr->affinity based on the expected return - ** type of the function - */ - return is_agg; - } -#ifndef SQLITE_OMIT_SUBQUERY - case TK_SELECT: - case TK_EXISTS: -#endif - case TK_IN: { - if( pExpr->pSelect ){ - int nRef = pNC->nRef; -#ifndef SQLITE_OMIT_CHECK - if( pNC->isCheck ){ - sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints"); - } -#endif - sqlite3SelectResolve(pParse, pExpr->pSelect, pNC); - assert( pNC->nRef>=nRef ); - if( nRef!=pNC->nRef ){ - ExprSetProperty(pExpr, EP_VarSelect); - } - } - break; - } -#ifndef SQLITE_OMIT_CHECK - case TK_VARIABLE: { - if( pNC->isCheck ){ - sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints"); - } - break; - } -#endif - } - return 0; -} - -/* -** This routine walks an expression tree and resolves references to -** table columns. Nodes of the form ID.ID or ID resolve into an -** index to the table in the table list and a column offset. The -** Expr.opcode for such nodes is changed to TK_COLUMN. The Expr.iTable -** value is changed to the index of the referenced table in pTabList -** plus the "base" value. The base value will ultimately become the -** VDBE cursor number for a cursor that is pointing into the referenced -** table. The Expr.iColumn value is changed to the index of the column -** of the referenced table. The Expr.iColumn value for the special -** ROWID column is -1. Any INTEGER PRIMARY KEY column is tried as an -** alias for ROWID. -** -** Also resolve function names and check the functions for proper -** usage. Make sure all function names are recognized and all functions -** have the correct number of arguments. Leave an error message -** in pParse->zErrMsg if anything is amiss. Return the number of errors. -** -** If the expression contains aggregate functions then set the EP_Agg -** property on the expression. -*/ -int sqlite3ExprResolveNames( - NameContext *pNC, /* Namespace to resolve expressions in. */ - Expr *pExpr /* The expression to be analyzed. */ -){ - int savedHasAgg; - if( pExpr==0 ) return 0; -#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0 - if( (pExpr->nHeight+pNC->pParse->nHeight)>SQLITE_MAX_EXPR_DEPTH ){ - sqlite3ErrorMsg(pNC->pParse, - "Expression tree is too large (maximum depth %d)", - SQLITE_MAX_EXPR_DEPTH - ); - return 1; - } - pNC->pParse->nHeight += pExpr->nHeight; -#endif - savedHasAgg = pNC->hasAgg; - pNC->hasAgg = 0; - walkExprTree(pExpr, nameResolverStep, pNC); -#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0 - pNC->pParse->nHeight -= pExpr->nHeight; -#endif - if( pNC->nErr>0 ){ - ExprSetProperty(pExpr, EP_Error); - } - if( pNC->hasAgg ){ - ExprSetProperty(pExpr, EP_Agg); - }else if( savedHasAgg ){ - pNC->hasAgg = 1; - } - return ExprHasProperty(pExpr, EP_Error); -} - -/* -** A pointer instance of this structure is used to pass information -** through walkExprTree into codeSubqueryStep(). -*/ -typedef struct QueryCoder QueryCoder; -struct QueryCoder { - Parse *pParse; /* The parsing context */ - NameContext *pNC; /* Namespace of first enclosing query */ -}; - - -/* -** Generate code for scalar subqueries used as an expression -** and IN operators. Examples: -** -** (SELECT a FROM b) -- subquery -** EXISTS (SELECT a FROM b) -- EXISTS subquery -** x IN (4,5,11) -- IN operator with list on right-hand side -** x IN (SELECT a FROM b) -- IN operator with subquery on the right -** -** The pExpr parameter describes the expression that contains the IN -** operator or subquery. -*/ -#ifndef SQLITE_OMIT_SUBQUERY -void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ - int testAddr = 0; /* One-time test address */ - Vdbe *v = sqlite3GetVdbe(pParse); - if( v==0 ) return; - - - /* This code must be run in its entirety every time it is encountered - ** if any of the following is true: - ** - ** * The right-hand side is a correlated subquery - ** * The right-hand side is an expression list containing variables - ** * We are inside a trigger - ** - ** If all of the above are false, then we can run this code just once - ** save the results, and reuse the same result on subsequent invocations. - */ - if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){ - int mem = pParse->nMem++; - sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0); - testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0); - assert( testAddr>0 || pParse->db->mallocFailed ); - sqlite3VdbeAddOp(v, OP_MemInt, 1, mem); - } - - switch( pExpr->op ){ - case TK_IN: { - char affinity; - KeyInfo keyInfo; - int addr; /* Address of OP_OpenEphemeral instruction */ - - affinity = sqlite3ExprAffinity(pExpr->pLeft); - - /* Whether this is an 'x IN(SELECT...)' or an 'x IN()' - ** expression it is handled the same way. A virtual table is - ** filled with single-field index keys representing the results - ** from the SELECT or the . - ** - ** If the 'x' expression is a column value, or the SELECT... - ** statement returns a column value, then the affinity of that - ** column is used to build the index keys. If both 'x' and the - ** SELECT... statement are columns, then numeric affinity is used - ** if either column has NUMERIC or INTEGER affinity. If neither - ** 'x' nor the SELECT... statement are columns, then numeric affinity - ** is used. - */ - pExpr->iTable = pParse->nTab++; - addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, pExpr->iTable, 0); - memset(&keyInfo, 0, sizeof(keyInfo)); - keyInfo.nField = 1; - sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1); - - if( pExpr->pSelect ){ - /* Case 1: expr IN (SELECT ...) - ** - ** Generate code to write the results of the select into the temporary - ** table allocated and opened above. - */ - int iParm = pExpr->iTable + (((int)affinity)<<16); - ExprList *pEList; - assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); - if( sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0) ){ - return; - } - pEList = pExpr->pSelect->pEList; - if( pEList && pEList->nExpr>0 ){ - keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, - pEList->a[0].pExpr); - } - }else if( pExpr->pList ){ - /* Case 2: expr IN (exprlist) - ** - ** For each expression, build an index key from the evaluation and - ** store it in the temporary table. If is a column, then use - ** that columns affinity when building index keys. If is not - ** a column, use numeric affinity. - */ - int i; - ExprList *pList = pExpr->pList; - struct ExprList_item *pItem; - - if( !affinity ){ - affinity = SQLITE_AFF_NONE; - } - keyInfo.aColl[0] = pExpr->pLeft->pColl; - - /* Loop through each expression in . */ - for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ - Expr *pE2 = pItem->pExpr; - - /* If the expression is not constant then we will need to - ** disable the test that was generated above that makes sure - ** this code only executes once. Because for a non-constant - ** expression we need to rerun this code each time. - */ - if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){ - sqlite3VdbeChangeToNoop(v, testAddr-1, 3); - testAddr = 0; - } - - /* Evaluate the expression and insert it into the temp table */ - sqlite3ExprCode(pParse, pE2); - sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); - sqlite3VdbeAddOp(v, OP_IdxInsert, pExpr->iTable, 0); - } - } - sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO); - break; - } - - case TK_EXISTS: - case TK_SELECT: { - /* This has to be a scalar SELECT. Generate code to put the - ** value of this select in a memory cell and record the number - ** of the memory cell in iColumn. - */ - static const Token one = { (u8*)"1", 0, 1 }; - Select *pSel; - int iMem; - int sop; - - pExpr->iColumn = iMem = pParse->nMem++; - pSel = pExpr->pSelect; - if( pExpr->op==TK_SELECT ){ - sop = SRT_Mem; - sqlite3VdbeAddOp(v, OP_MemNull, iMem, 0); - VdbeComment((v, "# Init subquery result")); - }else{ - sop = SRT_Exists; - sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem); - VdbeComment((v, "# Init EXISTS result")); - } - sqlite3ExprDelete(pSel->pLimit); - pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &one); - if( sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0) ){ - return; - } - break; - } - } - - if( testAddr ){ - sqlite3VdbeJumpHere(v, testAddr); - } - - return; -} -#endif /* SQLITE_OMIT_SUBQUERY */ - -/* -** Generate an instruction that will put the integer describe by -** text z[0..n-1] on the stack. -*/ -static void codeInteger(Vdbe *v, const char *z, int n){ - assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed ); - if( z ){ - int i; - if( sqlite3GetInt32(z, &i) ){ - sqlite3VdbeAddOp(v, OP_Integer, i, 0); - }else if( sqlite3FitsIn64Bits(z) ){ - sqlite3VdbeOp3(v, OP_Int64, 0, 0, z, n); - }else{ - sqlite3VdbeOp3(v, OP_Real, 0, 0, z, n); - } - } -} - - -/* -** Generate code that will extract the iColumn-th column from -** table pTab and push that column value on the stack. There -** is an open cursor to pTab in iTable. If iColumn<0 then -** code is generated that extracts the rowid. -*/ -void sqlite3ExprCodeGetColumn(Vdbe *v, Table *pTab, int iColumn, int iTable){ - if( iColumn<0 ){ - int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid; - sqlite3VdbeAddOp(v, op, iTable, 0); - }else if( pTab==0 ){ - sqlite3VdbeAddOp(v, OP_Column, iTable, iColumn); - }else{ - int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; - sqlite3VdbeAddOp(v, op, iTable, iColumn); - sqlite3ColumnDefault(v, pTab, iColumn); -#ifndef SQLITE_OMIT_FLOATING_POINT - if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){ - sqlite3VdbeAddOp(v, OP_RealAffinity, 0, 0); - } -#endif - } -} - -/* -** Generate code into the current Vdbe to evaluate the given -** expression and leave the result on the top of stack. -** -** This code depends on the fact that certain token values (ex: TK_EQ) -** are the same as opcode values (ex: OP_Eq) that implement the corresponding -** operation. Special comments in vdbe.c and the mkopcodeh.awk script in -** the make process cause these values to align. Assert()s in the code -** below verify that the numbers are aligned correctly. -*/ -void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ - Vdbe *v = pParse->pVdbe; - int op; - int stackChng = 1; /* Amount of change to stack depth */ - - if( v==0 ) return; - if( pExpr==0 ){ - sqlite3VdbeAddOp(v, OP_Null, 0, 0); - return; - } - op = pExpr->op; - switch( op ){ - case TK_AGG_COLUMN: { - AggInfo *pAggInfo = pExpr->pAggInfo; - struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg]; - if( !pAggInfo->directMode ){ - sqlite3VdbeAddOp(v, OP_MemLoad, pCol->iMem, 0); - break; - }else if( pAggInfo->useSortingIdx ){ - sqlite3VdbeAddOp(v, OP_Column, pAggInfo->sortingIdx, - pCol->iSorterColumn); - break; - } - /* Otherwise, fall thru into the TK_COLUMN case */ - } - case TK_COLUMN: { - if( pExpr->iTable<0 ){ - /* This only happens when coding check constraints */ - assert( pParse->ckOffset>0 ); - sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1); - }else{ - sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable); - } - break; - } - case TK_INTEGER: { - codeInteger(v, (char*)pExpr->token.z, pExpr->token.n); - break; - } - case TK_FLOAT: - case TK_STRING: { - assert( TK_FLOAT==OP_Real ); - assert( TK_STRING==OP_String8 ); - sqlite3DequoteExpr(pParse->db, pExpr); - sqlite3VdbeOp3(v, op, 0, 0, (char*)pExpr->token.z, pExpr->token.n); - break; - } - case TK_NULL: { - sqlite3VdbeAddOp(v, OP_Null, 0, 0); - break; - } -#ifndef SQLITE_OMIT_BLOB_LITERAL - case TK_BLOB: { - int n; - const char *z; - assert( TK_BLOB==OP_HexBlob ); - n = pExpr->token.n - 3; - z = (char*)pExpr->token.z + 2; - assert( n>=0 ); - if( n==0 ){ - z = ""; - } - sqlite3VdbeOp3(v, op, 0, 0, z, n); - break; - } -#endif - case TK_VARIABLE: { - sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0); - if( pExpr->token.n>1 ){ - sqlite3VdbeChangeP3(v, -1, (char*)pExpr->token.z, pExpr->token.n); - } - break; - } - case TK_REGISTER: { - sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iTable, 0); - break; - } -#ifndef SQLITE_OMIT_CAST - case TK_CAST: { - /* Expressions of the form: CAST(pLeft AS token) */ - int aff, to_op; - sqlite3ExprCode(pParse, pExpr->pLeft); - aff = sqlite3AffinityType(&pExpr->token); - to_op = aff - SQLITE_AFF_TEXT + OP_ToText; - assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT ); - assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE ); - assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC ); - assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER ); - assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL ); - sqlite3VdbeAddOp(v, to_op, 0, 0); - stackChng = 0; - break; - } -#endif /* SQLITE_OMIT_CAST */ - case TK_LT: - case TK_LE: - case TK_GT: - case TK_GE: - case TK_NE: - case TK_EQ: { - assert( TK_LT==OP_Lt ); - assert( TK_LE==OP_Le ); - assert( TK_GT==OP_Gt ); - assert( TK_GE==OP_Ge ); - assert( TK_EQ==OP_Eq ); - assert( TK_NE==OP_Ne ); - sqlite3ExprCode(pParse, pExpr->pLeft); - sqlite3ExprCode(pParse, pExpr->pRight); - codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0); - stackChng = -1; - break; - } - case TK_AND: - case TK_OR: - case TK_PLUS: - case TK_STAR: - case TK_MINUS: - case TK_REM: - case TK_BITAND: - case TK_BITOR: - case TK_SLASH: - case TK_LSHIFT: - case TK_RSHIFT: - case TK_CONCAT: { - assert( TK_AND==OP_And ); - assert( TK_OR==OP_Or ); - assert( TK_PLUS==OP_Add ); - assert( TK_MINUS==OP_Subtract ); - assert( TK_REM==OP_Remainder ); - assert( TK_BITAND==OP_BitAnd ); - assert( TK_BITOR==OP_BitOr ); - assert( TK_SLASH==OP_Divide ); - assert( TK_LSHIFT==OP_ShiftLeft ); - assert( TK_RSHIFT==OP_ShiftRight ); - assert( TK_CONCAT==OP_Concat ); - sqlite3ExprCode(pParse, pExpr->pLeft); - sqlite3ExprCode(pParse, pExpr->pRight); - sqlite3VdbeAddOp(v, op, 0, 0); - stackChng = -1; - break; - } - case TK_UMINUS: { - Expr *pLeft = pExpr->pLeft; - assert( pLeft ); - if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){ - Token *p = &pLeft->token; - char *z = sqlite3MPrintf(pParse->db, "-%.*s", p->n, p->z); - if( pLeft->op==TK_FLOAT ){ - sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1); - }else{ - codeInteger(v, z, p->n+1); - } - sqlite3_free(z); - break; - } - /* Fall through into TK_NOT */ - } - case TK_BITNOT: - case TK_NOT: { - assert( TK_BITNOT==OP_BitNot ); - assert( TK_NOT==OP_Not ); - sqlite3ExprCode(pParse, pExpr->pLeft); - sqlite3VdbeAddOp(v, op, 0, 0); - stackChng = 0; - break; - } - case TK_ISNULL: - case TK_NOTNULL: { - int dest; - assert( TK_ISNULL==OP_IsNull ); - assert( TK_NOTNULL==OP_NotNull ); - sqlite3VdbeAddOp(v, OP_Integer, 1, 0); - sqlite3ExprCode(pParse, pExpr->pLeft); - dest = sqlite3VdbeCurrentAddr(v) + 2; - sqlite3VdbeAddOp(v, op, 1, dest); - sqlite3VdbeAddOp(v, OP_AddImm, -1, 0); - stackChng = 0; - break; - } - case TK_AGG_FUNCTION: { - AggInfo *pInfo = pExpr->pAggInfo; - if( pInfo==0 ){ - sqlite3ErrorMsg(pParse, "misuse of aggregate: %T", - &pExpr->span); - }else{ - sqlite3VdbeAddOp(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem, 0); - } - break; - } - case TK_CONST_FUNC: - case TK_FUNCTION: { - ExprList *pList = pExpr->pList; - int nExpr = pList ? pList->nExpr : 0; - FuncDef *pDef; - int nId; - const char *zId; - int constMask = 0; - int i; - sqlite3 *db = pParse->db; - u8 enc = ENC(db); - CollSeq *pColl = 0; - - zId = (char*)pExpr->token.z; - nId = pExpr->token.n; - pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); - assert( pDef!=0 ); - nExpr = sqlite3ExprCodeExprList(pParse, pList); -#ifndef SQLITE_OMIT_VIRTUALTABLE - /* Possibly overload the function if the first argument is - ** a virtual table column. - ** - ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the - ** second argument, not the first, as the argument to test to - ** see if it is a column in a virtual table. This is done because - ** the left operand of infix functions (the operand we want to - ** control overloading) ends up as the second argument to the - ** function. The expression "A glob B" is equivalent to - ** "glob(B,A). We want to use the A in "A glob B" to test - ** for function overloading. But we use the B term in "glob(B,A)". - */ - if( nExpr>=2 && (pExpr->flags & EP_InfixFunc) ){ - pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[1].pExpr); - }else if( nExpr>0 ){ - pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[0].pExpr); - } -#endif - for(i=0; ia[i].pExpr) ){ - constMask |= (1<needCollSeq && !pColl ){ - pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr); - } - } - if( pDef->needCollSeq ){ - if( !pColl ) pColl = pParse->db->pDfltColl; - sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ); - } - sqlite3VdbeOp3(v, OP_Function, constMask, nExpr, (char*)pDef, P3_FUNCDEF); - stackChng = 1-nExpr; - break; - } -#ifndef SQLITE_OMIT_SUBQUERY - case TK_EXISTS: - case TK_SELECT: { - if( pExpr->iColumn==0 ){ - sqlite3CodeSubselect(pParse, pExpr); - } - sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0); - VdbeComment((v, "# load subquery result")); - break; - } - case TK_IN: { - int addr; - char affinity; - int ckOffset = pParse->ckOffset; - sqlite3CodeSubselect(pParse, pExpr); - - /* Figure out the affinity to use to create a key from the results - ** of the expression. affinityStr stores a static string suitable for - ** P3 of OP_MakeRecord. - */ - affinity = comparisonAffinity(pExpr); - - sqlite3VdbeAddOp(v, OP_Integer, 1, 0); - pParse->ckOffset = (ckOffset ? (ckOffset+1) : 0); - - /* Code the from " IN (...)". The temporary table - ** pExpr->iTable contains the values that make up the (...) set. - */ - sqlite3ExprCode(pParse, pExpr->pLeft); - addr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4); /* addr + 0 */ - sqlite3VdbeAddOp(v, OP_Pop, 2, 0); - sqlite3VdbeAddOp(v, OP_Null, 0, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7); - sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); /* addr + 4 */ - sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7); - sqlite3VdbeAddOp(v, OP_AddImm, -1, 0); /* addr + 6 */ - - break; - } -#endif - case TK_BETWEEN: { - Expr *pLeft = pExpr->pLeft; - struct ExprList_item *pLItem = pExpr->pList->a; - Expr *pRight = pLItem->pExpr; - sqlite3ExprCode(pParse, pLeft); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3ExprCode(pParse, pRight); - codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0); - sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - pLItem++; - pRight = pLItem->pExpr; - sqlite3ExprCode(pParse, pRight); - codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0); - sqlite3VdbeAddOp(v, OP_And, 0, 0); - break; - } - case TK_UPLUS: { - sqlite3ExprCode(pParse, pExpr->pLeft); - stackChng = 0; - break; - } - case TK_CASE: { - int expr_end_label; - int jumpInst; - int nExpr; - int i; - ExprList *pEList; - struct ExprList_item *aListelem; - - assert(pExpr->pList); - assert((pExpr->pList->nExpr % 2) == 0); - assert(pExpr->pList->nExpr > 0); - pEList = pExpr->pList; - aListelem = pEList->a; - nExpr = pEList->nExpr; - expr_end_label = sqlite3VdbeMakeLabel(v); - if( pExpr->pLeft ){ - sqlite3ExprCode(pParse, pExpr->pLeft); - } - for(i=0; ipLeft ){ - sqlite3VdbeAddOp(v, OP_Dup, 1, 1); - jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr, - OP_Ne, 0, 1); - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - }else{ - jumpInst = sqlite3VdbeAddOp(v, OP_IfNot, 1, 0); - } - sqlite3ExprCode(pParse, aListelem[i+1].pExpr); - sqlite3VdbeAddOp(v, OP_Goto, 0, expr_end_label); - sqlite3VdbeJumpHere(v, jumpInst); - } - if( pExpr->pLeft ){ - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - } - if( pExpr->pRight ){ - sqlite3ExprCode(pParse, pExpr->pRight); - }else{ - sqlite3VdbeAddOp(v, OP_Null, 0, 0); - } - sqlite3VdbeResolveLabel(v, expr_end_label); - break; - } -#ifndef SQLITE_OMIT_TRIGGER - case TK_RAISE: { - if( !pParse->trigStack ){ - sqlite3ErrorMsg(pParse, - "RAISE() may only be used within a trigger-program"); - return; - } - if( pExpr->iColumn!=OE_Ignore ){ - assert( pExpr->iColumn==OE_Rollback || - pExpr->iColumn == OE_Abort || - pExpr->iColumn == OE_Fail ); - sqlite3DequoteExpr(pParse->db, pExpr); - sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn, - (char*)pExpr->token.z, pExpr->token.n); - } else { - assert( pExpr->iColumn == OE_Ignore ); - sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->trigStack->ignoreJump); - VdbeComment((v, "# raise(IGNORE)")); - } - stackChng = 0; - break; - } -#endif - } - - if( pParse->ckOffset ){ - pParse->ckOffset += stackChng; - assert( pParse->ckOffset ); - } -} - -#ifndef SQLITE_OMIT_TRIGGER -/* -** Generate code that evalutes the given expression and leaves the result -** on the stack. See also sqlite3ExprCode(). -** -** This routine might also cache the result and modify the pExpr tree -** so that it will make use of the cached result on subsequent evaluations -** rather than evaluate the whole expression again. Trivial expressions are -** not cached. If the expression is cached, its result is stored in a -** memory location. -*/ -void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){ - Vdbe *v = pParse->pVdbe; - int iMem; - int addr1, addr2; - if( v==0 ) return; - addr1 = sqlite3VdbeCurrentAddr(v); - sqlite3ExprCode(pParse, pExpr); - addr2 = sqlite3VdbeCurrentAddr(v); - if( addr2>addr1+1 || sqlite3VdbeGetOp(v, addr1)->opcode==OP_Function ){ - iMem = pExpr->iTable = pParse->nMem++; - sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0); - pExpr->op = TK_REGISTER; - } -} -#endif - -/* -** Generate code that pushes the value of every element of the given -** expression list onto the stack. -** -** Return the number of elements pushed onto the stack. -*/ -int sqlite3ExprCodeExprList( - Parse *pParse, /* Parsing context */ - ExprList *pList /* The expression list to be coded */ -){ - struct ExprList_item *pItem; - int i, n; - if( pList==0 ) return 0; - n = pList->nExpr; - for(pItem=pList->a, i=n; i>0; i--, pItem++){ - sqlite3ExprCode(pParse, pItem->pExpr); - } - return n; -} - -/* -** Generate code for a boolean expression such that a jump is made -** to the label "dest" if the expression is true but execution -** continues straight thru if the expression is false. -** -** If the expression evaluates to NULL (neither true nor false), then -** take the jump if the jumpIfNull flag is true. -** -** This code depends on the fact that certain token values (ex: TK_EQ) -** are the same as opcode values (ex: OP_Eq) that implement the corresponding -** operation. Special comments in vdbe.c and the mkopcodeh.awk script in -** the make process cause these values to align. Assert()s in the code -** below verify that the numbers are aligned correctly. -*/ -void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ - Vdbe *v = pParse->pVdbe; - int op = 0; - int ckOffset = pParse->ckOffset; - if( v==0 || pExpr==0 ) return; - op = pExpr->op; - switch( op ){ - case TK_AND: { - int d2 = sqlite3VdbeMakeLabel(v); - sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, !jumpIfNull); - sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3VdbeResolveLabel(v, d2); - break; - } - case TK_OR: { - sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); - sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); - break; - } - case TK_NOT: { - sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); - break; - } - case TK_LT: - case TK_LE: - case TK_GT: - case TK_GE: - case TK_NE: - case TK_EQ: { - assert( TK_LT==OP_Lt ); - assert( TK_LE==OP_Le ); - assert( TK_GT==OP_Gt ); - assert( TK_GE==OP_Ge ); - assert( TK_EQ==OP_Eq ); - assert( TK_NE==OP_Ne ); - sqlite3ExprCode(pParse, pExpr->pLeft); - sqlite3ExprCode(pParse, pExpr->pRight); - codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull); - break; - } - case TK_ISNULL: - case TK_NOTNULL: { - assert( TK_ISNULL==OP_IsNull ); - assert( TK_NOTNULL==OP_NotNull ); - sqlite3ExprCode(pParse, pExpr->pLeft); - sqlite3VdbeAddOp(v, op, 1, dest); - break; - } - case TK_BETWEEN: { - /* The expression "x BETWEEN y AND z" is implemented as: - ** - ** 1 IF (x < y) GOTO 3 - ** 2 IF (x <= z) GOTO - ** 3 ... - */ - int addr; - Expr *pLeft = pExpr->pLeft; - Expr *pRight = pExpr->pList->a[0].pExpr; - sqlite3ExprCode(pParse, pLeft); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3ExprCode(pParse, pRight); - addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull); - - pRight = pExpr->pList->a[1].pExpr; - sqlite3ExprCode(pParse, pRight); - codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull); - - sqlite3VdbeAddOp(v, OP_Integer, 0, 0); - sqlite3VdbeJumpHere(v, addr); - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - break; - } - default: { - sqlite3ExprCode(pParse, pExpr); - sqlite3VdbeAddOp(v, OP_If, jumpIfNull, dest); - break; - } - } - pParse->ckOffset = ckOffset; -} - -/* -** Generate code for a boolean expression such that a jump is made -** to the label "dest" if the expression is false but execution -** continues straight thru if the expression is true. -** -** If the expression evaluates to NULL (neither true nor false) then -** jump if jumpIfNull is true or fall through if jumpIfNull is false. -*/ -void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ - Vdbe *v = pParse->pVdbe; - int op = 0; - int ckOffset = pParse->ckOffset; - if( v==0 || pExpr==0 ) return; - - /* The value of pExpr->op and op are related as follows: - ** - ** pExpr->op op - ** --------- ---------- - ** TK_ISNULL OP_NotNull - ** TK_NOTNULL OP_IsNull - ** TK_NE OP_Eq - ** TK_EQ OP_Ne - ** TK_GT OP_Le - ** TK_LE OP_Gt - ** TK_GE OP_Lt - ** TK_LT OP_Ge - ** - ** For other values of pExpr->op, op is undefined and unused. - ** The value of TK_ and OP_ constants are arranged such that we - ** can compute the mapping above using the following expression. - ** Assert()s verify that the computation is correct. - */ - op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1); - - /* Verify correct alignment of TK_ and OP_ constants - */ - assert( pExpr->op!=TK_ISNULL || op==OP_NotNull ); - assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull ); - assert( pExpr->op!=TK_NE || op==OP_Eq ); - assert( pExpr->op!=TK_EQ || op==OP_Ne ); - assert( pExpr->op!=TK_LT || op==OP_Ge ); - assert( pExpr->op!=TK_LE || op==OP_Gt ); - assert( pExpr->op!=TK_GT || op==OP_Le ); - assert( pExpr->op!=TK_GE || op==OP_Lt ); - - switch( pExpr->op ){ - case TK_AND: { - sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); - sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); - break; - } - case TK_OR: { - int d2 = sqlite3VdbeMakeLabel(v); - sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, !jumpIfNull); - sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3VdbeResolveLabel(v, d2); - break; - } - case TK_NOT: { - sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); - break; - } - case TK_LT: - case TK_LE: - case TK_GT: - case TK_GE: - case TK_NE: - case TK_EQ: { - sqlite3ExprCode(pParse, pExpr->pLeft); - sqlite3ExprCode(pParse, pExpr->pRight); - codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull); - break; - } - case TK_ISNULL: - case TK_NOTNULL: { - sqlite3ExprCode(pParse, pExpr->pLeft); - sqlite3VdbeAddOp(v, op, 1, dest); - break; - } - case TK_BETWEEN: { - /* The expression is "x BETWEEN y AND z". It is implemented as: - ** - ** 1 IF (x >= y) GOTO 3 - ** 2 GOTO - ** 3 IF (x > z) GOTO - */ - int addr; - Expr *pLeft = pExpr->pLeft; - Expr *pRight = pExpr->pList->a[0].pExpr; - sqlite3ExprCode(pParse, pLeft); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3ExprCode(pParse, pRight); - addr = sqlite3VdbeCurrentAddr(v); - codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull); - - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, dest); - pRight = pExpr->pList->a[1].pExpr; - sqlite3ExprCode(pParse, pRight); - codeCompare(pParse, pLeft, pRight, OP_Gt, dest, jumpIfNull); - break; - } - default: { - sqlite3ExprCode(pParse, pExpr); - sqlite3VdbeAddOp(v, OP_IfNot, jumpIfNull, dest); - break; - } - } - pParse->ckOffset = ckOffset; -} - -/* -** Do a deep comparison of two expression trees. Return TRUE (non-zero) -** if they are identical and return FALSE if they differ in any way. -** -** Sometimes this routine will return FALSE even if the two expressions -** really are equivalent. If we cannot prove that the expressions are -** identical, we return FALSE just to be safe. So if this routine -** returns false, then you do not really know for certain if the two -** expressions are the same. But if you get a TRUE return, then you -** can be sure the expressions are the same. In the places where -** this routine is used, it does not hurt to get an extra FALSE - that -** just might result in some slightly slower code. But returning -** an incorrect TRUE could lead to a malfunction. -*/ -int sqlite3ExprCompare(Expr *pA, Expr *pB){ - int i; - if( pA==0||pB==0 ){ - return pB==pA; - } - if( pA->op!=pB->op ) return 0; - if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 0; - if( !sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 0; - if( !sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 0; - if( pA->pList ){ - if( pB->pList==0 ) return 0; - if( pA->pList->nExpr!=pB->pList->nExpr ) return 0; - for(i=0; ipList->nExpr; i++){ - if( !sqlite3ExprCompare(pA->pList->a[i].pExpr, pB->pList->a[i].pExpr) ){ - return 0; - } - } - }else if( pB->pList ){ - return 0; - } - if( pA->pSelect || pB->pSelect ) return 0; - if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0; - if( pA->op!=TK_COLUMN && pA->token.z ){ - if( pB->token.z==0 ) return 0; - if( pB->token.n!=pA->token.n ) return 0; - if( sqlite3StrNICmp((char*)pA->token.z,(char*)pB->token.z,pB->token.n)!=0 ){ - return 0; - } - } - return 1; -} - - -/* -** Add a new element to the pAggInfo->aCol[] array. Return the index of -** the new element. Return a negative number if malloc fails. -*/ -static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ - int i; - pInfo->aCol = sqlite3ArrayAllocate( - db, - pInfo->aCol, - sizeof(pInfo->aCol[0]), - 3, - &pInfo->nColumn, - &pInfo->nColumnAlloc, - &i - ); - return i; -} - -/* -** Add a new element to the pAggInfo->aFunc[] array. Return the index of -** the new element. Return a negative number if malloc fails. -*/ -static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){ - int i; - pInfo->aFunc = sqlite3ArrayAllocate( - db, - pInfo->aFunc, - sizeof(pInfo->aFunc[0]), - 3, - &pInfo->nFunc, - &pInfo->nFuncAlloc, - &i - ); - return i; -} - -/* -** This is an xFunc for walkExprTree() used to implement -** sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates -** for additional information. -** -** This routine analyzes the aggregate function at pExpr. -*/ -static int analyzeAggregate(void *pArg, Expr *pExpr){ - int i; - NameContext *pNC = (NameContext *)pArg; - Parse *pParse = pNC->pParse; - SrcList *pSrcList = pNC->pSrcList; - AggInfo *pAggInfo = pNC->pAggInfo; - - switch( pExpr->op ){ - case TK_AGG_COLUMN: - case TK_COLUMN: { - /* Check to see if the column is in one of the tables in the FROM - ** clause of the aggregate query */ - if( pSrcList ){ - struct SrcList_item *pItem = pSrcList->a; - for(i=0; inSrc; i++, pItem++){ - struct AggInfo_col *pCol; - if( pExpr->iTable==pItem->iCursor ){ - /* If we reach this point, it means that pExpr refers to a table - ** that is in the FROM clause of the aggregate query. - ** - ** Make an entry for the column in pAggInfo->aCol[] if there - ** is not an entry there already. - */ - int k; - pCol = pAggInfo->aCol; - for(k=0; knColumn; k++, pCol++){ - if( pCol->iTable==pExpr->iTable && - pCol->iColumn==pExpr->iColumn ){ - break; - } - } - if( (k>=pAggInfo->nColumn) - && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 - ){ - pCol = &pAggInfo->aCol[k]; - pCol->pTab = pExpr->pTab; - pCol->iTable = pExpr->iTable; - pCol->iColumn = pExpr->iColumn; - pCol->iMem = pParse->nMem++; - pCol->iSorterColumn = -1; - pCol->pExpr = pExpr; - if( pAggInfo->pGroupBy ){ - int j, n; - ExprList *pGB = pAggInfo->pGroupBy; - struct ExprList_item *pTerm = pGB->a; - n = pGB->nExpr; - for(j=0; jpExpr; - if( pE->op==TK_COLUMN && pE->iTable==pExpr->iTable && - pE->iColumn==pExpr->iColumn ){ - pCol->iSorterColumn = j; - break; - } - } - } - if( pCol->iSorterColumn<0 ){ - pCol->iSorterColumn = pAggInfo->nSortingColumn++; - } - } - /* There is now an entry for pExpr in pAggInfo->aCol[] (either - ** because it was there before or because we just created it). - ** Convert the pExpr to be a TK_AGG_COLUMN referring to that - ** pAggInfo->aCol[] entry. - */ - pExpr->pAggInfo = pAggInfo; - pExpr->op = TK_AGG_COLUMN; - pExpr->iAgg = k; - break; - } /* endif pExpr->iTable==pItem->iCursor */ - } /* end loop over pSrcList */ - } - return 1; - } - case TK_AGG_FUNCTION: { - /* The pNC->nDepth==0 test causes aggregate functions in subqueries - ** to be ignored */ - if( pNC->nDepth==0 ){ - /* Check to see if pExpr is a duplicate of another aggregate - ** function that is already in the pAggInfo structure - */ - struct AggInfo_func *pItem = pAggInfo->aFunc; - for(i=0; inFunc; i++, pItem++){ - if( sqlite3ExprCompare(pItem->pExpr, pExpr) ){ - break; - } - } - if( i>=pAggInfo->nFunc ){ - /* pExpr is original. Make a new entry in pAggInfo->aFunc[] - */ - u8 enc = ENC(pParse->db); - i = addAggInfoFunc(pParse->db, pAggInfo); - if( i>=0 ){ - pItem = &pAggInfo->aFunc[i]; - pItem->pExpr = pExpr; - pItem->iMem = pParse->nMem++; - pItem->pFunc = sqlite3FindFunction(pParse->db, - (char*)pExpr->token.z, pExpr->token.n, - pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0); - if( pExpr->flags & EP_Distinct ){ - pItem->iDistinct = pParse->nTab++; - }else{ - pItem->iDistinct = -1; - } - } - } - /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry - */ - pExpr->iAgg = i; - pExpr->pAggInfo = pAggInfo; - return 1; - } - } - } - - /* Recursively walk subqueries looking for TK_COLUMN nodes that need - ** to be changed to TK_AGG_COLUMN. But increment nDepth so that - ** TK_AGG_FUNCTION nodes in subqueries will be unchanged. - */ - if( pExpr->pSelect ){ - pNC->nDepth++; - walkSelectExpr(pExpr->pSelect, analyzeAggregate, pNC); - pNC->nDepth--; - } - return 0; -} - -/* -** Analyze the given expression looking for aggregate functions and -** for variables that need to be added to the pParse->aAgg[] array. -** Make additional entries to the pParse->aAgg[] array as necessary. -** -** This routine should only be called after the expression has been -** analyzed by sqlite3ExprResolveNames(). -** -** If errors are seen, leave an error message in zErrMsg and return -** the number of errors. -*/ -int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ - int nErr = pNC->pParse->nErr; - walkExprTree(pExpr, analyzeAggregate, pNC); - return pNC->pParse->nErr - nErr; -} - -/* -** Call sqlite3ExprAnalyzeAggregates() for every expression in an -** expression list. Return the number of errors. -** -** If an error is found, the analysis is cut short. -*/ -int sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){ - struct ExprList_item *pItem; - int i; - int nErr = 0; - if( pList ){ - for(pItem=pList->a, i=0; nErr==0 && inExpr; i++, pItem++){ - nErr += sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr); - } - } - return nErr; -} diff --git a/extensions/sqlite/sqlite-source/func.c b/extensions/sqlite/sqlite-source/func.c deleted file mode 100644 index 82ed2d47..00000000 --- a/extensions/sqlite/sqlite-source/func.c +++ /dev/null @@ -1,1509 +0,0 @@ -/* -** 2002 February 23 -** -** 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 file contains the C functions that implement various SQL -** functions of SQLite. -** -** There is only one exported symbol in this file - the function -** sqliteRegisterBuildinFunctions() found at the bottom of the file. -** All other code has file scope. -** -** $Id$ -*/ -#include "sqliteInt.h" -#include -#include -#include -#include "vdbeInt.h" - - -/* -** Return the collating function associated with a function. -*/ -static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ - return context->pColl; -} - -/* -** Implementation of the non-aggregate min() and max() functions -*/ -static void minmaxFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int i; - int mask; /* 0 for min() or 0xffffffff for max() */ - int iBest; - CollSeq *pColl; - - if( argc==0 ) return; - mask = sqlite3_user_data(context)==0 ? 0 : -1; - pColl = sqlite3GetFuncCollSeq(context); - assert( pColl ); - assert( mask==-1 || mask==0 ); - iBest = 0; - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - for(i=1; i=0 ){ - iBest = i; - } - } - sqlite3_result_value(context, argv[iBest]); -} - -/* -** Return the type of the argument. -*/ -static void typeofFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const char *z = 0; - switch( sqlite3_value_type(argv[0]) ){ - case SQLITE_NULL: z = "null"; break; - case SQLITE_INTEGER: z = "integer"; break; - case SQLITE_TEXT: z = "text"; break; - case SQLITE_FLOAT: z = "real"; break; - case SQLITE_BLOB: z = "blob"; break; - } - sqlite3_result_text(context, z, -1, SQLITE_STATIC); -} - - -/* -** Implementation of the length() function -*/ -static void lengthFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int len; - - assert( argc==1 ); - switch( sqlite3_value_type(argv[0]) ){ - case SQLITE_BLOB: - case SQLITE_INTEGER: - case SQLITE_FLOAT: { - sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); - break; - } - case SQLITE_TEXT: { - const unsigned char *z = sqlite3_value_text(argv[0]); - if( z==0 ) return; - len = 0; - while( *z ){ - len++; - SQLITE_SKIP_UTF8(z); - } - sqlite3_result_int(context, len); - break; - } - default: { - sqlite3_result_null(context); - break; - } - } -} - -/* -** Implementation of the abs() function -*/ -static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - assert( argc==1 ); - switch( sqlite3_value_type(argv[0]) ){ - case SQLITE_INTEGER: { - i64 iVal = sqlite3_value_int64(argv[0]); - if( iVal<0 ){ - if( (iVal<<1)==0 ){ - sqlite3_result_error(context, "integer overflow", -1); - return; - } - iVal = -iVal; - } - sqlite3_result_int64(context, iVal); - break; - } - case SQLITE_NULL: { - sqlite3_result_null(context); - break; - } - default: { - double rVal = sqlite3_value_double(argv[0]); - if( rVal<0 ) rVal = -rVal; - sqlite3_result_double(context, rVal); - break; - } - } -} - -/* -** Implementation of the substr() function. -** -** substr(x,p1,p2) returns p2 characters of x[] beginning with p1. -** p1 is 1-indexed. So substr(x,1,1) returns the first character -** of x. If x is text, then we actually count UTF-8 characters. -** If x is a blob, then we count bytes. -** -** If p1 is negative, then we begin abs(p1) from the end of x[]. -*/ -static void substrFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const unsigned char *z; - const unsigned char *z2; - int len; - int p0type; - i64 p1, p2; - - assert( argc==3 ); - p0type = sqlite3_value_type(argv[0]); - if( p0type==SQLITE_BLOB ){ - len = sqlite3_value_bytes(argv[0]); - z = sqlite3_value_blob(argv[0]); - if( z==0 ) return; - assert( len==sqlite3_value_bytes(argv[0]) ); - }else{ - z = sqlite3_value_text(argv[0]); - if( z==0 ) return; - len = 0; - for(z2=z; *z2; len++){ - SQLITE_SKIP_UTF8(z2); - } - } - p1 = sqlite3_value_int(argv[1]); - p2 = sqlite3_value_int(argv[2]); - if( p1<0 ){ - p1 += len; - if( p1<0 ){ - p2 += p1; - p1 = 0; - } - }else if( p1>0 ){ - p1--; - } - if( p1+p2>len ){ - p2 = len-p1; - } - if( p0type!=SQLITE_BLOB ){ - while( *z && p1 ){ - SQLITE_SKIP_UTF8(z); - p1--; - } - for(z2=z; *z2 && p2; p2--){ - SQLITE_SKIP_UTF8(z2); - } - sqlite3_result_text(context, (char*)z, z2-z, SQLITE_TRANSIENT); - }else{ - if( p2<0 ) p2 = 0; - sqlite3_result_blob(context, (char*)&z[p1], p2, SQLITE_TRANSIENT); - } -} - -/* -** Implementation of the round() function -*/ -static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - int n = 0; - double r; - char zBuf[500]; /* larger than the %f representation of the largest double */ - assert( argc==1 || argc==2 ); - if( argc==2 ){ - if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; - n = sqlite3_value_int(argv[1]); - if( n>30 ) n = 30; - if( n<0 ) n = 0; - } - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - r = sqlite3_value_double(argv[0]); - sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r); - sqlite3AtoF(zBuf, &r); - sqlite3_result_double(context, r); -} - -/* -** Allocate nByte bytes of space using sqlite3_malloc(). If the -** allocation fails, call sqlite3_result_error_nomem() to notify -** the database handle that malloc() has failed. -*/ -static void *contextMalloc(sqlite3_context *context, int nByte){ - char *z = sqlite3_malloc(nByte); - if( !z && nByte>0 ){ - sqlite3_result_error_nomem(context); - } - return z; -} - -/* -** Implementation of the upper() and lower() SQL functions. -*/ -static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - char *z1; - const char *z2; - int i, n; - if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return; - z2 = (char*)sqlite3_value_text(argv[0]); - n = sqlite3_value_bytes(argv[0]); - /* Verify that the call to _bytes() does not invalidate the _text() pointer */ - assert( z2==(char*)sqlite3_value_text(argv[0]) ); - if( z2 ){ - z1 = contextMalloc(context, n+1); - if( z1 ){ - memcpy(z1, z2, n+1); - for(i=0; z1[i]; i++){ - z1[i] = toupper(z1[i]); - } - sqlite3_result_text(context, z1, -1, sqlite3_free); - } - } -} -static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - char *z1; - const char *z2; - int i, n; - if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return; - z2 = (char*)sqlite3_value_text(argv[0]); - n = sqlite3_value_bytes(argv[0]); - /* Verify that the call to _bytes() does not invalidate the _text() pointer */ - assert( z2==(char*)sqlite3_value_text(argv[0]) ); - if( z2 ){ - z1 = contextMalloc(context, n+1); - if( z1 ){ - memcpy(z1, z2, n+1); - for(i=0; z1[i]; i++){ - z1[i] = tolower(z1[i]); - } - sqlite3_result_text(context, z1, -1, sqlite3_free); - } - } -} - -/* -** Implementation of the IFNULL(), NVL(), and COALESCE() functions. -** All three do the same thing. They return the first non-NULL -** argument. -*/ -static void ifnullFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int i; - for(i=0; iSQLITE_MAX_LENGTH ){ - sqlite3_result_error_toobig(context); - return; - } - p = contextMalloc(context, n); - if( p ){ - sqlite3Randomness(n, p); - sqlite3_result_blob(context, (char*)p, n, sqlite3_free); - } -} - -/* -** Implementation of the last_insert_rowid() SQL function. The return -** value is the same as the sqlite3_last_insert_rowid() API function. -*/ -static void last_insert_rowid( - sqlite3_context *context, - int arg, - sqlite3_value **argv -){ - sqlite3 *db = sqlite3_user_data(context); - sqlite3_result_int64(context, sqlite3_last_insert_rowid(db)); -} - -/* -** Implementation of the changes() SQL function. The return value is the -** same as the sqlite3_changes() API function. -*/ -static void changes( - sqlite3_context *context, - int arg, - sqlite3_value **argv -){ - sqlite3 *db = sqlite3_user_data(context); - sqlite3_result_int(context, sqlite3_changes(db)); -} - -/* -** Implementation of the total_changes() SQL function. The return value is -** the same as the sqlite3_total_changes() API function. -*/ -static void total_changes( - sqlite3_context *context, - int arg, - sqlite3_value **argv -){ - sqlite3 *db = sqlite3_user_data(context); - sqlite3_result_int(context, sqlite3_total_changes(db)); -} - -/* -** A structure defining how to do GLOB-style comparisons. -*/ -struct compareInfo { - u8 matchAll; - u8 matchOne; - u8 matchSet; - u8 noCase; -}; - -static const struct compareInfo globInfo = { '*', '?', '[', 0 }; -/* The correct SQL-92 behavior is for the LIKE operator to ignore -** case. Thus 'a' LIKE 'A' would be true. */ -static const struct compareInfo likeInfoNorm = { '%', '_', 0, 1 }; -/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator -** is case sensitive causing 'a' LIKE 'A' to be false */ -static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 }; - -/* -** Compare two UTF-8 strings for equality where the first string can -** potentially be a "glob" expression. Return true (1) if they -** are the same and false (0) if they are different. -** -** Globbing rules: -** -** '*' Matches any sequence of zero or more characters. -** -** '?' Matches exactly one character. -** -** [...] Matches one character from the enclosed list of -** characters. -** -** [^...] Matches one character not in the enclosed list. -** -** With the [...] and [^...] matching, a ']' character can be included -** in the list by making it the first character after '[' or '^'. A -** range of characters can be specified using '-'. Example: -** "[a-z]" matches any single lower-case letter. To match a '-', make -** it the last character in the list. -** -** This routine is usually quick, but can be N**2 in the worst case. -** -** Hints: to match '*' or '?', put them in "[]". Like this: -** -** abc[*]xyz Matches "abc*xyz" only -*/ -static int patternCompare( - const u8 *zPattern, /* The glob pattern */ - const u8 *zString, /* The string to compare against the glob */ - const struct compareInfo *pInfo, /* Information about how to do the compare */ - const int esc /* The escape character */ -){ - int c, c2; - int invert; - int seen; - u8 matchOne = pInfo->matchOne; - u8 matchAll = pInfo->matchAll; - u8 matchSet = pInfo->matchSet; - u8 noCase = pInfo->noCase; - int prevEscape = 0; /* True if the previous character was 'escape' */ - - while( (c = sqlite3Utf8Read(zPattern,0,&zPattern))!=0 ){ - if( !prevEscape && c==matchAll ){ - while( (c=sqlite3Utf8Read(zPattern,0,&zPattern)) == matchAll - || c == matchOne ){ - if( c==matchOne && sqlite3Utf8Read(zString, 0, &zString)==0 ){ - return 0; - } - } - if( c==0 ){ - return 1; - }else if( c==esc ){ - c = sqlite3Utf8Read(zPattern, 0, &zPattern); - if( c==0 ){ - return 0; - } - }else if( c==matchSet ){ - assert( esc==0 ); /* This is GLOB, not LIKE */ - assert( matchSet<0x80 ); /* '[' is a single-byte character */ - while( *zString && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){ - SQLITE_SKIP_UTF8(zString); - } - return *zString!=0; - } - while( (c2 = sqlite3Utf8Read(zString,0,&zString))!=0 ){ - if( noCase ){ - c2 = c2<0x80 ? sqlite3UpperToLower[c2] : c2; - c = c<0x80 ? sqlite3UpperToLower[c] : c; - while( c2 != 0 && c2 != c ){ - c2 = sqlite3Utf8Read(zString, 0, &zString); - if( c2<0x80 ) c2 = sqlite3UpperToLower[c2]; - } - }else{ - while( c2 != 0 && c2 != c ){ - c2 = sqlite3Utf8Read(zString, 0, &zString); - } - } - if( c2==0 ) return 0; - if( patternCompare(zPattern,zString,pInfo,esc) ) return 1; - } - return 0; - }else if( !prevEscape && c==matchOne ){ - if( sqlite3Utf8Read(zString, 0, &zString)==0 ){ - return 0; - } - }else if( c==matchSet ){ - int prior_c = 0; - assert( esc==0 ); /* This only occurs for GLOB, not LIKE */ - seen = 0; - invert = 0; - c = sqlite3Utf8Read(zString, 0, &zString); - if( c==0 ) return 0; - c2 = sqlite3Utf8Read(zPattern, 0, &zPattern); - if( c2=='^' ){ - invert = 1; - c2 = sqlite3Utf8Read(zPattern, 0, &zPattern); - } - if( c2==']' ){ - if( c==']' ) seen = 1; - c2 = sqlite3Utf8Read(zPattern, 0, &zPattern); - } - while( c2 && c2!=']' ){ - if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){ - c2 = sqlite3Utf8Read(zPattern, 0, &zPattern); - if( c>=prior_c && c<=c2 ) seen = 1; - prior_c = 0; - }else{ - if( c==c2 ){ - seen = 1; - } - prior_c = c2; - } - c2 = sqlite3Utf8Read(zPattern, 0, &zPattern); - } - if( c2==0 || (seen ^ invert)==0 ){ - return 0; - } - }else if( esc==c && !prevEscape ){ - prevEscape = 1; - }else{ - c2 = sqlite3Utf8Read(zString, 0, &zString); - if( noCase ){ - c = c<0x80 ? sqlite3UpperToLower[c] : c; - c2 = c2<0x80 ? sqlite3UpperToLower[c2] : c2; - } - if( c!=c2 ){ - return 0; - } - prevEscape = 0; - } - } - return *zString==0; -} - -/* -** Count the number of times that the LIKE operator (or GLOB which is -** just a variation of LIKE) gets called. This is used for testing -** only. -*/ -#ifdef SQLITE_TEST -int sqlite3_like_count = 0; -#endif - - -/* -** Implementation of the like() SQL function. This function implements -** the build-in LIKE operator. The first argument to the function is the -** pattern and the second argument is the string. So, the SQL statements: -** -** A LIKE B -** -** is implemented as like(B,A). -** -** This same function (with a different compareInfo structure) computes -** the GLOB operator. -*/ -static void likeFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const unsigned char *zA, *zB; - int escape = 0; - - zB = sqlite3_value_text(argv[0]); - zA = sqlite3_value_text(argv[1]); - - /* Limit the length of the LIKE or GLOB pattern to avoid problems - ** of deep recursion and N*N behavior in patternCompare(). - */ - if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){ - sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); - return; - } - assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */ - - if( argc==3 ){ - /* The escape character string must consist of a single UTF-8 character. - ** Otherwise, return an error. - */ - const unsigned char *zEsc = sqlite3_value_text(argv[2]); - if( zEsc==0 ) return; - if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){ - sqlite3_result_error(context, - "ESCAPE expression must be a single character", -1); - return; - } - escape = sqlite3Utf8Read(zEsc, 0, &zEsc); - } - if( zA && zB ){ - struct compareInfo *pInfo = sqlite3_user_data(context); -#ifdef SQLITE_TEST - sqlite3_like_count++; -#endif - - sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)); - } -} - -/* -** Implementation of the NULLIF(x,y) function. The result is the first -** argument if the arguments are different. The result is NULL if the -** arguments are equal to each other. -*/ -static void nullifFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - CollSeq *pColl = sqlite3GetFuncCollSeq(context); - if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){ - sqlite3_result_value(context, argv[0]); - } -} - -/* -** Implementation of the VERSION(*) function. The result is the version -** of the SQLite library that is running. -*/ -static void versionFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC); -} - -/* Array for converting from half-bytes (nybbles) into ASCII hex -** digits. */ -static const char hexdigits[] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' -}; - -/* -** EXPERIMENTAL - This is not an official function. The interface may -** change. This function may disappear. Do not write code that depends -** on this function. -** -** Implementation of the QUOTE() function. This function takes a single -** argument. If the argument is numeric, the return value is the same as -** the argument. If the argument is NULL, the return value is the string -** "NULL". Otherwise, the argument is enclosed in single quotes with -** single-quote escapes. -*/ -static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - if( argc<1 ) return; - switch( sqlite3_value_type(argv[0]) ){ - case SQLITE_NULL: { - sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC); - break; - } - case SQLITE_INTEGER: - case SQLITE_FLOAT: { - sqlite3_result_value(context, argv[0]); - break; - } - case SQLITE_BLOB: { - char *zText = 0; - char const *zBlob = sqlite3_value_blob(argv[0]); - int nBlob = sqlite3_value_bytes(argv[0]); - assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ - - if( 2*nBlob+4>SQLITE_MAX_LENGTH ){ - sqlite3_result_error_toobig(context); - return; - } - zText = (char *)contextMalloc(context, (2*nBlob)+4); - if( zText ){ - int i; - for(i=0; i>4)&0x0F]; - zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F]; - } - zText[(nBlob*2)+2] = '\''; - zText[(nBlob*2)+3] = '\0'; - zText[0] = 'X'; - zText[1] = '\''; - sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); - sqlite3_free(zText); - } - break; - } - case SQLITE_TEXT: { - int i,j; - u64 n; - const unsigned char *zArg = sqlite3_value_text(argv[0]); - char *z; - - if( zArg==0 ) return; - for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } - if( i+n+3>SQLITE_MAX_LENGTH ){ - sqlite3_result_error_toobig(context); - return; - } - z = contextMalloc(context, i+n+3); - if( z ){ - z[0] = '\''; - for(i=0, j=1; zArg[i]; i++){ - z[j++] = zArg[i]; - if( zArg[i]=='\'' ){ - z[j++] = '\''; - } - } - z[j++] = '\''; - z[j] = 0; - sqlite3_result_text(context, z, j, sqlite3_free); - } - } - } -} - -/* -** The hex() function. Interpret the argument as a blob. Return -** a hexadecimal rendering as text. -*/ -static void hexFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int i, n; - const unsigned char *pBlob; - char *zHex, *z; - assert( argc==1 ); - pBlob = sqlite3_value_blob(argv[0]); - n = sqlite3_value_bytes(argv[0]); - if( n*2+1>SQLITE_MAX_LENGTH ){ - sqlite3_result_error_toobig(context); - return; - } - assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ - z = zHex = contextMalloc(context, n*2 + 1); - if( zHex ){ - for(i=0; i>4)&0xf]; - *(z++) = hexdigits[c&0xf]; - } - *z = 0; - sqlite3_result_text(context, zHex, n*2, sqlite3_free); - } -} - -/* -** The zeroblob(N) function returns a zero-filled blob of size N bytes. -*/ -static void zeroblobFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - i64 n; - assert( argc==1 ); - n = sqlite3_value_int64(argv[0]); - if( n>SQLITE_MAX_LENGTH ){ - sqlite3_result_error_toobig(context); - }else{ - sqlite3_result_zeroblob(context, n); - } -} - -/* -** The replace() function. Three arguments are all strings: call -** them A, B, and C. The result is also a string which is derived -** from A by replacing every occurance of B with C. The match -** must be exact. Collating sequences are not used. -*/ -static void replaceFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const unsigned char *zStr; /* The input string A */ - const unsigned char *zPattern; /* The pattern string B */ - const unsigned char *zRep; /* The replacement string C */ - unsigned char *zOut; /* The output */ - int nStr; /* Size of zStr */ - int nPattern; /* Size of zPattern */ - int nRep; /* Size of zRep */ - i64 nOut; /* Maximum size of zOut */ - int loopLimit; /* Last zStr[] that might match zPattern[] */ - int i, j; /* Loop counters */ - - assert( argc==3 ); - zStr = sqlite3_value_text(argv[0]); - if( zStr==0 ) return; - nStr = sqlite3_value_bytes(argv[0]); - assert( zStr==sqlite3_value_text(argv[0]) ); /* No encoding change */ - zPattern = sqlite3_value_text(argv[1]); - if( zPattern==0 || zPattern[0]==0 ) return; - nPattern = sqlite3_value_bytes(argv[1]); - assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */ - zRep = sqlite3_value_text(argv[2]); - if( zRep==0 ) return; - nRep = sqlite3_value_bytes(argv[2]); - assert( zRep==sqlite3_value_text(argv[2]) ); - nOut = nStr + 1; - assert( nOut=SQLITE_MAX_LENGTH ){ - sqlite3_result_error_toobig(context); - sqlite3_free(zOut); - return; - } - zOld = zOut; - zOut = sqlite3_realloc(zOut, (int)nOut); - if( zOut==0 ){ - sqlite3_result_error_nomem(context); - sqlite3_free(zOld); - return; - } - memcpy(&zOut[j], zRep, nRep); - j += nRep; - i += nPattern-1; - } - } - assert( j+nStr-i+1==nOut ); - memcpy(&zOut[j], &zStr[i], nStr-i); - j += nStr - i; - assert( j<=nOut ); - zOut[j] = 0; - sqlite3_result_text(context, (char*)zOut, j, sqlite3_free); -} - -/* -** Implementation of the TRIM(), LTRIM(), and RTRIM() functions. -** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both. -*/ -static void trimFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const unsigned char *zIn; /* Input string */ - const unsigned char *zCharSet; /* Set of characters to trim */ - int nIn; /* Number of bytes in input */ - int flags; /* 1: trimleft 2: trimright 3: trim */ - int i; /* Loop counter */ - unsigned char *aLen; /* Length of each character in zCharSet */ - const unsigned char **azChar; /* Individual characters in zCharSet */ - int nChar; /* Number of characters in zCharSet */ - - if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ - return; - } - zIn = sqlite3_value_text(argv[0]); - if( zIn==0 ) return; - nIn = sqlite3_value_bytes(argv[0]); - assert( zIn==sqlite3_value_text(argv[0]) ); - if( argc==1 ){ - static const unsigned char lenOne[] = { 1 }; - static const unsigned char *azOne[] = { (u8*)" " }; - nChar = 1; - aLen = (u8*)lenOne; - azChar = azOne; - zCharSet = 0; - }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){ - return; - }else{ - const unsigned char *z; - for(z=zCharSet, nChar=0; *z; nChar++){ - SQLITE_SKIP_UTF8(z); - } - if( nChar>0 ){ - azChar = contextMalloc(context, nChar*(sizeof(char*)+1)); - if( azChar==0 ){ - return; - } - aLen = (unsigned char*)&azChar[nChar]; - for(z=zCharSet, nChar=0; *z; nChar++){ - azChar[nChar] = z; - SQLITE_SKIP_UTF8(z); - aLen[nChar] = z - azChar[nChar]; - } - } - } - if( nChar>0 ){ - flags = (int)sqlite3_user_data(context); - if( flags & 1 ){ - while( nIn>0 ){ - int len; - for(i=0; i=nChar ) break; - zIn += len; - nIn -= len; - } - } - if( flags & 2 ){ - while( nIn>0 ){ - int len; - for(i=0; i=nChar ) break; - nIn -= len; - } - } - if( zCharSet ){ - sqlite3_free(azChar); - } - } - sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); -} - -#ifdef SQLITE_SOUNDEX -/* -** Compute the soundex encoding of a word. -*/ -static void soundexFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - char zResult[8]; - const u8 *zIn; - int i, j; - static const unsigned char iCode[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, - 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, - 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, - }; - assert( argc==1 ); - zIn = (u8*)sqlite3_value_text(argv[0]); - if( zIn==0 ) zIn = (u8*)""; - for(i=0; zIn[i] && !isalpha(zIn[i]); i++){} - if( zIn[i] ){ - u8 prevcode = iCode[zIn[i]&0x7f]; - zResult[0] = toupper(zIn[i]); - for(j=1; j<4 && zIn[i]; i++){ - int code = iCode[zIn[i]&0x7f]; - if( code>0 ){ - if( code!=prevcode ){ - prevcode = code; - zResult[j++] = code + '0'; - } - }else{ - prevcode = 0; - } - } - while( j<4 ){ - zResult[j++] = '0'; - } - zResult[j] = 0; - sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT); - }else{ - sqlite3_result_text(context, "?000", 4, SQLITE_STATIC); - } -} -#endif - -#ifndef SQLITE_OMIT_LOAD_EXTENSION -/* -** A function that loads a shared-library extension then returns NULL. -*/ -static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ - const char *zFile = (const char *)sqlite3_value_text(argv[0]); - const char *zProc; - sqlite3 *db = sqlite3_user_data(context); - char *zErrMsg = 0; - - if( argc==2 ){ - zProc = (const char *)sqlite3_value_text(argv[1]); - }else{ - zProc = 0; - } - if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){ - sqlite3_result_error(context, zErrMsg, -1); - sqlite3_free(zErrMsg); - } -} -#endif - -#ifdef SQLITE_TEST -/* -** This function generates a string of random characters. Used for -** generating test data. -*/ -static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){ - static const unsigned char zSrc[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789" - ".-!,:*^+=_|?/<> "; - int iMin, iMax, n, r, i; - unsigned char zBuf[1000]; - - /* It used to be possible to call randstr() with any number of arguments, - ** but now it is registered with SQLite as requiring exactly 2. - */ - assert(argc==2); - - iMin = sqlite3_value_int(argv[0]); - if( iMin<0 ) iMin = 0; - if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1; - iMax = sqlite3_value_int(argv[1]); - if( iMax=sizeof(zBuf) ) iMax = sizeof(zBuf)-1; - n = iMin; - if( iMax>iMin ){ - sqlite3Randomness(sizeof(r), &r); - r &= 0x7fffffff; - n += r%(iMax + 1 - iMin); - } - assert( ncnt++; - if( type==SQLITE_INTEGER ){ - i64 v = sqlite3_value_int64(argv[0]); - p->rSum += v; - if( (p->approx|p->overflow)==0 ){ - i64 iNewSum = p->iSum + v; - int s1 = p->iSum >> (sizeof(i64)*8-1); - int s2 = v >> (sizeof(i64)*8-1); - int s3 = iNewSum >> (sizeof(i64)*8-1); - p->overflow = (s1&s2&~s3) | (~s1&~s2&s3); - p->iSum = iNewSum; - } - }else{ - p->rSum += sqlite3_value_double(argv[0]); - p->approx = 1; - } - } -} -static void sumFinalize(sqlite3_context *context){ - SumCtx *p; - p = sqlite3_aggregate_context(context, 0); - if( p && p->cnt>0 ){ - if( p->overflow ){ - sqlite3_result_error(context,"integer overflow",-1); - }else if( p->approx ){ - sqlite3_result_double(context, p->rSum); - }else{ - sqlite3_result_int64(context, p->iSum); - } - } -} -static void avgFinalize(sqlite3_context *context){ - SumCtx *p; - p = sqlite3_aggregate_context(context, 0); - if( p && p->cnt>0 ){ - sqlite3_result_double(context, p->rSum/(double)p->cnt); - } -} -static void totalFinalize(sqlite3_context *context){ - SumCtx *p; - p = sqlite3_aggregate_context(context, 0); - sqlite3_result_double(context, p ? p->rSum : 0.0); -} - -/* -** The following structure keeps track of state information for the -** count() aggregate function. -*/ -typedef struct CountCtx CountCtx; -struct CountCtx { - i64 n; -}; - -/* -** Routines to implement the count() aggregate function. -*/ -static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ - CountCtx *p; - p = sqlite3_aggregate_context(context, sizeof(*p)); - if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){ - p->n++; - } -} -static void countFinalize(sqlite3_context *context){ - CountCtx *p; - p = sqlite3_aggregate_context(context, 0); - sqlite3_result_int64(context, p ? p->n : 0); -} - -/* -** Routines to implement min() and max() aggregate functions. -*/ -static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv){ - Mem *pArg = (Mem *)argv[0]; - Mem *pBest; - - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest)); - if( !pBest ) return; - - if( pBest->flags ){ - int max; - int cmp; - CollSeq *pColl = sqlite3GetFuncCollSeq(context); - /* This step function is used for both the min() and max() aggregates, - ** the only difference between the two being that the sense of the - ** comparison is inverted. For the max() aggregate, the - ** sqlite3_user_data() function returns (void *)-1. For min() it - ** returns (void *)db, where db is the sqlite3* database pointer. - ** Therefore the next statement sets variable 'max' to 1 for the max() - ** aggregate, or 0 for min(). - */ - max = sqlite3_user_data(context)!=0; - cmp = sqlite3MemCompare(pBest, pArg, pColl); - if( (max && cmp<0) || (!max && cmp>0) ){ - sqlite3VdbeMemCopy(pBest, pArg); - } - }else{ - sqlite3VdbeMemCopy(pBest, pArg); - } -} -static void minMaxFinalize(sqlite3_context *context){ - sqlite3_value *pRes; - pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0); - if( pRes ){ - if( pRes->flags ){ - sqlite3_result_value(context, pRes); - } - sqlite3VdbeMemRelease(pRes); - } -} - - -/* -** This function registered all of the above C functions as SQL -** functions. This should be the only routine in this file with -** external linkage. -*/ -void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ - static const struct { - char *zName; - signed char nArg; - u8 argType; /* ff: db 1: 0, 2: 1, 3: 2,... N: N-1. */ - u8 eTextRep; /* 1: UTF-16. 0: UTF-8 */ - u8 needCollSeq; - void (*xFunc)(sqlite3_context*,int,sqlite3_value **); - } aFuncs[] = { - { "min", -1, 0, SQLITE_UTF8, 1, minmaxFunc }, - { "min", 0, 0, SQLITE_UTF8, 1, 0 }, - { "max", -1, 1, SQLITE_UTF8, 1, minmaxFunc }, - { "max", 0, 1, SQLITE_UTF8, 1, 0 }, - { "typeof", 1, 0, SQLITE_UTF8, 0, typeofFunc }, - { "length", 1, 0, SQLITE_UTF8, 0, lengthFunc }, - { "substr", 3, 0, SQLITE_UTF8, 0, substrFunc }, - { "abs", 1, 0, SQLITE_UTF8, 0, absFunc }, - { "round", 1, 0, SQLITE_UTF8, 0, roundFunc }, - { "round", 2, 0, SQLITE_UTF8, 0, roundFunc }, - { "upper", 1, 0, SQLITE_UTF8, 0, upperFunc }, - { "lower", 1, 0, SQLITE_UTF8, 0, lowerFunc }, - { "coalesce", -1, 0, SQLITE_UTF8, 0, ifnullFunc }, - { "coalesce", 0, 0, SQLITE_UTF8, 0, 0 }, - { "coalesce", 1, 0, SQLITE_UTF8, 0, 0 }, - { "hex", 1, 0, SQLITE_UTF8, 0, hexFunc }, - { "ifnull", 2, 0, SQLITE_UTF8, 1, ifnullFunc }, - { "random", -1, 0, SQLITE_UTF8, 0, randomFunc }, - { "randomblob", 1, 0, SQLITE_UTF8, 0, randomBlob }, - { "nullif", 2, 0, SQLITE_UTF8, 1, nullifFunc }, - { "sqlite_version", 0, 0, SQLITE_UTF8, 0, versionFunc}, - { "quote", 1, 0, SQLITE_UTF8, 0, quoteFunc }, - { "last_insert_rowid", 0, 0xff, SQLITE_UTF8, 0, last_insert_rowid }, - { "changes", 0, 0xff, SQLITE_UTF8, 0, changes }, - { "total_changes", 0, 0xff, SQLITE_UTF8, 0, total_changes }, - { "replace", 3, 0, SQLITE_UTF8, 0, replaceFunc }, - { "ltrim", 1, 1, SQLITE_UTF8, 0, trimFunc }, - { "ltrim", 2, 1, SQLITE_UTF8, 0, trimFunc }, - { "rtrim", 1, 2, SQLITE_UTF8, 0, trimFunc }, - { "rtrim", 2, 2, SQLITE_UTF8, 0, trimFunc }, - { "trim", 1, 3, SQLITE_UTF8, 0, trimFunc }, - { "trim", 2, 3, SQLITE_UTF8, 0, trimFunc }, - { "zeroblob", 1, 0, SQLITE_UTF8, 0, zeroblobFunc }, -#ifdef SQLITE_SOUNDEX - { "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc}, -#endif -#ifndef SQLITE_OMIT_LOAD_EXTENSION - { "load_extension", 1, 0xff, SQLITE_UTF8, 0, loadExt }, - { "load_extension", 2, 0xff, SQLITE_UTF8, 0, loadExt }, -#endif -#ifdef SQLITE_TEST - { "randstr", 2, 0, SQLITE_UTF8, 0, randStr }, - { "test_destructor", 1, 0xff, SQLITE_UTF8, 0, test_destructor}, - { "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count}, - { "test_auxdata", -1, 0, SQLITE_UTF8, 0, test_auxdata}, - { "test_error", 1, 0, SQLITE_UTF8, 0, test_error}, -#endif - }; - static const struct { - char *zName; - signed char nArg; - u8 argType; - u8 needCollSeq; - void (*xStep)(sqlite3_context*,int,sqlite3_value**); - void (*xFinalize)(sqlite3_context*); - } aAggs[] = { - { "min", 1, 0, 1, minmaxStep, minMaxFinalize }, - { "max", 1, 1, 1, minmaxStep, minMaxFinalize }, - { "sum", 1, 0, 0, sumStep, sumFinalize }, - { "total", 1, 0, 0, sumStep, totalFinalize }, - { "avg", 1, 0, 0, sumStep, avgFinalize }, - { "count", 0, 0, 0, countStep, countFinalize }, - { "count", 1, 0, 0, countStep, countFinalize }, - }; - int i; - - for(i=0; ineedCollSeq = 1; - } - } - } -#ifndef SQLITE_OMIT_ALTERTABLE - sqlite3AlterFunctions(db); -#endif -#ifndef SQLITE_OMIT_PARSER - sqlite3AttachFunctions(db); -#endif - for(i=0; ineedCollSeq = 1; - } - } - } - sqlite3RegisterDateTimeFunctions(db); - if( !db->mallocFailed ){ - int rc = sqlite3_overload_function(db, "MATCH", 2); - assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); - if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; - } - } -#ifdef SQLITE_SSE - (void)sqlite3SseFunctions(db); -#endif -#ifdef SQLITE_CASE_SENSITIVE_LIKE - sqlite3RegisterLikeFunctions(db, 1); -#else - sqlite3RegisterLikeFunctions(db, 0); -#endif -} - -/* -** Set the LIKEOPT flag on the 2-argument function with the given name. -*/ -static void setLikeOptFlag(sqlite3 *db, const char *zName, int flagVal){ - FuncDef *pDef; - pDef = sqlite3FindFunction(db, zName, strlen(zName), 2, SQLITE_UTF8, 0); - if( pDef ){ - pDef->flags = flagVal; - } -} - -/* -** Register the built-in LIKE and GLOB functions. The caseSensitive -** parameter determines whether or not the LIKE operator is case -** sensitive. GLOB is always case sensitive. -*/ -void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ - struct compareInfo *pInfo; - if( caseSensitive ){ - pInfo = (struct compareInfo*)&likeInfoAlt; - }else{ - pInfo = (struct compareInfo*)&likeInfoNorm; - } - sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0); - sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0); - sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, - (struct compareInfo*)&globInfo, likeFunc, 0,0); - setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE); - setLikeOptFlag(db, "like", - caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE); -} - -/* -** pExpr points to an expression which implements a function. If -** it is appropriate to apply the LIKE optimization to that function -** then set aWc[0] through aWc[2] to the wildcard characters and -** return TRUE. If the function is not a LIKE-style function then -** return FALSE. -*/ -int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ - FuncDef *pDef; - if( pExpr->op!=TK_FUNCTION || !pExpr->pList ){ - return 0; - } - if( pExpr->pList->nExpr!=2 ){ - return 0; - } - pDef = sqlite3FindFunction(db, (char*)pExpr->token.z, pExpr->token.n, 2, - SQLITE_UTF8, 0); - if( pDef==0 || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){ - return 0; - } - - /* The memcpy() statement assumes that the wildcard characters are - ** the first three statements in the compareInfo structure. The - ** asserts() that follow verify that assumption - */ - memcpy(aWc, pDef->pUserData, 3); - assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll ); - assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne ); - assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet ); - *pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0; - return 1; -} diff --git a/extensions/sqlite/sqlite-source/hash.c b/extensions/sqlite/sqlite-source/hash.c deleted file mode 100644 index a6bcdc32..00000000 --- a/extensions/sqlite/sqlite-source/hash.c +++ /dev/null @@ -1,418 +0,0 @@ -/* -** 2001 September 22 -** -** 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 is the implementation of generic hash-tables -** used in SQLite. -** -** $Id$ -*/ -#include "sqliteInt.h" -#include - -/* Turn bulk memory into a hash table object by initializing the -** fields of the Hash structure. -** -** "pNew" is a pointer to the hash table that is to be initialized. -** keyClass is one of the constants SQLITE_HASH_INT, SQLITE_HASH_POINTER, -** SQLITE_HASH_BINARY, or SQLITE_HASH_STRING. The value of keyClass -** determines what kind of key the hash table will use. "copyKey" is -** true if the hash table should make its own private copy of keys and -** false if it should just use the supplied pointer. CopyKey only makes -** sense for SQLITE_HASH_STRING and SQLITE_HASH_BINARY and is ignored -** for other key classes. -*/ -void sqlite3HashInit(Hash *pNew, int keyClass, int copyKey){ - assert( pNew!=0 ); - assert( keyClass>=SQLITE_HASH_STRING && keyClass<=SQLITE_HASH_BINARY ); - pNew->keyClass = keyClass; -#if 0 - if( keyClass==SQLITE_HASH_POINTER || keyClass==SQLITE_HASH_INT ) copyKey = 0; -#endif - pNew->copyKey = copyKey; - pNew->first = 0; - pNew->count = 0; - pNew->htsize = 0; - pNew->ht = 0; -} - -/* Remove all entries from a hash table. Reclaim all memory. -** Call this routine to delete a hash table or to reset a hash table -** to the empty state. -*/ -void sqlite3HashClear(Hash *pH){ - HashElem *elem; /* For looping over all elements of the table */ - - assert( pH!=0 ); - elem = pH->first; - pH->first = 0; - if( pH->ht ) sqlite3_free(pH->ht); - pH->ht = 0; - pH->htsize = 0; - while( elem ){ - HashElem *next_elem = elem->next; - if( pH->copyKey && elem->pKey ){ - sqlite3_free(elem->pKey); - } - sqlite3_free(elem); - elem = next_elem; - } - pH->count = 0; -} - -#if 0 /* NOT USED */ -/* -** Hash and comparison functions when the mode is SQLITE_HASH_INT -*/ -static int intHash(const void *pKey, int nKey){ - return nKey ^ (nKey<<8) ^ (nKey>>8); -} -static int intCompare(const void *pKey1, int n1, const void *pKey2, int n2){ - return n2 - n1; -} -#endif - -#if 0 /* NOT USED */ -/* -** Hash and comparison functions when the mode is SQLITE_HASH_POINTER -*/ -static int ptrHash(const void *pKey, int nKey){ - uptr x = Addr(pKey); - return x ^ (x<<8) ^ (x>>8); -} -static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2){ - if( pKey1==pKey2 ) return 0; - if( pKey1 0 ){ - h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++]; - nKey--; - } - return h & 0x7fffffff; -} -static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){ - if( n1!=n2 ) return 1; - return sqlite3StrNICmp((const char*)pKey1,(const char*)pKey2,n1); -} - -/* -** Hash and comparison functions when the mode is SQLITE_HASH_BINARY -*/ -static int binHash(const void *pKey, int nKey){ - int h = 0; - const char *z = (const char *)pKey; - while( nKey-- > 0 ){ - h = (h<<3) ^ h ^ *(z++); - } - return h & 0x7fffffff; -} -static int binCompare(const void *pKey1, int n1, const void *pKey2, int n2){ - if( n1!=n2 ) return 1; - return memcmp(pKey1,pKey2,n1); -} - -/* -** Return a pointer to the appropriate hash function given the key class. -** -** The C syntax in this function definition may be unfamilar to some -** programmers, so we provide the following additional explanation: -** -** The name of the function is "hashFunction". The function takes a -** single parameter "keyClass". The return value of hashFunction() -** is a pointer to another function. Specifically, the return value -** of hashFunction() is a pointer to a function that takes two parameters -** with types "const void*" and "int" and returns an "int". -*/ -static int (*hashFunction(int keyClass))(const void*,int){ -#if 0 /* HASH_INT and HASH_POINTER are never used */ - switch( keyClass ){ - case SQLITE_HASH_INT: return &intHash; - case SQLITE_HASH_POINTER: return &ptrHash; - case SQLITE_HASH_STRING: return &strHash; - case SQLITE_HASH_BINARY: return &binHash;; - default: break; - } - return 0; -#else - if( keyClass==SQLITE_HASH_STRING ){ - return &strHash; - }else{ - assert( keyClass==SQLITE_HASH_BINARY ); - return &binHash; - } -#endif -} - -/* -** Return a pointer to the appropriate hash function given the key class. -** -** For help in interpreted the obscure C code in the function definition, -** see the header comment on the previous function. -*/ -static int (*compareFunction(int keyClass))(const void*,int,const void*,int){ -#if 0 /* HASH_INT and HASH_POINTER are never used */ - switch( keyClass ){ - case SQLITE_HASH_INT: return &intCompare; - case SQLITE_HASH_POINTER: return &ptrCompare; - case SQLITE_HASH_STRING: return &strCompare; - case SQLITE_HASH_BINARY: return &binCompare; - default: break; - } - return 0; -#else - if( keyClass==SQLITE_HASH_STRING ){ - return &strCompare; - }else{ - assert( keyClass==SQLITE_HASH_BINARY ); - return &binCompare; - } -#endif -} - -/* Link an element into the hash table -*/ -static void insertElement( - Hash *pH, /* The complete hash table */ - struct _ht *pEntry, /* The entry into which pNew is inserted */ - HashElem *pNew /* The element to be inserted */ -){ - HashElem *pHead; /* First element already in pEntry */ - pHead = pEntry->chain; - if( pHead ){ - pNew->next = pHead; - pNew->prev = pHead->prev; - if( pHead->prev ){ pHead->prev->next = pNew; } - else { pH->first = pNew; } - pHead->prev = pNew; - }else{ - pNew->next = pH->first; - if( pH->first ){ pH->first->prev = pNew; } - pNew->prev = 0; - pH->first = pNew; - } - pEntry->count++; - pEntry->chain = pNew; -} - - -/* Resize the hash table so that it cantains "new_size" buckets. -** "new_size" must be a power of 2. The hash table might fail -** to resize if sqlite3_malloc() fails. -*/ -static void rehash(Hash *pH, int new_size){ - struct _ht *new_ht; /* The new hash table */ - HashElem *elem, *next_elem; /* For looping over existing elements */ - int (*xHash)(const void*,int); /* The hash function */ - - assert( (new_size & (new_size-1))==0 ); - - /* There is a call to sqlite3_malloc() inside rehash(). If there is - ** already an allocation at pH->ht, then if this malloc() fails it - ** is benign (since failing to resize a hash table is a performance - ** hit only, not a fatal error). - */ - sqlite3MallocBenignFailure(pH->htsize>0); - - new_ht = (struct _ht *)sqlite3MallocZero( new_size*sizeof(struct _ht) ); - if( new_ht==0 ) return; - if( pH->ht ) sqlite3_free(pH->ht); - pH->ht = new_ht; - pH->htsize = new_size; - xHash = hashFunction(pH->keyClass); - for(elem=pH->first, pH->first=0; elem; elem = next_elem){ - int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1); - next_elem = elem->next; - insertElement(pH, &new_ht[h], elem); - } -} - -/* This function (for internal use only) locates an element in an -** hash table that matches the given key. The hash for this key has -** already been computed and is passed as the 4th parameter. -*/ -static HashElem *findElementGivenHash( - const Hash *pH, /* The pH to be searched */ - const void *pKey, /* The key we are searching for */ - int nKey, - int h /* The hash for this key. */ -){ - HashElem *elem; /* Used to loop thru the element list */ - int count; /* Number of elements left to test */ - int (*xCompare)(const void*,int,const void*,int); /* comparison function */ - - if( pH->ht ){ - struct _ht *pEntry = &pH->ht[h]; - elem = pEntry->chain; - count = pEntry->count; - xCompare = compareFunction(pH->keyClass); - while( count-- && elem ){ - if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){ - return elem; - } - elem = elem->next; - } - } - return 0; -} - -/* Remove a single entry from the hash table given a pointer to that -** element and a hash on the element's key. -*/ -static void removeElementGivenHash( - Hash *pH, /* The pH containing "elem" */ - HashElem* elem, /* The element to be removed from the pH */ - int h /* Hash value for the element */ -){ - struct _ht *pEntry; - if( elem->prev ){ - elem->prev->next = elem->next; - }else{ - pH->first = elem->next; - } - if( elem->next ){ - elem->next->prev = elem->prev; - } - pEntry = &pH->ht[h]; - if( pEntry->chain==elem ){ - pEntry->chain = elem->next; - } - pEntry->count--; - if( pEntry->count<=0 ){ - pEntry->chain = 0; - } - if( pH->copyKey ){ - sqlite3_free(elem->pKey); - } - sqlite3_free( elem ); - pH->count--; - if( pH->count<=0 ){ - assert( pH->first==0 ); - assert( pH->count==0 ); - sqlite3HashClear(pH); - } -} - -/* Attempt to locate an element of the hash table pH with a key -** that matches pKey,nKey. Return a pointer to the corresponding -** HashElem structure for this element if it is found, or NULL -** otherwise. -*/ -HashElem *sqlite3HashFindElem(const Hash *pH, const void *pKey, int nKey){ - int h; /* A hash on key */ - HashElem *elem; /* The element that matches key */ - int (*xHash)(const void*,int); /* The hash function */ - - if( pH==0 || pH->ht==0 ) return 0; - xHash = hashFunction(pH->keyClass); - assert( xHash!=0 ); - h = (*xHash)(pKey,nKey); - assert( (pH->htsize & (pH->htsize-1))==0 ); - elem = findElementGivenHash(pH,pKey,nKey, h & (pH->htsize-1)); - return elem; -} - -/* Attempt to locate an element of the hash table pH with a key -** that matches pKey,nKey. Return the data for this element if it is -** found, or NULL if there is no match. -*/ -void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){ - HashElem *elem; /* The element that matches key */ - elem = sqlite3HashFindElem(pH, pKey, nKey); - return elem ? elem->data : 0; -} - -/* Insert an element into the hash table pH. The key is pKey,nKey -** and the data is "data". -** -** If no element exists with a matching key, then a new -** element is created. A copy of the key is made if the copyKey -** flag is set. NULL is returned. -** -** If another element already exists with the same key, then the -** new data replaces the old data and the old data is returned. -** The key is not copied in this instance. If a malloc fails, then -** the new data is returned and the hash table is unchanged. -** -** If the "data" parameter to this function is NULL, then the -** element corresponding to "key" is removed from the hash table. -*/ -void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){ - int hraw; /* Raw hash value of the key */ - int h; /* the hash of the key modulo hash table size */ - HashElem *elem; /* Used to loop thru the element list */ - HashElem *new_elem; /* New element added to the pH */ - int (*xHash)(const void*,int); /* The hash function */ - - assert( pH!=0 ); - xHash = hashFunction(pH->keyClass); - assert( xHash!=0 ); - hraw = (*xHash)(pKey, nKey); - assert( (pH->htsize & (pH->htsize-1))==0 ); - h = hraw & (pH->htsize-1); - elem = findElementGivenHash(pH,pKey,nKey,h); - if( elem ){ - void *old_data = elem->data; - if( data==0 ){ - removeElementGivenHash(pH,elem,h); - }else{ - elem->data = data; - if( !pH->copyKey ){ - elem->pKey = (void *)pKey; - } - assert(nKey==elem->nKey); - } - return old_data; - } - if( data==0 ) return 0; - new_elem = (HashElem*)sqlite3_malloc( sizeof(HashElem) ); - if( new_elem==0 ) return data; - if( pH->copyKey && pKey!=0 ){ - new_elem->pKey = sqlite3_malloc( nKey ); - if( new_elem->pKey==0 ){ - sqlite3_free(new_elem); - return data; - } - memcpy((void*)new_elem->pKey, pKey, nKey); - }else{ - new_elem->pKey = (void*)pKey; - } - new_elem->nKey = nKey; - pH->count++; - if( pH->htsize==0 ){ - rehash(pH,8); - if( pH->htsize==0 ){ - pH->count = 0; - if( pH->copyKey ){ - sqlite3_free(new_elem->pKey); - } - sqlite3_free(new_elem); - return data; - } - } - if( pH->count > pH->htsize ){ - rehash(pH,pH->htsize*2); - } - assert( pH->htsize>0 ); - assert( (pH->htsize & (pH->htsize-1))==0 ); - h = hraw & (pH->htsize-1); - insertElement(pH, &pH->ht[h], new_elem); - new_elem->data = data; - return 0; -} diff --git a/extensions/sqlite/sqlite-source/hash.h b/extensions/sqlite/sqlite-source/hash.h deleted file mode 100644 index 84a45270..00000000 --- a/extensions/sqlite/sqlite-source/hash.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -** 2001 September 22 -** -** 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 is the header file for the generic hash-table implemenation -** used in SQLite. -** -** $Id$ -*/ -#ifndef _SQLITE_HASH_H_ -#define _SQLITE_HASH_H_ - -/* Forward declarations of structures. */ -typedef struct Hash Hash; -typedef struct HashElem HashElem; - -/* A complete hash table is an instance of the following structure. -** The internals of this structure are intended to be opaque -- client -** code should not attempt to access or modify the fields of this structure -** directly. Change this structure only by using the routines below. -** However, many of the "procedures" and "functions" for modifying and -** accessing this structure are really macros, so we can't really make -** this structure opaque. -*/ -struct Hash { - char keyClass; /* SQLITE_HASH_INT, _POINTER, _STRING, _BINARY */ - char copyKey; /* True if copy of key made on insert */ - int count; /* Number of entries in this table */ - int htsize; /* Number of buckets in the hash table */ - HashElem *first; /* The first element of the array */ - struct _ht { /* the hash table */ - int count; /* Number of entries with this hash */ - HashElem *chain; /* Pointer to first entry with this hash */ - } *ht; -}; - -/* Each element in the hash table is an instance of the following -** structure. All elements are stored on a single doubly-linked list. -** -** Again, this structure is intended to be opaque, but it can't really -** be opaque because it is used by macros. -*/ -struct HashElem { - HashElem *next, *prev; /* Next and previous elements in the table */ - void *data; /* Data associated with this element */ - void *pKey; int nKey; /* Key associated with this element */ -}; - -/* -** There are 4 different modes of operation for a hash table: -** -** SQLITE_HASH_INT nKey is used as the key and pKey is ignored. -** -** SQLITE_HASH_POINTER pKey is used as the key and nKey is ignored. -** -** SQLITE_HASH_STRING pKey points to a string that is nKey bytes long -** (including the null-terminator, if any). Case -** is ignored in comparisons. -** -** SQLITE_HASH_BINARY pKey points to binary data nKey bytes long. -** memcmp() is used to compare keys. -** -** A copy of the key is made for SQLITE_HASH_STRING and SQLITE_HASH_BINARY -** if the copyKey parameter to HashInit is 1. -*/ -/* #define SQLITE_HASH_INT 1 // NOT USED */ -/* #define SQLITE_HASH_POINTER 2 // NOT USED */ -#define SQLITE_HASH_STRING 3 -#define SQLITE_HASH_BINARY 4 - -/* -** Access routines. To delete, insert a NULL pointer. -*/ -void sqlite3HashInit(Hash*, int keytype, int copyKey); -void *sqlite3HashInsert(Hash*, const void *pKey, int nKey, void *pData); -void *sqlite3HashFind(const Hash*, const void *pKey, int nKey); -HashElem *sqlite3HashFindElem(const Hash*, const void *pKey, int nKey); -void sqlite3HashClear(Hash*); - -/* -** Macros for looping over all elements of a hash table. The idiom is -** like this: -** -** Hash h; -** HashElem *p; -** ... -** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){ -** SomeStructure *pData = sqliteHashData(p); -** // do something with pData -** } -*/ -#define sqliteHashFirst(H) ((H)->first) -#define sqliteHashNext(E) ((E)->next) -#define sqliteHashData(E) ((E)->data) -#define sqliteHashKey(E) ((E)->pKey) -#define sqliteHashKeysize(E) ((E)->nKey) - -/* -** Number of entries in a hash table -*/ -#define sqliteHashCount(H) ((H)->count) - -#endif /* _SQLITE_HASH_H_ */ diff --git a/extensions/sqlite/sqlite-source/insert.c b/extensions/sqlite/sqlite-source/insert.c deleted file mode 100644 index 18fc30b4..00000000 --- a/extensions/sqlite/sqlite-source/insert.c +++ /dev/null @@ -1,1605 +0,0 @@ -/* -** 2001 September 15 -** -** 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 file contains C code routines that are called by the parser -** to handle INSERT statements in SQLite. -** -** $Id$ -*/ -#include "sqliteInt.h" - -/* -** Set P3 of the most recently inserted opcode to a column affinity -** string for index pIdx. A column affinity string has one character -** for each column in the table, according to the affinity of the column: -** -** Character Column affinity -** ------------------------------ -** 'a' TEXT -** 'b' NONE -** 'c' NUMERIC -** 'd' INTEGER -** 'e' REAL -*/ -void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ - if( !pIdx->zColAff ){ - /* The first time a column affinity string for a particular index is - ** required, it is allocated and populated here. It is then stored as - ** a member of the Index structure for subsequent use. - ** - ** The column affinity string will eventually be deleted by - ** sqliteDeleteIndex() when the Index structure itself is cleaned - ** up. - */ - int n; - Table *pTab = pIdx->pTable; - sqlite3 *db = sqlite3VdbeDb(v); - pIdx->zColAff = (char *)sqlite3DbMallocZero(db, pIdx->nColumn+1); - if( !pIdx->zColAff ){ - return; - } - for(n=0; nnColumn; n++){ - pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity; - } - pIdx->zColAff[pIdx->nColumn] = '\0'; - } - - sqlite3VdbeChangeP3(v, -1, pIdx->zColAff, 0); -} - -/* -** Set P3 of the most recently inserted opcode to a column affinity -** string for table pTab. A column affinity string has one character -** for each column indexed by the index, according to the affinity of the -** column: -** -** Character Column affinity -** ------------------------------ -** 'a' TEXT -** 'b' NONE -** 'c' NUMERIC -** 'd' INTEGER -** 'e' REAL -*/ -void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ - /* The first time a column affinity string for a particular table - ** is required, it is allocated and populated here. It is then - ** stored as a member of the Table structure for subsequent use. - ** - ** The column affinity string will eventually be deleted by - ** sqlite3DeleteTable() when the Table structure itself is cleaned up. - */ - if( !pTab->zColAff ){ - char *zColAff; - int i; - sqlite3 *db = sqlite3VdbeDb(v); - - zColAff = (char *)sqlite3DbMallocZero(db, pTab->nCol+1); - if( !zColAff ){ - return; - } - - for(i=0; inCol; i++){ - zColAff[i] = pTab->aCol[i].affinity; - } - zColAff[pTab->nCol] = '\0'; - - pTab->zColAff = zColAff; - } - - sqlite3VdbeChangeP3(v, -1, pTab->zColAff, 0); -} - -/* -** Return non-zero if SELECT statement p opens the table with rootpage -** iTab in database iDb. This is used to see if a statement of the form -** "INSERT INTO SELECT ..." can run without using temporary -** table for the results of the SELECT. -** -** No checking is done for sub-selects that are part of expressions. -*/ -static int selectReadsTable(Select *p, Schema *pSchema, int iTab){ - int i; - struct SrcList_item *pItem; - if( p->pSrc==0 ) return 0; - for(i=0, pItem=p->pSrc->a; ipSrc->nSrc; i++, pItem++){ - if( pItem->pSelect ){ - if( selectReadsTable(pItem->pSelect, pSchema, iTab) ) return 1; - }else{ - if( pItem->pTab->pSchema==pSchema && pItem->pTab->tnum==iTab ) return 1; - } - } - return 0; -} - -#ifndef SQLITE_OMIT_AUTOINCREMENT -/* -** Write out code to initialize the autoincrement logic. This code -** looks up the current autoincrement value in the sqlite_sequence -** table and stores that value in a memory cell. Code generated by -** autoIncStep() will keep that memory cell holding the largest -** rowid value. Code generated by autoIncEnd() will write the new -** largest value of the counter back into the sqlite_sequence table. -** -** This routine returns the index of the mem[] cell that contains -** the maximum rowid counter. -** -** Two memory cells are allocated. The next memory cell after the -** one returned holds the rowid in sqlite_sequence where we will -** write back the revised maximum rowid. -*/ -static int autoIncBegin( - Parse *pParse, /* Parsing context */ - int iDb, /* Index of the database holding pTab */ - Table *pTab /* The table we are writing to */ -){ - int memId = 0; - if( pTab->autoInc ){ - Vdbe *v = pParse->pVdbe; - Db *pDb = &pParse->db->aDb[iDb]; - int iCur = pParse->nTab; - int addr; - assert( v ); - addr = sqlite3VdbeCurrentAddr(v); - memId = pParse->nMem+1; - pParse->nMem += 2; - sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead); - sqlite3VdbeAddOp(v, OP_Rewind, iCur, addr+13); - sqlite3VdbeAddOp(v, OP_Column, iCur, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); - sqlite3VdbeAddOp(v, OP_Ne, 0x100, addr+12); - sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); - sqlite3VdbeAddOp(v, OP_MemStore, memId-1, 1); - sqlite3VdbeAddOp(v, OP_Column, iCur, 1); - sqlite3VdbeAddOp(v, OP_MemStore, memId, 1); - sqlite3VdbeAddOp(v, OP_Goto, 0, addr+13); - sqlite3VdbeAddOp(v, OP_Next, iCur, addr+4); - sqlite3VdbeAddOp(v, OP_Close, iCur, 0); - } - return memId; -} - -/* -** Update the maximum rowid for an autoincrement calculation. -** -** This routine should be called when the top of the stack holds a -** new rowid that is about to be inserted. If that new rowid is -** larger than the maximum rowid in the memId memory cell, then the -** memory cell is updated. The stack is unchanged. -*/ -static void autoIncStep(Parse *pParse, int memId){ - if( memId>0 ){ - sqlite3VdbeAddOp(pParse->pVdbe, OP_MemMax, memId, 0); - } -} - -/* -** After doing one or more inserts, the maximum rowid is stored -** in mem[memId]. Generate code to write this value back into the -** the sqlite_sequence table. -*/ -static void autoIncEnd( - Parse *pParse, /* The parsing context */ - int iDb, /* Index of the database holding pTab */ - Table *pTab, /* Table we are inserting into */ - int memId /* Memory cell holding the maximum rowid */ -){ - if( pTab->autoInc ){ - int iCur = pParse->nTab; - Vdbe *v = pParse->pVdbe; - Db *pDb = &pParse->db->aDb[iDb]; - int addr; - assert( v ); - addr = sqlite3VdbeCurrentAddr(v); - sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); - sqlite3VdbeAddOp(v, OP_MemLoad, memId-1, 0); - sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+7); - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3VdbeAddOp(v, OP_NewRowid, iCur, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); - sqlite3VdbeAddOp(v, OP_MemLoad, memId, 0); - sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0); - sqlite3VdbeAddOp(v, OP_Insert, iCur, OPFLAG_APPEND); - sqlite3VdbeAddOp(v, OP_Close, iCur, 0); - } -} -#else -/* -** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines -** above are all no-ops -*/ -# define autoIncBegin(A,B,C) (0) -# define autoIncStep(A,B) -# define autoIncEnd(A,B,C,D) -#endif /* SQLITE_OMIT_AUTOINCREMENT */ - - -/* Forward declaration */ -static int xferOptimization( - Parse *pParse, /* Parser context */ - Table *pDest, /* The table we are inserting into */ - Select *pSelect, /* A SELECT statement to use as the data source */ - int onError, /* How to handle constraint errors */ - int iDbDest /* The database of pDest */ -); - -/* -** This routine is call to handle SQL of the following forms: -** -** insert into TABLE (IDLIST) values(EXPRLIST) -** insert into TABLE (IDLIST) select -** -** The IDLIST following the table name is always optional. If omitted, -** then a list of all columns for the table is substituted. The IDLIST -** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted. -** -** The pList parameter holds EXPRLIST in the first form of the INSERT -** statement above, and pSelect is NULL. For the second form, pList is -** NULL and pSelect is a pointer to the select statement used to generate -** data for the insert. -** -** The code generated follows one of four templates. For a simple -** select with data coming from a VALUES clause, the code executes -** once straight down through. The template looks like this: -** -** open write cursor to and its indices -** puts VALUES clause expressions onto the stack -** write the resulting record into
-** cleanup -** -** The three remaining templates assume the statement is of the form -** -** INSERT INTO
SELECT ... -** -** If the SELECT clause is of the restricted form "SELECT * FROM " - -** in other words if the SELECT pulls all columns from a single table -** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and -** if and are distinct tables but have identical -** schemas, including all the same indices, then a special optimization -** is invoked that copies raw records from over to . -** See the xferOptimization() function for the implementation of this -** template. This is the second template. -** -** open a write cursor to
-** open read cursor on -** transfer all records in over to
-** close cursors -** foreach index on
-** open a write cursor on the
index -** open a read cursor on the corresponding index -** transfer all records from the read to the write cursors -** close cursors -** end foreach -** -** The third template is for when the second template does not apply -** and the SELECT clause does not read from
at any time. -** The generated code follows this template: -** -** goto B -** A: setup for the SELECT -** loop over the rows in the SELECT -** gosub C -** end loop -** cleanup after the SELECT -** goto D -** B: open write cursor to
and its indices -** goto A -** C: insert the select result into
-** return -** D: cleanup -** -** The fourth template is used if the insert statement takes its -** values from a SELECT but the data is being inserted into a table -** that is also read as part of the SELECT. In the third form, -** we have to use a intermediate table to store the results of -** the select. The template is like this: -** -** goto B -** A: setup for the SELECT -** loop over the tables in the SELECT -** gosub C -** end loop -** cleanup after the SELECT -** goto D -** C: insert the select result into the intermediate table -** return -** B: open a cursor to an intermediate table -** goto A -** D: open write cursor to
and its indices -** loop over the intermediate table -** transfer values form intermediate table into
-** end the loop -** cleanup -*/ -void sqlite3Insert( - Parse *pParse, /* Parser context */ - SrcList *pTabList, /* Name of table into which we are inserting */ - ExprList *pList, /* List of values to be inserted */ - Select *pSelect, /* A SELECT statement to use as the data source */ - IdList *pColumn, /* Column names corresponding to IDLIST. */ - int onError /* How to handle constraint errors */ -){ - Table *pTab; /* The table to insert into */ - char *zTab; /* Name of the table into which we are inserting */ - const char *zDb; /* Name of the database holding this table */ - int i, j, idx; /* Loop counters */ - Vdbe *v; /* Generate code into this virtual machine */ - Index *pIdx; /* For looping over indices of the table */ - int nColumn; /* Number of columns in the data */ - int base = 0; /* VDBE Cursor number for pTab */ - int iCont=0,iBreak=0; /* Beginning and end of the loop over srcTab */ - sqlite3 *db; /* The main database structure */ - int keyColumn = -1; /* Column that is the INTEGER PRIMARY KEY */ - int endOfLoop; /* Label for the end of the insertion loop */ - int useTempTable = 0; /* Store SELECT results in intermediate table */ - int srcTab = 0; /* Data comes from this temporary cursor if >=0 */ - int iSelectLoop = 0; /* Address of code that implements the SELECT */ - int iCleanup = 0; /* Address of the cleanup code */ - int iInsertBlock = 0; /* Address of the subroutine used to insert data */ - int iCntMem = 0; /* Memory cell used for the row counter */ - int newIdx = -1; /* Cursor for the NEW table */ - Db *pDb; /* The database containing table being inserted into */ - int counterMem = 0; /* Memory cell holding AUTOINCREMENT counter */ - int appendFlag = 0; /* True if the insert is likely to be an append */ - int iDb; - - int nHidden = 0; - -#ifndef SQLITE_OMIT_TRIGGER - int isView; /* True if attempting to insert into a view */ - int triggers_exist = 0; /* True if there are FOR EACH ROW triggers */ -#endif - - db = pParse->db; - if( pParse->nErr || db->mallocFailed ){ - goto insert_cleanup; - } - - /* Locate the table into which we will be inserting new information. - */ - assert( pTabList->nSrc==1 ); - zTab = pTabList->a[0].zName; - if( zTab==0 ) goto insert_cleanup; - pTab = sqlite3SrcListLookup(pParse, pTabList); - if( pTab==0 ){ - goto insert_cleanup; - } - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDbnDb ); - pDb = &db->aDb[iDb]; - zDb = pDb->zName; - if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){ - goto insert_cleanup; - } - - /* Figure out if we have any triggers and if the table being - ** inserted into is a view - */ -#ifndef SQLITE_OMIT_TRIGGER - triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0); - isView = pTab->pSelect!=0; -#else -# define triggers_exist 0 -# define isView 0 -#endif -#ifdef SQLITE_OMIT_VIEW -# undef isView -# define isView 0 -#endif - - /* Ensure that: - * (a) the table is not read-only, - * (b) that if it is a view then ON INSERT triggers exist - */ - if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){ - goto insert_cleanup; - } - assert( pTab!=0 ); - - /* If pTab is really a view, make sure it has been initialized. - ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual - ** module table). - */ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto insert_cleanup; - } - - /* Allocate a VDBE - */ - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto insert_cleanup; - if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, iDb); - - /* if there are row triggers, allocate a temp table for new.* references. */ - if( triggers_exist ){ - newIdx = pParse->nTab++; - } - -#ifndef SQLITE_OMIT_XFER_OPT - /* If the statement is of the form - ** - ** INSERT INTO SELECT * FROM ; - ** - ** Then special optimizations can be applied that make the transfer - ** very fast and which reduce fragmentation of indices. - */ - if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ - assert( !triggers_exist ); - assert( pList==0 ); - goto insert_cleanup; - } -#endif /* SQLITE_OMIT_XFER_OPT */ - - /* If this is an AUTOINCREMENT table, look up the sequence number in the - ** sqlite_sequence table and store it in memory cell counterMem. Also - ** remember the rowid of the sqlite_sequence table entry in memory cell - ** counterRowid. - */ - counterMem = autoIncBegin(pParse, iDb, pTab); - - /* Figure out how many columns of data are supplied. If the data - ** is coming from a SELECT statement, then this step also generates - ** all the code to implement the SELECT statement and invoke a subroutine - ** to process each row of the result. (Template 2.) If the SELECT - ** statement uses the the table that is being inserted into, then the - ** subroutine is also coded here. That subroutine stores the SELECT - ** results in a temporary table. (Template 3.) - */ - if( pSelect ){ - /* Data is coming from a SELECT. Generate code to implement that SELECT - */ - int rc, iInitCode; - iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); - iSelectLoop = sqlite3VdbeCurrentAddr(v); - iInsertBlock = sqlite3VdbeMakeLabel(v); - - /* Resolve the expressions in the SELECT statement and execute it. */ - rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0); - if( rc || pParse->nErr || db->mallocFailed ){ - goto insert_cleanup; - } - - iCleanup = sqlite3VdbeMakeLabel(v); - sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup); - assert( pSelect->pEList ); - nColumn = pSelect->pEList->nExpr; - - /* Set useTempTable to TRUE if the result of the SELECT statement - ** should be written into a temporary table. Set to FALSE if each - ** row of the SELECT can be written directly into the result table. - ** - ** A temp table must be used if the table being updated is also one - ** of the tables being read by the SELECT statement. Also use a - ** temp table in the case of row triggers. - */ - if( triggers_exist || selectReadsTable(pSelect,pTab->pSchema,pTab->tnum) ){ - useTempTable = 1; - } - - if( useTempTable ){ - /* Generate the subroutine that SELECT calls to process each row of - ** the result. Store the result in a temporary table - */ - srcTab = pParse->nTab++; - sqlite3VdbeResolveLabel(v, iInsertBlock); - sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); - sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0); - sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_Insert, srcTab, OPFLAG_APPEND); - sqlite3VdbeAddOp(v, OP_Return, 0, 0); - - /* The following code runs first because the GOTO at the very top - ** of the program jumps to it. Create the temporary table, then jump - ** back up and execute the SELECT code above. - */ - sqlite3VdbeJumpHere(v, iInitCode); - sqlite3VdbeAddOp(v, OP_OpenEphemeral, srcTab, 0); - sqlite3VdbeAddOp(v, OP_SetNumColumns, srcTab, nColumn); - sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop); - sqlite3VdbeResolveLabel(v, iCleanup); - }else{ - sqlite3VdbeJumpHere(v, iInitCode); - } - }else{ - /* This is the case if the data for the INSERT is coming from a VALUES - ** clause - */ - NameContext sNC; - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - srcTab = -1; - useTempTable = 0; - nColumn = pList ? pList->nExpr : 0; - for(i=0; ia[i].pExpr) ){ - goto insert_cleanup; - } - } - } - - /* Make sure the number of columns in the source data matches the number - ** of columns to be inserted into the table. - */ - if( IsVirtual(pTab) ){ - for(i=0; inCol; i++){ - nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0); - } - } - if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){ - sqlite3ErrorMsg(pParse, - "table %S has %d columns but %d values were supplied", - pTabList, 0, pTab->nCol, nColumn); - goto insert_cleanup; - } - if( pColumn!=0 && nColumn!=pColumn->nId ){ - sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); - goto insert_cleanup; - } - - /* If the INSERT statement included an IDLIST term, then make sure - ** all elements of the IDLIST really are columns of the table and - ** remember the column indices. - ** - ** If the table has an INTEGER PRIMARY KEY column and that column - ** is named in the IDLIST, then record in the keyColumn variable - ** the index into IDLIST of the primary key column. keyColumn is - ** the index of the primary key as it appears in IDLIST, not as - ** is appears in the original table. (The index of the primary - ** key in the original table is pTab->iPKey.) - */ - if( pColumn ){ - for(i=0; inId; i++){ - pColumn->a[i].idx = -1; - } - for(i=0; inId; i++){ - for(j=0; jnCol; j++){ - if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ - pColumn->a[i].idx = j; - if( j==pTab->iPKey ){ - keyColumn = i; - } - break; - } - } - if( j>=pTab->nCol ){ - if( sqlite3IsRowid(pColumn->a[i].zName) ){ - keyColumn = i; - }else{ - sqlite3ErrorMsg(pParse, "table %S has no column named %s", - pTabList, 0, pColumn->a[i].zName); - pParse->nErr++; - goto insert_cleanup; - } - } - } - } - - /* If there is no IDLIST term but the table has an integer primary - ** key, the set the keyColumn variable to the primary key column index - ** in the original table definition. - */ - if( pColumn==0 && nColumn>0 ){ - keyColumn = pTab->iPKey; - } - - /* Open the temp table for FOR EACH ROW triggers - */ - if( triggers_exist ){ - sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0); - sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol); - } - - /* Initialize the count of rows to be inserted - */ - if( db->flags & SQLITE_CountRows ){ - iCntMem = pParse->nMem++; - sqlite3VdbeAddOp(v, OP_MemInt, 0, iCntMem); - } - - /* Open tables and indices if there are no row triggers */ - if( !triggers_exist ){ - base = pParse->nTab; - sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite); - } - - /* If the data source is a temporary table, then we have to create - ** a loop because there might be multiple rows of data. If the data - ** source is a subroutine call from the SELECT statement, then we need - ** to launch the SELECT statement processing. - */ - if( useTempTable ){ - iBreak = sqlite3VdbeMakeLabel(v); - sqlite3VdbeAddOp(v, OP_Rewind, srcTab, iBreak); - iCont = sqlite3VdbeCurrentAddr(v); - }else if( pSelect ){ - sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop); - sqlite3VdbeResolveLabel(v, iInsertBlock); - } - - /* Run the BEFORE and INSTEAD OF triggers, if there are any - */ - endOfLoop = sqlite3VdbeMakeLabel(v); - if( triggers_exist & TRIGGER_BEFORE ){ - - /* build the NEW.* reference row. Note that if there is an INTEGER - ** PRIMARY KEY into which a NULL is being inserted, that NULL will be - ** translated into a unique ID for the row. But on a BEFORE trigger, - ** we do not know what the unique ID will be (because the insert has - ** not happened yet) so we substitute a rowid of -1 - */ - if( keyColumn<0 ){ - sqlite3VdbeAddOp(v, OP_Integer, -1, 0); - }else if( useTempTable ){ - sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn); - }else{ - assert( pSelect==0 ); /* Otherwise useTempTable is true */ - sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr); - sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3VdbeAddOp(v, OP_Integer, -1, 0); - sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); - } - - /* Cannot have triggers on a virtual table. If it were possible, - ** this block would have to account for hidden column. - */ - assert(!IsVirtual(pTab)); - - /* Create the new column data - */ - for(i=0; inCol; i++){ - if( pColumn==0 ){ - j = i; - }else{ - for(j=0; jnId; j++){ - if( pColumn->a[j].idx==i ) break; - } - } - if( pColumn && j>=pColumn->nId ){ - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); - }else if( useTempTable ){ - sqlite3VdbeAddOp(v, OP_Column, srcTab, j); - }else{ - assert( pSelect==0 ); /* Otherwise useTempTable is true */ - sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr); - } - } - sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); - - /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger, - ** do not attempt any conversions before assembling the record. - ** If this is a real table, attempt conversions as required by the - ** table column affinities. - */ - if( !isView ){ - sqlite3TableAffinityStr(v, pTab); - } - sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0); - - /* Fire BEFORE or INSTEAD OF triggers */ - if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab, - newIdx, -1, onError, endOfLoop) ){ - goto insert_cleanup; - } - } - - /* If any triggers exists, the opening of tables and indices is deferred - ** until now. - */ - if( triggers_exist && !isView ){ - base = pParse->nTab; - sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite); - } - - /* Push the record number for the new entry onto the stack. The - ** record number is a randomly generate integer created by NewRowid - ** except when the table has an INTEGER PRIMARY KEY column, in which - ** case the record number is the same as that column. - */ - if( !isView ){ - if( IsVirtual(pTab) ){ - /* The row that the VUpdate opcode will delete: none */ - sqlite3VdbeAddOp(v, OP_Null, 0, 0); - } - if( keyColumn>=0 ){ - if( useTempTable ){ - sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn); - }else if( pSelect ){ - sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1); - }else{ - VdbeOp *pOp; - sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr); - pOp = sqlite3VdbeGetOp(v, sqlite3VdbeCurrentAddr(v) - 1); - if( pOp && pOp->opcode==OP_Null ){ - appendFlag = 1; - pOp->opcode = OP_NewRowid; - pOp->p1 = base; - pOp->p2 = counterMem; - } - } - /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid - ** to generate a unique primary key value. - */ - if( !appendFlag ){ - sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem); - sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); - } - }else if( IsVirtual(pTab) ){ - sqlite3VdbeAddOp(v, OP_Null, 0, 0); - }else{ - sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem); - appendFlag = 1; - } - autoIncStep(pParse, counterMem); - - /* Push onto the stack, data for all columns of the new entry, beginning - ** with the first column. - */ - nHidden = 0; - for(i=0; inCol; i++){ - if( i==pTab->iPKey ){ - /* The value of the INTEGER PRIMARY KEY column is always a NULL. - ** Whenever this column is read, the record number will be substituted - ** in its place. So will fill this column with a NULL to avoid - ** taking up data space with information that will never be used. */ - sqlite3VdbeAddOp(v, OP_Null, 0, 0); - continue; - } - if( pColumn==0 ){ - if( IsHiddenColumn(&pTab->aCol[i]) ){ - assert( IsVirtual(pTab) ); - j = -1; - nHidden++; - }else{ - j = i - nHidden; - } - }else{ - for(j=0; jnId; j++){ - if( pColumn->a[j].idx==i ) break; - } - } - if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){ - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); - }else if( useTempTable ){ - sqlite3VdbeAddOp(v, OP_Column, srcTab, j); - }else if( pSelect ){ - sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1); - }else{ - sqlite3ExprCode(pParse, pList->a[j].pExpr); - } - } - - /* Generate code to check constraints and generate index keys and - ** do the insertion. - */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - pParse->pVirtualLock = pTab; - sqlite3VdbeOp3(v, OP_VUpdate, 1, pTab->nCol+2, - (const char*)pTab->pVtab, P3_VTAB); - }else -#endif - { - sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0, - 0, onError, endOfLoop); - sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0, - (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1, - appendFlag); - } - } - - /* Update the count of rows that are inserted - */ - if( (db->flags & SQLITE_CountRows)!=0 ){ - sqlite3VdbeAddOp(v, OP_MemIncr, 1, iCntMem); - } - - if( triggers_exist ){ - /* Close all tables opened */ - if( !isView ){ - sqlite3VdbeAddOp(v, OP_Close, base, 0); - for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ - sqlite3VdbeAddOp(v, OP_Close, idx+base, 0); - } - } - - /* Code AFTER triggers */ - if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_AFTER, pTab, - newIdx, -1, onError, endOfLoop) ){ - goto insert_cleanup; - } - } - - /* The bottom of the loop, if the data source is a SELECT statement - */ - sqlite3VdbeResolveLabel(v, endOfLoop); - if( useTempTable ){ - sqlite3VdbeAddOp(v, OP_Next, srcTab, iCont); - sqlite3VdbeResolveLabel(v, iBreak); - sqlite3VdbeAddOp(v, OP_Close, srcTab, 0); - }else if( pSelect ){ - sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); - sqlite3VdbeAddOp(v, OP_Return, 0, 0); - sqlite3VdbeResolveLabel(v, iCleanup); - } - - if( !triggers_exist && !IsVirtual(pTab) ){ - /* Close all tables opened */ - sqlite3VdbeAddOp(v, OP_Close, base, 0); - for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ - sqlite3VdbeAddOp(v, OP_Close, idx+base, 0); - } - } - - /* Update the sqlite_sequence table by storing the content of the - ** counter value in memory counterMem back into the sqlite_sequence - ** table. - */ - autoIncEnd(pParse, iDb, pTab, counterMem); - - /* - ** Return the number of rows inserted. If this routine is - ** generating code because of a call to sqlite3NestedParse(), do not - ** invoke the callback function. - */ - if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){ - sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0); - sqlite3VdbeAddOp(v, OP_Callback, 1, 0); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", P3_STATIC); - } - -insert_cleanup: - sqlite3SrcListDelete(pTabList); - sqlite3ExprListDelete(pList); - sqlite3SelectDelete(pSelect); - sqlite3IdListDelete(pColumn); -} - -/* -** Generate code to do a constraint check prior to an INSERT or an UPDATE. -** -** When this routine is called, the stack contains (from bottom to top) -** the following values: -** -** 1. The rowid of the row to be updated before the update. This -** value is omitted unless we are doing an UPDATE that involves a -** change to the record number. -** -** 2. The rowid of the row after the update. -** -** 3. The data in the first column of the entry after the update. -** -** i. Data from middle columns... -** -** N. The data in the last column of the entry after the update. -** -** The old rowid shown as entry (1) above is omitted unless both isUpdate -** and rowidChng are 1. isUpdate is true for UPDATEs and false for -** INSERTs and rowidChng is true if the record number is being changed. -** -** The code generated by this routine pushes additional entries onto -** the stack which are the keys for new index entries for the new record. -** The order of index keys is the same as the order of the indices on -** the pTable->pIndex list. A key is only created for index i if -** aIdxUsed!=0 and aIdxUsed[i]!=0. -** -** This routine also generates code to check constraints. NOT NULL, -** CHECK, and UNIQUE constraints are all checked. If a constraint fails, -** then the appropriate action is performed. There are five possible -** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE. -** -** Constraint type Action What Happens -** --------------- ---------- ---------------------------------------- -** any ROLLBACK The current transaction is rolled back and -** sqlite3_exec() returns immediately with a -** return code of SQLITE_CONSTRAINT. -** -** any ABORT Back out changes from the current command -** only (do not do a complete rollback) then -** cause sqlite3_exec() to return immediately -** with SQLITE_CONSTRAINT. -** -** any FAIL Sqlite_exec() returns immediately with a -** return code of SQLITE_CONSTRAINT. The -** transaction is not rolled back and any -** prior changes are retained. -** -** any IGNORE The record number and data is popped from -** the stack and there is an immediate jump -** to label ignoreDest. -** -** NOT NULL REPLACE The NULL value is replace by the default -** value for that column. If the default value -** is NULL, the action is the same as ABORT. -** -** UNIQUE REPLACE The other row that conflicts with the row -** being inserted is removed. -** -** CHECK REPLACE Illegal. The results in an exception. -** -** Which action to take is determined by the overrideError parameter. -** Or if overrideError==OE_Default, then the pParse->onError parameter -** is used. Or if pParse->onError==OE_Default then the onError value -** for the constraint is used. -** -** The calling routine must open a read/write cursor for pTab with -** cursor number "base". All indices of pTab must also have open -** read/write cursors with cursor number base+i for the i-th cursor. -** Except, if there is no possibility of a REPLACE action then -** cursors do not need to be open for indices where aIdxUsed[i]==0. -** -** If the isUpdate flag is true, it means that the "base" cursor is -** initially pointing to an entry that is being updated. The isUpdate -** flag causes extra code to be generated so that the "base" cursor -** is still pointing at the same entry after the routine returns. -** Without the isUpdate flag, the "base" cursor might be moved. -*/ -void sqlite3GenerateConstraintChecks( - Parse *pParse, /* The parser context */ - Table *pTab, /* the table into which we are inserting */ - int base, /* Index of a read/write cursor pointing at pTab */ - char *aIdxUsed, /* Which indices are used. NULL means all are used */ - int rowidChng, /* True if the record number will change */ - int isUpdate, /* True for UPDATE, False for INSERT */ - int overrideError, /* Override onError to this if not OE_Default */ - int ignoreDest /* Jump to this label on an OE_Ignore resolution */ -){ - int i; - Vdbe *v; - int nCol; - int onError; - int addr; - int extra; - int iCur; - Index *pIdx; - int seenReplace = 0; - int jumpInst1=0, jumpInst2; - int hasTwoRowids = (isUpdate && rowidChng); - - v = sqlite3GetVdbe(pParse); - assert( v!=0 ); - assert( pTab->pSelect==0 ); /* This table is not a VIEW */ - nCol = pTab->nCol; - - /* Test all NOT NULL constraints. - */ - for(i=0; iiPKey ){ - continue; - } - onError = pTab->aCol[i].notNull; - if( onError==OE_None ) continue; - if( overrideError!=OE_Default ){ - onError = overrideError; - }else if( onError==OE_Default ){ - onError = OE_Abort; - } - if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){ - onError = OE_Abort; - } - sqlite3VdbeAddOp(v, OP_Dup, nCol-1-i, 1); - addr = sqlite3VdbeAddOp(v, OP_NotNull, 1, 0); - assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail - || onError==OE_Ignore || onError==OE_Replace ); - switch( onError ){ - case OE_Rollback: - case OE_Abort: - case OE_Fail: { - char *zMsg = 0; - sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError); - sqlite3SetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName, - " may not be NULL", (char*)0); - sqlite3VdbeChangeP3(v, -1, zMsg, P3_DYNAMIC); - break; - } - case OE_Ignore: { - sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest); - break; - } - case OE_Replace: { - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); - sqlite3VdbeAddOp(v, OP_Push, nCol-i, 0); - break; - } - } - sqlite3VdbeJumpHere(v, addr); - } - - /* Test all CHECK constraints - */ -#ifndef SQLITE_OMIT_CHECK - if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){ - int allOk = sqlite3VdbeMakeLabel(v); - assert( pParse->ckOffset==0 ); - pParse->ckOffset = nCol; - sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, 1); - assert( pParse->ckOffset==nCol ); - pParse->ckOffset = 0; - onError = overrideError!=OE_Default ? overrideError : OE_Abort; - if( onError==OE_Ignore ){ - sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest); - }else{ - sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError); - } - sqlite3VdbeResolveLabel(v, allOk); - } -#endif /* !defined(SQLITE_OMIT_CHECK) */ - - /* If we have an INTEGER PRIMARY KEY, make sure the primary key - ** of the new record does not previously exist. Except, if this - ** is an UPDATE and the primary key is not changing, that is OK. - */ - if( rowidChng ){ - onError = pTab->keyConf; - if( overrideError!=OE_Default ){ - onError = overrideError; - }else if( onError==OE_Default ){ - onError = OE_Abort; - } - - if( isUpdate ){ - sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1); - sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1); - jumpInst1 = sqlite3VdbeAddOp(v, OP_Eq, 0, 0); - } - sqlite3VdbeAddOp(v, OP_Dup, nCol, 1); - jumpInst2 = sqlite3VdbeAddOp(v, OP_NotExists, base, 0); - switch( onError ){ - default: { - onError = OE_Abort; - /* Fall thru into the next case */ - } - case OE_Rollback: - case OE_Abort: - case OE_Fail: { - sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, - "PRIMARY KEY must be unique", P3_STATIC); - break; - } - case OE_Replace: { - sqlite3GenerateRowIndexDelete(v, pTab, base, 0); - if( isUpdate ){ - sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRowids, 1); - sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); - } - seenReplace = 1; - break; - } - case OE_Ignore: { - assert( seenReplace==0 ); - sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest); - break; - } - } - sqlite3VdbeJumpHere(v, jumpInst2); - if( isUpdate ){ - sqlite3VdbeJumpHere(v, jumpInst1); - sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1); - sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); - } - } - - /* Test all UNIQUE constraints by creating entries for each UNIQUE - ** index and making sure that duplicate entries do not already exist. - ** Add the new records to the indices as we go. - */ - extra = -1; - for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){ - if( aIdxUsed && aIdxUsed[iCur]==0 ) continue; /* Skip unused indices */ - extra++; - - /* Create a key for accessing the index entry */ - sqlite3VdbeAddOp(v, OP_Dup, nCol+extra, 1); - for(i=0; inColumn; i++){ - int idx = pIdx->aiColumn[i]; - if( idx==pTab->iPKey ){ - sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1); - }else{ - sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1); - } - } - jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0); - sqlite3IndexAffinityStr(v, pIdx); - - /* Find out what action to take in case there is an indexing conflict */ - onError = pIdx->onError; - if( onError==OE_None ) continue; /* pIdx is not a UNIQUE index */ - if( overrideError!=OE_Default ){ - onError = overrideError; - }else if( onError==OE_Default ){ - onError = OE_Abort; - } - if( seenReplace ){ - if( onError==OE_Ignore ) onError = OE_Replace; - else if( onError==OE_Fail ) onError = OE_Abort; - } - - - /* Check to see if the new index entry will be unique */ - sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1); - jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0); - - /* Generate code that executes if the new index entry is not unique */ - assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail - || onError==OE_Ignore || onError==OE_Replace ); - switch( onError ){ - case OE_Rollback: - case OE_Abort: - case OE_Fail: { - int j, n1, n2; - char zErrMsg[200]; - sqlite3_snprintf(sizeof(zErrMsg), zErrMsg, - pIdx->nColumn>1 ? "columns " : "column "); - n1 = strlen(zErrMsg); - for(j=0; jnColumn && n1aCol[pIdx->aiColumn[j]].zName; - n2 = strlen(zCol); - if( j>0 ){ - sqlite3_snprintf(sizeof(zErrMsg)-n1, &zErrMsg[n1], ", "); - n1 += 2; - } - if( n1+n2>sizeof(zErrMsg)-30 ){ - sqlite3_snprintf(sizeof(zErrMsg)-n1, &zErrMsg[n1], "..."); - n1 += 3; - break; - }else{ - sqlite3_snprintf(sizeof(zErrMsg)-n1, &zErrMsg[n1], "%s", zCol); - n1 += n2; - } - } - sqlite3_snprintf(sizeof(zErrMsg)-n1, &zErrMsg[n1], - pIdx->nColumn>1 ? " are not unique" : " is not unique"); - sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0); - break; - } - case OE_Ignore: { - assert( seenReplace==0 ); - sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRowids, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest); - break; - } - case OE_Replace: { - sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0); - if( isUpdate ){ - sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1); - sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); - } - seenReplace = 1; - break; - } - } -#if NULL_DISTINCT_FOR_UNIQUE - sqlite3VdbeJumpHere(v, jumpInst1); -#endif - sqlite3VdbeJumpHere(v, jumpInst2); - } -} - -/* -** This routine generates code to finish the INSERT or UPDATE operation -** that was started by a prior call to sqlite3GenerateConstraintChecks. -** The stack must contain keys for all active indices followed by data -** and the rowid for the new entry. This routine creates the new -** entries in all indices and in the main table. -** -** The arguments to this routine should be the same as the first six -** arguments to sqlite3GenerateConstraintChecks. -*/ -void sqlite3CompleteInsertion( - Parse *pParse, /* The parser context */ - Table *pTab, /* the table into which we are inserting */ - int base, /* Index of a read/write cursor pointing at pTab */ - char *aIdxUsed, /* Which indices are used. NULL means all are used */ - int rowidChng, /* True if the record number will change */ - int isUpdate, /* True for UPDATE, False for INSERT */ - int newIdx, /* Index of NEW table for triggers. -1 if none */ - int appendBias /* True if this is likely to be an append */ -){ - int i; - Vdbe *v; - int nIdx; - Index *pIdx; - int pik_flags; - - v = sqlite3GetVdbe(pParse); - assert( v!=0 ); - assert( pTab->pSelect==0 ); /* This table is not a VIEW */ - for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){} - for(i=nIdx-1; i>=0; i--){ - if( aIdxUsed && aIdxUsed[i]==0 ) continue; - sqlite3VdbeAddOp(v, OP_IdxInsert, base+i+1, 0); - } - sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); - sqlite3TableAffinityStr(v, pTab); -#ifndef SQLITE_OMIT_TRIGGER - if( newIdx>=0 ){ - sqlite3VdbeAddOp(v, OP_Dup, 1, 0); - sqlite3VdbeAddOp(v, OP_Dup, 1, 0); - sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0); - } -#endif - if( pParse->nested ){ - pik_flags = 0; - }else{ - pik_flags = OPFLAG_NCHANGE; - pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID); - } - if( appendBias ){ - pik_flags |= OPFLAG_APPEND; - } - sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags); - if( !pParse->nested ){ - sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC); - } - - if( isUpdate && rowidChng ){ - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - } -} - -/* -** Generate code that will open cursors for a table and for all -** indices of that table. The "base" parameter is the cursor number used -** for the table. Indices are opened on subsequent cursors. -*/ -void sqlite3OpenTableAndIndices( - Parse *pParse, /* Parsing context */ - Table *pTab, /* Table to be opened */ - int base, /* Cursor number assigned to the table */ - int op /* OP_OpenRead or OP_OpenWrite */ -){ - int i; - int iDb; - Index *pIdx; - Vdbe *v; - - if( IsVirtual(pTab) ) return; - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - v = sqlite3GetVdbe(pParse); - assert( v!=0 ); - sqlite3OpenTable(pParse, base, iDb, pTab, op); - for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ - KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); - assert( pIdx->pSchema==pTab->pSchema ); - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); - VdbeComment((v, "# %s", pIdx->zName)); - sqlite3VdbeOp3(v, op, i+base, pIdx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF); - } - if( pParse->nTab<=base+i ){ - pParse->nTab = base+i; - } -} - - -#ifdef SQLITE_TEST -/* -** The following global variable is incremented whenever the -** transfer optimization is used. This is used for testing -** purposes only - to make sure the transfer optimization really -** is happening when it is suppose to. -*/ -int sqlite3_xferopt_count; -#endif /* SQLITE_TEST */ - - -#ifndef SQLITE_OMIT_XFER_OPT -/* -** Check to collation names to see if they are compatible. -*/ -static int xferCompatibleCollation(const char *z1, const char *z2){ - if( z1==0 ){ - return z2==0; - } - if( z2==0 ){ - return 0; - } - return sqlite3StrICmp(z1, z2)==0; -} - - -/* -** Check to see if index pSrc is compatible as a source of data -** for index pDest in an insert transfer optimization. The rules -** for a compatible index: -** -** * The index is over the same set of columns -** * The same DESC and ASC markings occurs on all columns -** * The same onError processing (OE_Abort, OE_Ignore, etc) -** * The same collating sequence on each column -*/ -static int xferCompatibleIndex(Index *pDest, Index *pSrc){ - int i; - assert( pDest && pSrc ); - assert( pDest->pTable!=pSrc->pTable ); - if( pDest->nColumn!=pSrc->nColumn ){ - return 0; /* Different number of columns */ - } - if( pDest->onError!=pSrc->onError ){ - return 0; /* Different conflict resolution strategies */ - } - for(i=0; inColumn; i++){ - if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){ - return 0; /* Different columns indexed */ - } - if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){ - return 0; /* Different sort orders */ - } - if( pSrc->azColl[i]!=pDest->azColl[i] ){ - return 0; /* Different sort orders */ - } - } - - /* If no test above fails then the indices must be compatible */ - return 1; -} - -/* -** Attempt the transfer optimization on INSERTs of the form -** -** INSERT INTO tab1 SELECT * FROM tab2; -** -** This optimization is only attempted if -** -** (1) tab1 and tab2 have identical schemas including all the -** same indices and constraints -** -** (2) tab1 and tab2 are different tables -** -** (3) There must be no triggers on tab1 -** -** (4) The result set of the SELECT statement is "*" -** -** (5) The SELECT statement has no WHERE, HAVING, ORDER BY, GROUP BY, -** or LIMIT clause. -** -** (6) The SELECT statement is a simple (not a compound) select that -** contains only tab2 in its FROM clause -** -** This method for implementing the INSERT transfers raw records from -** tab2 over to tab1. The columns are not decoded. Raw records from -** the indices of tab2 are transfered to tab1 as well. In so doing, -** the resulting tab1 has much less fragmentation. -** -** This routine returns TRUE if the optimization is attempted. If any -** of the conditions above fail so that the optimization should not -** be attempted, then this routine returns FALSE. -*/ -static int xferOptimization( - Parse *pParse, /* Parser context */ - Table *pDest, /* The table we are inserting into */ - Select *pSelect, /* A SELECT statement to use as the data source */ - int onError, /* How to handle constraint errors */ - int iDbDest /* The database of pDest */ -){ - ExprList *pEList; /* The result set of the SELECT */ - Table *pSrc; /* The table in the FROM clause of SELECT */ - Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ - struct SrcList_item *pItem; /* An element of pSelect->pSrc */ - int i; /* Loop counter */ - int iDbSrc; /* The database of pSrc */ - int iSrc, iDest; /* Cursors from source and destination */ - int addr1, addr2; /* Loop addresses */ - int emptyDestTest; /* Address of test for empty pDest */ - int emptySrcTest; /* Address of test for empty pSrc */ - Vdbe *v; /* The VDBE we are building */ - KeyInfo *pKey; /* Key information for an index */ - int counterMem; /* Memory register used by AUTOINC */ - int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */ - - if( pSelect==0 ){ - return 0; /* Must be of the form INSERT INTO ... SELECT ... */ - } - if( pDest->pTrigger ){ - return 0; /* tab1 must not have triggers */ - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( pDest->isVirtual ){ - return 0; /* tab1 must not be a virtual table */ - } -#endif - if( onError==OE_Default ){ - onError = OE_Abort; - } - if( onError!=OE_Abort && onError!=OE_Rollback ){ - return 0; /* Cannot do OR REPLACE or OR IGNORE or OR FAIL */ - } - assert(pSelect->pSrc); /* allocated even if there is no FROM clause */ - if( pSelect->pSrc->nSrc!=1 ){ - return 0; /* FROM clause must have exactly one term */ - } - if( pSelect->pSrc->a[0].pSelect ){ - return 0; /* FROM clause cannot contain a subquery */ - } - if( pSelect->pWhere ){ - return 0; /* SELECT may not have a WHERE clause */ - } - if( pSelect->pOrderBy ){ - return 0; /* SELECT may not have an ORDER BY clause */ - } - /* Do not need to test for a HAVING clause. If HAVING is present but - ** there is no ORDER BY, we will get an error. */ - if( pSelect->pGroupBy ){ - return 0; /* SELECT may not have a GROUP BY clause */ - } - if( pSelect->pLimit ){ - return 0; /* SELECT may not have a LIMIT clause */ - } - assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */ - if( pSelect->pPrior ){ - return 0; /* SELECT may not be a compound query */ - } - if( pSelect->isDistinct ){ - return 0; /* SELECT may not be DISTINCT */ - } - pEList = pSelect->pEList; - assert( pEList!=0 ); - if( pEList->nExpr!=1 ){ - return 0; /* The result set must have exactly one column */ - } - assert( pEList->a[0].pExpr ); - if( pEList->a[0].pExpr->op!=TK_ALL ){ - return 0; /* The result set must be the special operator "*" */ - } - - /* At this point we have established that the statement is of the - ** correct syntactic form to participate in this optimization. Now - ** we have to check the semantics. - */ - pItem = pSelect->pSrc->a; - pSrc = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase); - if( pSrc==0 ){ - return 0; /* FROM clause does not contain a real table */ - } - if( pSrc==pDest ){ - return 0; /* tab1 and tab2 may not be the same table */ - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( pSrc->isVirtual ){ - return 0; /* tab2 must not be a virtual table */ - } -#endif - if( pSrc->pSelect ){ - return 0; /* tab2 may not be a view */ - } - if( pDest->nCol!=pSrc->nCol ){ - return 0; /* Number of columns must be the same in tab1 and tab2 */ - } - if( pDest->iPKey!=pSrc->iPKey ){ - return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ - } - for(i=0; inCol; i++){ - if( pDest->aCol[i].affinity!=pSrc->aCol[i].affinity ){ - return 0; /* Affinity must be the same on all columns */ - } - if( !xferCompatibleCollation(pDest->aCol[i].zColl, pSrc->aCol[i].zColl) ){ - return 0; /* Collating sequence must be the same on all columns */ - } - if( pDest->aCol[i].notNull && !pSrc->aCol[i].notNull ){ - return 0; /* tab2 must be NOT NULL if tab1 is */ - } - } - for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ - if( pDestIdx->onError!=OE_None ){ - destHasUniqueIdx = 1; - } - for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){ - if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; - } - if( pSrcIdx==0 ){ - return 0; /* pDestIdx has no corresponding index in pSrc */ - } - } -#ifndef SQLITE_OMIT_CHECK - if( pDest->pCheck && !sqlite3ExprCompare(pSrc->pCheck, pDest->pCheck) ){ - return 0; /* Tables have different CHECK constraints. Ticket #2252 */ - } -#endif - - /* If we get this far, it means either: - ** - ** * We can always do the transfer if the table contains an - ** an integer primary key - ** - ** * We can conditionally do the transfer if the destination - ** table is empty. - */ -#ifdef SQLITE_TEST - sqlite3_xferopt_count++; -#endif - iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema); - v = sqlite3GetVdbe(pParse); - sqlite3CodeVerifySchema(pParse, iDbSrc); - iSrc = pParse->nTab++; - iDest = pParse->nTab++; - counterMem = autoIncBegin(pParse, iDbDest, pDest); - sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); - if( (pDest->iPKey<0 && pDest->pIndex!=0) || destHasUniqueIdx ){ - /* If tables do not have an INTEGER PRIMARY KEY and there - ** are indices to be copied and the destination is not empty, - ** we have to disallow the transfer optimization because the - ** the rowids might change which will mess up indexing. - ** - ** Or if the destination has a UNIQUE index and is not empty, - ** we also disallow the transfer optimization because we cannot - ** insure that all entries in the union of DEST and SRC will be - ** unique. - */ - addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iDest, 0); - emptyDestTest = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); - sqlite3VdbeJumpHere(v, addr1); - }else{ - emptyDestTest = 0; - } - sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); - emptySrcTest = sqlite3VdbeAddOp(v, OP_Rewind, iSrc, 0); - if( pDest->iPKey>=0 ){ - addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - addr2 = sqlite3VdbeAddOp(v, OP_NotExists, iDest, 0); - sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, - "PRIMARY KEY must be unique", P3_STATIC); - sqlite3VdbeJumpHere(v, addr2); - autoIncStep(pParse, counterMem); - }else if( pDest->pIndex==0 ){ - addr1 = sqlite3VdbeAddOp(v, OP_NewRowid, iDest, 0); - }else{ - addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0); - assert( pDest->autoInc==0 ); - } - sqlite3VdbeAddOp(v, OP_RowData, iSrc, 0); - sqlite3VdbeOp3(v, OP_Insert, iDest, - OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND, - pDest->zName, 0); - sqlite3VdbeAddOp(v, OP_Next, iSrc, addr1); - autoIncEnd(pParse, iDbDest, pDest, counterMem); - for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ - for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){ - if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; - } - assert( pSrcIdx ); - sqlite3VdbeAddOp(v, OP_Close, iSrc, 0); - sqlite3VdbeAddOp(v, OP_Close, iDest, 0); - sqlite3VdbeAddOp(v, OP_Integer, iDbSrc, 0); - pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx); - VdbeComment((v, "# %s", pSrcIdx->zName)); - sqlite3VdbeOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, - (char*)pKey, P3_KEYINFO_HANDOFF); - sqlite3VdbeAddOp(v, OP_Integer, iDbDest, 0); - pKey = sqlite3IndexKeyinfo(pParse, pDestIdx); - VdbeComment((v, "# %s", pDestIdx->zName)); - sqlite3VdbeOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, - (char*)pKey, P3_KEYINFO_HANDOFF); - addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iSrc, 0); - sqlite3VdbeAddOp(v, OP_RowKey, iSrc, 0); - sqlite3VdbeAddOp(v, OP_IdxInsert, iDest, 1); - sqlite3VdbeAddOp(v, OP_Next, iSrc, addr1+1); - sqlite3VdbeJumpHere(v, addr1); - } - sqlite3VdbeJumpHere(v, emptySrcTest); - sqlite3VdbeAddOp(v, OP_Close, iSrc, 0); - sqlite3VdbeAddOp(v, OP_Close, iDest, 0); - if( emptyDestTest ){ - sqlite3VdbeAddOp(v, OP_Halt, SQLITE_OK, 0); - sqlite3VdbeJumpHere(v, emptyDestTest); - sqlite3VdbeAddOp(v, OP_Close, iDest, 0); - return 0; - }else{ - return 1; - } -} -#endif /* SQLITE_OMIT_XFER_OPT */ diff --git a/extensions/sqlite/sqlite-source/journal.c b/extensions/sqlite/sqlite-source/journal.c deleted file mode 100644 index 9e2b3b8e..00000000 --- a/extensions/sqlite/sqlite-source/journal.c +++ /dev/null @@ -1,238 +0,0 @@ -/* -** 2007 August 22 -** -** 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. -** -************************************************************************* -** -** @(#) $Id$ -*/ - -#ifdef SQLITE_ENABLE_ATOMIC_WRITE - -/* -** This file implements a special kind of sqlite3_file object used -** by SQLite to create journal files if the atomic-write optimization -** is enabled. -** -** The distinctive characteristic of this sqlite3_file is that the -** actual on disk file is created lazily. When the file is created, -** the caller specifies a buffer size for an in-memory buffer to -** be used to service read() and write() requests. The actual file -** on disk is not created or populated until either: -** -** 1) The in-memory representation grows too large for the allocated -** buffer, or -** 2) The xSync() method is called. -*/ - -#include "sqliteInt.h" - - -/* -** A JournalFile object is a subclass of sqlite3_file used by -** as an open file handle for journal files. -*/ -struct JournalFile { - sqlite3_io_methods *pMethod; /* I/O methods on journal files */ - int nBuf; /* Size of zBuf[] in bytes */ - char *zBuf; /* Space to buffer journal writes */ - int iSize; /* Amount of zBuf[] currently used */ - int flags; /* xOpen flags */ - sqlite3_vfs *pVfs; /* The "real" underlying VFS */ - sqlite3_file *pReal; /* The "real" underlying file descriptor */ - const char *zJournal; /* Name of the journal file */ -}; -typedef struct JournalFile JournalFile; - -/* -** If it does not already exists, create and populate the on-disk file -** for JournalFile p. -*/ -static int createFile(JournalFile *p){ - int rc = SQLITE_OK; - if( !p->pReal ){ - sqlite3_file *pReal = (sqlite3_file *)&p[1]; - rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0); - if( rc==SQLITE_OK ){ - p->pReal = pReal; - if( p->iSize>0 ){ - assert(p->iSize<=p->nBuf); - rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0); - } - } - } - return rc; -} - -/* -** Close the file. -*/ -static int jrnlClose(sqlite3_file *pJfd){ - JournalFile *p = (JournalFile *)pJfd; - if( p->pReal ){ - sqlite3OsClose(p->pReal); - } - sqlite3_free(p->zBuf); - return SQLITE_OK; -} - -/* -** Read data from the file. -*/ -static int jrnlRead( - sqlite3_file *pJfd, /* The journal file from which to read */ - void *zBuf, /* Put the results here */ - int iAmt, /* Number of bytes to read */ - sqlite_int64 iOfst /* Begin reading at this offset */ -){ - int rc = SQLITE_OK; - JournalFile *p = (JournalFile *)pJfd; - if( p->pReal ){ - rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst); - }else{ - assert( iAmt+iOfst<=p->iSize ); - memcpy(zBuf, &p->zBuf[iOfst], iAmt); - } - return rc; -} - -/* -** Write data to the file. -*/ -static int jrnlWrite( - sqlite3_file *pJfd, /* The journal file into which to write */ - const void *zBuf, /* Take data to be written from here */ - int iAmt, /* Number of bytes to write */ - sqlite_int64 iOfst /* Begin writing at this offset into the file */ -){ - int rc = SQLITE_OK; - JournalFile *p = (JournalFile *)pJfd; - if( !p->pReal && (iOfst+iAmt)>p->nBuf ){ - rc = createFile(p); - } - if( rc==SQLITE_OK ){ - if( p->pReal ){ - rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst); - }else{ - memcpy(&p->zBuf[iOfst], zBuf, iAmt); - if( p->iSize<(iOfst+iAmt) ){ - p->iSize = (iOfst+iAmt); - } - } - } - return rc; -} - -/* -** Truncate the file. -*/ -static int jrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ - int rc = SQLITE_OK; - JournalFile *p = (JournalFile *)pJfd; - if( p->pReal ){ - rc = sqlite3OsTruncate(p->pReal, size); - }else if( sizeiSize ){ - p->iSize = size; - } - return rc; -} - -/* -** Sync the file. -*/ -static int jrnlSync(sqlite3_file *pJfd, int flags){ - int rc; - JournalFile *p = (JournalFile *)pJfd; - rc = createFile(p); - if( rc==SQLITE_OK ){ - rc = sqlite3OsSync(p->pReal, flags); - } - return rc; -} - -/* -** Query the size of the file in bytes. -*/ -static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){ - int rc = SQLITE_OK; - JournalFile *p = (JournalFile *)pJfd; - if( p->pReal ){ - rc = sqlite3OsFileSize(p->pReal, pSize); - }else{ - *pSize = (sqlite_int64) p->iSize; - } - return rc; -} - -/* -** Table of methods for JournalFile sqlite3_file object. -*/ -static struct sqlite3_io_methods JournalFileMethods = { - 1, /* iVersion */ - jrnlClose, /* xClose */ - jrnlRead, /* xRead */ - jrnlWrite, /* xWrite */ - jrnlTruncate, /* xTruncate */ - jrnlSync, /* xSync */ - jrnlFileSize, /* xFileSize */ - 0, /* xLock */ - 0, /* xUnlock */ - 0, /* xCheckReservedLock */ - 0, /* xFileControl */ - 0, /* xSectorSize */ - 0 /* xDeviceCharacteristics */ -}; - -/* -** Open a journal file. -*/ -int sqlite3JournalOpen( - sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */ - const char *zName, /* Name of the journal file */ - sqlite3_file *pJfd, /* Preallocated, blank file handle */ - int flags, /* Opening flags */ - int nBuf /* Bytes buffered before opening the file */ -){ - JournalFile *p = (JournalFile *)pJfd; - memset(p, 0, sqlite3JournalSize(pVfs)); - if( nBuf>0 ){ - p->zBuf = sqlite3MallocZero(nBuf); - if( !p->zBuf ){ - return SQLITE_NOMEM; - } - }else{ - return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0); - } - p->pMethod = &JournalFileMethods; - p->nBuf = nBuf; - p->flags = flags; - p->zJournal = zName; - p->pVfs = pVfs; - return SQLITE_OK; -} - -/* -** If the argument p points to a JournalFile structure, and the underlying -** file has not yet been created, create it now. -*/ -int sqlite3JournalCreate(sqlite3_file *p){ - if( p->pMethods!=&JournalFileMethods ){ - return SQLITE_OK; - } - return createFile((JournalFile *)p); -} - -/* -** Return the number of bytes required to store a JournalFile that uses vfs -** pVfs to create the underlying on-disk files. -*/ -int sqlite3JournalSize(sqlite3_vfs *pVfs){ - return (pVfs->szOsFile+sizeof(JournalFile)); -} -#endif diff --git a/extensions/sqlite/sqlite-source/keywordhash.h b/extensions/sqlite/sqlite-source/keywordhash.h deleted file mode 100644 index 609ff207..00000000 --- a/extensions/sqlite/sqlite-source/keywordhash.h +++ /dev/null @@ -1,112 +0,0 @@ -/***** This file contains automatically generated code ****** -** -** The code in this file has been automatically generated by -** -** $Header: /sqlite/sqlite/tool/mkkeywordhash.c,v 1.31 2007/07/30 18:26:20 rse Exp $ -** -** The code in this file implements a function that determines whether -** or not a given identifier is really an SQL keyword. The same thing -** might be implemented more directly using a hand-written hash table. -** But by using this automatically generated code, the size of the code -** is substantially reduced. This is important for embedded applications -** on platforms with limited memory. -*/ -/* Hash score: 165 */ -static int keywordCode(const char *z, int n){ - /* zText[] encodes 775 bytes of keywords in 526 bytes */ - static const char zText[526] = - "BEFOREIGNOREGEXPLAINSTEADDESCAPEACHECKEYCONSTRAINTERSECTABLEFT" - "HENDATABASELECTRANSACTIONATURALTERAISELSEXCEPTRIGGEREFERENCES" - "UNIQUERYATTACHAVINGROUPDATEMPORARYBEGINNEREINDEXCLUSIVEXISTSBETWEEN" - "OTNULLIKECASCADEFERRABLECASECOLLATECREATECURRENT_DATEDELETEDETACH" - "IMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHEN" - "WHERENAMEAFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMITCONFLICT" - "CROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAILFROMFULLGLOB" - "YIFINTOFFSETISNULLORDERESTRICTOUTERIGHTROLLBACKROWUNIONUSINGVACUUM" - "VIEWINITIALLY"; - static const unsigned char aHash[127] = { - 63, 92, 109, 61, 0, 38, 0, 0, 69, 0, 64, 0, 0, - 102, 4, 65, 7, 0, 108, 72, 103, 99, 0, 22, 0, 0, - 113, 0, 111, 106, 0, 18, 80, 0, 1, 0, 0, 56, 57, - 0, 55, 11, 0, 33, 77, 89, 0, 110, 88, 0, 0, 45, - 0, 90, 54, 0, 20, 0, 114, 34, 19, 0, 10, 97, 28, - 83, 0, 0, 116, 93, 47, 115, 41, 12, 44, 0, 78, 0, - 87, 29, 0, 86, 0, 0, 0, 82, 79, 84, 75, 96, 6, - 14, 95, 0, 68, 0, 21, 76, 98, 27, 0, 112, 67, 104, - 49, 40, 71, 0, 0, 81, 100, 0, 107, 0, 15, 0, 0, - 24, 0, 73, 42, 50, 0, 16, 48, 0, 37, - }; - static const unsigned char aNext[116] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, - 17, 0, 0, 0, 36, 39, 0, 0, 25, 0, 0, 31, 0, - 0, 0, 43, 52, 0, 0, 0, 53, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 51, 0, 0, 0, 0, 26, 0, 8, 46, - 2, 0, 0, 0, 0, 0, 0, 0, 3, 58, 66, 0, 13, - 0, 91, 85, 0, 94, 0, 74, 0, 0, 62, 0, 35, 101, - 0, 0, 105, 23, 30, 60, 70, 0, 0, 59, 0, 0, - }; - static const unsigned char aLen[116] = { - 6, 7, 3, 6, 6, 7, 7, 3, 4, 6, 4, 5, 3, - 10, 9, 5, 4, 4, 3, 8, 2, 6, 11, 2, 7, 5, - 5, 4, 6, 7, 10, 6, 5, 6, 6, 5, 6, 4, 9, - 2, 5, 5, 7, 5, 9, 6, 7, 7, 3, 4, 4, 7, - 3, 10, 4, 7, 6, 12, 6, 6, 9, 4, 6, 5, 4, - 7, 6, 5, 6, 7, 5, 4, 5, 6, 5, 7, 3, 7, - 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 8, 8, - 2, 4, 4, 4, 4, 4, 2, 2, 4, 6, 2, 3, 6, - 5, 8, 5, 5, 8, 3, 5, 5, 6, 4, 9, 3, - }; - static const unsigned short int aOffset[116] = { - 0, 2, 2, 6, 10, 13, 18, 23, 25, 26, 31, 33, 37, - 40, 47, 55, 58, 61, 63, 65, 70, 71, 76, 85, 86, 91, - 95, 99, 102, 107, 113, 123, 126, 131, 136, 141, 144, 148, 148, - 152, 157, 160, 164, 166, 169, 177, 183, 189, 189, 192, 195, 199, - 200, 204, 214, 218, 225, 231, 243, 249, 255, 264, 266, 272, 277, - 279, 286, 291, 296, 302, 308, 313, 317, 320, 326, 330, 337, 339, - 346, 348, 350, 359, 363, 369, 375, 383, 388, 388, 404, 411, 418, - 419, 426, 430, 434, 438, 442, 445, 447, 449, 452, 452, 455, 458, - 464, 468, 476, 480, 485, 493, 496, 501, 506, 512, 516, 521, - }; - static const unsigned char aCode[116] = { - TK_BEFORE, TK_FOREIGN, TK_FOR, TK_IGNORE, TK_LIKE_KW, - TK_EXPLAIN, TK_INSTEAD, TK_ADD, TK_DESC, TK_ESCAPE, - TK_EACH, TK_CHECK, TK_KEY, TK_CONSTRAINT, TK_INTERSECT, - TK_TABLE, TK_JOIN_KW, TK_THEN, TK_END, TK_DATABASE, - TK_AS, TK_SELECT, TK_TRANSACTION,TK_ON, TK_JOIN_KW, - TK_ALTER, TK_RAISE, TK_ELSE, TK_EXCEPT, TK_TRIGGER, - TK_REFERENCES, TK_UNIQUE, TK_QUERY, TK_ATTACH, TK_HAVING, - TK_GROUP, TK_UPDATE, TK_TEMP, TK_TEMP, TK_OR, - TK_BEGIN, TK_JOIN_KW, TK_REINDEX, TK_INDEX, TK_EXCLUSIVE, - TK_EXISTS, TK_BETWEEN, TK_NOTNULL, TK_NOT, TK_NULL, - TK_LIKE_KW, TK_CASCADE, TK_ASC, TK_DEFERRABLE, TK_CASE, - TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_DELETE, TK_DETACH, - TK_IMMEDIATE, TK_JOIN, TK_INSERT, TK_MATCH, TK_PLAN, - TK_ANALYZE, TK_PRAGMA, TK_ABORT, TK_VALUES, TK_VIRTUAL, - TK_LIMIT, TK_WHEN, TK_WHERE, TK_RENAME, TK_AFTER, - TK_REPLACE, TK_AND, TK_DEFAULT, TK_AUTOINCR, TK_TO, - TK_IN, TK_CAST, TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, - TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, - TK_DISTINCT, TK_IS, TK_DROP, TK_FAIL, TK_FROM, - TK_JOIN_KW, TK_LIKE_KW, TK_BY, TK_IF, TK_INTO, - TK_OFFSET, TK_OF, TK_SET, TK_ISNULL, TK_ORDER, - TK_RESTRICT, TK_JOIN_KW, TK_JOIN_KW, TK_ROLLBACK, TK_ROW, - TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_INITIALLY, - TK_ALL, - }; - int h, i; - if( n<2 ) return TK_ID; - h = ((charMap(z[0])*4) ^ - (charMap(z[n-1])*3) ^ - n) % 127; - for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){ - if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){ - return aCode[i]; - } - } - return TK_ID; -} -int sqlite3KeywordCode(const unsigned char *z, int n){ - return keywordCode((char*)z, n); -} diff --git a/extensions/sqlite/sqlite-source/legacy.c b/extensions/sqlite/sqlite-source/legacy.c deleted file mode 100644 index 4f23ede0..00000000 --- a/extensions/sqlite/sqlite-source/legacy.c +++ /dev/null @@ -1,134 +0,0 @@ -/* -** 2001 September 15 -** -** 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. -** -************************************************************************* -** Main file for the SQLite library. The routines in this file -** implement the programmer interface to the library. Routines in -** other files are for internal use by SQLite and should not be -** accessed by users of the library. -** -** $Id$ -*/ - -#include "sqliteInt.h" -#include - -/* -** Execute SQL code. Return one of the SQLITE_ success/failure -** codes. Also write an error message into memory obtained from -** malloc() and make *pzErrMsg point to that message. -** -** If the SQL is a query, then for each row in the query result -** the xCallback() function is called. pArg becomes the first -** argument to xCallback(). If xCallback=NULL then no callback -** is invoked, even for queries. -*/ -int sqlite3_exec( - sqlite3 *db, /* The database on which the SQL executes */ - const char *zSql, /* The SQL to be executed */ - sqlite3_callback xCallback, /* Invoke this callback routine */ - void *pArg, /* First argument to xCallback() */ - char **pzErrMsg /* Write error messages here */ -){ - int rc = SQLITE_OK; - const char *zLeftover; - sqlite3_stmt *pStmt = 0; - char **azCols = 0; - - int nRetry = 0; - int nCallback; - - if( zSql==0 ) return SQLITE_OK; - - sqlite3_mutex_enter(db->mutex); - while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){ - int nCol; - char **azVals = 0; - - pStmt = 0; - rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover); - assert( rc==SQLITE_OK || pStmt==0 ); - if( rc!=SQLITE_OK ){ - continue; - } - if( !pStmt ){ - /* this happens for a comment or white-space */ - zSql = zLeftover; - continue; - } - - nCallback = 0; - - nCol = sqlite3_column_count(pStmt); - azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char *) + 1); - if( azCols==0 ){ - goto exec_out; - } - - while( 1 ){ - int i; - rc = sqlite3_step(pStmt); - - /* Invoke the callback function if required */ - if( xCallback && (SQLITE_ROW==rc || - (SQLITE_DONE==rc && !nCallback && db->flags&SQLITE_NullCallback)) ){ - if( 0==nCallback ){ - for(i=0; ierrMask)==rc ); - sqlite3_mutex_leave(db->mutex); - return rc; -} diff --git a/extensions/sqlite/sqlite-source/main.c b/extensions/sqlite/sqlite-source/main.c deleted file mode 100644 index b532708f..00000000 --- a/extensions/sqlite/sqlite-source/main.c +++ /dev/null @@ -1,1485 +0,0 @@ -/* -** 2001 September 15 -** -** 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. -** -************************************************************************* -** Main file for the SQLite library. The routines in this file -** implement the programmer interface to the library. Routines in -** other files are for internal use by SQLite and should not be -** accessed by users of the library. -** -** $Id$ -*/ -#include "sqliteInt.h" -#include - -/* -** The version of the library -*/ -const char sqlite3_version[] = SQLITE_VERSION; -const char *sqlite3_libversion(void){ return sqlite3_version; } -int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } -int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } - -/* -** If the following function pointer is not NULL and if -** SQLITE_ENABLE_IOTRACE is enabled, then messages describing -** I/O active are written using this function. These messages -** are intended for debugging activity only. -*/ -void (*sqlite3_io_trace)(const char*, ...) = 0; - -/* -** If the following global variable points to a string which is the -** name of a directory, then that directory will be used to store -** temporary files. -** -** See also the "PRAGMA temp_store_directory" SQL command. -*/ -char *sqlite3_temp_directory = 0; - - -/* -** This is the default collating function named "BINARY" which is always -** available. -*/ -static int binCollFunc( - void *NotUsed, - int nKey1, const void *pKey1, - int nKey2, const void *pKey2 -){ - int rc, n; - n = nKey1lastRowid; -} - -/* -** Return the number of changes in the most recent call to sqlite3_exec(). -*/ -int sqlite3_changes(sqlite3 *db){ - return db->nChange; -} - -/* -** Return the number of changes since the database handle was opened. -*/ -int sqlite3_total_changes(sqlite3 *db){ - return db->nTotalChange; -} - -/* -** Close an existing SQLite database -*/ -int sqlite3_close(sqlite3 *db){ - HashElem *i; - int j; - - if( !db ){ - return SQLITE_OK; - } - if( sqlite3SafetyCheck(db) ){ - return SQLITE_MISUSE; - } - sqlite3_mutex_enter(db->mutex); - -#ifdef SQLITE_SSE - { - extern void sqlite3SseCleanup(sqlite3*); - sqlite3SseCleanup(db); - } -#endif - - sqlite3ResetInternalSchema(db, 0); - - /* If a transaction is open, the ResetInternalSchema() call above - ** will not have called the xDisconnect() method on any virtual - ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback() - ** call will do so. We need to do this before the check for active - ** SQL statements below, as the v-table implementation may be storing - ** some prepared statements internally. - */ - sqlite3VtabRollback(db); - - /* If there are any outstanding VMs, return SQLITE_BUSY. */ - if( db->pVdbe ){ - sqlite3Error(db, SQLITE_BUSY, - "Unable to close due to unfinalised statements"); - sqlite3_mutex_leave(db->mutex); - return SQLITE_BUSY; - } - assert( !sqlite3SafetyCheck(db) ); - - /* FIX ME: db->magic may be set to SQLITE_MAGIC_CLOSED if the database - ** cannot be opened for some reason. So this routine needs to run in - ** that case. But maybe there should be an extra magic value for the - ** "failed to open" state. - ** - ** TODO: Coverage tests do not test the case where this condition is - ** true. It's hard to see how to cause it without messing with threads. - */ - if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){ - /* printf("DID NOT CLOSE\n"); fflush(stdout); */ - sqlite3_mutex_leave(db->mutex); - return SQLITE_ERROR; - } - - for(j=0; jnDb; j++){ - struct Db *pDb = &db->aDb[j]; - if( pDb->pBt ){ - sqlite3BtreeClose(pDb->pBt); - pDb->pBt = 0; - if( j!=1 ){ - pDb->pSchema = 0; - } - } - } - sqlite3ResetInternalSchema(db, 0); - assert( db->nDb<=2 ); - assert( db->aDb==db->aDbStatic ); - for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){ - FuncDef *pFunc, *pNext; - for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){ - pNext = pFunc->pNext; - sqlite3_free(pFunc); - } - } - - for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){ - CollSeq *pColl = (CollSeq *)sqliteHashData(i); - /* Invoke any destructors registered for collation sequence user data. */ - for(j=0; j<3; j++){ - if( pColl[j].xDel ){ - pColl[j].xDel(pColl[j].pUser); - } - } - sqlite3_free(pColl); - } - sqlite3HashClear(&db->aCollSeq); -#ifndef SQLITE_OMIT_VIRTUALTABLE - for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ - Module *pMod = (Module *)sqliteHashData(i); - if( pMod->xDestroy ){ - pMod->xDestroy(pMod->pAux); - } - sqlite3_free(pMod); - } - sqlite3HashClear(&db->aModule); -#endif - - sqlite3HashClear(&db->aFunc); - sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */ - if( db->pErr ){ - sqlite3ValueFree(db->pErr); - } - sqlite3CloseExtensions(db); - - db->magic = SQLITE_MAGIC_ERROR; - - /* The temp-database schema is allocated differently from the other schema - ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). - ** So it needs to be freed here. Todo: Why not roll the temp schema into - ** the same sqliteMalloc() as the one that allocates the database - ** structure? - */ - sqlite3_free(db->aDb[1].pSchema); - sqlite3_mutex_leave(db->mutex); - sqlite3_mutex_free(db->mutex); - sqlite3_free(db); - return SQLITE_OK; -} - -/* -** Rollback all database files. -*/ -void sqlite3RollbackAll(sqlite3 *db){ - int i; - int inTrans = 0; - assert( sqlite3_mutex_held(db->mutex) ); - sqlite3MallocEnterBenignBlock(1); /* Enter benign region */ - for(i=0; inDb; i++){ - if( db->aDb[i].pBt ){ - if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){ - inTrans = 1; - } - sqlite3BtreeRollback(db->aDb[i].pBt); - db->aDb[i].inTrans = 0; - } - } - sqlite3VtabRollback(db); - sqlite3MallocLeaveBenignBlock(); /* Leave benign region */ - - if( db->flags&SQLITE_InternChanges ){ - sqlite3ExpirePreparedStatements(db); - sqlite3ResetInternalSchema(db, 0); - } - - /* If one has been configured, invoke the rollback-hook callback */ - if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ - db->xRollbackCallback(db->pRollbackArg); - } -} - -/* -** Return a static string that describes the kind of error specified in the -** argument. -*/ -const char *sqlite3ErrStr(int rc){ - const char *z; - switch( rc & 0xff ){ - case SQLITE_ROW: - case SQLITE_DONE: - case SQLITE_OK: z = "not an error"; break; - case SQLITE_ERROR: z = "SQL logic error or missing database"; break; - case SQLITE_PERM: z = "access permission denied"; break; - case SQLITE_ABORT: z = "callback requested query abort"; break; - case SQLITE_BUSY: z = "database is locked"; break; - case SQLITE_LOCKED: z = "database table is locked"; break; - case SQLITE_NOMEM: z = "out of memory"; break; - case SQLITE_READONLY: z = "attempt to write a readonly database"; break; - case SQLITE_INTERRUPT: z = "interrupted"; break; - case SQLITE_IOERR: z = "disk I/O error"; break; - case SQLITE_CORRUPT: z = "database disk image is malformed"; break; - case SQLITE_FULL: z = "database or disk is full"; break; - case SQLITE_CANTOPEN: z = "unable to open database file"; break; - case SQLITE_EMPTY: z = "table contains no data"; break; - case SQLITE_SCHEMA: z = "database schema has changed"; break; - case SQLITE_TOOBIG: z = "String or BLOB exceeded size limit"; break; - case SQLITE_CONSTRAINT: z = "constraint failed"; break; - case SQLITE_MISMATCH: z = "datatype mismatch"; break; - case SQLITE_MISUSE: z = "library routine called out of sequence";break; - case SQLITE_NOLFS: z = "kernel lacks large file support"; break; - case SQLITE_AUTH: z = "authorization denied"; break; - case SQLITE_FORMAT: z = "auxiliary database format error"; break; - case SQLITE_RANGE: z = "bind or column index out of range"; break; - case SQLITE_NOTADB: z = "file is encrypted or is not a database";break; - default: z = "unknown error"; break; - } - return z; -} - -/* -** This routine implements a busy callback that sleeps and tries -** again until a timeout value is reached. The timeout value is -** an integer number of milliseconds passed in as the first -** argument. -*/ -static int sqliteDefaultBusyCallback( - void *ptr, /* Database connection */ - int count /* Number of times table has been busy */ -){ -#if OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP) - static const u8 delays[] = - { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; - static const u8 totals[] = - { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 }; -# define NDELAY (sizeof(delays)/sizeof(delays[0])) - sqlite3 *db = (sqlite3 *)ptr; - int timeout = db->busyTimeout; - int delay, prior; - - assert( count>=0 ); - if( count < NDELAY ){ - delay = delays[count]; - prior = totals[count]; - }else{ - delay = delays[NDELAY-1]; - prior = totals[NDELAY-1] + delay*(count-(NDELAY-1)); - } - if( prior + delay > timeout ){ - delay = timeout - prior; - if( delay<=0 ) return 0; - } - sqlite3OsSleep(db->pVfs, delay*1000); - return 1; -#else - sqlite3 *db = (sqlite3 *)ptr; - int timeout = ((sqlite3 *)ptr)->busyTimeout; - if( (count+1)*1000 > timeout ){ - return 0; - } - sqlite3OsSleep(db->pVfs, 1000000); - return 1; -#endif -} - -/* -** Invoke the given busy handler. -** -** This routine is called when an operation failed with a lock. -** If this routine returns non-zero, the lock is retried. If it -** returns 0, the operation aborts with an SQLITE_BUSY error. -*/ -int sqlite3InvokeBusyHandler(BusyHandler *p){ - int rc; - if( p==0 || p->xFunc==0 || p->nBusy<0 ) return 0; - rc = p->xFunc(p->pArg, p->nBusy); - if( rc==0 ){ - p->nBusy = -1; - }else{ - p->nBusy++; - } - return rc; -} - -/* -** This routine sets the busy callback for an Sqlite database to the -** given callback function with the given argument. -*/ -int sqlite3_busy_handler( - sqlite3 *db, - int (*xBusy)(void*,int), - void *pArg -){ - if( sqlite3SafetyCheck(db) ){ - return SQLITE_MISUSE; - } - sqlite3_mutex_enter(db->mutex); - db->busyHandler.xFunc = xBusy; - db->busyHandler.pArg = pArg; - db->busyHandler.nBusy = 0; - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} - -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK -/* -** This routine sets the progress callback for an Sqlite database to the -** given callback function with the given argument. The progress callback will -** be invoked every nOps opcodes. -*/ -void sqlite3_progress_handler( - sqlite3 *db, - int nOps, - int (*xProgress)(void*), - void *pArg -){ - if( !sqlite3SafetyCheck(db) ){ - sqlite3_mutex_enter(db->mutex); - if( nOps>0 ){ - db->xProgress = xProgress; - db->nProgressOps = nOps; - db->pProgressArg = pArg; - }else{ - db->xProgress = 0; - db->nProgressOps = 0; - db->pProgressArg = 0; - } - sqlite3_mutex_leave(db->mutex); - } -} -#endif - - -/* -** This routine installs a default busy handler that waits for the -** specified number of milliseconds before returning 0. -*/ -int sqlite3_busy_timeout(sqlite3 *db, int ms){ - if( sqlite3SafetyCheck(db) ){ - return SQLITE_MISUSE; - } - if( ms>0 ){ - db->busyTimeout = ms; - sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); - }else{ - sqlite3_busy_handler(db, 0, 0); - } - return SQLITE_OK; -} - -/* -** Cause any pending operation to stop at its earliest opportunity. -*/ -void sqlite3_interrupt(sqlite3 *db){ - if( db && (db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_BUSY) ){ - db->u1.isInterrupted = 1; - } -} - - -/* -** This function is exactly the same as sqlite3_create_function(), except -** that it is designed to be called by internal code. The difference is -** that if a malloc() fails in sqlite3_create_function(), an error code -** is returned and the mallocFailed flag cleared. -*/ -int sqlite3CreateFunc( - sqlite3 *db, - const char *zFunctionName, - int nArg, - int enc, - void *pUserData, - void (*xFunc)(sqlite3_context*,int,sqlite3_value **), - void (*xStep)(sqlite3_context*,int,sqlite3_value **), - void (*xFinal)(sqlite3_context*) -){ - FuncDef *p; - int nName; - - assert( sqlite3_mutex_held(db->mutex) ); - if( sqlite3SafetyCheck(db) ){ - return SQLITE_MISUSE; - } - if( zFunctionName==0 || - (xFunc && (xFinal || xStep)) || - (!xFunc && (xFinal && !xStep)) || - (!xFunc && (!xFinal && xStep)) || - (nArg<-1 || nArg>127) || - (255<(nName = strlen(zFunctionName))) ){ - sqlite3Error(db, SQLITE_ERROR, "bad parameters"); - return SQLITE_ERROR; - } - -#ifndef SQLITE_OMIT_UTF16 - /* If SQLITE_UTF16 is specified as the encoding type, transform this - ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the - ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. - ** - ** If SQLITE_ANY is specified, add three versions of the function - ** to the hash table. - */ - if( enc==SQLITE_UTF16 ){ - enc = SQLITE_UTF16NATIVE; - }else if( enc==SQLITE_ANY ){ - int rc; - rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8, - pUserData, xFunc, xStep, xFinal); - if( rc==SQLITE_OK ){ - rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE, - pUserData, xFunc, xStep, xFinal); - } - if( rc!=SQLITE_OK ){ - return rc; - } - enc = SQLITE_UTF16BE; - } -#else - enc = SQLITE_UTF8; -#endif - - /* Check if an existing function is being overridden or deleted. If so, - ** and there are active VMs, then return SQLITE_BUSY. If a function - ** is being overridden/deleted but there are no active VMs, allow the - ** operation to continue but invalidate all precompiled statements. - */ - p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 0); - if( p && p->iPrefEnc==enc && p->nArg==nArg ){ - if( db->activeVdbeCnt ){ - sqlite3Error(db, SQLITE_BUSY, - "Unable to delete/modify user-function due to active statements"); - assert( !db->mallocFailed ); - return SQLITE_BUSY; - }else{ - sqlite3ExpirePreparedStatements(db); - } - } - - p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1); - assert(p || db->mallocFailed); - if( !p ){ - return SQLITE_NOMEM; - } - p->flags = 0; - p->xFunc = xFunc; - p->xStep = xStep; - p->xFinalize = xFinal; - p->pUserData = pUserData; - p->nArg = nArg; - return SQLITE_OK; -} - -/* -** Create new user functions. -*/ -int sqlite3_create_function( - sqlite3 *db, - const char *zFunctionName, - int nArg, - int enc, - void *p, - void (*xFunc)(sqlite3_context*,int,sqlite3_value **), - void (*xStep)(sqlite3_context*,int,sqlite3_value **), - void (*xFinal)(sqlite3_context*) -){ - int rc; - sqlite3_mutex_enter(db->mutex); - assert( !db->mallocFailed ); - rc = sqlite3CreateFunc(db, zFunctionName, nArg, enc, p, xFunc, xStep, xFinal); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -#ifndef SQLITE_OMIT_UTF16 -int sqlite3_create_function16( - sqlite3 *db, - const void *zFunctionName, - int nArg, - int eTextRep, - void *p, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*) -){ - int rc; - char *zFunc8; - sqlite3_mutex_enter(db->mutex); - assert( !db->mallocFailed ); - zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1); - rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal); - sqlite3_free(zFunc8); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} -#endif - - -/* -** Declare that a function has been overloaded by a virtual table. -** -** If the function already exists as a regular global function, then -** this routine is a no-op. If the function does not exist, then create -** a new one that always throws a run-time error. -** -** When virtual tables intend to provide an overloaded function, they -** should call this routine to make sure the global function exists. -** A global function must exist in order for name resolution to work -** properly. -*/ -int sqlite3_overload_function( - sqlite3 *db, - const char *zName, - int nArg -){ - int nName = strlen(zName); - int rc; - sqlite3_mutex_enter(db->mutex); - if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){ - sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8, - 0, sqlite3InvalidFunction, 0, 0); - } - rc = sqlite3ApiExit(db, SQLITE_OK); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -#ifndef SQLITE_OMIT_TRACE -/* -** Register a trace function. The pArg from the previously registered trace -** is returned. -** -** A NULL trace function means that no tracing is executes. A non-NULL -** trace is a pointer to a function that is invoked at the start of each -** SQL statement. -*/ -void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ - void *pOld; - sqlite3_mutex_enter(db->mutex); - pOld = db->pTraceArg; - db->xTrace = xTrace; - db->pTraceArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pOld; -} -/* -** Register a profile function. The pArg from the previously registered -** profile function is returned. -** -** A NULL profile function means that no profiling is executes. A non-NULL -** profile is a pointer to a function that is invoked at the conclusion of -** each SQL statement that is run. -*/ -void *sqlite3_profile( - sqlite3 *db, - void (*xProfile)(void*,const char*,sqlite_uint64), - void *pArg -){ - void *pOld; - sqlite3_mutex_enter(db->mutex); - pOld = db->pProfileArg; - db->xProfile = xProfile; - db->pProfileArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pOld; -} -#endif /* SQLITE_OMIT_TRACE */ - -/*** EXPERIMENTAL *** -** -** Register a function to be invoked when a transaction comments. -** If the invoked function returns non-zero, then the commit becomes a -** rollback. -*/ -void *sqlite3_commit_hook( - sqlite3 *db, /* Attach the hook to this database */ - int (*xCallback)(void*), /* Function to invoke on each commit */ - void *pArg /* Argument to the function */ -){ - void *pOld; - sqlite3_mutex_enter(db->mutex); - pOld = db->pCommitArg; - db->xCommitCallback = xCallback; - db->pCommitArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pOld; -} - -/* -** Register a callback to be invoked each time a row is updated, -** inserted or deleted using this database connection. -*/ -void *sqlite3_update_hook( - sqlite3 *db, /* Attach the hook to this database */ - void (*xCallback)(void*,int,char const *,char const *,sqlite_int64), - void *pArg /* Argument to the function */ -){ - void *pRet; - sqlite3_mutex_enter(db->mutex); - pRet = db->pUpdateArg; - db->xUpdateCallback = xCallback; - db->pUpdateArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pRet; -} - -/* -** Register a callback to be invoked each time a transaction is rolled -** back by this database connection. -*/ -void *sqlite3_rollback_hook( - sqlite3 *db, /* Attach the hook to this database */ - void (*xCallback)(void*), /* Callback function */ - void *pArg /* Argument to the function */ -){ - void *pRet; - sqlite3_mutex_enter(db->mutex); - pRet = db->pRollbackArg; - db->xRollbackCallback = xCallback; - db->pRollbackArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pRet; -} - -/* -** This routine is called to create a connection to a database BTree -** driver. If zFilename is the name of a file, then that file is -** opened and used. If zFilename is the magic name ":memory:" then -** the database is stored in memory (and is thus forgotten as soon as -** the connection is closed.) If zFilename is NULL then the database -** is a "virtual" database for transient use only and is deleted as -** soon as the connection is closed. -** -** A virtual database can be either a disk file (that is automatically -** deleted when the file is closed) or it an be held entirely in memory, -** depending on the values of the TEMP_STORE compile-time macro and the -** db->temp_store variable, according to the following chart: -** -** TEMP_STORE db->temp_store Location of temporary database -** ---------- -------------- ------------------------------ -** 0 any file -** 1 1 file -** 1 2 memory -** 1 0 file -** 2 1 file -** 2 2 memory -** 2 0 memory -** 3 any memory -*/ -int sqlite3BtreeFactory( - const sqlite3 *db, /* Main database when opening aux otherwise 0 */ - const char *zFilename, /* Name of the file containing the BTree database */ - int omitJournal, /* if TRUE then do not journal this file */ - int nCache, /* How many pages in the page cache */ - int vfsFlags, /* Flags passed through to vfsOpen */ - Btree **ppBtree /* Pointer to new Btree object written here */ -){ - int btFlags = 0; - int rc; - - assert( sqlite3_mutex_held(db->mutex) ); - assert( ppBtree != 0); - if( omitJournal ){ - btFlags |= BTREE_OMIT_JOURNAL; - } - if( db->flags & SQLITE_NoReadlock ){ - btFlags |= BTREE_NO_READLOCK; - } - if( zFilename==0 ){ -#if TEMP_STORE==0 - /* Do nothing */ -#endif -#ifndef SQLITE_OMIT_MEMORYDB -#if TEMP_STORE==1 - if( db->temp_store==2 ) zFilename = ":memory:"; -#endif -#if TEMP_STORE==2 - if( db->temp_store!=1 ) zFilename = ":memory:"; -#endif -#if TEMP_STORE==3 - zFilename = ":memory:"; -#endif -#endif /* SQLITE_OMIT_MEMORYDB */ - } - - if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (zFilename==0 || *zFilename==0) ){ - vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; - } - rc = sqlite3BtreeOpen(zFilename, (sqlite3 *)db, ppBtree, btFlags, vfsFlags); - if( rc==SQLITE_OK ){ - sqlite3BtreeSetBusyHandler(*ppBtree, (void*)&db->busyHandler); - sqlite3BtreeSetCacheSize(*ppBtree, nCache); - } - return rc; -} - -/* -** Return UTF-8 encoded English language explanation of the most recent -** error. -*/ -const char *sqlite3_errmsg(sqlite3 *db){ - const char *z; - if( !db ){ - return sqlite3ErrStr(SQLITE_NOMEM); - } - if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){ - return sqlite3ErrStr(SQLITE_MISUSE); - } - sqlite3_mutex_enter(db->mutex); - assert( !db->mallocFailed ); - z = (char*)sqlite3_value_text(db->pErr); - if( z==0 ){ - z = sqlite3ErrStr(db->errCode); - } - sqlite3_mutex_leave(db->mutex); - return z; -} - -#ifndef SQLITE_OMIT_UTF16 -/* -** Return UTF-16 encoded English language explanation of the most recent -** error. -*/ -const void *sqlite3_errmsg16(sqlite3 *db){ - /* Because all the characters in the string are in the unicode - ** range 0x00-0xFF, if we pad the big-endian string with a - ** zero byte, we can obtain the little-endian string with - ** &big_endian[1]. - */ - static const char outOfMemBe[] = { - 0, 'o', 0, 'u', 0, 't', 0, ' ', - 0, 'o', 0, 'f', 0, ' ', - 0, 'm', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, 0, 0 - }; - static const char misuseBe [] = { - 0, 'l', 0, 'i', 0, 'b', 0, 'r', 0, 'a', 0, 'r', 0, 'y', 0, ' ', - 0, 'r', 0, 'o', 0, 'u', 0, 't', 0, 'i', 0, 'n', 0, 'e', 0, ' ', - 0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', - 0, 'o', 0, 'u', 0, 't', 0, ' ', - 0, 'o', 0, 'f', 0, ' ', - 0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0 - }; - - const void *z; - if( !db ){ - return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]); - } - if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){ - return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]); - } - sqlite3_mutex_enter(db->mutex); - assert( !db->mallocFailed ); - z = sqlite3_value_text16(db->pErr); - if( z==0 ){ - sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode), - SQLITE_UTF8, SQLITE_STATIC); - z = sqlite3_value_text16(db->pErr); - } - sqlite3ApiExit(0, 0); - sqlite3_mutex_leave(db->mutex); - return z; -} -#endif /* SQLITE_OMIT_UTF16 */ - -/* -** Return the most recent error code generated by an SQLite routine. If NULL is -** passed to this function, we assume a malloc() failed during sqlite3_open(). -*/ -int sqlite3_errcode(sqlite3 *db){ - if( !db || db->mallocFailed ){ - return SQLITE_NOMEM; - } - if( sqlite3SafetyCheck(db) ){ - return SQLITE_MISUSE; - } - return db->errCode & db->errMask; -} - -/* -** Create a new collating function for database "db". The name is zName -** and the encoding is enc. -*/ -static int createCollation( - sqlite3* db, - const char *zName, - int enc, - void* pCtx, - int(*xCompare)(void*,int,const void*,int,const void*), - void(*xDel)(void*) -){ - CollSeq *pColl; - int enc2; - - if( sqlite3SafetyCheck(db) ){ - return SQLITE_MISUSE; - } - assert( sqlite3_mutex_held(db->mutex) ); - - /* If SQLITE_UTF16 is specified as the encoding type, transform this - ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the - ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. - */ - enc2 = enc & ~SQLITE_UTF16_ALIGNED; - if( enc2==SQLITE_UTF16 ){ - enc2 = SQLITE_UTF16NATIVE; - } - - if( (enc2&~3)!=0 ){ - sqlite3Error(db, SQLITE_ERROR, "unknown encoding"); - return SQLITE_ERROR; - } - - /* Check if this call is removing or replacing an existing collation - ** sequence. If so, and there are active VMs, return busy. If there - ** are no active VMs, invalidate any pre-compiled statements. - */ - pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 0); - if( pColl && pColl->xCmp ){ - if( db->activeVdbeCnt ){ - sqlite3Error(db, SQLITE_BUSY, - "Unable to delete/modify collation sequence due to active statements"); - return SQLITE_BUSY; - } - sqlite3ExpirePreparedStatements(db); - - /* If collation sequence pColl was created directly by a call to - ** sqlite3_create_collation, and not generated by synthCollSeq(), - ** then any copies made by synthCollSeq() need to be invalidated. - ** Also, collation destructor - CollSeq.xDel() - function may need - ** to be called. - */ - if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){ - CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName, strlen(zName)); - int j; - for(j=0; j<3; j++){ - CollSeq *p = &aColl[j]; - if( p->enc==pColl->enc ){ - if( p->xDel ){ - p->xDel(p->pUser); - } - p->xCmp = 0; - } - } - } - } - - pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 1); - if( pColl ){ - pColl->xCmp = xCompare; - pColl->pUser = pCtx; - pColl->xDel = xDel; - pColl->enc = enc2 | (enc & SQLITE_UTF16_ALIGNED); - } - sqlite3Error(db, SQLITE_OK, 0); - return SQLITE_OK; -} - - -/* -** This routine does the work of opening a database on behalf of -** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" -** is UTF-8 encoded. -*/ -static int openDatabase( - const char *zFilename, /* Database filename UTF-8 encoded */ - sqlite3 **ppDb, /* OUT: Returned database handle */ - unsigned flags, /* Operational flags */ - const char *zVfs /* Name of the VFS to use */ -){ - sqlite3 *db; - int rc; - CollSeq *pColl; - - /* Allocate the sqlite data structure */ - db = sqlite3MallocZero( sizeof(sqlite3) ); - if( db==0 ) goto opendb_out; - db->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE); - if( db->mutex==0 ){ - sqlite3_free(db); - db = 0; - goto opendb_out; - } - sqlite3_mutex_enter(db->mutex); - db->errMask = 0xff; - db->priorNewRowid = 0; - db->nDb = 2; - db->magic = SQLITE_MAGIC_BUSY; - db->aDb = db->aDbStatic; - db->autoCommit = 1; - db->flags |= SQLITE_ShortColNames -#if SQLITE_DEFAULT_FILE_FORMAT<4 - | SQLITE_LegacyFileFmt -#endif -#ifdef SQLITE_ENABLE_LOAD_EXTENSION - | SQLITE_LoadExtension -#endif - ; - sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0); - sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0); -#ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3HashInit(&db->aModule, SQLITE_HASH_STRING, 0); -#endif - - db->pVfs = sqlite3_vfs_find(zVfs); - if( !db->pVfs ){ - rc = SQLITE_ERROR; - db->magic = SQLITE_MAGIC_CLOSED; - sqlite3Error(db, rc, "no such vfs: %s", (zVfs?zVfs:"(null)")); - goto opendb_out; - } - - /* Add the default collation sequence BINARY. BINARY works for both UTF-8 - ** and UTF-16, so add a version for each to avoid any unnecessary - ** conversions. The only error that can occur here is a malloc() failure. - */ - if( createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0) || - createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0) || - createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0) || - (db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0 - ){ - assert( db->mallocFailed ); - db->magic = SQLITE_MAGIC_CLOSED; - goto opendb_out; - } - - /* Also add a UTF-8 case-insensitive collation sequence. */ - createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); - - /* Set flags on the built-in collating sequences */ - db->pDfltColl->type = SQLITE_COLL_BINARY; - pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "NOCASE", 6, 0); - if( pColl ){ - pColl->type = SQLITE_COLL_NOCASE; - } - - /* Open the backend database driver */ - db->openFlags = flags; - rc = sqlite3BtreeFactory(db, zFilename, 0, SQLITE_DEFAULT_CACHE_SIZE, - flags | SQLITE_OPEN_MAIN_DB, - &db->aDb[0].pBt); - if( rc!=SQLITE_OK ){ - sqlite3Error(db, rc, 0); - db->magic = SQLITE_MAGIC_CLOSED; - goto opendb_out; - } - db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); - db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); - - - /* The default safety_level for the main database is 'full'; for the temp - ** database it is 'NONE'. This matches the pager layer defaults. - */ - db->aDb[0].zName = "main"; - db->aDb[0].safety_level = 3; -#ifndef SQLITE_OMIT_TEMPDB - db->aDb[1].zName = "temp"; - db->aDb[1].safety_level = 1; -#endif - - db->magic = SQLITE_MAGIC_OPEN; - if( db->mallocFailed ){ - goto opendb_out; - } - - /* Register all built-in functions, but do not attempt to read the - ** database schema yet. This is delayed until the first time the database - ** is accessed. - */ - sqlite3Error(db, SQLITE_OK, 0); - sqlite3RegisterBuiltinFunctions(db); - - /* Load automatic extensions - extensions that have been registered - ** using the sqlite3_automatic_extension() API. - */ - (void)sqlite3AutoLoadExtensions(db); - if( sqlite3_errcode(db)!=SQLITE_OK ){ - goto opendb_out; - } - -#ifdef SQLITE_ENABLE_FTS1 - if( !db->mallocFailed ){ - extern int sqlite3Fts1Init(sqlite3*); - rc = sqlite3Fts1Init(db); - } -#endif - -#ifdef SQLITE_ENABLE_FTS2 - if( !db->mallocFailed && rc==SQLITE_OK ){ - extern int sqlite3Fts2Init(sqlite3*); - rc = sqlite3Fts2Init(db); - } -#endif - -#ifdef SQLITE_ENABLE_FTS3 - if( !db->mallocFailed && rc==SQLITE_OK ){ - extern int sqlite3Fts3Init(sqlite3*); - rc = sqlite3Fts3Init(db); - } -#endif - -#ifdef SQLITE_ENABLE_ICU - if( !db->mallocFailed && rc==SQLITE_OK ){ - extern int sqlite3IcuInit(sqlite3*); - rc = sqlite3IcuInit(db); - } -#endif - sqlite3Error(db, rc, 0); - - /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking - ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking - ** mode. Doing nothing at all also makes NORMAL the default. - */ -#ifdef SQLITE_DEFAULT_LOCKING_MODE - db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; - sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), - SQLITE_DEFAULT_LOCKING_MODE); -#endif - -opendb_out: - if( db && db->mutex ){ - sqlite3_mutex_leave(db->mutex); - } - if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){ - sqlite3_close(db); - db = 0; - } - *ppDb = db; - return sqlite3ApiExit(0, rc); -} - -/* -** Open a new database handle. -*/ -int sqlite3_open( - const char *zFilename, - sqlite3 **ppDb -){ - return openDatabase(zFilename, ppDb, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); -} -int sqlite3_open_v2( - const char *filename, /* Database filename (UTF-8) */ - sqlite3 **ppDb, /* OUT: SQLite db handle */ - int flags, /* Flags */ - const char *zVfs /* Name of VFS module to use */ -){ - return openDatabase(filename, ppDb, flags, zVfs); -} - -#ifndef SQLITE_OMIT_UTF16 -/* -** Open a new database handle. -*/ -int sqlite3_open16( - const void *zFilename, - sqlite3 **ppDb -){ - char const *zFilename8; /* zFilename encoded in UTF-8 instead of UTF-16 */ - sqlite3_value *pVal; - int rc = SQLITE_NOMEM; - - assert( zFilename ); - assert( ppDb ); - *ppDb = 0; - pVal = sqlite3ValueNew(0); - sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC); - zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8); - if( zFilename8 ){ - rc = openDatabase(zFilename8, ppDb, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); - if( rc==SQLITE_OK && *ppDb ){ - rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0); - if( rc!=SQLITE_OK ){ - sqlite3_close(*ppDb); - *ppDb = 0; - } - } - } - sqlite3ValueFree(pVal); - - return sqlite3ApiExit(0, rc); -} -#endif /* SQLITE_OMIT_UTF16 */ - -/* -** Register a new collation sequence with the database handle db. -*/ -int sqlite3_create_collation( - sqlite3* db, - const char *zName, - int enc, - void* pCtx, - int(*xCompare)(void*,int,const void*,int,const void*) -){ - int rc; - sqlite3_mutex_enter(db->mutex); - assert( !db->mallocFailed ); - rc = createCollation(db, zName, enc, pCtx, xCompare, 0); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** Register a new collation sequence with the database handle db. -*/ -int sqlite3_create_collation_v2( - sqlite3* db, - const char *zName, - int enc, - void* pCtx, - int(*xCompare)(void*,int,const void*,int,const void*), - void(*xDel)(void*) -){ - int rc; - sqlite3_mutex_enter(db->mutex); - assert( !db->mallocFailed ); - rc = createCollation(db, zName, enc, pCtx, xCompare, xDel); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -#ifndef SQLITE_OMIT_UTF16 -/* -** Register a new collation sequence with the database handle db. -*/ -int sqlite3_create_collation16( - sqlite3* db, - const char *zName, - int enc, - void* pCtx, - int(*xCompare)(void*,int,const void*,int,const void*) -){ - int rc = SQLITE_OK; - char *zName8; - sqlite3_mutex_enter(db->mutex); - assert( !db->mallocFailed ); - zName8 = sqlite3Utf16to8(db, zName, -1); - if( zName8 ){ - rc = createCollation(db, zName8, enc, pCtx, xCompare, 0); - sqlite3_free(zName8); - } - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} -#endif /* SQLITE_OMIT_UTF16 */ - -/* -** Register a collation sequence factory callback with the database handle -** db. Replace any previously installed collation sequence factory. -*/ -int sqlite3_collation_needed( - sqlite3 *db, - void *pCollNeededArg, - void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*) -){ - if( sqlite3SafetyCheck(db) ){ - return SQLITE_MISUSE; - } - sqlite3_mutex_enter(db->mutex); - db->xCollNeeded = xCollNeeded; - db->xCollNeeded16 = 0; - db->pCollNeededArg = pCollNeededArg; - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} - -#ifndef SQLITE_OMIT_UTF16 -/* -** Register a collation sequence factory callback with the database handle -** db. Replace any previously installed collation sequence factory. -*/ -int sqlite3_collation_needed16( - sqlite3 *db, - void *pCollNeededArg, - void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*) -){ - if( sqlite3SafetyCheck(db) ){ - return SQLITE_MISUSE; - } - sqlite3_mutex_enter(db->mutex); - db->xCollNeeded = 0; - db->xCollNeeded16 = xCollNeeded16; - db->pCollNeededArg = pCollNeededArg; - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} -#endif /* SQLITE_OMIT_UTF16 */ - -#ifndef SQLITE_OMIT_GLOBALRECOVER -/* -** This function is now an anachronism. It used to be used to recover from a -** malloc() failure, but SQLite now does this automatically. -*/ -int sqlite3_global_recover(){ - return SQLITE_OK; -} -#endif - -/* -** Test to see whether or not the database connection is in autocommit -** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on -** by default. Autocommit is disabled by a BEGIN statement and reenabled -** by the next COMMIT or ROLLBACK. -** -******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** -*/ -int sqlite3_get_autocommit(sqlite3 *db){ - return db->autoCommit; -} - -#ifdef SQLITE_DEBUG -/* -** The following routine is subtituted for constant SQLITE_CORRUPT in -** debugging builds. This provides a way to set a breakpoint for when -** corruption is first detected. -*/ -int sqlite3Corrupt(void){ - return SQLITE_CORRUPT; -} -#endif - -/* -** This is a convenience routine that makes sure that all thread-specific -** data for this thread has been deallocated. -** -** SQLite no longer uses thread-specific data so this routine is now a -** no-op. It is retained for historical compatibility. -*/ -void sqlite3_thread_cleanup(void){ -} - -/* -** Return meta information about a specific column of a database table. -** See comment in sqlite3.h (sqlite.h.in) for details. -*/ -#ifdef SQLITE_ENABLE_COLUMN_METADATA -int sqlite3_table_column_metadata( - sqlite3 *db, /* Connection handle */ - const char *zDbName, /* Database name or NULL */ - const char *zTableName, /* Table name */ - const char *zColumnName, /* Column name */ - char const **pzDataType, /* OUTPUT: Declared data type */ - char const **pzCollSeq, /* OUTPUT: Collation sequence name */ - int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ - int *pPrimaryKey, /* OUTPUT: True if column part of PK */ - int *pAutoinc /* OUTPUT: True if colums is auto-increment */ -){ - int rc; - char *zErrMsg = 0; - Table *pTab = 0; - Column *pCol = 0; - int iCol; - - char const *zDataType = 0; - char const *zCollSeq = 0; - int notnull = 0; - int primarykey = 0; - int autoinc = 0; - - /* Ensure the database schema has been loaded */ - if( sqlite3SafetyOn(db) ){ - return SQLITE_MISUSE; - } - sqlite3_mutex_enter(db->mutex); - rc = sqlite3Init(db, &zErrMsg); - if( SQLITE_OK!=rc ){ - goto error_out; - } - - /* Locate the table in question */ - pTab = sqlite3FindTable(db, zTableName, zDbName); - if( !pTab || pTab->pSelect ){ - pTab = 0; - goto error_out; - } - - /* Find the column for which info is requested */ - if( sqlite3IsRowid(zColumnName) ){ - iCol = pTab->iPKey; - if( iCol>=0 ){ - pCol = &pTab->aCol[iCol]; - } - }else{ - for(iCol=0; iColnCol; iCol++){ - pCol = &pTab->aCol[iCol]; - if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){ - break; - } - } - if( iCol==pTab->nCol ){ - pTab = 0; - goto error_out; - } - } - - /* The following block stores the meta information that will be returned - ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey - ** and autoinc. At this point there are two possibilities: - ** - ** 1. The specified column name was rowid", "oid" or "_rowid_" - ** and there is no explicitly declared IPK column. - ** - ** 2. The table is not a view and the column name identified an - ** explicitly declared column. Copy meta information from *pCol. - */ - if( pCol ){ - zDataType = pCol->zType; - zCollSeq = pCol->zColl; - notnull = (pCol->notNull?1:0); - primarykey = (pCol->isPrimKey?1:0); - autoinc = ((pTab->iPKey==iCol && pTab->autoInc)?1:0); - }else{ - zDataType = "INTEGER"; - primarykey = 1; - } - if( !zCollSeq ){ - zCollSeq = "BINARY"; - } - -error_out: - if( sqlite3SafetyOff(db) ){ - rc = SQLITE_MISUSE; - } - - /* Whether the function call succeeded or failed, set the output parameters - ** to whatever their local counterparts contain. If an error did occur, - ** this has the effect of zeroing all output parameters. - */ - if( pzDataType ) *pzDataType = zDataType; - if( pzCollSeq ) *pzCollSeq = zCollSeq; - if( pNotNull ) *pNotNull = notnull; - if( pPrimaryKey ) *pPrimaryKey = primarykey; - if( pAutoinc ) *pAutoinc = autoinc; - - if( SQLITE_OK==rc && !pTab ){ - sqlite3SetString(&zErrMsg, "no such table column: ", zTableName, ".", - zColumnName, 0); - rc = SQLITE_ERROR; - } - sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg); - sqlite3_free(zErrMsg); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} -#endif - -/* -** Sleep for a little while. Return the amount of time slept. -*/ -int sqlite3_sleep(int ms){ - sqlite3_vfs *pVfs; - int rc; - pVfs = sqlite3_vfs_find(0); - - /* This function works in milliseconds, but the underlying OsSleep() - ** API uses microseconds. Hence the 1000's. - */ - rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000); - return rc; -} - -/* -** Enable or disable the extended result codes. -*/ -int sqlite3_extended_result_codes(sqlite3 *db, int onoff){ - sqlite3_mutex_enter(db->mutex); - db->errMask = onoff ? 0xffffffff : 0xff; - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} - -/* -** Invoke the xFileControl method on a particular database. -*/ -int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ - int rc = SQLITE_ERROR; - int iDb; - sqlite3_mutex_enter(db->mutex); - if( zDbName==0 ){ - iDb = 0; - }else{ - for(iDb=0; iDbnDb; iDb++){ - if( strcmp(db->aDb[iDb].zName, zDbName)==0 ) break; - } - } - if( iDbnDb ){ - Btree *pBtree = db->aDb[iDb].pBt; - if( pBtree ){ - Pager *pPager; - sqlite3BtreeEnter(pBtree); - pPager = sqlite3BtreePager(pBtree); - if( pPager ){ - sqlite3_file *fd = sqlite3PagerFile(pPager); - if( fd ){ - rc = sqlite3OsFileControl(fd, op, pArg); - } - } - sqlite3BtreeLeave(pBtree); - } - } - sqlite3_mutex_leave(db->mutex); - return rc; -} diff --git a/extensions/sqlite/sqlite-source/malloc.c b/extensions/sqlite/sqlite-source/malloc.c deleted file mode 100644 index 5ac8a9f2..00000000 --- a/extensions/sqlite/sqlite-source/malloc.c +++ /dev/null @@ -1,240 +0,0 @@ -/* -** 2001 September 15 -** -** 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. -** -************************************************************************* -** Memory allocation functions used throughout sqlite. -** -** -** $Id$ -*/ -#include "sqliteInt.h" -#include -#include - -/* -** This routine runs when the memory allocator sees that the -** total memory allocation is about to exceed the soft heap -** limit. -*/ -static void softHeapLimitEnforcer( - void *NotUsed, - sqlite3_int64 inUse, - int allocSize -){ - sqlite3_release_memory(allocSize); -} - -/* -** Set the soft heap-size limit for the current thread. Passing a -** zero or negative value indicates no limit. -*/ -void sqlite3_soft_heap_limit(int n){ - sqlite3_uint64 iLimit; - int overage; - if( n<0 ){ - iLimit = 0; - }else{ - iLimit = n; - } - if( iLimit>0 ){ - sqlite3_memory_alarm(softHeapLimitEnforcer, 0, iLimit); - }else{ - sqlite3_memory_alarm(0, 0, 0); - } - overage = sqlite3_memory_used() - n; - if( overage>0 ){ - sqlite3_release_memory(overage); - } -} - -/* -** Release memory held by SQLite instances created by the current thread. -*/ -int sqlite3_release_memory(int n){ -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - return sqlite3PagerReleaseMemory(n); -#else - return SQLITE_OK; -#endif -} - - -/* -** Allocate and zero memory. -*/ -void *sqlite3MallocZero(unsigned n){ - void *p = sqlite3_malloc(n); - if( p ){ - memset(p, 0, n); - } - return p; -} - -/* -** Allocate and zero memory. If the allocation fails, make -** the mallocFailed flag in the connection pointer. -*/ -void *sqlite3DbMallocZero(sqlite3 *db, unsigned n){ - void *p = sqlite3DbMallocRaw(db, n); - if( p ){ - memset(p, 0, n); - } - return p; -} - -/* -** Allocate and zero memory. If the allocation fails, make -** the mallocFailed flag in the connection pointer. -*/ -void *sqlite3DbMallocRaw(sqlite3 *db, unsigned n){ - void *p = 0; - if( !db || db->mallocFailed==0 ){ - p = sqlite3_malloc(n); - if( !p && db ){ - db->mallocFailed = 1; - } - } - return p; -} - -/* -** Resize the block of memory pointed to by p to n bytes. If the -** resize fails, set the mallocFailed flag inthe connection object. -*/ -void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){ - void *pNew = 0; - if( db->mallocFailed==0 ){ - pNew = sqlite3_realloc(p, n); - if( !pNew ){ - db->mallocFailed = 1; - } - } - return pNew; -} - -/* -** Attempt to reallocate p. If the reallocation fails, then free p -** and set the mallocFailed flag in the database connection. -*/ -void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){ - void *pNew; - pNew = sqlite3DbRealloc(db, p, n); - if( !pNew ){ - sqlite3_free(p); - } - return pNew; -} - -/* -** Make a copy of a string in memory obtained from sqliteMalloc(). These -** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This -** is because when memory debugging is turned on, these two functions are -** called via macros that record the current file and line number in the -** ThreadData structure. -*/ -char *sqlite3StrDup(const char *z){ - char *zNew; - int n; - if( z==0 ) return 0; - n = strlen(z)+1; - zNew = sqlite3_malloc(n); - if( zNew ) memcpy(zNew, z, n); - return zNew; -} -char *sqlite3StrNDup(const char *z, int n){ - char *zNew; - if( z==0 ) return 0; - zNew = sqlite3_malloc(n+1); - if( zNew ){ - memcpy(zNew, z, n); - zNew[n] = 0; - } - return zNew; -} - -char *sqlite3DbStrDup(sqlite3 *db, const char *z){ - char *zNew = sqlite3StrDup(z); - if( z && !zNew ){ - db->mallocFailed = 1; - } - return zNew; -} -char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){ - char *zNew = sqlite3StrNDup(z, n); - if( z && !zNew ){ - db->mallocFailed = 1; - } - return zNew; -} - -/* -** Create a string from the 2nd and subsequent arguments (up to the -** first NULL argument), store the string in memory obtained from -** sqliteMalloc() and make the pointer indicated by the 1st argument -** point to that string. The 1st argument must either be NULL or -** point to memory obtained from sqliteMalloc(). -*/ -void sqlite3SetString(char **pz, ...){ - va_list ap; - int nByte; - const char *z; - char *zResult; - - assert( pz!=0 ); - nByte = 1; - va_start(ap, pz); - while( (z = va_arg(ap, const char*))!=0 ){ - nByte += strlen(z); - } - va_end(ap); - sqlite3_free(*pz); - *pz = zResult = sqlite3_malloc(nByte); - if( zResult==0 ){ - return; - } - *zResult = 0; - va_start(ap, pz); - while( (z = va_arg(ap, const char*))!=0 ){ - int n = strlen(z); - memcpy(zResult, z, n); - zResult += n; - } - zResult[0] = 0; - va_end(ap); -} - - -/* -** This function must be called before exiting any API function (i.e. -** returning control to the user) that has called sqlite3_malloc or -** sqlite3_realloc. -** -** The returned value is normally a copy of the second argument to this -** function. However, if a malloc() failure has occured since the previous -** invocation SQLITE_NOMEM is returned instead. -** -** If the first argument, db, is not NULL and a malloc() error has occured, -** then the connection error-code (the value returned by sqlite3_errcode()) -** is set to SQLITE_NOMEM. -*/ -int sqlite3ApiExit(sqlite3* db, int rc){ - /* If the db handle is not NULL, then we must hold the connection handle - ** mutex here. Otherwise the read (and possible write) of db->mallocFailed - ** is unsafe, as is the call to sqlite3Error(). - */ - assert( !db || sqlite3_mutex_held(db->mutex) ); - if( db && db->mallocFailed ){ - sqlite3Error(db, SQLITE_NOMEM, 0); - db->mallocFailed = 0; - rc = SQLITE_NOMEM; - } - return rc & (db ? db->errMask : 0xff); -} - diff --git a/extensions/sqlite/sqlite-source/mem1.c b/extensions/sqlite/sqlite-source/mem1.c deleted file mode 100644 index fa99d8db..00000000 --- a/extensions/sqlite/sqlite-source/mem1.c +++ /dev/null @@ -1,229 +0,0 @@ -/* -** 2007 August 14 -** -** 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 file contains the C functions that implement a memory -** allocation subsystem for use by SQLite. -** -** $Id$ -*/ - -/* -** This version of the memory allocator is the default. It is -** used when no other memory allocator is specified using compile-time -** macros. -*/ -#if !defined(SQLITE_MEMDEBUG) && !defined(SQLITE_OMIT_MEMORY_ALLOCATION) - -/* -** We will eventually construct multiple memory allocation subsystems -** suitable for use in various contexts: -** -** * Normal multi-threaded builds -** * Normal single-threaded builds -** * Debugging builds -** -** This initial version is suitable for use in normal multi-threaded -** builds. We envision that alternative versions will be stored in -** separate source files. #ifdefs will be used to select the code from -** one of the various memN.c source files for use in any given build. -*/ -#include "sqliteInt.h" - -/* -** All of the static variables used by this module are collected -** into a single structure named "mem". This is to keep the -** static variables organized and to reduce namespace pollution -** when this module is combined with other in the amalgamation. -*/ -static struct { - /* - ** The alarm callback and its arguments. The mem.mutex lock will - ** be held while the callback is running. Recursive calls into - ** the memory subsystem are allowed, but no new callbacks will be - ** issued. The alarmBusy variable is set to prevent recursive - ** callbacks. - */ - sqlite3_int64 alarmThreshold; - void (*alarmCallback)(void*, sqlite3_int64,int); - void *alarmArg; - int alarmBusy; - - /* - ** Mutex to control access to the memory allocation subsystem. - */ - sqlite3_mutex *mutex; - - /* - ** Current allocation and high-water mark. - */ - sqlite3_int64 nowUsed; - sqlite3_int64 mxUsed; - - -} mem; - -/* -** Enter the mutex mem.mutex. Allocate it if it is not already allocated. -*/ -static void enterMem(void){ - if( mem.mutex==0 ){ - mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); - } - sqlite3_mutex_enter(mem.mutex); -} - -/* -** Return the amount of memory currently checked out. -*/ -sqlite3_int64 sqlite3_memory_used(void){ - sqlite3_int64 n; - enterMem(); - n = mem.nowUsed; - sqlite3_mutex_leave(mem.mutex); - return n; -} - -/* -** Return the maximum amount of memory that has ever been -** checked out since either the beginning of this process -** or since the most recent reset. -*/ -sqlite3_int64 sqlite3_memory_highwater(int resetFlag){ - sqlite3_int64 n; - enterMem(); - n = mem.mxUsed; - if( resetFlag ){ - mem.mxUsed = mem.nowUsed; - } - sqlite3_mutex_leave(mem.mutex); - return n; -} - -/* -** Change the alarm callback -*/ -int sqlite3_memory_alarm( - void(*xCallback)(void *pArg, sqlite3_int64 used,int N), - void *pArg, - sqlite3_int64 iThreshold -){ - enterMem(); - mem.alarmCallback = xCallback; - mem.alarmArg = pArg; - mem.alarmThreshold = iThreshold; - sqlite3_mutex_leave(mem.mutex); - return SQLITE_OK; -} - -/* -** Trigger the alarm -*/ -static void sqlite3MemsysAlarm(int nByte){ - void (*xCallback)(void*,sqlite3_int64,int); - sqlite3_int64 nowUsed; - void *pArg; - if( mem.alarmCallback==0 || mem.alarmBusy ) return; - mem.alarmBusy = 1; - xCallback = mem.alarmCallback; - nowUsed = mem.nowUsed; - pArg = mem.alarmArg; - sqlite3_mutex_leave(mem.mutex); - xCallback(pArg, nowUsed, nByte); - sqlite3_mutex_enter(mem.mutex); - mem.alarmBusy = 0; -} - -/* -** Allocate nBytes of memory -*/ -void *sqlite3_malloc(int nBytes){ - sqlite3_int64 *p = 0; - if( nBytes>0 ){ - enterMem(); - if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){ - sqlite3MemsysAlarm(nBytes); - } - p = malloc(nBytes+8); - if( p==0 ){ - sqlite3MemsysAlarm(nBytes); - p = malloc(nBytes+8); - } - if( p ){ - p[0] = nBytes; - p++; - mem.nowUsed += nBytes; - if( mem.nowUsed>mem.mxUsed ){ - mem.mxUsed = mem.nowUsed; - } - } - sqlite3_mutex_leave(mem.mutex); - } - return (void*)p; -} - -/* -** Free memory. -*/ -void sqlite3_free(void *pPrior){ - sqlite3_int64 *p; - int nByte; - if( pPrior==0 ){ - return; - } - assert( mem.mutex!=0 ); - p = pPrior; - p--; - nByte = (int)*p; - sqlite3_mutex_enter(mem.mutex); - mem.nowUsed -= nByte; - free(p); - sqlite3_mutex_leave(mem.mutex); -} - -/* -** Change the size of an existing memory allocation -*/ -void *sqlite3_realloc(void *pPrior, int nBytes){ - int nOld; - sqlite3_int64 *p; - if( pPrior==0 ){ - return sqlite3_malloc(nBytes); - } - if( nBytes<=0 ){ - sqlite3_free(pPrior); - return 0; - } - p = pPrior; - p--; - nOld = (int)p[0]; - assert( mem.mutex!=0 ); - sqlite3_mutex_enter(mem.mutex); - if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){ - sqlite3MemsysAlarm(nBytes-nOld); - } - p = realloc(p, nBytes+8); - if( p==0 ){ - sqlite3MemsysAlarm(nBytes); - p = realloc(p, nBytes+8); - } - if( p ){ - p[0] = nBytes; - p++; - mem.nowUsed += nBytes-nOld; - if( mem.nowUsed>mem.mxUsed ){ - mem.mxUsed = mem.nowUsed; - } - } - sqlite3_mutex_leave(mem.mutex); - return (void*)p; -} - -#endif /* !SQLITE_MEMDEBUG && !SQLITE_OMIT_MEMORY_ALLOCATION */ diff --git a/extensions/sqlite/sqlite-source/mem2.c b/extensions/sqlite/sqlite-source/mem2.c deleted file mode 100644 index 3cdf5cb8..00000000 --- a/extensions/sqlite/sqlite-source/mem2.c +++ /dev/null @@ -1,546 +0,0 @@ -/* -** 2007 August 15 -** -** 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 file contains the C functions that implement a memory -** allocation subsystem for use by SQLite. -** -** $Id$ -*/ - -/* -** This version of the memory allocator is used only if the -** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION -** is not defined. -*/ -#if defined(SQLITE_MEMDEBUG) && !defined(SQLITE_OMIT_MEMORY_ALLOCATION) - -/* -** We will eventually construct multiple memory allocation subsystems -** suitable for use in various contexts: -** -** * Normal multi-threaded builds -** * Normal single-threaded builds -** * Debugging builds -** -** This version is suitable for use in debugging builds. -** -** Features: -** -** * Every allocate has guards at both ends. -** * New allocations are initialized with randomness -** * Allocations are overwritten with randomness when freed -** * Optional logs of malloc activity generated -** * Summary of outstanding allocations with backtraces to the -** point of allocation. -** * The ability to simulate memory allocation failure -*/ -#include "sqliteInt.h" -#include - -/* -** The backtrace functionality is only available with GLIBC -*/ -#ifdef __GLIBC__ - extern int backtrace(void**,int); - extern void backtrace_symbols_fd(void*const*,int,int); -#else -# define backtrace(A,B) 0 -# define backtrace_symbols_fd(A,B,C) -#endif - -/* -** Each memory allocation looks like this: -** -** ------------------------------------------------------------------------ -** | Title | backtrace pointers | MemBlockHdr | allocation | EndGuard | -** ------------------------------------------------------------------------ -** -** The application code sees only a pointer to the allocation. We have -** to back up from the allocation pointer to find the MemBlockHdr. The -** MemBlockHdr tells us the size of the allocation and the number of -** backtrace pointers. There is also a guard word at the end of the -** MemBlockHdr. -*/ -struct MemBlockHdr { - struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */ - int iSize; /* Size of this allocation */ - char nBacktrace; /* Number of backtraces on this alloc */ - char nBacktraceSlots; /* Available backtrace slots */ - short nTitle; /* Bytes of title; includes '\0' */ - int iForeGuard; /* Guard word for sanity */ -}; - -/* -** Guard words -*/ -#define FOREGUARD 0x80F5E153 -#define REARGUARD 0xE4676B53 - -/* -** All of the static variables used by this module are collected -** into a single structure named "mem". This is to keep the -** static variables organized and to reduce namespace pollution -** when this module is combined with other in the amalgamation. -*/ -static struct { - /* - ** The alarm callback and its arguments. The mem.mutex lock will - ** be held while the callback is running. Recursive calls into - ** the memory subsystem are allowed, but no new callbacks will be - ** issued. The alarmBusy variable is set to prevent recursive - ** callbacks. - */ - sqlite3_int64 alarmThreshold; - void (*alarmCallback)(void*, sqlite3_int64, int); - void *alarmArg; - int alarmBusy; - - /* - ** Mutex to control access to the memory allocation subsystem. - */ - sqlite3_mutex *mutex; - - /* - ** Current allocation and high-water mark. - */ - sqlite3_int64 nowUsed; - sqlite3_int64 mxUsed; - - /* - ** Head and tail of a linked list of all outstanding allocations - */ - struct MemBlockHdr *pFirst; - struct MemBlockHdr *pLast; - - /* - ** The number of levels of backtrace to save in new allocations. - */ - int nBacktrace; - - /* - ** Title text to insert in front of each block - */ - int nTitle; /* Bytes of zTitle to save. Includes '\0' and padding */ - char zTitle[100]; /* The title text */ - - /* - ** These values are used to simulate malloc failures. When - ** iFail is 1, simulate a malloc failures and reset the value - ** to iReset. - */ - int iFail; /* Decrement and fail malloc when this is 1 */ - int iReset; /* When malloc fails set iiFail to this value */ - int iFailCnt; /* Number of failures */ - int iBenignFailCnt; /* Number of benign failures */ - int iNextIsBenign; /* True if the next call to malloc may fail benignly */ - int iIsBenign; /* All malloc calls may fail benignly */ - - /* - ** sqlite3MallocDisallow() increments the following counter. - ** sqlite3MallocAllow() decrements it. - */ - int disallow; /* Do not allow memory allocation */ - - -} mem; - - -/* -** Enter the mutex mem.mutex. Allocate it if it is not already allocated. -*/ -static void enterMem(void){ - if( mem.mutex==0 ){ - mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); - } - sqlite3_mutex_enter(mem.mutex); -} - -/* -** Return the amount of memory currently checked out. -*/ -sqlite3_int64 sqlite3_memory_used(void){ - sqlite3_int64 n; - enterMem(); - n = mem.nowUsed; - sqlite3_mutex_leave(mem.mutex); - return n; -} - -/* -** Return the maximum amount of memory that has ever been -** checked out since either the beginning of this process -** or since the most recent reset. -*/ -sqlite3_int64 sqlite3_memory_highwater(int resetFlag){ - sqlite3_int64 n; - enterMem(); - n = mem.mxUsed; - if( resetFlag ){ - mem.mxUsed = mem.nowUsed; - } - sqlite3_mutex_leave(mem.mutex); - return n; -} - -/* -** Change the alarm callback -*/ -int sqlite3_memory_alarm( - void(*xCallback)(void *pArg, sqlite3_int64 used, int N), - void *pArg, - sqlite3_int64 iThreshold -){ - enterMem(); - mem.alarmCallback = xCallback; - mem.alarmArg = pArg; - mem.alarmThreshold = iThreshold; - sqlite3_mutex_leave(mem.mutex); - return SQLITE_OK; -} - -/* -** Trigger the alarm -*/ -static void sqlite3MemsysAlarm(int nByte){ - void (*xCallback)(void*,sqlite3_int64,int); - sqlite3_int64 nowUsed; - void *pArg; - if( mem.alarmCallback==0 || mem.alarmBusy ) return; - mem.alarmBusy = 1; - xCallback = mem.alarmCallback; - nowUsed = mem.nowUsed; - pArg = mem.alarmArg; - sqlite3_mutex_leave(mem.mutex); - xCallback(pArg, nowUsed, nByte); - sqlite3_mutex_enter(mem.mutex); - mem.alarmBusy = 0; -} - -/* -** Given an allocation, find the MemBlockHdr for that allocation. -** -** This routine checks the guards at either end of the allocation and -** if they are incorrect it asserts. -*/ -static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){ - struct MemBlockHdr *p; - int *pInt; - - p = (struct MemBlockHdr*)pAllocation; - p--; - assert( p->iForeGuard==FOREGUARD ); - assert( (p->iSize & 3)==0 ); - pInt = (int*)pAllocation; - assert( pInt[p->iSize/sizeof(int)]==REARGUARD ); - return p; -} - -/* -** This routine is called once the first time a simulated memory -** failure occurs. The sole purpose of this routine is to provide -** a convenient place to set a debugger breakpoint when debugging -** errors related to malloc() failures. -*/ -static void sqlite3MemsysFailed(void){ - mem.iFailCnt = 0; - mem.iBenignFailCnt = 0; -} - -/* -** Allocate nByte bytes of memory. -*/ -void *sqlite3_malloc(int nByte){ - struct MemBlockHdr *pHdr; - void **pBt; - char *z; - int *pInt; - void *p = 0; - int totalSize; - - if( nByte>0 ){ - enterMem(); - assert( mem.disallow==0 ); - if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){ - sqlite3MemsysAlarm(nByte); - } - nByte = (nByte+3)&~3; - totalSize = nByte + sizeof(*pHdr) + sizeof(int) + - mem.nBacktrace*sizeof(void*) + mem.nTitle; - if( mem.iFail>0 ){ - if( mem.iFail==1 ){ - p = 0; - mem.iFail = mem.iReset; - if( mem.iFailCnt==0 ){ - sqlite3MemsysFailed(); /* A place to set a breakpoint */ - } - mem.iFailCnt++; - if( mem.iNextIsBenign || mem.iIsBenign ){ - mem.iBenignFailCnt++; - } - }else{ - p = malloc(totalSize); - mem.iFail--; - } - }else{ - p = malloc(totalSize); - if( p==0 ){ - sqlite3MemsysAlarm(nByte); - p = malloc(totalSize); - } - } - if( p ){ - z = p; - pBt = (void**)&z[mem.nTitle]; - pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace]; - pHdr->pNext = 0; - pHdr->pPrev = mem.pLast; - if( mem.pLast ){ - mem.pLast->pNext = pHdr; - }else{ - mem.pFirst = pHdr; - } - mem.pLast = pHdr; - pHdr->iForeGuard = FOREGUARD; - pHdr->nBacktraceSlots = mem.nBacktrace; - pHdr->nTitle = mem.nTitle; - if( mem.nBacktrace ){ - void *aAddr[40]; - pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1; - memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*)); - }else{ - pHdr->nBacktrace = 0; - } - if( mem.nTitle ){ - memcpy(z, mem.zTitle, mem.nTitle); - } - pHdr->iSize = nByte; - pInt = (int*)&pHdr[1]; - pInt[nByte/sizeof(int)] = REARGUARD; - memset(pInt, 0x65, nByte); - mem.nowUsed += nByte; - if( mem.nowUsed>mem.mxUsed ){ - mem.mxUsed = mem.nowUsed; - } - p = (void*)pInt; - } - sqlite3_mutex_leave(mem.mutex); - } - mem.iNextIsBenign = 0; - return p; -} - -/* -** Free memory. -*/ -void sqlite3_free(void *pPrior){ - struct MemBlockHdr *pHdr; - void **pBt; - char *z; - if( pPrior==0 ){ - return; - } - assert( mem.mutex!=0 ); - pHdr = sqlite3MemsysGetHeader(pPrior); - pBt = (void**)pHdr; - pBt -= pHdr->nBacktraceSlots; - sqlite3_mutex_enter(mem.mutex); - mem.nowUsed -= pHdr->iSize; - if( pHdr->pPrev ){ - assert( pHdr->pPrev->pNext==pHdr ); - pHdr->pPrev->pNext = pHdr->pNext; - }else{ - assert( mem.pFirst==pHdr ); - mem.pFirst = pHdr->pNext; - } - if( pHdr->pNext ){ - assert( pHdr->pNext->pPrev==pHdr ); - pHdr->pNext->pPrev = pHdr->pPrev; - }else{ - assert( mem.pLast==pHdr ); - mem.pLast = pHdr->pPrev; - } - z = (char*)pBt; - z -= pHdr->nTitle; - memset(z, 0x2b, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + - pHdr->iSize + sizeof(int) + pHdr->nTitle); - free(z); - sqlite3_mutex_leave(mem.mutex); -} - -/* -** Change the size of an existing memory allocation. -** -** For this debugging implementation, we *always* make a copy of the -** allocation into a new place in memory. In this way, if the -** higher level code is using pointer to the old allocation, it is -** much more likely to break and we are much more liking to find -** the error. -*/ -void *sqlite3_realloc(void *pPrior, int nByte){ - struct MemBlockHdr *pOldHdr; - void *pNew; - if( pPrior==0 ){ - return sqlite3_malloc(nByte); - } - if( nByte<=0 ){ - sqlite3_free(pPrior); - return 0; - } - assert( mem.disallow==0 ); - pOldHdr = sqlite3MemsysGetHeader(pPrior); - pNew = sqlite3_malloc(nByte); - if( pNew ){ - memcpy(pNew, pPrior, nByteiSize ? nByte : pOldHdr->iSize); - if( nByte>pOldHdr->iSize ){ - memset(&((char*)pNew)[pOldHdr->iSize], 0x2b, nByte - pOldHdr->iSize); - } - sqlite3_free(pPrior); - } - return pNew; -} - -/* -** Set the number of backtrace levels kept for each allocation. -** A value of zero turns of backtracing. The number is always rounded -** up to a multiple of 2. -*/ -void sqlite3_memdebug_backtrace(int depth){ - if( depth<0 ){ depth = 0; } - if( depth>20 ){ depth = 20; } - depth = (depth+1)&0xfe; - mem.nBacktrace = depth; -} - -/* -** Set the title string for subsequent allocations. -*/ -void sqlite3_memdebug_settitle(const char *zTitle){ - int n = strlen(zTitle) + 1; - enterMem(); - if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1; - memcpy(mem.zTitle, zTitle, n); - mem.zTitle[n] = 0; - mem.nTitle = (n+3)&~3; - sqlite3_mutex_leave(mem.mutex); -} - -/* -** Open the file indicated and write a log of all unfreed memory -** allocations into that log. -*/ -void sqlite3_memdebug_dump(const char *zFilename){ - FILE *out; - struct MemBlockHdr *pHdr; - void **pBt; - out = fopen(zFilename, "w"); - if( out==0 ){ - fprintf(stderr, "** Unable to output memory debug output log: %s **\n", - zFilename); - return; - } - for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ - char *z = (char*)pHdr; - z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle; - fprintf(out, "**** %d bytes at %p from %s ****\n", - pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???"); - if( pHdr->nBacktrace ){ - fflush(out); - pBt = (void**)pHdr; - pBt -= pHdr->nBacktraceSlots; - backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out)); - fprintf(out, "\n"); - } - } - fclose(out); -} - -/* -** This routine is used to simulate malloc failures. -** -** After calling this routine, there will be iFail successful -** memory allocations and then a failure. If iRepeat is 1 -** all subsequent memory allocations will fail. If iRepeat is -** 0, only a single allocation will fail. If iRepeat is negative -** then the previous setting for iRepeat is unchanged. -** -** Each call to this routine overrides the previous. To disable -** the simulated allocation failure mechanism, set iFail to -1. -** -** This routine returns the number of simulated failures that have -** occurred since the previous call. -*/ -int sqlite3_memdebug_fail(int iFail, int iRepeat, int *piBenign){ - int n = mem.iFailCnt; - if( piBenign ){ - *piBenign = mem.iBenignFailCnt; - } - mem.iFail = iFail+1; - if( iRepeat>=0 ){ - mem.iReset = iRepeat; - } - mem.iFailCnt = 0; - mem.iBenignFailCnt = 0; - return n; -} - -int sqlite3_memdebug_pending(){ - return (mem.iFail-1); -} - -/* -** The following three functions are used to indicate to the test -** infrastructure which malloc() calls may fail benignly without -** affecting functionality. This can happen when resizing hash tables -** (failing to resize a hash-table is a performance hit, but not an -** error) or sometimes during a rollback operation. -** -** If the argument is true, sqlite3MallocBenignFailure() indicates that the -** next call to allocate memory may fail benignly. -** -** If sqlite3MallocEnterBenignBlock() is called with a non-zero argument, -** then all memory allocations requested before the next call to -** sqlite3MallocLeaveBenignBlock() may fail benignly. -*/ -void sqlite3MallocBenignFailure(int isBenign){ - if( isBenign ){ - mem.iNextIsBenign = 1; - } -} -void sqlite3MallocEnterBenignBlock(int isBenign){ - if( isBenign ){ - mem.iIsBenign = 1; - } -} -void sqlite3MallocLeaveBenignBlock(){ - mem.iIsBenign = 0; -} - -/* -** The following two routines are used to assert that no memory -** allocations occur between one call and the next. The use of -** these routines does not change the computed results in any way. -** These routines are like asserts. -*/ -void sqlite3MallocDisallow(void){ - assert( mem.mutex!=0 ); - sqlite3_mutex_enter(mem.mutex); - mem.disallow++; - sqlite3_mutex_leave(mem.mutex); -} -void sqlite3MallocAllow(void){ - assert( mem.mutex ); - sqlite3_mutex_enter(mem.mutex); - assert( mem.disallow>0 ); - mem.disallow--; - sqlite3_mutex_leave(mem.mutex); -} - -#endif /* SQLITE_MEMDEBUG && !SQLITE_OMIT_MEMORY_ALLOCATION */ diff --git a/extensions/sqlite/sqlite-source/mutex.c b/extensions/sqlite/sqlite-source/mutex.c deleted file mode 100644 index 687ee549..00000000 --- a/extensions/sqlite/sqlite-source/mutex.c +++ /dev/null @@ -1,126 +0,0 @@ -/* -** 2007 August 14 -** -** 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 file contains the C functions that implement mutexes. -** -** The implementation in this file does not provide any mutual -** exclusion and is thus suitable for use only in applications -** that use SQLite in a single thread. But this implementation -** does do a lot of error checking on mutexes to make sure they -** are called correctly and at appropriate times. Hence, this -** implementation is suitable for testing. -** debugging purposes -** -** $Id$ -*/ -#include "sqliteInt.h" - -#ifdef SQLITE_MUTEX_NOOP_DEBUG -/* -** In this implementation, mutexes do not provide any mutual exclusion. -** But the error checking is provided. This implementation is useful -** for test purposes. -*/ - -/* -** The mutex object -*/ -struct sqlite3_mutex { - int id; /* The mutex type */ - int cnt; /* Number of entries without a matching leave */ -}; - -/* -** The sqlite3_mutex_alloc() routine allocates a new -** mutex and returns a pointer to it. If it returns NULL -** that means that a mutex could not be allocated. -*/ -sqlite3_mutex *sqlite3_mutex_alloc(int id){ - static sqlite3_mutex aStatic[5]; - sqlite3_mutex *pNew = 0; - switch( id ){ - case SQLITE_MUTEX_FAST: - case SQLITE_MUTEX_RECURSIVE: { - pNew = sqlite3_malloc(sizeof(*pNew)); - if( pNew ){ - pNew->id = id; - pNew->cnt = 0; - } - break; - } - default: { - assert( id-2 >= 0 ); - assert( id-2 < sizeof(aStatic)/sizeof(aStatic[0]) ); - pNew = &aStatic[id-2]; - pNew->id = id; - break; - } - } - return pNew; -} - -/* -** This routine deallocates a previously allocated mutex. -*/ -void sqlite3_mutex_free(sqlite3_mutex *p){ - assert( p ); - assert( p->cnt==0 ); - assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); - sqlite3_free(p); -} - -/* -** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt -** to enter a mutex. If another thread is already within the mutex, -** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return -** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK -** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can -** be entered multiple times by the same thread. In such cases the, -** mutex must be exited an equal number of times before another thread -** can enter. If the same thread tries to enter any other kind of mutex -** more than once, the behavior is undefined. -*/ -void sqlite3_mutex_enter(sqlite3_mutex *p){ - assert( p ); - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); - p->cnt++; -} -int sqlite3_mutex_try(sqlite3_mutex *p){ - assert( p ); - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); - p->cnt++; - return SQLITE_OK; -} - -/* -** The sqlite3_mutex_leave() routine exits a mutex that was -** previously entered by the same thread. The behavior -** is undefined if the mutex is not currently entered or -** is not currently allocated. SQLite will never do either. -*/ -void sqlite3_mutex_leave(sqlite3_mutex *p){ - assert( p ); - assert( sqlite3_mutex_held(p) ); - p->cnt--; - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); -} - -/* -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are -** intended for use inside assert() statements. -*/ -int sqlite3_mutex_held(sqlite3_mutex *p){ - return p==0 || p->cnt>0; -} -int sqlite3_mutex_notheld(sqlite3_mutex *p){ - return p==0 || p->cnt==0; -} -#endif /* SQLITE_MUTEX_NOOP_DEBUG */ diff --git a/extensions/sqlite/sqlite-source/mutex.h b/extensions/sqlite/sqlite-source/mutex.h deleted file mode 100644 index 008a1e52..00000000 --- a/extensions/sqlite/sqlite-source/mutex.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -** 2007 August 28 -** -** 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 file contains the common header for all mutex implementations. -** The sqliteInt.h header #includes this file so that it is available -** to all source files. We break it out in an effort to keep the code -** better organized. -** -** NOTE: source files should *not* #include this header file directly. -** Source files should #include the sqliteInt.h file and let that file -** include this one indirectly. -** -** $Id$ -*/ - - -#ifdef SQLITE_MUTEX_APPDEF -/* -** If SQLITE_MUTEX_APPDEF is defined, then this whole module is -** omitted and equivalent functionality must be provided by the -** application that links against the SQLite library. -*/ -#else -/* -** Figure out what version of the code to use. The choices are -** -** SQLITE_MUTEX_NOOP For single-threaded applications that -** do not desire error checking. -** -** SQLITE_MUTEX_NOOP_DEBUG For single-threaded applications with -** error checking to help verify that mutexes -** are being used correctly even though they -** are not needed. Used when SQLITE_DEBUG is -** defined on single-threaded builds. -** -** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix. -** -** SQLITE_MUTEX_W32 For multi-threaded applications on Win32. -** -** SQLITE_MUTEX_OS2 For multi-threaded applications on OS/2. -*/ -#define SQLITE_MUTEX_NOOP 1 /* The default */ -#if defined(SQLITE_DEBUG) && !SQLITE_THREADSAFE -# undef SQLITE_MUTEX_NOOP -# define SQLITE_MUTEX_NOOP_DEBUG -#endif -#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && OS_UNIX -# undef SQLITE_MUTEX_NOOP -# define SQLITE_MUTEX_PTHREADS -#endif -#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && OS_WIN -# undef SQLITE_MUTEX_NOOP -# define SQLITE_MUTEX_W32 -#endif -#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && OS_OS2 -# undef SQLITE_MUTEX_NOOP -# define SQLITE_MUTEX_OS2 -#endif - -#ifdef SQLITE_MUTEX_NOOP -/* -** If this is a no-op implementation, implement everything as macros. -*/ -#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) -#define sqlite3_mutex_free(X) -#define sqlite3_mutex_enter(X) -#define sqlite3_mutex_try(X) SQLITE_OK -#define sqlite3_mutex_leave(X) -#define sqlite3_mutex_held(X) 1 -#define sqlite3_mutex_notheld(X) 1 -#endif - -#endif /* SQLITE_MUTEX_APPDEF */ diff --git a/extensions/sqlite/sqlite-source/mutex_unix.c b/extensions/sqlite/sqlite-source/mutex_unix.c deleted file mode 100644 index 941d6689..00000000 --- a/extensions/sqlite/sqlite-source/mutex_unix.c +++ /dev/null @@ -1,223 +0,0 @@ -/* -** 2007 August 28 -** -** 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 file contains the C functions that implement mutexes for pthreads -** -** $Id$ -*/ -#include "sqliteInt.h" - -/* -** The code in this file is only used if we are compiling threadsafe -** under unix with pthreads. -** -** Note that this implementation requires a version of pthreads that -** supports recursive mutexes. -*/ -#ifdef SQLITE_MUTEX_PTHREADS - -#include - -/* -** Each recursive mutex is an instance of the following structure. -*/ -struct sqlite3_mutex { - pthread_mutex_t mutex; /* Mutex controlling the lock */ - int id; /* Mutex type */ - int nRef; /* Number of entrances */ - pthread_t owner; /* Thread that is within this mutex */ -#ifdef SQLITE_DEBUG - int trace; /* True to trace changes */ -#endif -}; - -/* -** The sqlite3_mutex_alloc() routine allocates a new -** mutex and returns a pointer to it. If it returns NULL -** that means that a mutex could not be allocated. SQLite -** will unwind its stack and return an error. The argument -** to sqlite3_mutex_alloc() is one of these integer constants: -** -**
    -**
  • SQLITE_MUTEX_FAST -**
  • SQLITE_MUTEX_RECURSIVE -**
  • SQLITE_MUTEX_STATIC_MASTER -**
  • SQLITE_MUTEX_STATIC_MEM -**
  • SQLITE_MUTEX_STATIC_MEM2 -**
  • SQLITE_MUTEX_STATIC_PRNG -**
  • SQLITE_MUTEX_STATIC_LRU -**
-** -** The first two constants cause sqlite3_mutex_alloc() to create -** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE -** is used but not necessarily so when SQLITE_MUTEX_FAST is used. -** The mutex implementation does not need to make a distinction -** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does -** not want to. But SQLite will only request a recursive mutex in -** cases where it really needs one. If a faster non-recursive mutex -** implementation is available on the host platform, the mutex subsystem -** might return such a mutex in response to SQLITE_MUTEX_FAST. -** -** The other allowed parameters to sqlite3_mutex_alloc() each return -** a pointer to a static preexisting mutex. Three static mutexes are -** used by the current version of SQLite. Future versions of SQLite -** may add additional static mutexes. Static mutexes are for internal -** use by SQLite only. Applications that use SQLite mutexes should -** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or -** SQLITE_MUTEX_RECURSIVE. -** -** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST -** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() -** returns a different mutex on every call. But for the static -** mutex types, the same mutex is returned on every call that has -** the same type number. -*/ -sqlite3_mutex *sqlite3_mutex_alloc(int iType){ - static sqlite3_mutex staticMutexes[] = { - { PTHREAD_MUTEX_INITIALIZER, }, - { PTHREAD_MUTEX_INITIALIZER, }, - { PTHREAD_MUTEX_INITIALIZER, }, - { PTHREAD_MUTEX_INITIALIZER, }, - { PTHREAD_MUTEX_INITIALIZER, }, - }; - sqlite3_mutex *p; - switch( iType ){ - case SQLITE_MUTEX_RECURSIVE: { - p = sqlite3MallocZero( sizeof(*p) ); - if( p ){ - pthread_mutexattr_t recursiveAttr; - pthread_mutexattr_init(&recursiveAttr); - pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&p->mutex, &recursiveAttr); - pthread_mutexattr_destroy(&recursiveAttr); - p->id = iType; - } - break; - } - case SQLITE_MUTEX_FAST: { - p = sqlite3MallocZero( sizeof(*p) ); - if( p ){ - p->id = iType; - pthread_mutex_init(&p->mutex, 0); - } - break; - } - default: { - assert( iType-2 >= 0 ); - assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) ); - p = &staticMutexes[iType-2]; - p->id = iType; - break; - } - } - return p; -} - - -/* -** This routine deallocates a previously -** allocated mutex. SQLite is careful to deallocate every -** mutex that it allocates. -*/ -void sqlite3_mutex_free(sqlite3_mutex *p){ - assert( p ); - assert( p->nRef==0 ); - assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); - pthread_mutex_destroy(&p->mutex); - sqlite3_free(p); -} - -/* -** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt -** to enter a mutex. If another thread is already within the mutex, -** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return -** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK -** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can -** be entered multiple times by the same thread. In such cases the, -** mutex must be exited an equal number of times before another thread -** can enter. If the same thread tries to enter any other kind of mutex -** more than once, the behavior is undefined. -*/ -void sqlite3_mutex_enter(sqlite3_mutex *p){ - assert( p ); - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); - pthread_mutex_lock(&p->mutex); - p->owner = pthread_self(); - p->nRef++; -#ifdef SQLITE_DEBUG - if( p->trace ){ - printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); - } -#endif -} -int sqlite3_mutex_try(sqlite3_mutex *p){ - int rc; - assert( p ); - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); - if( pthread_mutex_trylock(&p->mutex)==0 ){ - p->owner = pthread_self(); - p->nRef++; - rc = SQLITE_OK; -#ifdef SQLITE_DEBUG - if( p->trace ){ - printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); - } -#endif - }else{ - rc = SQLITE_BUSY; - } - return rc; -} - -/* -** The sqlite3_mutex_leave() routine exits a mutex that was -** previously entered by the same thread. The behavior -** is undefined if the mutex is not currently entered or -** is not currently allocated. SQLite will never do either. -*/ -void sqlite3_mutex_leave(sqlite3_mutex *p){ - assert( p ); - assert( sqlite3_mutex_held(p) ); - p->nRef--; - assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); -#ifdef SQLITE_DEBUG - if( p->trace ){ - printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); - } -#endif - pthread_mutex_unlock(&p->mutex); -} - -/* -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are -** intended for use only inside assert() statements. On some platforms, -** there might be race conditions that can cause these routines to -** deliver incorrect results. In particular, if pthread_equal() is -** not an atomic operation, then these routines might delivery -** incorrect results. On most platforms, pthread_equal() is a -** comparison of two integers and is therefore atomic. But we are -** told that HPUX is not such a platform. If so, then these routines -** will not always work correctly on HPUX. -** -** On those platforms where pthread_equal() is not atomic, SQLite -** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to -** make sure no assert() statements are evaluated and hence these -** routines are never called. -*/ -#ifndef NDEBUG -int sqlite3_mutex_held(sqlite3_mutex *p){ - return p==0 || (p->nRef!=0 && pthread_equal(p->owner, pthread_self())); -} -int sqlite3_mutex_notheld(sqlite3_mutex *p){ - return p==0 || p->nRef==0 || pthread_equal(p->owner, pthread_self())==0; -} -#endif -#endif /* SQLITE_MUTEX_PTHREAD */ diff --git a/extensions/sqlite/sqlite-source/mutex_w32.c b/extensions/sqlite/sqlite-source/mutex_w32.c deleted file mode 100644 index 9e9f00c0..00000000 --- a/extensions/sqlite/sqlite-source/mutex_w32.c +++ /dev/null @@ -1,208 +0,0 @@ -/* -** 2007 August 14 -** -** 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 file contains the C functions that implement mutexes for win32 -** -** $Id$ -*/ -#include "sqliteInt.h" - -/* -** The code in this file is only used if we are compiling multithreaded -** on a win32 system. -*/ -#ifdef SQLITE_MUTEX_W32 - -/* -** Each recursive mutex is an instance of the following structure. -*/ -struct sqlite3_mutex { - CRITICAL_SECTION mutex; /* Mutex controlling the lock */ - int id; /* Mutex type */ - int nRef; /* Number of enterances */ - DWORD owner; /* Thread holding this mutex */ -}; - -/* -** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, -** or WinCE. Return false (zero) for Win95, Win98, or WinME. -** -** Here is an interesting observation: Win95, Win98, and WinME lack -** the LockFileEx() API. But we can still statically link against that -** API as long as we don't call it win running Win95/98/ME. A call to -** this routine is used to determine if the host is Win95/98/ME or -** WinNT/2K/XP so that we will know whether or not we can safely call -** the LockFileEx() API. -*/ -#if OS_WINCE -# define mutexIsNT() (1) -#else - static int mutexIsNT(void){ - static int osType = 0; - if( osType==0 ){ - OSVERSIONINFO sInfo; - sInfo.dwOSVersionInfoSize = sizeof(sInfo); - GetVersionEx(&sInfo); - osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; - } - return osType==2; - } -#endif /* OS_WINCE */ - - -/* -** The sqlite3_mutex_alloc() routine allocates a new -** mutex and returns a pointer to it. If it returns NULL -** that means that a mutex could not be allocated. SQLite -** will unwind its stack and return an error. The argument -** to sqlite3_mutex_alloc() is one of these integer constants: -** -**
    -**
  • SQLITE_MUTEX_FAST 0 -**
  • SQLITE_MUTEX_RECURSIVE 1 -**
  • SQLITE_MUTEX_STATIC_MASTER 2 -**
  • SQLITE_MUTEX_STATIC_MEM 3 -**
  • SQLITE_MUTEX_STATIC_PRNG 4 -**
-** -** The first two constants cause sqlite3_mutex_alloc() to create -** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE -** is used but not necessarily so when SQLITE_MUTEX_FAST is used. -** The mutex implementation does not need to make a distinction -** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does -** not want to. But SQLite will only request a recursive mutex in -** cases where it really needs one. If a faster non-recursive mutex -** implementation is available on the host platform, the mutex subsystem -** might return such a mutex in response to SQLITE_MUTEX_FAST. -** -** The other allowed parameters to sqlite3_mutex_alloc() each return -** a pointer to a static preexisting mutex. Three static mutexes are -** used by the current version of SQLite. Future versions of SQLite -** may add additional static mutexes. Static mutexes are for internal -** use by SQLite only. Applications that use SQLite mutexes should -** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or -** SQLITE_MUTEX_RECURSIVE. -** -** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST -** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() -** returns a different mutex on every call. But for the static -** mutex types, the same mutex is returned on every call that has -** the same type number. -*/ -sqlite3_mutex *sqlite3_mutex_alloc(int iType){ - sqlite3_mutex *p; - - switch( iType ){ - case SQLITE_MUTEX_FAST: - case SQLITE_MUTEX_RECURSIVE: { - p = sqlite3MallocZero( sizeof(*p) ); - if( p ){ - p->id = iType; - InitializeCriticalSection(&p->mutex); - } - break; - } - default: { - static sqlite3_mutex staticMutexes[5]; - static int isInit = 0; - while( !isInit ){ - static long lock = 0; - if( InterlockedIncrement(&lock)==1 ){ - int i; - for(i=0; i= 0 ); - assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) ); - p = &staticMutexes[iType-2]; - p->id = iType; - break; - } - } - return p; -} - - -/* -** This routine deallocates a previously -** allocated mutex. SQLite is careful to deallocate every -** mutex that it allocates. -*/ -void sqlite3_mutex_free(sqlite3_mutex *p){ - assert( p ); - assert( p->nRef==0 ); - assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); - DeleteCriticalSection(&p->mutex); - sqlite3_free(p); -} - -/* -** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt -** to enter a mutex. If another thread is already within the mutex, -** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return -** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK -** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can -** be entered multiple times by the same thread. In such cases the, -** mutex must be exited an equal number of times before another thread -** can enter. If the same thread tries to enter any other kind of mutex -** more than once, the behavior is undefined. -*/ -void sqlite3_mutex_enter(sqlite3_mutex *p){ - assert( p ); - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); - EnterCriticalSection(&p->mutex); - p->owner = GetCurrentThreadId(); - p->nRef++; -} -int sqlite3_mutex_try(sqlite3_mutex *p){ - int rc; - assert( p ); - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); - if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){ - p->owner = GetCurrentThreadId(); - p->nRef++; - rc = SQLITE_OK; - }else{ - rc = SQLITE_BUSY; - } - return rc; -} - -/* -** The sqlite3_mutex_leave() routine exits a mutex that was -** previously entered by the same thread. The behavior -** is undefined if the mutex is not currently entered or -** is not currently allocated. SQLite will never do either. -*/ -void sqlite3_mutex_leave(sqlite3_mutex *p){ - assert( p->nRef>0 ); - assert( p->owner==GetCurrentThreadId() ); - p->nRef--; - assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); - LeaveCriticalSection(&p->mutex); -} - -/* -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are -** intended for use only inside assert() statements. -*/ -int sqlite3_mutex_held(sqlite3_mutex *p){ - return p==0 || (p->nRef!=0 && p->owner==GetCurrentThreadId()); -} -int sqlite3_mutex_notheld(sqlite3_mutex *p){ - return p==0 || p->nRef==0 || p->owner!=GetCurrentThreadId(); -} -#endif /* SQLITE_MUTEX_W32 */ diff --git a/extensions/sqlite/sqlite-source/opcodes.c b/extensions/sqlite/sqlite-source/opcodes.c deleted file mode 100644 index ac283bd7..00000000 --- a/extensions/sqlite/sqlite-source/opcodes.c +++ /dev/null @@ -1,151 +0,0 @@ -/* Automatically generated. Do not edit */ -/* See the mkopcodec.awk script for details. */ -#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) -const char *sqlite3OpcodeName(int i){ - static const char *const azName[] = { "?", - /* 1 */ "MemLoad", - /* 2 */ "VNext", - /* 3 */ "Column", - /* 4 */ "SetCookie", - /* 5 */ "IfMemPos", - /* 6 */ "Sequence", - /* 7 */ "MoveGt", - /* 8 */ "RowKey", - /* 9 */ "OpenWrite", - /* 10 */ "If", - /* 11 */ "Pop", - /* 12 */ "VRowid", - /* 13 */ "CollSeq", - /* 14 */ "OpenRead", - /* 15 */ "Expire", - /* 16 */ "Not", - /* 17 */ "AutoCommit", - /* 18 */ "IntegrityCk", - /* 19 */ "Sort", - /* 20 */ "Function", - /* 21 */ "Noop", - /* 22 */ "Return", - /* 23 */ "NewRowid", - /* 24 */ "IfMemNeg", - /* 25 */ "Variable", - /* 26 */ "String", - /* 27 */ "RealAffinity", - /* 28 */ "VRename", - /* 29 */ "ParseSchema", - /* 30 */ "VOpen", - /* 31 */ "Close", - /* 32 */ "CreateIndex", - /* 33 */ "IsUnique", - /* 34 */ "NotFound", - /* 35 */ "Int64", - /* 36 */ "MustBeInt", - /* 37 */ "Halt", - /* 38 */ "Rowid", - /* 39 */ "IdxLT", - /* 40 */ "AddImm", - /* 41 */ "Statement", - /* 42 */ "RowData", - /* 43 */ "MemMax", - /* 44 */ "Push", - /* 45 */ "NotExists", - /* 46 */ "MemIncr", - /* 47 */ "Gosub", - /* 48 */ "Integer", - /* 49 */ "MemInt", - /* 50 */ "Prev", - /* 51 */ "VColumn", - /* 52 */ "CreateTable", - /* 53 */ "Last", - /* 54 */ "IncrVacuum", - /* 55 */ "IdxRowid", - /* 56 */ "MakeIdxRec", - /* 57 */ "ResetCount", - /* 58 */ "FifoWrite", - /* 59 */ "Callback", - /* 60 */ "Or", - /* 61 */ "And", - /* 62 */ "ContextPush", - /* 63 */ "DropTrigger", - /* 64 */ "DropIndex", - /* 65 */ "IsNull", - /* 66 */ "NotNull", - /* 67 */ "Ne", - /* 68 */ "Eq", - /* 69 */ "Gt", - /* 70 */ "Le", - /* 71 */ "Lt", - /* 72 */ "Ge", - /* 73 */ "IdxGE", - /* 74 */ "BitAnd", - /* 75 */ "BitOr", - /* 76 */ "ShiftLeft", - /* 77 */ "ShiftRight", - /* 78 */ "Add", - /* 79 */ "Subtract", - /* 80 */ "Multiply", - /* 81 */ "Divide", - /* 82 */ "Remainder", - /* 83 */ "Concat", - /* 84 */ "IdxDelete", - /* 85 */ "Negative", - /* 86 */ "Vacuum", - /* 87 */ "BitNot", - /* 88 */ "String8", - /* 89 */ "MoveLe", - /* 90 */ "IfNot", - /* 91 */ "DropTable", - /* 92 */ "MakeRecord", - /* 93 */ "Delete", - /* 94 */ "AggFinal", - /* 95 */ "Dup", - /* 96 */ "Goto", - /* 97 */ "TableLock", - /* 98 */ "FifoRead", - /* 99 */ "Clear", - /* 100 */ "IdxGT", - /* 101 */ "MoveLt", - /* 102 */ "VerifyCookie", - /* 103 */ "AggStep", - /* 104 */ "Pull", - /* 105 */ "SetNumColumns", - /* 106 */ "AbsValue", - /* 107 */ "Transaction", - /* 108 */ "VFilter", - /* 109 */ "VDestroy", - /* 110 */ "ContextPop", - /* 111 */ "Next", - /* 112 */ "IdxInsert", - /* 113 */ "Distinct", - /* 114 */ "Insert", - /* 115 */ "Destroy", - /* 116 */ "ReadCookie", - /* 117 */ "ForceInt", - /* 118 */ "LoadAnalysis", - /* 119 */ "Explain", - /* 120 */ "IfMemZero", - /* 121 */ "OpenPseudo", - /* 122 */ "OpenEphemeral", - /* 123 */ "Null", - /* 124 */ "Blob", - /* 125 */ "Real", - /* 126 */ "HexBlob", - /* 127 */ "MemStore", - /* 128 */ "Rewind", - /* 129 */ "MoveGe", - /* 130 */ "VBegin", - /* 131 */ "VUpdate", - /* 132 */ "VCreate", - /* 133 */ "MemMove", - /* 134 */ "MemNull", - /* 135 */ "Found", - /* 136 */ "NullRow", - /* 137 */ "NotUsed_137", - /* 138 */ "ToText", - /* 139 */ "ToBlob", - /* 140 */ "ToNumeric", - /* 141 */ "ToInt", - /* 142 */ "ToReal", - }; - return azName[i]; -} -#endif diff --git a/extensions/sqlite/sqlite-source/opcodes.h b/extensions/sqlite/sqlite-source/opcodes.h deleted file mode 100644 index c4b57608..00000000 --- a/extensions/sqlite/sqlite-source/opcodes.h +++ /dev/null @@ -1,160 +0,0 @@ -/* Automatically generated. Do not edit */ -/* See the mkopcodeh.awk script for details */ -#define OP_MemLoad 1 -#define OP_VNext 2 -#define OP_HexBlob 126 /* same as TK_BLOB */ -#define OP_Column 3 -#define OP_SetCookie 4 -#define OP_IfMemPos 5 -#define OP_Real 125 /* same as TK_FLOAT */ -#define OP_Sequence 6 -#define OP_MoveGt 7 -#define OP_Ge 72 /* same as TK_GE */ -#define OP_RowKey 8 -#define OP_Eq 68 /* same as TK_EQ */ -#define OP_OpenWrite 9 -#define OP_NotNull 66 /* same as TK_NOTNULL */ -#define OP_If 10 -#define OP_ToInt 141 /* same as TK_TO_INT */ -#define OP_String8 88 /* same as TK_STRING */ -#define OP_Pop 11 -#define OP_VRowid 12 -#define OP_CollSeq 13 -#define OP_OpenRead 14 -#define OP_Expire 15 -#define OP_AutoCommit 17 -#define OP_Gt 69 /* same as TK_GT */ -#define OP_IntegrityCk 18 -#define OP_Sort 19 -#define OP_Function 20 -#define OP_And 61 /* same as TK_AND */ -#define OP_Subtract 79 /* same as TK_MINUS */ -#define OP_Noop 21 -#define OP_Return 22 -#define OP_Remainder 82 /* same as TK_REM */ -#define OP_NewRowid 23 -#define OP_Multiply 80 /* same as TK_STAR */ -#define OP_IfMemNeg 24 -#define OP_Variable 25 -#define OP_String 26 -#define OP_RealAffinity 27 -#define OP_VRename 28 -#define OP_ParseSchema 29 -#define OP_VOpen 30 -#define OP_Close 31 -#define OP_CreateIndex 32 -#define OP_IsUnique 33 -#define OP_NotFound 34 -#define OP_Int64 35 -#define OP_MustBeInt 36 -#define OP_Halt 37 -#define OP_Rowid 38 -#define OP_IdxLT 39 -#define OP_AddImm 40 -#define OP_Statement 41 -#define OP_RowData 42 -#define OP_MemMax 43 -#define OP_Push 44 -#define OP_Or 60 /* same as TK_OR */ -#define OP_NotExists 45 -#define OP_MemIncr 46 -#define OP_Gosub 47 -#define OP_Divide 81 /* same as TK_SLASH */ -#define OP_Integer 48 -#define OP_ToNumeric 140 /* same as TK_TO_NUMERIC*/ -#define OP_MemInt 49 -#define OP_Prev 50 -#define OP_Concat 83 /* same as TK_CONCAT */ -#define OP_BitAnd 74 /* same as TK_BITAND */ -#define OP_VColumn 51 -#define OP_CreateTable 52 -#define OP_Last 53 -#define OP_IsNull 65 /* same as TK_ISNULL */ -#define OP_IncrVacuum 54 -#define OP_IdxRowid 55 -#define OP_MakeIdxRec 56 -#define OP_ShiftRight 77 /* same as TK_RSHIFT */ -#define OP_ResetCount 57 -#define OP_FifoWrite 58 -#define OP_Callback 59 -#define OP_ContextPush 62 -#define OP_DropTrigger 63 -#define OP_DropIndex 64 -#define OP_IdxGE 73 -#define OP_IdxDelete 84 -#define OP_Vacuum 86 -#define OP_MoveLe 89 -#define OP_IfNot 90 -#define OP_DropTable 91 -#define OP_MakeRecord 92 -#define OP_ToBlob 139 /* same as TK_TO_BLOB */ -#define OP_Delete 93 -#define OP_AggFinal 94 -#define OP_ShiftLeft 76 /* same as TK_LSHIFT */ -#define OP_Dup 95 -#define OP_Goto 96 -#define OP_TableLock 97 -#define OP_FifoRead 98 -#define OP_Clear 99 -#define OP_IdxGT 100 -#define OP_MoveLt 101 -#define OP_Le 70 /* same as TK_LE */ -#define OP_VerifyCookie 102 -#define OP_AggStep 103 -#define OP_Pull 104 -#define OP_ToText 138 /* same as TK_TO_TEXT */ -#define OP_Not 16 /* same as TK_NOT */ -#define OP_ToReal 142 /* same as TK_TO_REAL */ -#define OP_SetNumColumns 105 -#define OP_AbsValue 106 -#define OP_Transaction 107 -#define OP_VFilter 108 -#define OP_Negative 85 /* same as TK_UMINUS */ -#define OP_Ne 67 /* same as TK_NE */ -#define OP_VDestroy 109 -#define OP_ContextPop 110 -#define OP_BitOr 75 /* same as TK_BITOR */ -#define OP_Next 111 -#define OP_IdxInsert 112 -#define OP_Distinct 113 -#define OP_Lt 71 /* same as TK_LT */ -#define OP_Insert 114 -#define OP_Destroy 115 -#define OP_ReadCookie 116 -#define OP_ForceInt 117 -#define OP_LoadAnalysis 118 -#define OP_Explain 119 -#define OP_IfMemZero 120 -#define OP_OpenPseudo 121 -#define OP_OpenEphemeral 122 -#define OP_Null 123 -#define OP_Blob 124 -#define OP_Add 78 /* same as TK_PLUS */ -#define OP_MemStore 127 -#define OP_Rewind 128 -#define OP_MoveGe 129 -#define OP_VBegin 130 -#define OP_VUpdate 131 -#define OP_BitNot 87 /* same as TK_BITNOT */ -#define OP_VCreate 132 -#define OP_MemMove 133 -#define OP_MemNull 134 -#define OP_Found 135 -#define OP_NullRow 136 - -/* The following opcode values are never used */ -#define OP_NotUsed_137 137 - -/* Opcodes that are guaranteed to never push a value onto the stack -** contain a 1 their corresponding position of the following mask -** set. See the opcodeNoPush() function in vdbeaux.c */ -#define NOPUSH_MASK_0 0xeeb4 -#define NOPUSH_MASK_1 0xf96b -#define NOPUSH_MASK_2 0xfbb6 -#define NOPUSH_MASK_3 0xfe64 -#define NOPUSH_MASK_4 0xffff -#define NOPUSH_MASK_5 0x6ef7 -#define NOPUSH_MASK_6 0xfbfb -#define NOPUSH_MASK_7 0x8767 -#define NOPUSH_MASK_8 0x7d9f -#define NOPUSH_MASK_9 0x0000 diff --git a/extensions/sqlite/sqlite-source/os.c b/extensions/sqlite/sqlite-source/os.c deleted file mode 100644 index 3b6ca7bc..00000000 --- a/extensions/sqlite/sqlite-source/os.c +++ /dev/null @@ -1,282 +0,0 @@ - /* -** 2005 November 29 -** -** 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 file contains OS interface code that is common to all -** architectures. -*/ -#define _SQLITE_OS_C_ 1 -#include "sqliteInt.h" -#undef _SQLITE_OS_C_ - -/* -** The default SQLite sqlite3_vfs implementations do not allocate -** memory (actually, os_unix.c allocates a small amount of memory -** from within OsOpen()), but some third-party implementations may. -** So we test the effects of a malloc() failing and the sqlite3OsXXX() -** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro. -** -** The following functions are instrumented for malloc() failure -** testing: -** -** sqlite3OsOpen() -** sqlite3OsRead() -** sqlite3OsWrite() -** sqlite3OsSync() -** sqlite3OsLock() -** -*/ -#ifdef SQLITE_TEST - #define DO_OS_MALLOC_TEST if (1) { \ - void *pTstAlloc = sqlite3_malloc(10); \ - if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ - sqlite3_free(pTstAlloc); \ - } -#else - #define DO_OS_MALLOC_TEST -#endif - -/* -** The following routines are convenience wrappers around methods -** of the sqlite3_file object. This is mostly just syntactic sugar. All -** of this would be completely automatic if SQLite were coded using -** C++ instead of plain old C. -*/ -int sqlite3OsClose(sqlite3_file *pId){ - int rc = SQLITE_OK; - if( pId->pMethods ){ - rc = pId->pMethods->xClose(pId); - pId->pMethods = 0; - } - return rc; -} -int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ - DO_OS_MALLOC_TEST; - return id->pMethods->xRead(id, pBuf, amt, offset); -} -int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ - DO_OS_MALLOC_TEST; - return id->pMethods->xWrite(id, pBuf, amt, offset); -} -int sqlite3OsTruncate(sqlite3_file *id, i64 size){ - return id->pMethods->xTruncate(id, size); -} -int sqlite3OsSync(sqlite3_file *id, int flags){ - DO_OS_MALLOC_TEST; - return id->pMethods->xSync(id, flags); -} -int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ - return id->pMethods->xFileSize(id, pSize); -} -int sqlite3OsLock(sqlite3_file *id, int lockType){ - DO_OS_MALLOC_TEST; - return id->pMethods->xLock(id, lockType); -} -int sqlite3OsUnlock(sqlite3_file *id, int lockType){ - return id->pMethods->xUnlock(id, lockType); -} -int sqlite3OsCheckReservedLock(sqlite3_file *id){ - return id->pMethods->xCheckReservedLock(id); -} -int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ - return id->pMethods->xFileControl(id,op,pArg); -} - -#ifdef SQLITE_TEST - /* The following two variables are used to override the values returned - ** by the xSectorSize() and xDeviceCharacteristics() vfs methods for - ** testing purposes. They are usually set by a test command implemented - ** in test6.c. - */ - int sqlite3_test_sector_size = 0; - int sqlite3_test_device_characteristics = 0; - int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ - int dc = id->pMethods->xDeviceCharacteristics(id); - return dc | sqlite3_test_device_characteristics; - } - int sqlite3OsSectorSize(sqlite3_file *id){ - if( sqlite3_test_sector_size==0 ){ - int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; - return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); - } - return sqlite3_test_sector_size; - } -#else - int sqlite3OsSectorSize(sqlite3_file *id){ - int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; - return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); - } - int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ - return id->pMethods->xDeviceCharacteristics(id); - } -#endif - -/* -** The next group of routines are convenience wrappers around the -** VFS methods. -*/ -int sqlite3OsOpen( - sqlite3_vfs *pVfs, - const char *zPath, - sqlite3_file *pFile, - int flags, - int *pFlagsOut -){ - DO_OS_MALLOC_TEST; - return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut); -} -int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ - return pVfs->xDelete(pVfs, zPath, dirSync); -} -int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ - return pVfs->xAccess(pVfs, zPath, flags); -} -int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){ - return pVfs->xGetTempname(pVfs, nBufOut, zBufOut); -} -int sqlite3OsFullPathname( - sqlite3_vfs *pVfs, - const char *zPath, - int nPathOut, - char *zPathOut -){ - return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); -} -void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ - return pVfs->xDlOpen(pVfs, zPath); -} -void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ - pVfs->xDlError(pVfs, nByte, zBufOut); -} -void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ - return pVfs->xDlSym(pVfs, pHandle, zSymbol); -} -void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ - pVfs->xDlClose(pVfs, pHandle); -} -int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ - return pVfs->xRandomness(pVfs, nByte, zBufOut); -} -int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ - return pVfs->xSleep(pVfs, nMicro); -} -int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ - return pVfs->xCurrentTime(pVfs, pTimeOut); -} - -int sqlite3OsOpenMalloc( - sqlite3_vfs *pVfs, - const char *zFile, - sqlite3_file **ppFile, - int flags, - int *pOutFlags -){ - int rc = SQLITE_NOMEM; - sqlite3_file *pFile; - pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile); - if( pFile ){ - rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); - if( rc!=SQLITE_OK ){ - sqlite3_free(pFile); - }else{ - *ppFile = pFile; - } - } - return rc; -} -int sqlite3OsCloseFree(sqlite3_file *pFile){ - int rc = SQLITE_OK; - if( pFile ){ - rc = sqlite3OsClose(pFile); - sqlite3_free(pFile); - } - return rc; -} - -/* -** The list of all registered VFS implementations. This list is -** initialized to the single VFS returned by sqlite3OsDefaultVfs() -** upon the first call to sqlite3_vfs_find(). -*/ -static sqlite3_vfs *vfsList = 0; - -/* -** Locate a VFS by name. If no name is given, simply return the -** first VFS on the list. -*/ -sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ - sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); - sqlite3_vfs *pVfs; - static int isInit = 0; - sqlite3_mutex_enter(mutex); - if( !isInit ){ - vfsList = sqlite3OsDefaultVfs(); - isInit = 1; - } - for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){ - if( zVfs==0 ) break; - if( strcmp(zVfs, pVfs->zName)==0 ) break; - } - sqlite3_mutex_leave(mutex); - return pVfs; -} - -/* -** Unlink a VFS from the linked list -*/ -static void vfsUnlink(sqlite3_vfs *pVfs){ - assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) ); - if( vfsList==pVfs ){ - vfsList = pVfs->pNext; - }else{ - sqlite3_vfs *p = vfsList; - while( p->pNext && p->pNext!=pVfs ){ - p = p->pNext; - } - if( p->pNext==pVfs ){ - p->pNext = pVfs->pNext; - } - } -} - -/* -** Register a VFS with the system. It is harmless to register the same -** VFS multiple times. The new VFS becomes the default if makeDflt is -** true. -*/ -int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ - sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); - sqlite3_vfs_find(0); /* Make sure we are initialized */ - sqlite3_mutex_enter(mutex); - vfsUnlink(pVfs); - if( makeDflt || vfsList==0 ){ - pVfs->pNext = vfsList; - vfsList = pVfs; - }else{ - pVfs->pNext = vfsList->pNext; - vfsList->pNext = pVfs; - } - assert(vfsList); - sqlite3_mutex_leave(mutex); - return SQLITE_OK; -} - -/* -** Unregister a VFS so that it is no longer accessible. -*/ -int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ - sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); - sqlite3_mutex_enter(mutex); - vfsUnlink(pVfs); - assert(vfsList); - sqlite3_mutex_leave(mutex); - return SQLITE_OK; -} diff --git a/extensions/sqlite/sqlite-source/os.h b/extensions/sqlite/sqlite-source/os.h deleted file mode 100644 index 554952df..00000000 --- a/extensions/sqlite/sqlite-source/os.h +++ /dev/null @@ -1,284 +0,0 @@ -/* -** 2001 September 16 -** -** 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 (together with is companion C source-code file -** "os.c") attempt to abstract the underlying operating system so that -** the SQLite library will work on both POSIX and windows systems. -** -** This header file is #include-ed by sqliteInt.h and thus ends up -** being included by every source file. -*/ -#ifndef _SQLITE_OS_H_ -#define _SQLITE_OS_H_ - -/* -** Figure out if we are dealing with Unix, Windows, or some other -** operating system. After the following block of preprocess macros, -** all of OS_UNIX, OS_WIN, OS_OS2, and OS_OTHER will defined to either -** 1 or 0. One of the four will be 1. The other three will be 0. -*/ -#if defined(OS_OTHER) -# if OS_OTHER==1 -# undef OS_UNIX -# define OS_UNIX 0 -# undef OS_WIN -# define OS_WIN 0 -# undef OS_OS2 -# define OS_OS2 0 -# else -# undef OS_OTHER -# endif -#endif -#if !defined(OS_UNIX) && !defined(OS_OTHER) -# define OS_OTHER 0 -# ifndef OS_WIN -# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) -# define OS_WIN 1 -# define OS_UNIX 0 -# define OS_OS2 0 -# elif defined(__EMX__) || defined(_OS2) || defined(OS2) || defined(_OS2_) || defined(__OS2__) -# define OS_WIN 0 -# define OS_UNIX 0 -# define OS_OS2 1 -# else -# define OS_WIN 0 -# define OS_UNIX 1 -# define OS_OS2 0 -# endif -# else -# define OS_UNIX 0 -# define OS_OS2 0 -# endif -#else -# ifndef OS_WIN -# define OS_WIN 0 -# endif -#endif - - - -/* -** Define the maximum size of a temporary filename -*/ -#if OS_WIN -# include -# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50) -#elif OS_OS2 -# if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY) -# include /* has to be included before os2.h for linking to work */ -# endif -# define INCL_DOSDATETIME -# define INCL_DOSFILEMGR -# define INCL_DOSERRORS -# define INCL_DOSMISC -# define INCL_DOSPROCESS -# define INCL_DOSMODULEMGR -# include -# define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP) -#else -# define SQLITE_TEMPNAME_SIZE 200 -#endif - -/* If the SET_FULLSYNC macro is not defined above, then make it -** a no-op -*/ -#ifndef SET_FULLSYNC -# define SET_FULLSYNC(x,y) -#endif - -/* -** The default size of a disk sector -*/ -#ifndef SQLITE_DEFAULT_SECTOR_SIZE -# define SQLITE_DEFAULT_SECTOR_SIZE 512 -#endif - -/* -** Temporary files are named starting with this prefix followed by 16 random -** alphanumeric characters, and no file extension. They are stored in the -** OS's standard temporary file directory, and are deleted prior to exit. -** If sqlite is being embedded in another program, you may wish to change the -** prefix to reflect your program's name, so that if your program exits -** prematurely, old temporary files can be easily identified. This can be done -** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. -** -** 2006-10-31: The default prefix used to be "sqlite_". But then -** Mcafee started using SQLite in their anti-virus product and it -** started putting files with the "sqlite" name in the c:/temp folder. -** This annoyed many windows users. Those users would then do a -** Google search for "sqlite", find the telephone numbers of the -** developers and call to wake them up at night and complain. -** For this reason, the default name prefix is changed to be "sqlite" -** spelled backwards. So the temp files are still identified, but -** anybody smart enough to figure out the code is also likely smart -** enough to know that calling the developer will not help get rid -** of the file. -*/ -#ifndef SQLITE_TEMP_FILE_PREFIX -# define SQLITE_TEMP_FILE_PREFIX "etilqs_" -#endif - -/* -** If using an alternative OS interface, then we must have an "os_other.h" -** header file available for that interface. Presumably the "os_other.h" -** header file contains #defines similar to those above. -*/ -#if OS_OTHER -# include "os_other.h" -#endif - - -/* -** The following values may be passed as the second argument to -** sqlite3OsLock(). The various locks exhibit the following semantics: -** -** SHARED: Any number of processes may hold a SHARED lock simultaneously. -** RESERVED: A single process may hold a RESERVED lock on a file at -** any time. Other processes may hold and obtain new SHARED locks. -** PENDING: A single process may hold a PENDING lock on a file at -** any one time. Existing SHARED locks may persist, but no new -** SHARED locks may be obtained by other processes. -** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. -** -** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a -** process that requests an EXCLUSIVE lock may actually obtain a PENDING -** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to -** sqlite3OsLock(). -*/ -#define NO_LOCK 0 -#define SHARED_LOCK 1 -#define RESERVED_LOCK 2 -#define PENDING_LOCK 3 -#define EXCLUSIVE_LOCK 4 - -/* -** File Locking Notes: (Mostly about windows but also some info for Unix) -** -** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because -** those functions are not available. So we use only LockFile() and -** UnlockFile(). -** -** LockFile() prevents not just writing but also reading by other processes. -** A SHARED_LOCK is obtained by locking a single randomly-chosen -** byte out of a specific range of bytes. The lock byte is obtained at -** random so two separate readers can probably access the file at the -** same time, unless they are unlucky and choose the same lock byte. -** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. -** There can only be one writer. A RESERVED_LOCK is obtained by locking -** a single byte of the file that is designated as the reserved lock byte. -** A PENDING_LOCK is obtained by locking a designated byte different from -** the RESERVED_LOCK byte. -** -** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, -** which means we can use reader/writer locks. When reader/writer locks -** are used, the lock is placed on the same range of bytes that is used -** for probabilistic locking in Win95/98/ME. Hence, the locking scheme -** will support two or more Win95 readers or two or more WinNT readers. -** But a single Win95 reader will lock out all WinNT readers and a single -** WinNT reader will lock out all other Win95 readers. -** -** The following #defines specify the range of bytes used for locking. -** SHARED_SIZE is the number of bytes available in the pool from which -** a random byte is selected for a shared lock. The pool of bytes for -** shared locks begins at SHARED_FIRST. -** -** These #defines are available in sqlite_aux.h so that adaptors for -** connecting SQLite to other operating systems can use the same byte -** ranges for locking. In particular, the same locking strategy and -** byte ranges are used for Unix. This leaves open the possiblity of having -** clients on win95, winNT, and unix all talking to the same shared file -** and all locking correctly. To do so would require that samba (or whatever -** tool is being used for file sharing) implements locks correctly between -** windows and unix. I'm guessing that isn't likely to happen, but by -** using the same locking range we are at least open to the possibility. -** -** Locking in windows is manditory. For this reason, we cannot store -** actual data in the bytes used for locking. The pager never allocates -** the pages involved in locking therefore. SHARED_SIZE is selected so -** that all locks will fit on a single page even at the minimum page size. -** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE -** is set high so that we don't have to allocate an unused page except -** for very large databases. But one should test the page skipping logic -** by setting PENDING_BYTE low and running the entire regression suite. -** -** Changing the value of PENDING_BYTE results in a subtly incompatible -** file format. Depending on how it is changed, you might not notice -** the incompatibility right away, even running a full regression test. -** The default location of PENDING_BYTE is the first byte past the -** 1GB boundary. -** -*/ -#ifndef SQLITE_TEST -#define PENDING_BYTE 0x40000000 /* First byte past the 1GB boundary */ -#else -extern unsigned int sqlite3_pending_byte; -#define PENDING_BYTE sqlite3_pending_byte -#endif - -#define RESERVED_BYTE (PENDING_BYTE+1) -#define SHARED_FIRST (PENDING_BYTE+2) -#define SHARED_SIZE 510 - -/* -** Functions for accessing sqlite3_file methods -*/ -int sqlite3OsClose(sqlite3_file*); -int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); -int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); -int sqlite3OsTruncate(sqlite3_file*, i64 size); -int sqlite3OsSync(sqlite3_file*, int); -int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); -int sqlite3OsLock(sqlite3_file*, int); -int sqlite3OsUnlock(sqlite3_file*, int); -int sqlite3OsCheckReservedLock(sqlite3_file *id); -int sqlite3OsFileControl(sqlite3_file*,int,void*); -int sqlite3OsSectorSize(sqlite3_file *id); -int sqlite3OsDeviceCharacteristics(sqlite3_file *id); - -/* -** Functions for accessing sqlite3_vfs methods -*/ -int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); -int sqlite3OsDelete(sqlite3_vfs *, const char *, int); -int sqlite3OsAccess(sqlite3_vfs *, const char *, int); -int sqlite3OsGetTempname(sqlite3_vfs *, int, char *); -int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); -void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); -void sqlite3OsDlError(sqlite3_vfs *, int, char *); -void *sqlite3OsDlSym(sqlite3_vfs *, void *, const char *); -void sqlite3OsDlClose(sqlite3_vfs *, void *); -int sqlite3OsRandomness(sqlite3_vfs *, int, char *); -int sqlite3OsSleep(sqlite3_vfs *, int); -int sqlite3OsCurrentTime(sqlite3_vfs *, double*); - -/* -** Convenience functions for opening and closing files using -** sqlite3_malloc() to obtain space for the file-handle structure. -*/ -int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); -int sqlite3OsCloseFree(sqlite3_file *); - -/* -** Each OS-specific backend defines an instance of the following -** structure for returning a pointer to its sqlite3_vfs. If OS_OTHER -** is defined (meaning that the application-defined OS interface layer -** is used) then there is no default VFS. The application must -** register one or more VFS structures using sqlite3_vfs_register() -** before attempting to use SQLite. -*/ -#if OS_UNIX || OS_WIN || OS_OS2 -sqlite3_vfs *sqlite3OsDefaultVfs(void); -#else -# define sqlite3OsDefaultVfs(X) 0 -#endif - -#endif /* _SQLITE_OS_H_ */ diff --git a/extensions/sqlite/sqlite-source/os_common.h b/extensions/sqlite/sqlite-source/os_common.h deleted file mode 100644 index 8de4be97..00000000 --- a/extensions/sqlite/sqlite-source/os_common.h +++ /dev/null @@ -1,127 +0,0 @@ -/* -** 2004 May 22 -** -** 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 file contains macros and a little bit of code that is common to -** all of the platform-specific files (os_*.c) and is #included into those -** files. -** -** This file should be #included by the os_*.c files only. It is not a -** general purpose header file. -*/ - -/* -** At least two bugs have slipped in because we changed the MEMORY_DEBUG -** macro to SQLITE_DEBUG and some older makefiles have not yet made the -** switch. The following code should catch this problem at compile-time. -*/ -#ifdef MEMORY_DEBUG -# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." -#endif - - -/* - * When testing, this global variable stores the location of the - * pending-byte in the database file. - */ -#ifdef SQLITE_TEST -unsigned int sqlite3_pending_byte = 0x40000000; -#endif - -#ifdef SQLITE_DEBUG -int sqlite3_os_trace = 0; -#define OSTRACE1(X) if( sqlite3_os_trace ) sqlite3DebugPrintf(X) -#define OSTRACE2(X,Y) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y) -#define OSTRACE3(X,Y,Z) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z) -#define OSTRACE4(X,Y,Z,A) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A) -#define OSTRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B) -#define OSTRACE6(X,Y,Z,A,B,C) \ - if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C) -#define OSTRACE7(X,Y,Z,A,B,C,D) \ - if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D) -#else -#define OSTRACE1(X) -#define OSTRACE2(X,Y) -#define OSTRACE3(X,Y,Z) -#define OSTRACE4(X,Y,Z,A) -#define OSTRACE5(X,Y,Z,A,B) -#define OSTRACE6(X,Y,Z,A,B,C) -#define OSTRACE7(X,Y,Z,A,B,C,D) -#endif - -/* -** Macros for performance tracing. Normally turned off. Only works -** on i486 hardware. -*/ -#ifdef SQLITE_PERFORMANCE_TRACE -__inline__ unsigned long long int hwtime(void){ - unsigned long long int x; - __asm__("rdtsc\n\t" - "mov %%edx, %%ecx\n\t" - :"=A" (x)); - return x; -} -static unsigned long long int g_start; -static unsigned int elapse; -#define TIMER_START g_start=hwtime() -#define TIMER_END elapse=hwtime()-g_start -#define TIMER_ELAPSED elapse -#else -#define TIMER_START -#define TIMER_END -#define TIMER_ELAPSED 0 -#endif - -/* -** If we compile with the SQLITE_TEST macro set, then the following block -** of code will give us the ability to simulate a disk I/O error. This -** is used for testing the I/O recovery logic. -*/ -#ifdef SQLITE_TEST -int sqlite3_io_error_hit = 0; -int sqlite3_io_error_pending = 0; -int sqlite3_io_error_persist = 0; -int sqlite3_diskfull_pending = 0; -int sqlite3_diskfull = 0; -#define SimulateIOError(CODE) \ - if( sqlite3_io_error_pending || sqlite3_io_error_hit ) \ - if( sqlite3_io_error_pending-- == 1 \ - || (sqlite3_io_error_persist && sqlite3_io_error_hit) ) \ - { local_ioerr(); CODE; } -static void local_ioerr(){ - IOTRACE(("IOERR\n")); - sqlite3_io_error_hit = 1; -} -#define SimulateDiskfullError(CODE) \ - if( sqlite3_diskfull_pending ){ \ - if( sqlite3_diskfull_pending == 1 ){ \ - local_ioerr(); \ - sqlite3_diskfull = 1; \ - sqlite3_io_error_hit = 1; \ - CODE; \ - }else{ \ - sqlite3_diskfull_pending--; \ - } \ - } -#else -#define SimulateIOError(A) -#define SimulateDiskfullError(A) -#endif - -/* -** When testing, keep a count of the number of open files. -*/ -#ifdef SQLITE_TEST -int sqlite3_open_file_count = 0; -#define OpenCounter(X) sqlite3_open_file_count+=(X) -#else -#define OpenCounter(X) -#endif diff --git a/extensions/sqlite/sqlite-source/os_unix.c b/extensions/sqlite/sqlite-source/os_unix.c deleted file mode 100644 index e95435e7..00000000 --- a/extensions/sqlite/sqlite-source/os_unix.c +++ /dev/null @@ -1,2749 +0,0 @@ -/* -** 2004 May 22 -** -** 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 file contains code that is specific to Unix systems. -*/ -#include "sqliteInt.h" -#if OS_UNIX /* This file is used on unix only */ - -/* #define SQLITE_ENABLE_LOCKING_STYLE 0 */ - -/* -** These #defines should enable >2GB file support on Posix if the -** underlying operating system supports it. If the OS lacks -** large file support, these should be no-ops. -** -** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch -** on the compiler command line. This is necessary if you are compiling -** on a recent machine (ex: RedHat 7.2) but you want your code to work -** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2 -** without this option, LFS is enable. But LFS does not exist in the kernel -** in RedHat 6.0, so the code won't work. Hence, for maximum binary -** portability you should omit LFS. -*/ -#ifndef SQLITE_DISABLE_LFS -# define _LARGE_FILE 1 -# ifndef _FILE_OFFSET_BITS -# define _FILE_OFFSET_BITS 64 -# endif -# define _LARGEFILE_SOURCE 1 -#endif - -/* -** standard include files. -*/ -#include -#include -#include -#include -#include -#include -#include -#ifdef SQLITE_ENABLE_LOCKING_STYLE -#include -#include -#include -#endif /* SQLITE_ENABLE_LOCKING_STYLE */ - -/* -** If we are to be thread-safe, include the pthreads header and define -** the SQLITE_UNIX_THREADS macro. -*/ -#if SQLITE_THREADSAFE -# include -# define SQLITE_UNIX_THREADS 1 -#endif - -/* -** Default permissions when creating a new file -*/ -#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS -# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 -#endif - -/* -** Maximum supported path-length. -*/ -#define MAX_PATHNAME 512 - - -/* -** The unixFile structure is subclass of sqlite3_file specific for the unix -** protability layer. -*/ -typedef struct unixFile unixFile; -struct unixFile { - sqlite3_io_methods const *pMethod; /* Always the first entry */ -#ifdef SQLITE_TEST - /* In test mode, increase the size of this structure a bit so that - ** it is larger than the struct CrashFile defined in test6.c. - */ - char aPadding[32]; -#endif - struct openCnt *pOpen; /* Info about all open fd's on this inode */ - struct lockInfo *pLock; /* Info about locks on this inode */ -#ifdef SQLITE_ENABLE_LOCKING_STYLE - void *lockingContext; /* Locking style specific state */ -#endif /* SQLITE_ENABLE_LOCKING_STYLE */ - int h; /* The file descriptor */ - unsigned char locktype; /* The type of lock held on this fd */ - int dirfd; /* File descriptor for the directory */ -#if SQLITE_THREADSAFE - pthread_t tid; /* The thread that "owns" this unixFile */ -#endif -}; - -/* -** Include code that is common to all os_*.c files -*/ -#include "os_common.h" - -/* -** Define various macros that are missing from some systems. -*/ -#ifndef O_LARGEFILE -# define O_LARGEFILE 0 -#endif -#ifdef SQLITE_DISABLE_LFS -# undef O_LARGEFILE -# define O_LARGEFILE 0 -#endif -#ifndef O_NOFOLLOW -# define O_NOFOLLOW 0 -#endif -#ifndef O_BINARY -# define O_BINARY 0 -#endif - -/* -** The DJGPP compiler environment looks mostly like Unix, but it -** lacks the fcntl() system call. So redefine fcntl() to be something -** that always succeeds. This means that locking does not occur under -** DJGPP. But it's DOS - what did you expect? -*/ -#ifdef __DJGPP__ -# define fcntl(A,B,C) 0 -#endif - -/* -** The threadid macro resolves to the thread-id or to 0. Used for -** testing and debugging only. -*/ -#if SQLITE_THREADSAFE -#define threadid pthread_self() -#else -#define threadid 0 -#endif - -/* -** Set or check the unixFile.tid field. This field is set when an unixFile -** is first opened. All subsequent uses of the unixFile verify that the -** same thread is operating on the unixFile. Some operating systems do -** not allow locks to be overridden by other threads and that restriction -** means that sqlite3* database handles cannot be moved from one thread -** to another. This logic makes sure a user does not try to do that -** by mistake. -** -** Version 3.3.1 (2006-01-15): unixFile can be moved from one thread to -** another as long as we are running on a system that supports threads -** overriding each others locks (which now the most common behavior) -** or if no locks are held. But the unixFile.pLock field needs to be -** recomputed because its key includes the thread-id. See the -** transferOwnership() function below for additional information -*/ -#if SQLITE_THREADSAFE -# define SET_THREADID(X) (X)->tid = pthread_self() -# define CHECK_THREADID(X) (threadsOverrideEachOthersLocks==0 && \ - !pthread_equal((X)->tid, pthread_self())) -#else -# define SET_THREADID(X) -# define CHECK_THREADID(X) 0 -#endif - -/* -** Here is the dirt on POSIX advisory locks: ANSI STD 1003.1 (1996) -** section 6.5.2.2 lines 483 through 490 specify that when a process -** sets or clears a lock, that operation overrides any prior locks set -** by the same process. It does not explicitly say so, but this implies -** that it overrides locks set by the same process using a different -** file descriptor. Consider this test case: -** -** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644); -** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644); -** -** Suppose ./file1 and ./file2 are really the same file (because -** one is a hard or symbolic link to the other) then if you set -** an exclusive lock on fd1, then try to get an exclusive lock -** on fd2, it works. I would have expected the second lock to -** fail since there was already a lock on the file due to fd1. -** But not so. Since both locks came from the same process, the -** second overrides the first, even though they were on different -** file descriptors opened on different file names. -** -** Bummer. If you ask me, this is broken. Badly broken. It means -** that we cannot use POSIX locks to synchronize file access among -** competing threads of the same process. POSIX locks will work fine -** to synchronize access for threads in separate processes, but not -** threads within the same process. -** -** To work around the problem, SQLite has to manage file locks internally -** on its own. Whenever a new database is opened, we have to find the -** specific inode of the database file (the inode is determined by the -** st_dev and st_ino fields of the stat structure that fstat() fills in) -** and check for locks already existing on that inode. When locks are -** created or removed, we have to look at our own internal record of the -** locks to see if another thread has previously set a lock on that same -** inode. -** -** The sqlite3_file structure for POSIX is no longer just an integer file -** descriptor. It is now a structure that holds the integer file -** descriptor and a pointer to a structure that describes the internal -** locks on the corresponding inode. There is one locking structure -** per inode, so if the same inode is opened twice, both unixFile structures -** point to the same locking structure. The locking structure keeps -** a reference count (so we will know when to delete it) and a "cnt" -** field that tells us its internal lock status. cnt==0 means the -** file is unlocked. cnt==-1 means the file has an exclusive lock. -** cnt>0 means there are cnt shared locks on the file. -** -** Any attempt to lock or unlock a file first checks the locking -** structure. The fcntl() system call is only invoked to set a -** POSIX lock if the internal lock structure transitions between -** a locked and an unlocked state. -** -** 2004-Jan-11: -** More recent discoveries about POSIX advisory locks. (The more -** I discover, the more I realize the a POSIX advisory locks are -** an abomination.) -** -** If you close a file descriptor that points to a file that has locks, -** all locks on that file that are owned by the current process are -** released. To work around this problem, each unixFile structure contains -** a pointer to an openCnt structure. There is one openCnt structure -** per open inode, which means that multiple unixFile can point to a single -** openCnt. When an attempt is made to close an unixFile, if there are -** other unixFile open on the same inode that are holding locks, the call -** to close() the file descriptor is deferred until all of the locks clear. -** The openCnt structure keeps a list of file descriptors that need to -** be closed and that list is walked (and cleared) when the last lock -** clears. -** -** First, under Linux threads, because each thread has a separate -** process ID, lock operations in one thread do not override locks -** to the same file in other threads. Linux threads behave like -** separate processes in this respect. But, if you close a file -** descriptor in linux threads, all locks are cleared, even locks -** on other threads and even though the other threads have different -** process IDs. Linux threads is inconsistent in this respect. -** (I'm beginning to think that linux threads is an abomination too.) -** The consequence of this all is that the hash table for the lockInfo -** structure has to include the process id as part of its key because -** locks in different threads are treated as distinct. But the -** openCnt structure should not include the process id in its -** key because close() clears lock on all threads, not just the current -** thread. Were it not for this goofiness in linux threads, we could -** combine the lockInfo and openCnt structures into a single structure. -** -** 2004-Jun-28: -** On some versions of linux, threads can override each others locks. -** On others not. Sometimes you can change the behavior on the same -** system by setting the LD_ASSUME_KERNEL environment variable. The -** POSIX standard is silent as to which behavior is correct, as far -** as I can tell, so other versions of unix might show the same -** inconsistency. There is no little doubt in my mind that posix -** advisory locks and linux threads are profoundly broken. -** -** To work around the inconsistencies, we have to test at runtime -** whether or not threads can override each others locks. This test -** is run once, the first time any lock is attempted. A static -** variable is set to record the results of this test for future -** use. -*/ - -/* -** An instance of the following structure serves as the key used -** to locate a particular lockInfo structure given its inode. -** -** If threads cannot override each others locks, then we set the -** lockKey.tid field to the thread ID. If threads can override -** each others locks then tid is always set to zero. tid is omitted -** if we compile without threading support. -*/ -struct lockKey { - dev_t dev; /* Device number */ - ino_t ino; /* Inode number */ -#if SQLITE_THREADSAFE - pthread_t tid; /* Thread ID or zero if threads can override each other */ -#endif -}; - -/* -** An instance of the following structure is allocated for each open -** inode on each thread with a different process ID. (Threads have -** different process IDs on linux, but not on most other unixes.) -** -** A single inode can have multiple file descriptors, so each unixFile -** structure contains a pointer to an instance of this object and this -** object keeps a count of the number of unixFile pointing to it. -*/ -struct lockInfo { - struct lockKey key; /* The lookup key */ - int cnt; /* Number of SHARED locks held */ - int locktype; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ - int nRef; /* Number of pointers to this structure */ -}; - -/* -** An instance of the following structure serves as the key used -** to locate a particular openCnt structure given its inode. This -** is the same as the lockKey except that the thread ID is omitted. -*/ -struct openKey { - dev_t dev; /* Device number */ - ino_t ino; /* Inode number */ -}; - -/* -** An instance of the following structure is allocated for each open -** inode. This structure keeps track of the number of locks on that -** inode. If a close is attempted against an inode that is holding -** locks, the close is deferred until all locks clear by adding the -** file descriptor to be closed to the pending list. -*/ -struct openCnt { - struct openKey key; /* The lookup key */ - int nRef; /* Number of pointers to this structure */ - int nLock; /* Number of outstanding locks */ - int nPending; /* Number of pending close() operations */ - int *aPending; /* Malloced space holding fd's awaiting a close() */ -}; - -/* -** These hash tables map inodes and file descriptors (really, lockKey and -** openKey structures) into lockInfo and openCnt structures. Access to -** these hash tables must be protected by a mutex. -*/ -static Hash lockHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0}; -static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0}; - -#ifdef SQLITE_ENABLE_LOCKING_STYLE -/* -** The locking styles are associated with the different file locking -** capabilities supported by different file systems. -** -** POSIX locking style fully supports shared and exclusive byte-range locks -** ADP locking only supports exclusive byte-range locks -** FLOCK only supports a single file-global exclusive lock -** DOTLOCK isn't a true locking style, it refers to the use of a special -** file named the same as the database file with a '.lock' extension, this -** can be used on file systems that do not offer any reliable file locking -** NO locking means that no locking will be attempted, this is only used for -** read-only file systems currently -** UNSUPPORTED means that no locking will be attempted, this is only used for -** file systems that are known to be unsupported -*/ -typedef enum { - posixLockingStyle = 0, /* standard posix-advisory locks */ - afpLockingStyle, /* use afp locks */ - flockLockingStyle, /* use flock() */ - dotlockLockingStyle, /* use .lock files */ - noLockingStyle, /* useful for read-only file system */ - unsupportedLockingStyle /* indicates unsupported file system */ -} sqlite3LockingStyle; -#endif /* SQLITE_ENABLE_LOCKING_STYLE */ - -/* -** Helper functions to obtain and relinquish the global mutex. -*/ -static void enterMutex(){ - sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); -} -static void leaveMutex(){ - sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); -} - -#if SQLITE_THREADSAFE -/* -** This variable records whether or not threads can override each others -** locks. -** -** 0: No. Threads cannot override each others locks. -** 1: Yes. Threads can override each others locks. -** -1: We don't know yet. -** -** On some systems, we know at compile-time if threads can override each -** others locks. On those systems, the SQLITE_THREAD_OVERRIDE_LOCK macro -** will be set appropriately. On other systems, we have to check at -** runtime. On these latter systems, SQLTIE_THREAD_OVERRIDE_LOCK is -** undefined. -** -** This variable normally has file scope only. But during testing, we make -** it a global so that the test code can change its value in order to verify -** that the right stuff happens in either case. -*/ -#ifndef SQLITE_THREAD_OVERRIDE_LOCK -# define SQLITE_THREAD_OVERRIDE_LOCK -1 -#endif -#ifdef SQLITE_TEST -int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK; -#else -static int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK; -#endif - -/* -** This structure holds information passed into individual test -** threads by the testThreadLockingBehavior() routine. -*/ -struct threadTestData { - int fd; /* File to be locked */ - struct flock lock; /* The locking operation */ - int result; /* Result of the locking operation */ -}; - -#ifdef SQLITE_LOCK_TRACE -/* -** Print out information about all locking operations. -** -** This routine is used for troubleshooting locks on multithreaded -** platforms. Enable by compiling with the -DSQLITE_LOCK_TRACE -** command-line option on the compiler. This code is normally -** turned off. -*/ -static int lockTrace(int fd, int op, struct flock *p){ - char *zOpName, *zType; - int s; - int savedErrno; - if( op==F_GETLK ){ - zOpName = "GETLK"; - }else if( op==F_SETLK ){ - zOpName = "SETLK"; - }else{ - s = fcntl(fd, op, p); - sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s); - return s; - } - if( p->l_type==F_RDLCK ){ - zType = "RDLCK"; - }else if( p->l_type==F_WRLCK ){ - zType = "WRLCK"; - }else if( p->l_type==F_UNLCK ){ - zType = "UNLCK"; - }else{ - assert( 0 ); - } - assert( p->l_whence==SEEK_SET ); - s = fcntl(fd, op, p); - savedErrno = errno; - sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n", - threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len, - (int)p->l_pid, s); - if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ - struct flock l2; - l2 = *p; - fcntl(fd, F_GETLK, &l2); - if( l2.l_type==F_RDLCK ){ - zType = "RDLCK"; - }else if( l2.l_type==F_WRLCK ){ - zType = "WRLCK"; - }else if( l2.l_type==F_UNLCK ){ - zType = "UNLCK"; - }else{ - assert( 0 ); - } - sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n", - zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid); - } - errno = savedErrno; - return s; -} -#define fcntl lockTrace -#endif /* SQLITE_LOCK_TRACE */ - -/* -** The testThreadLockingBehavior() routine launches two separate -** threads on this routine. This routine attempts to lock a file -** descriptor then returns. The success or failure of that attempt -** allows the testThreadLockingBehavior() procedure to determine -** whether or not threads can override each others locks. -*/ -static void *threadLockingTest(void *pArg){ - struct threadTestData *pData = (struct threadTestData*)pArg; - pData->result = fcntl(pData->fd, F_SETLK, &pData->lock); - return pArg; -} - -/* -** This procedure attempts to determine whether or not threads -** can override each others locks then sets the -** threadsOverrideEachOthersLocks variable appropriately. -*/ -static void testThreadLockingBehavior(int fd_orig){ - int fd; - struct threadTestData d[2]; - pthread_t t[2]; - - fd = dup(fd_orig); - if( fd<0 ) return; - memset(d, 0, sizeof(d)); - d[0].fd = fd; - d[0].lock.l_type = F_RDLCK; - d[0].lock.l_len = 1; - d[0].lock.l_start = 0; - d[0].lock.l_whence = SEEK_SET; - d[1] = d[0]; - d[1].lock.l_type = F_WRLCK; - pthread_create(&t[0], 0, threadLockingTest, &d[0]); - pthread_create(&t[1], 0, threadLockingTest, &d[1]); - pthread_join(t[0], 0); - pthread_join(t[1], 0); - close(fd); - threadsOverrideEachOthersLocks = d[0].result==0 && d[1].result==0; -} -#endif /* SQLITE_THREADSAFE */ - -/* -** Release a lockInfo structure previously allocated by findLockInfo(). -*/ -static void releaseLockInfo(struct lockInfo *pLock){ - if (pLock == NULL) - return; - pLock->nRef--; - if( pLock->nRef==0 ){ - sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0); - sqlite3_free(pLock); - } -} - -/* -** Release a openCnt structure previously allocated by findLockInfo(). -*/ -static void releaseOpenCnt(struct openCnt *pOpen){ - if (pOpen == NULL) - return; - pOpen->nRef--; - if( pOpen->nRef==0 ){ - sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0); - free(pOpen->aPending); - sqlite3_free(pOpen); - } -} - -#ifdef SQLITE_ENABLE_LOCKING_STYLE -/* -** Tests a byte-range locking query to see if byte range locks are -** supported, if not we fall back to dotlockLockingStyle. -*/ -static sqlite3LockingStyle sqlite3TestLockingStyle( - const char *filePath, - int fd -){ - /* test byte-range lock using fcntl */ - struct flock lockInfo; - - lockInfo.l_len = 1; - lockInfo.l_start = 0; - lockInfo.l_whence = SEEK_SET; - lockInfo.l_type = F_RDLCK; - - if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) { - return posixLockingStyle; - } - - /* testing for flock can give false positives. So if if the above test - ** fails, then we fall back to using dot-lock style locking. - */ - return dotlockLockingStyle; -} - -/* -** Examines the f_fstypename entry in the statfs structure as returned by -** stat() for the file system hosting the database file, assigns the -** appropriate locking style based on it's value. These values and -** assignments are based on Darwin/OSX behavior and have not been tested on -** other systems. -*/ -static sqlite3LockingStyle sqlite3DetectLockingStyle( - const char *filePath, - int fd -){ - -#ifdef SQLITE_FIXED_LOCKING_STYLE - return (sqlite3LockingStyle)SQLITE_FIXED_LOCKING_STYLE; -#else - struct statfs fsInfo; - - if (statfs(filePath, &fsInfo) == -1) - return sqlite3TestLockingStyle(filePath, fd); - - if (fsInfo.f_flags & MNT_RDONLY) - return noLockingStyle; - - if( (!strcmp(fsInfo.f_fstypename, "hfs")) || - (!strcmp(fsInfo.f_fstypename, "ufs")) ) - return posixLockingStyle; - - if(!strcmp(fsInfo.f_fstypename, "afpfs")) - return afpLockingStyle; - - if(!strcmp(fsInfo.f_fstypename, "nfs")) - return sqlite3TestLockingStyle(filePath, fd); - - if(!strcmp(fsInfo.f_fstypename, "smbfs")) - return flockLockingStyle; - - if(!strcmp(fsInfo.f_fstypename, "msdos")) - return dotlockLockingStyle; - - if(!strcmp(fsInfo.f_fstypename, "webdav")) - return unsupportedLockingStyle; - - return sqlite3TestLockingStyle(filePath, fd); -#endif /* SQLITE_FIXED_LOCKING_STYLE */ -} - -#endif /* SQLITE_ENABLE_LOCKING_STYLE */ - -/* -** Given a file descriptor, locate lockInfo and openCnt structures that -** describes that file descriptor. Create new ones if necessary. The -** return values might be uninitialized if an error occurs. -** -** Return the number of errors. -*/ -static int findLockInfo( - int fd, /* The file descriptor used in the key */ - struct lockInfo **ppLock, /* Return the lockInfo structure here */ - struct openCnt **ppOpen /* Return the openCnt structure here */ -){ - int rc; - struct lockKey key1; - struct openKey key2; - struct stat statbuf; - struct lockInfo *pLock; - struct openCnt *pOpen; - rc = fstat(fd, &statbuf); - if( rc!=0 ) return 1; - - memset(&key1, 0, sizeof(key1)); - key1.dev = statbuf.st_dev; - key1.ino = statbuf.st_ino; -#if SQLITE_THREADSAFE - if( threadsOverrideEachOthersLocks<0 ){ - testThreadLockingBehavior(fd); - } - key1.tid = threadsOverrideEachOthersLocks ? 0 : pthread_self(); -#endif - memset(&key2, 0, sizeof(key2)); - key2.dev = statbuf.st_dev; - key2.ino = statbuf.st_ino; - pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1)); - if( pLock==0 ){ - struct lockInfo *pOld; - pLock = sqlite3_malloc( sizeof(*pLock) ); - if( pLock==0 ){ - rc = 1; - goto exit_findlockinfo; - } - pLock->key = key1; - pLock->nRef = 1; - pLock->cnt = 0; - pLock->locktype = 0; - pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock); - if( pOld!=0 ){ - assert( pOld==pLock ); - sqlite3_free(pLock); - rc = 1; - goto exit_findlockinfo; - } - }else{ - pLock->nRef++; - } - *ppLock = pLock; - if( ppOpen!=0 ){ - pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2)); - if( pOpen==0 ){ - struct openCnt *pOld; - pOpen = sqlite3_malloc( sizeof(*pOpen) ); - if( pOpen==0 ){ - releaseLockInfo(pLock); - rc = 1; - goto exit_findlockinfo; - } - pOpen->key = key2; - pOpen->nRef = 1; - pOpen->nLock = 0; - pOpen->nPending = 0; - pOpen->aPending = 0; - pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen); - if( pOld!=0 ){ - assert( pOld==pOpen ); - sqlite3_free(pOpen); - releaseLockInfo(pLock); - rc = 1; - goto exit_findlockinfo; - } - }else{ - pOpen->nRef++; - } - *ppOpen = pOpen; - } - -exit_findlockinfo: - return rc; -} - -#ifdef SQLITE_DEBUG -/* -** Helper function for printing out trace information from debugging -** binaries. This returns the string represetation of the supplied -** integer lock-type. -*/ -static const char *locktypeName(int locktype){ - switch( locktype ){ - case NO_LOCK: return "NONE"; - case SHARED_LOCK: return "SHARED"; - case RESERVED_LOCK: return "RESERVED"; - case PENDING_LOCK: return "PENDING"; - case EXCLUSIVE_LOCK: return "EXCLUSIVE"; - } - return "ERROR"; -} -#endif - -/* -** If we are currently in a different thread than the thread that the -** unixFile argument belongs to, then transfer ownership of the unixFile -** over to the current thread. -** -** A unixFile is only owned by a thread on systems where one thread is -** unable to override locks created by a different thread. RedHat9 is -** an example of such a system. -** -** Ownership transfer is only allowed if the unixFile is currently unlocked. -** If the unixFile is locked and an ownership is wrong, then return -** SQLITE_MISUSE. SQLITE_OK is returned if everything works. -*/ -#if SQLITE_THREADSAFE -static int transferOwnership(unixFile *pFile){ - int rc; - pthread_t hSelf; - if( threadsOverrideEachOthersLocks ){ - /* Ownership transfers not needed on this system */ - return SQLITE_OK; - } - hSelf = pthread_self(); - if( pthread_equal(pFile->tid, hSelf) ){ - /* We are still in the same thread */ - OSTRACE1("No-transfer, same thread\n"); - return SQLITE_OK; - } - if( pFile->locktype!=NO_LOCK ){ - /* We cannot change ownership while we are holding a lock! */ - return SQLITE_MISUSE; - } - OSTRACE4("Transfer ownership of %d from %d to %d\n", - pFile->h, pFile->tid, hSelf); - pFile->tid = hSelf; - if (pFile->pLock != NULL) { - releaseLockInfo(pFile->pLock); - rc = findLockInfo(pFile->h, &pFile->pLock, 0); - OSTRACE5("LOCK %d is now %s(%s,%d)\n", pFile->h, - locktypeName(pFile->locktype), - locktypeName(pFile->pLock->locktype), pFile->pLock->cnt); - return rc; - } else { - return SQLITE_OK; - } -} -#else - /* On single-threaded builds, ownership transfer is a no-op */ -# define transferOwnership(X) SQLITE_OK -#endif - -/* -** Seek to the offset passed as the second argument, then read cnt -** bytes into pBuf. Return the number of bytes actually read. -*/ -static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ - int got; - i64 newOffset; - TIMER_START; -#if defined(USE_PREAD) - got = pread(id->h, pBuf, cnt, offset); - SimulateIOError( got = -1 ); -#elif defined(USE_PREAD64) - got = pread64(id->h, pBuf, cnt, offset); - SimulateIOError( got = -1 ); -#else - newOffset = lseek(id->h, offset, SEEK_SET); - SimulateIOError( newOffset-- ); - if( newOffset!=offset ){ - return -1; - } - got = read(id->h, pBuf, cnt); -#endif - TIMER_END; - OSTRACE5("READ %-3d %5d %7lld %d\n", id->h, got, offset, TIMER_ELAPSED); - return got; -} - -/* -** Read data from a file into a buffer. Return SQLITE_OK if all -** bytes were read successfully and SQLITE_IOERR if anything goes -** wrong. -*/ -static int unixRead( - sqlite3_file *id, - void *pBuf, - int amt, - sqlite3_int64 offset -){ - int got; - assert( id ); - got = seekAndRead((unixFile*)id, offset, pBuf, amt); - if( got==amt ){ - return SQLITE_OK; - }else if( got<0 ){ - return SQLITE_IOERR_READ; - }else{ - memset(&((char*)pBuf)[got], 0, amt-got); - return SQLITE_IOERR_SHORT_READ; - } -} - -/* -** Seek to the offset in id->offset then read cnt bytes into pBuf. -** Return the number of bytes actually read. Update the offset. -*/ -static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ - int got; - i64 newOffset; - TIMER_START; -#if defined(USE_PREAD) - got = pwrite(id->h, pBuf, cnt, offset); -#elif defined(USE_PREAD64) - got = pwrite64(id->h, pBuf, cnt, offset); -#else - newOffset = lseek(id->h, offset, SEEK_SET); - if( newOffset!=offset ){ - return -1; - } - got = write(id->h, pBuf, cnt); -#endif - TIMER_END; - OSTRACE5("WRITE %-3d %5d %7lld %d\n", id->h, got, offset, TIMER_ELAPSED); - return got; -} - - -/* -** Write data from a buffer into a file. Return SQLITE_OK on success -** or some other error code on failure. -*/ -static int unixWrite( - sqlite3_file *id, - const void *pBuf, - int amt, - sqlite3_int64 offset -){ - int wrote = 0; - assert( id ); - assert( amt>0 ); - while( amt>0 && (wrote = seekAndWrite((unixFile*)id, offset, pBuf, amt))>0 ){ - amt -= wrote; - offset += wrote; - pBuf = &((char*)pBuf)[wrote]; - } - SimulateIOError(( wrote=(-1), amt=1 )); - SimulateDiskfullError(( wrote=0, amt=1 )); - if( amt>0 ){ - if( wrote<0 ){ - return SQLITE_IOERR_WRITE; - }else{ - return SQLITE_FULL; - } - } - return SQLITE_OK; -} - -#ifdef SQLITE_TEST -/* -** Count the number of fullsyncs and normal syncs. This is used to test -** that syncs and fullsyncs are occuring at the right times. -*/ -int sqlite3_sync_count = 0; -int sqlite3_fullsync_count = 0; -#endif - -/* -** Use the fdatasync() API only if the HAVE_FDATASYNC macro is defined. -** Otherwise use fsync() in its place. -*/ -#ifndef HAVE_FDATASYNC -# define fdatasync fsync -#endif - -/* -** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not -** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently -** only available on Mac OS X. But that could change. -*/ -#ifdef F_FULLFSYNC -# define HAVE_FULLFSYNC 1 -#else -# define HAVE_FULLFSYNC 0 -#endif - - -/* -** The fsync() system call does not work as advertised on many -** unix systems. The following procedure is an attempt to make -** it work better. -** -** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful -** for testing when we want to run through the test suite quickly. -** You are strongly advised *not* to deploy with SQLITE_NO_SYNC -** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash -** or power failure will likely corrupt the database file. -*/ -static int full_fsync(int fd, int fullSync, int dataOnly){ - int rc; - - /* Record the number of times that we do a normal fsync() and - ** FULLSYNC. This is used during testing to verify that this procedure - ** gets called with the correct arguments. - */ -#ifdef SQLITE_TEST - if( fullSync ) sqlite3_fullsync_count++; - sqlite3_sync_count++; -#endif - - /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a - ** no-op - */ -#ifdef SQLITE_NO_SYNC - rc = SQLITE_OK; -#else - -#if HAVE_FULLFSYNC - if( fullSync ){ - rc = fcntl(fd, F_FULLFSYNC, 0); - }else{ - rc = 1; - } - /* If the FULLFSYNC failed, fall back to attempting an fsync(). - * It shouldn't be possible for fullfsync to fail on the local - * file system (on OSX), so failure indicates that FULLFSYNC - * isn't supported for this file system. So, attempt an fsync - * and (for now) ignore the overhead of a superfluous fcntl call. - * It'd be better to detect fullfsync support once and avoid - * the fcntl call every time sync is called. - */ - if( rc ) rc = fsync(fd); - -#else - if( dataOnly ){ - rc = fdatasync(fd); - }else{ - rc = fsync(fd); - } -#endif /* HAVE_FULLFSYNC */ -#endif /* defined(SQLITE_NO_SYNC) */ - - return rc; -} - -/* -** Make sure all writes to a particular file are committed to disk. -** -** If dataOnly==0 then both the file itself and its metadata (file -** size, access time, etc) are synced. If dataOnly!=0 then only the -** file data is synced. -** -** Under Unix, also make sure that the directory entry for the file -** has been created by fsync-ing the directory that contains the file. -** If we do not do this and we encounter a power failure, the directory -** entry for the journal might not exist after we reboot. The next -** SQLite to access the file will not know that the journal exists (because -** the directory entry for the journal was never created) and the transaction -** will not roll back - possibly leading to database corruption. -*/ -static int unixSync(sqlite3_file *id, int flags){ - int rc; - unixFile *pFile = (unixFile*)id; - - int isDataOnly = (flags&SQLITE_SYNC_DATAONLY); - int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL; - - /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ - assert((flags&0x0F)==SQLITE_SYNC_NORMAL - || (flags&0x0F)==SQLITE_SYNC_FULL - ); - - assert( pFile ); - OSTRACE2("SYNC %-3d\n", pFile->h); - rc = full_fsync(pFile->h, isFullsync, isDataOnly); - SimulateIOError( rc=1 ); - if( rc ){ - return SQLITE_IOERR_FSYNC; - } - if( pFile->dirfd>=0 ){ - OSTRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd, - HAVE_FULLFSYNC, isFullsync); -#ifndef SQLITE_DISABLE_DIRSYNC - /* The directory sync is only attempted if full_fsync is - ** turned off or unavailable. If a full_fsync occurred above, - ** then the directory sync is superfluous. - */ - if( (!HAVE_FULLFSYNC || !isFullsync) && full_fsync(pFile->dirfd,0,0) ){ - /* - ** We have received multiple reports of fsync() returning - ** errors when applied to directories on certain file systems. - ** A failed directory sync is not a big deal. So it seems - ** better to ignore the error. Ticket #1657 - */ - /* return SQLITE_IOERR; */ - } -#endif - close(pFile->dirfd); /* Only need to sync once, so close the directory */ - pFile->dirfd = -1; /* when we are done. */ - } - return SQLITE_OK; -} - -/* -** Truncate an open file to a specified size -*/ -static int unixTruncate(sqlite3_file *id, i64 nByte){ - int rc; - assert( id ); - rc = ftruncate(((unixFile*)id)->h, (off_t)nByte); - SimulateIOError( rc=1 ); - if( rc ){ - return SQLITE_IOERR_TRUNCATE; - }else{ - return SQLITE_OK; - } -} - -/* -** Determine the current size of a file in bytes -*/ -static int unixFileSize(sqlite3_file *id, i64 *pSize){ - int rc; - struct stat buf; - assert( id ); - rc = fstat(((unixFile*)id)->h, &buf); - SimulateIOError( rc=1 ); - if( rc!=0 ){ - return SQLITE_IOERR_FSTAT; - } - *pSize = buf.st_size; - return SQLITE_OK; -} - -/* -** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, return -** non-zero. If the file is unlocked or holds only SHARED locks, then -** return zero. -*/ -static int unixCheckReservedLock(sqlite3_file *id){ - int r = 0; - unixFile *pFile = (unixFile*)id; - - assert( pFile ); - enterMutex(); /* Because pFile->pLock is shared across threads */ - - /* Check if a thread in this process holds such a lock */ - if( pFile->pLock->locktype>SHARED_LOCK ){ - r = 1; - } - - /* Otherwise see if some other process holds it. - */ - if( !r ){ - struct flock lock; - lock.l_whence = SEEK_SET; - lock.l_start = RESERVED_BYTE; - lock.l_len = 1; - lock.l_type = F_WRLCK; - fcntl(pFile->h, F_GETLK, &lock); - if( lock.l_type!=F_UNLCK ){ - r = 1; - } - } - - leaveMutex(); - OSTRACE3("TEST WR-LOCK %d %d\n", pFile->h, r); - - return r; -} - -/* -** Lock the file with the lock specified by parameter locktype - one -** of the following: -** -** (1) SHARED_LOCK -** (2) RESERVED_LOCK -** (3) PENDING_LOCK -** (4) EXCLUSIVE_LOCK -** -** Sometimes when requesting one lock state, additional lock states -** are inserted in between. The locking might fail on one of the later -** transitions leaving the lock state different from what it started but -** still short of its goal. The following chart shows the allowed -** transitions and the inserted intermediate states: -** -** UNLOCKED -> SHARED -** SHARED -> RESERVED -** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> (PENDING) -> EXCLUSIVE -** PENDING -> EXCLUSIVE -** -** This routine will only increase a lock. Use the sqlite3OsUnlock() -** routine to lower a locking level. -*/ -static int unixLock(sqlite3_file *id, int locktype){ - /* The following describes the implementation of the various locks and - ** lock transitions in terms of the POSIX advisory shared and exclusive - ** lock primitives (called read-locks and write-locks below, to avoid - ** confusion with SQLite lock names). The algorithms are complicated - ** slightly in order to be compatible with windows systems simultaneously - ** accessing the same database file, in case that is ever required. - ** - ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved - ** byte', each single bytes at well known offsets, and the 'shared byte - ** range', a range of 510 bytes at a well known offset. - ** - ** To obtain a SHARED lock, a read-lock is obtained on the 'pending - ** byte'. If this is successful, a random byte from the 'shared byte - ** range' is read-locked and the lock on the 'pending byte' released. - ** - ** A process may only obtain a RESERVED lock after it has a SHARED lock. - ** A RESERVED lock is implemented by grabbing a write-lock on the - ** 'reserved byte'. - ** - ** A process may only obtain a PENDING lock after it has obtained a - ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock - ** on the 'pending byte'. This ensures that no new SHARED locks can be - ** obtained, but existing SHARED locks are allowed to persist. A process - ** does not have to obtain a RESERVED lock on the way to a PENDING lock. - ** This property is used by the algorithm for rolling back a journal file - ** after a crash. - ** - ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is - ** implemented by obtaining a write-lock on the entire 'shared byte - ** range'. Since all other locks require a read-lock on one of the bytes - ** within this range, this ensures that no other locks are held on the - ** database. - ** - ** The reason a single byte cannot be used instead of the 'shared byte - ** range' is that some versions of windows do not support read-locks. By - ** locking a random byte from a range, concurrent SHARED locks may exist - ** even if the locking primitive used is always a write-lock. - */ - int rc = SQLITE_OK; - unixFile *pFile = (unixFile*)id; - struct lockInfo *pLock = pFile->pLock; - struct flock lock; - int s; - - assert( pFile ); - OSTRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", pFile->h, - locktypeName(locktype), locktypeName(pFile->locktype), - locktypeName(pLock->locktype), pLock->cnt , getpid()); - - /* If there is already a lock of this type or more restrictive on the - ** unixFile, do nothing. Don't use the end_lock: exit path, as - ** enterMutex() hasn't been called yet. - */ - if( pFile->locktype>=locktype ){ - OSTRACE3("LOCK %d %s ok (already held)\n", pFile->h, - locktypeName(locktype)); - return SQLITE_OK; - } - - /* Make sure the locking sequence is correct - */ - assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); - assert( locktype!=PENDING_LOCK ); - assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); - - /* This mutex is needed because pFile->pLock is shared across threads - */ - enterMutex(); - - /* Make sure the current thread owns the pFile. - */ - rc = transferOwnership(pFile); - if( rc!=SQLITE_OK ){ - leaveMutex(); - return rc; - } - pLock = pFile->pLock; - - /* If some thread using this PID has a lock via a different unixFile* - ** handle that precludes the requested lock, return BUSY. - */ - if( (pFile->locktype!=pLock->locktype && - (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK)) - ){ - rc = SQLITE_BUSY; - goto end_lock; - } - - /* If a SHARED lock is requested, and some thread using this PID already - ** has a SHARED or RESERVED lock, then increment reference counts and - ** return SQLITE_OK. - */ - if( locktype==SHARED_LOCK && - (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){ - assert( locktype==SHARED_LOCK ); - assert( pFile->locktype==0 ); - assert( pLock->cnt>0 ); - pFile->locktype = SHARED_LOCK; - pLock->cnt++; - pFile->pOpen->nLock++; - goto end_lock; - } - - lock.l_len = 1L; - - lock.l_whence = SEEK_SET; - - /* A PENDING lock is needed before acquiring a SHARED lock and before - ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will - ** be released. - */ - if( locktype==SHARED_LOCK - || (locktype==EXCLUSIVE_LOCK && pFile->locktypeh, F_SETLK, &lock); - if( s==(-1) ){ - rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; - goto end_lock; - } - } - - - /* If control gets to this point, then actually go ahead and make - ** operating system calls for the specified lock. - */ - if( locktype==SHARED_LOCK ){ - assert( pLock->cnt==0 ); - assert( pLock->locktype==0 ); - - /* Now get the read-lock */ - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - s = fcntl(pFile->h, F_SETLK, &lock); - - /* Drop the temporary PENDING lock */ - lock.l_start = PENDING_BYTE; - lock.l_len = 1L; - lock.l_type = F_UNLCK; - if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){ - rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ - goto end_lock; - } - if( s==(-1) ){ - rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; - }else{ - pFile->locktype = SHARED_LOCK; - pFile->pOpen->nLock++; - pLock->cnt = 1; - } - }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){ - /* We are trying for an exclusive lock but another thread in this - ** same process is still holding a shared lock. */ - rc = SQLITE_BUSY; - }else{ - /* The request was for a RESERVED or EXCLUSIVE lock. It is - ** assumed that there is a SHARED or greater lock on the file - ** already. - */ - assert( 0!=pFile->locktype ); - lock.l_type = F_WRLCK; - switch( locktype ){ - case RESERVED_LOCK: - lock.l_start = RESERVED_BYTE; - break; - case EXCLUSIVE_LOCK: - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - break; - default: - assert(0); - } - s = fcntl(pFile->h, F_SETLK, &lock); - if( s==(-1) ){ - rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; - } - } - - if( rc==SQLITE_OK ){ - pFile->locktype = locktype; - pLock->locktype = locktype; - }else if( locktype==EXCLUSIVE_LOCK ){ - pFile->locktype = PENDING_LOCK; - pLock->locktype = PENDING_LOCK; - } - -end_lock: - leaveMutex(); - OSTRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype), - rc==SQLITE_OK ? "ok" : "failed"); - return rc; -} - -/* -** Lower the locking level on file descriptor pFile to locktype. locktype -** must be either NO_LOCK or SHARED_LOCK. -** -** If the locking level of the file descriptor is already at or below -** the requested locking level, this routine is a no-op. -*/ -static int unixUnlock(sqlite3_file *id, int locktype){ - struct lockInfo *pLock; - struct flock lock; - int rc = SQLITE_OK; - unixFile *pFile = (unixFile*)id; - - assert( pFile ); - OSTRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype, - pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid()); - - assert( locktype<=SHARED_LOCK ); - if( pFile->locktype<=locktype ){ - return SQLITE_OK; - } - if( CHECK_THREADID(pFile) ){ - return SQLITE_MISUSE; - } - enterMutex(); - pLock = pFile->pLock; - assert( pLock->cnt!=0 ); - if( pFile->locktype>SHARED_LOCK ){ - assert( pLock->locktype==pFile->locktype ); - if( locktype==SHARED_LOCK ){ - lock.l_type = F_RDLCK; - lock.l_whence = SEEK_SET; - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - if( fcntl(pFile->h, F_SETLK, &lock)==(-1) ){ - /* This should never happen */ - rc = SQLITE_IOERR_RDLOCK; - } - } - lock.l_type = F_UNLCK; - lock.l_whence = SEEK_SET; - lock.l_start = PENDING_BYTE; - lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); - if( fcntl(pFile->h, F_SETLK, &lock)!=(-1) ){ - pLock->locktype = SHARED_LOCK; - }else{ - rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ - } - } - if( locktype==NO_LOCK ){ - struct openCnt *pOpen; - - /* Decrement the shared lock counter. Release the lock using an - ** OS call only when all threads in this same process have released - ** the lock. - */ - pLock->cnt--; - if( pLock->cnt==0 ){ - lock.l_type = F_UNLCK; - lock.l_whence = SEEK_SET; - lock.l_start = lock.l_len = 0L; - if( fcntl(pFile->h, F_SETLK, &lock)!=(-1) ){ - pLock->locktype = NO_LOCK; - }else{ - rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ - } - } - - /* Decrement the count of locks against this same file. When the - ** count reaches zero, close any other file descriptors whose close - ** was deferred because of outstanding locks. - */ - pOpen = pFile->pOpen; - pOpen->nLock--; - assert( pOpen->nLock>=0 ); - if( pOpen->nLock==0 && pOpen->nPending>0 ){ - int i; - for(i=0; inPending; i++){ - close(pOpen->aPending[i]); - } - free(pOpen->aPending); - pOpen->nPending = 0; - pOpen->aPending = 0; - } - } - leaveMutex(); - pFile->locktype = locktype; - return rc; -} - -/* -** Close a file. -*/ -static int unixClose(sqlite3_file *id){ - unixFile *pFile = (unixFile *)id; - if( !pFile ) return SQLITE_OK; - unixUnlock(id, NO_LOCK); - if( pFile->dirfd>=0 ) close(pFile->dirfd); - pFile->dirfd = -1; - enterMutex(); - - if( pFile->pOpen->nLock ){ - /* If there are outstanding locks, do not actually close the file just - ** yet because that would clear those locks. Instead, add the file - ** descriptor to pOpen->aPending. It will be automatically closed when - ** the last lock is cleared. - */ - int *aNew; - struct openCnt *pOpen = pFile->pOpen; - aNew = realloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) ); - if( aNew==0 ){ - /* If a malloc fails, just leak the file descriptor */ - }else{ - pOpen->aPending = aNew; - pOpen->aPending[pOpen->nPending] = pFile->h; - pOpen->nPending++; - } - }else{ - /* There are no outstanding locks so we can close the file immediately */ - close(pFile->h); - } - releaseLockInfo(pFile->pLock); - releaseOpenCnt(pFile->pOpen); - - leaveMutex(); - OSTRACE2("CLOSE %-3d\n", pFile->h); - OpenCounter(-1); - memset(pFile, 0, sizeof(unixFile)); - return SQLITE_OK; -} - - -#ifdef SQLITE_ENABLE_LOCKING_STYLE -#pragma mark AFP Support - -/* - ** The afpLockingContext structure contains all afp lock specific state - */ -typedef struct afpLockingContext afpLockingContext; -struct afpLockingContext { - unsigned long long sharedLockByte; - char *filePath; -}; - -struct ByteRangeLockPB2 -{ - unsigned long long offset; /* offset to first byte to lock */ - unsigned long long length; /* nbr of bytes to lock */ - unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */ - unsigned char unLockFlag; /* 1 = unlock, 0 = lock */ - unsigned char startEndFlag; /* 1=rel to end of fork, 0=rel to start */ - int fd; /* file desc to assoc this lock with */ -}; - -#define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2) - -/* -** Return 0 on success, 1 on failure. To match the behavior of the -** normal posix file locking (used in unixLock for example), we should -** provide 'richer' return codes - specifically to differentiate between -** 'file busy' and 'file system error' results. -*/ -static int _AFPFSSetLock( - const char *path, - int fd, - unsigned long long offset, - unsigned long long length, - int setLockFlag -){ - struct ByteRangeLockPB2 pb; - int err; - - pb.unLockFlag = setLockFlag ? 0 : 1; - pb.startEndFlag = 0; - pb.offset = offset; - pb.length = length; - pb.fd = fd; - OSTRACE5("AFPLOCK setting lock %s for %d in range %llx:%llx\n", - (setLockFlag?"ON":"OFF"), fd, offset, length); - err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0); - if ( err==-1 ) { - OSTRACE4("AFPLOCK failed to fsctl() '%s' %d %s\n", path, errno, - strerror(errno)); - return 1; /* error */ - } else { - return 0; - } -} - -/* - ** This routine checks if there is a RESERVED lock held on the specified - ** file by this or any other process. If such a lock is held, return - ** non-zero. If the file is unlocked or holds only SHARED locks, then - ** return zero. - */ -static int afpUnixCheckReservedLock(sqlite3_file *id){ - int r = 0; - unixFile *pFile = (unixFile*)id; - - assert( pFile ); - afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; - - /* Check if a thread in this process holds such a lock */ - if( pFile->locktype>SHARED_LOCK ){ - r = 1; - } - - /* Otherwise see if some other process holds it. - */ - if ( !r ) { - /* lock the byte */ - int failed = _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1,1); - if (failed) { - /* if we failed to get the lock then someone else must have it */ - r = 1; - } else { - /* if we succeeded in taking the reserved lock, unlock it to restore - ** the original state */ - _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1, 0); - } - } - OSTRACE3("TEST WR-LOCK %d %d\n", pFile->h, r); - - return r; -} - -/* AFP-style locking following the behavior of unixLock, see the unixLock -** function comments for details of lock management. */ -static int afpUnixLock(sqlite3_file *id, int locktype) -{ - int rc = SQLITE_OK; - unixFile *pFile = (unixFile*)id; - afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; - int gotPendingLock = 0; - - assert( pFile ); - OSTRACE5("LOCK %d %s was %s pid=%d\n", pFile->h, - locktypeName(locktype), locktypeName(pFile->locktype), getpid()); - /* If there is already a lock of this type or more restrictive on the - ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as - ** enterMutex() hasn't been called yet. - */ - if( pFile->locktype>=locktype ){ - OSTRACE3("LOCK %d %s ok (already held)\n", pFile->h, - locktypeName(locktype)); - return SQLITE_OK; - } - - /* Make sure the locking sequence is correct - */ - assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); - assert( locktype!=PENDING_LOCK ); - assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); - - /* This mutex is needed because pFile->pLock is shared across threads - */ - enterMutex(); - - /* Make sure the current thread owns the pFile. - */ - rc = transferOwnership(pFile); - if( rc!=SQLITE_OK ){ - leaveMutex(); - return rc; - } - - /* A PENDING lock is needed before acquiring a SHARED lock and before - ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will - ** be released. - */ - if( locktype==SHARED_LOCK - || (locktype==EXCLUSIVE_LOCK && pFile->locktypefilePath, pFile->h, - PENDING_BYTE, 1, 1); - if (failed) { - rc = SQLITE_BUSY; - goto afp_end_lock; - } - } - - /* If control gets to this point, then actually go ahead and make - ** operating system calls for the specified lock. - */ - if( locktype==SHARED_LOCK ){ - int lk, failed; - int tries = 0; - - /* Now get the read-lock */ - /* note that the quality of the randomness doesn't matter that much */ - lk = random(); - context->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1); - failed = _AFPFSSetLock(context->filePath, pFile->h, - SHARED_FIRST+context->sharedLockByte, 1, 1); - - /* Drop the temporary PENDING lock */ - if (_AFPFSSetLock(context->filePath, pFile->h, PENDING_BYTE, 1, 0)) { - rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ - goto afp_end_lock; - } - - if( failed ){ - rc = SQLITE_BUSY; - } else { - pFile->locktype = SHARED_LOCK; - } - }else{ - /* The request was for a RESERVED or EXCLUSIVE lock. It is - ** assumed that there is a SHARED or greater lock on the file - ** already. - */ - int failed = 0; - assert( 0!=pFile->locktype ); - if (locktype >= RESERVED_LOCK && pFile->locktype < RESERVED_LOCK) { - /* Acquire a RESERVED lock */ - failed = _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1,1); - } - if (!failed && locktype == EXCLUSIVE_LOCK) { - /* Acquire an EXCLUSIVE lock */ - - /* Remove the shared lock before trying the range. we'll need to - ** reestablish the shared lock if we can't get the afpUnixUnlock - */ - if (!_AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST + - context->sharedLockByte, 1, 0)) { - /* now attemmpt to get the exclusive lock range */ - failed = _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST, - SHARED_SIZE, 1); - if (failed && _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST + - context->sharedLockByte, 1, 1)) { - rc = SQLITE_IOERR_RDLOCK; /* this should never happen */ - } - } else { - /* */ - rc = SQLITE_IOERR_UNLOCK; /* this should never happen */ - } - } - if( failed && rc == SQLITE_OK){ - rc = SQLITE_BUSY; - } - } - - if( rc==SQLITE_OK ){ - pFile->locktype = locktype; - }else if( locktype==EXCLUSIVE_LOCK ){ - pFile->locktype = PENDING_LOCK; - } - -afp_end_lock: - leaveMutex(); - OSTRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype), - rc==SQLITE_OK ? "ok" : "failed"); - return rc; -} - -/* - ** Lower the locking level on file descriptor pFile to locktype. locktype - ** must be either NO_LOCK or SHARED_LOCK. - ** - ** If the locking level of the file descriptor is already at or below - ** the requested locking level, this routine is a no-op. - */ -static int afpUnixUnlock(sqlite3_file *id, int locktype) { - struct flock lock; - int rc = SQLITE_OK; - unixFile *pFile = (unixFile*)id; - afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; - - assert( pFile ); - OSTRACE5("UNLOCK %d %d was %d pid=%d\n", pFile->h, locktype, - pFile->locktype, getpid()); - - assert( locktype<=SHARED_LOCK ); - if( pFile->locktype<=locktype ){ - return SQLITE_OK; - } - if( CHECK_THREADID(pFile) ){ - return SQLITE_MISUSE; - } - enterMutex(); - if( pFile->locktype>SHARED_LOCK ){ - if( locktype==SHARED_LOCK ){ - int failed = 0; - - /* unlock the exclusive range - then re-establish the shared lock */ - if (pFile->locktype==EXCLUSIVE_LOCK) { - failed = _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST, - SHARED_SIZE, 0); - if (!failed) { - /* successfully removed the exclusive lock */ - if (_AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST+ - context->sharedLockByte, 1, 1)) { - /* failed to re-establish our shared lock */ - rc = SQLITE_IOERR_RDLOCK; /* This should never happen */ - } - } else { - /* This should never happen - failed to unlock the exclusive range */ - rc = SQLITE_IOERR_UNLOCK; - } - } - } - if (rc == SQLITE_OK && pFile->locktype>=PENDING_LOCK) { - if (_AFPFSSetLock(context->filePath, pFile->h, PENDING_BYTE, 1, 0)){ - /* failed to release the pending lock */ - rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ - } - } - if (rc == SQLITE_OK && pFile->locktype>=RESERVED_LOCK) { - if (_AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1, 0)) { - /* failed to release the reserved lock */ - rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ - } - } - } - if( locktype==NO_LOCK ){ - int failed = _AFPFSSetLock(context->filePath, pFile->h, - SHARED_FIRST + context->sharedLockByte, 1, 0); - if (failed) { - rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ - } - } - if (rc == SQLITE_OK) - pFile->locktype = locktype; - leaveMutex(); - return rc; -} - -/* - ** Close a file & cleanup AFP specific locking context - */ -static int afpUnixClose(sqlite3_file *id) { - unixFile *pFile = (unixFile*)pId; - - if( !pFile ) return SQLITE_OK; - afpUnixUnlock(*pId, NO_LOCK); - /* free the AFP locking structure */ - if (pFile->lockingContext != NULL) { - if (((afpLockingContext *)pFile->lockingContext)->filePath != NULL) - sqlite3_free(((afpLockingContext*)pFile->lockingContext)->filePath); - sqlite3_free(pFile->lockingContext); - } - - if( pFile->dirfd>=0 ) close(pFile->dirfd); - pFile->dirfd = -1; - close(pFile->h); - OSTRACE2("CLOSE %-3d\n", pFile->h); - OpenCounter(-1); - return SQLITE_OK; -} - - -#pragma mark flock() style locking - -/* - ** The flockLockingContext is not used - */ -typedef void flockLockingContext; - -static int flockUnixCheckReservedLock(sqlite3_file *id) { - unixFile *pFile = (unixFile*)id; - - if (pFile->locktype == RESERVED_LOCK) { - return 1; /* already have a reserved lock */ - } else { - /* attempt to get the lock */ - int rc = flock(pFile->h, LOCK_EX | LOCK_NB); - if (!rc) { - /* got the lock, unlock it */ - flock(pFile->h, LOCK_UN); - return 0; /* no one has it reserved */ - } - return 1; /* someone else might have it reserved */ - } -} - -static int flockUnixLock(sqlite3_file *id, int locktype) { - unixFile *pFile = (unixFile*)id; - - /* if we already have a lock, it is exclusive. - ** Just adjust level and punt on outta here. */ - if (pFile->locktype > NO_LOCK) { - pFile->locktype = locktype; - return SQLITE_OK; - } - - /* grab an exclusive lock */ - int rc = flock(pFile->h, LOCK_EX | LOCK_NB); - if (rc) { - /* didn't get, must be busy */ - return SQLITE_BUSY; - } else { - /* got it, set the type and return ok */ - pFile->locktype = locktype; - return SQLITE_OK; - } -} - -static int flockUnixUnlock(sqlite3_file *id, int locktype) { - unixFile *pFile = (unixFile*)id; - - assert( locktype<=SHARED_LOCK ); - - /* no-op if possible */ - if( pFile->locktype==locktype ){ - return SQLITE_OK; - } - - /* shared can just be set because we always have an exclusive */ - if (locktype==SHARED_LOCK) { - pFile->locktype = locktype; - return SQLITE_OK; - } - - /* no, really, unlock. */ - int rc = flock(pFile->h, LOCK_UN); - if (rc) - return SQLITE_IOERR_UNLOCK; - else { - pFile->locktype = NO_LOCK; - return SQLITE_OK; - } -} - -/* - ** Close a file. - */ -static int flockUnixClose(sqlite3_file *pId) { - unixFile *pFile = (unixFile*)*pId; - - if( !pFile ) return SQLITE_OK; - flockUnixUnlock(*pId, NO_LOCK); - - if( pFile->dirfd>=0 ) close(pFile->dirfd); - pFile->dirfd = -1; - enterMutex(); - - close(pFile->h); - leaveMutex(); - OSTRACE2("CLOSE %-3d\n", pFile->h); - OpenCounter(-1); - return SQLITE_OK; -} - -#pragma mark Old-School .lock file based locking - -/* - ** The dotlockLockingContext structure contains all dotlock (.lock) lock - ** specific state - */ -typedef struct dotlockLockingContext dotlockLockingContext; -struct dotlockLockingContext { - char *lockPath; -}; - - -static int dotlockUnixCheckReservedLock(sqlite3_file *id) { - unixFile *pFile = (unixFile*)id; - dotlockLockingContext *context = - (dotlockLockingContext *) pFile->lockingContext; - - if (pFile->locktype == RESERVED_LOCK) { - return 1; /* already have a reserved lock */ - } else { - struct stat statBuf; - if (lstat(context->lockPath,&statBuf) == 0) - /* file exists, someone else has the lock */ - return 1; - else - /* file does not exist, we could have it if we want it */ - return 0; - } -} - -static int dotlockUnixLock(sqlite3_file *id, int locktype) { - unixFile *pFile = (unixFile*)id; - dotlockLockingContext *context = - (dotlockLockingContext *) pFile->lockingContext; - - /* if we already have a lock, it is exclusive. - ** Just adjust level and punt on outta here. */ - if (pFile->locktype > NO_LOCK) { - pFile->locktype = locktype; - - /* Always update the timestamp on the old file */ - utimes(context->lockPath,NULL); - return SQLITE_OK; - } - - /* check to see if lock file already exists */ - struct stat statBuf; - if (lstat(context->lockPath,&statBuf) == 0){ - return SQLITE_BUSY; /* it does, busy */ - } - - /* grab an exclusive lock */ - int fd = open(context->lockPath,O_RDONLY|O_CREAT|O_EXCL,0600); - if (fd < 0) { - /* failed to open/create the file, someone else may have stolen the lock */ - return SQLITE_BUSY; - } - close(fd); - - /* got it, set the type and return ok */ - pFile->locktype = locktype; - return SQLITE_OK; -} - -static int dotlockUnixUnlock(sqlite3_file *id, int locktype) { - unixFile *pFile = (unixFile*)id; - dotlockLockingContext *context = - (dotlockLockingContext *) pFile->lockingContext; - - assert( locktype<=SHARED_LOCK ); - - /* no-op if possible */ - if( pFile->locktype==locktype ){ - return SQLITE_OK; - } - - /* shared can just be set because we always have an exclusive */ - if (locktype==SHARED_LOCK) { - pFile->locktype = locktype; - return SQLITE_OK; - } - - /* no, really, unlock. */ - unlink(context->lockPath); - pFile->locktype = NO_LOCK; - return SQLITE_OK; -} - -/* - ** Close a file. - */ -static int dotlockUnixClose(sqlite3_file *id) { - unixFile *pFile = (unixFile*)id; - - if( !pFile ) return SQLITE_OK; - dotlockUnixUnlock(*pId, NO_LOCK); - /* free the dotlock locking structure */ - if (pFile->lockingContext != NULL) { - if (((dotlockLockingContext *)pFile->lockingContext)->lockPath != NULL) - sqlite3_free( ( (dotlockLockingContext *) - pFile->lockingContext)->lockPath); - sqlite3_free(pFile->lockingContext); - } - - if( pFile->dirfd>=0 ) close(pFile->dirfd); - pFile->dirfd = -1; - enterMutex(); - - close(pFile->h); - - leaveMutex(); - OSTRACE2("CLOSE %-3d\n", pFile->h); - OpenCounter(-1); - return SQLITE_OK; -} - - -#pragma mark No locking - -/* - ** The nolockLockingContext is void - */ -typedef void nolockLockingContext; - -static int nolockUnixCheckReservedLock(sqlite3_file *id) { - return 0; -} - -static int nolockUnixLock(sqlite3_file *id, int locktype) { - return SQLITE_OK; -} - -static int nolockUnixUnlock(sqlite3_file *id, int locktype) { - return SQLITE_OK; -} - -/* - ** Close a file. - */ -static int nolockUnixClose(sqlite3_file *id) { - unixFile *pFile = (unixFile*)id; - - if( !pFile ) return SQLITE_OK; - if( pFile->dirfd>=0 ) close(pFile->dirfd); - pFile->dirfd = -1; - enterMutex(); - - close(pFile->h); - - leaveMutex(); - OSTRACE2("CLOSE %-3d\n", pFile->h); - OpenCounter(-1); - return SQLITE_OK; -} - -#endif /* SQLITE_ENABLE_LOCKING_STYLE */ - - -/* -** Information and control of an open file handle. -*/ -static int unixFileControl(sqlite3_file *id, int op, void *pArg){ - switch( op ){ - case SQLITE_FCNTL_LOCKSTATE: { - *(int*)pArg = ((unixFile*)id)->locktype; - return SQLITE_OK; - } - } - return SQLITE_ERROR; -} - -/* -** Return the sector size in bytes of the underlying block device for -** the specified file. This is almost always 512 bytes, but may be -** larger for some devices. -** -** SQLite code assumes this function cannot fail. It also assumes that -** if two files are created in the same file-system directory (i.e. -** a database and it's journal file) that the sector size will be the -** same for both. -*/ -static int unixSectorSize(sqlite3_file *id){ - return SQLITE_DEFAULT_SECTOR_SIZE; -} - -/* -** Return the device characteristics for the file. This is always 0. -*/ -static int unixDeviceCharacteristics(sqlite3_file *id){ - return 0; -} - -/* -** This vector defines all the methods that can operate on an sqlite3_file -** for unix. -*/ -static const sqlite3_io_methods sqlite3UnixIoMethod = { - 1, /* iVersion */ - unixClose, - unixRead, - unixWrite, - unixTruncate, - unixSync, - unixFileSize, - unixLock, - unixUnlock, - unixCheckReservedLock, - unixFileControl, - unixSectorSize, - unixDeviceCharacteristics -}; - -#ifdef SQLITE_ENABLE_LOCKING_STYLE -/* -** This vector defines all the methods that can operate on an sqlite3_file -** for unix with AFP style file locking. -*/ -static const sqlite3_io_methods sqlite3AFPLockingUnixIoMethod = { - 1, /* iVersion */ - unixClose, - unixRead, - unixWrite, - unixTruncate, - unixSync, - unixFileSize, - afpUnixLock, - afpUnixUnlock, - afpUnixCheckReservedLock, - unixFileControl, - unixSectorSize, - unixDeviceCharacteristics -}; - -/* -** This vector defines all the methods that can operate on an sqlite3_file -** for unix with flock() style file locking. -*/ -static const sqlite3_io_methods sqlite3FlockLockingUnixIoMethod = { - 1, /* iVersion */ - flockUnixClose, - unixRead, - unixWrite, - unixTruncate, - unixSync, - unixFileSize, - flockUnixLock, - flockUnixUnlock, - flockUnixCheckReservedLock, - unixFileControl, - unixSectorSize, - unixDeviceCharacteristics -}; - -/* -** This vector defines all the methods that can operate on an sqlite3_file -** for unix with dotlock style file locking. -*/ -static const sqlite3_io_methods sqlite3DotlockLockingUnixIoMethod = { - 1, /* iVersion */ - dotlockUnixClose, - unixRead, - unixWrite, - unixTruncate, - unixSync, - unixFileSize, - dotlockUnixLock, - dotlockUnixUnlock, - dotlockUnixCheckReservedLock, - unixFileControl, - unixSectorSize, - unixDeviceCharacteristics -}; - -/* -** This vector defines all the methods that can operate on an sqlite3_file -** for unix with dotlock style file locking. -*/ -static const sqlite3_io_methods sqlite3NolockLockingUnixIoMethod = { - 1, /* iVersion */ - nolockUnixClose, - unixRead, - unixWrite, - unixTruncate, - unixSync, - unixFileSize, - nolockUnixLock, - nolockUnixUnlock, - nolockUnixCheckReservedLock, - unixFileControl, - unixSectorSize, - unixDeviceCharacteristics -}; - -#endif /* SQLITE_ENABLE_LOCKING_STYLE */ - -/* -** Allocate memory for a new unixFile and initialize that unixFile. -** Write a pointer to the new unixFile into *pId. -** If we run out of memory, close the file and return an error. -*/ -#ifdef SQLITE_ENABLE_LOCKING_STYLE -/* -** When locking extensions are enabled, the filepath and locking style -** are needed to determine the unixFile pMethod to use for locking operations. -** The locking-style specific lockingContext data structure is created -** and assigned here also. -*/ -static int fillInUnixFile( - int h, /* Open file descriptor of file being opened */ - int dirfd, /* Directory file descriptor */ - sqlite3_file *pId, /* Write completed initialization here */ - const char *zFilename, /* Name of the file being opened */ -){ - sqlite3LockingStyle lockingStyle; - unixFile *pNew = (unixFile *)pId; - int rc; - - memset(pNew, 0, sizeof(unixFile)); - lockingStyle = sqlite3DetectLockingStyle(zFilename, h); - if ( lockingStyle == posixLockingStyle ) { - enterMutex(); - rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen); - leaveMutex(); - if( rc ){ - close(h); - unlink(zFilename); - return SQLITE_NOMEM; - } - } else { - /* pLock and pOpen are only used for posix advisory locking */ - pNew->pLock = NULL; - pNew->pOpen = NULL; - } - pNew->dirfd = -1; - pNew->h = h; - SET_THREADID(pNew); - pNew = sqlite3_malloc( sizeof(unixFile) ); - if( pNew==0 ){ - close(h); - enterMutex(); - releaseLockInfo(pNew->pLock); - releaseOpenCnt(pNew->pOpen); - leaveMutex(); - return SQLITE_NOMEM; - }else{ - switch(lockingStyle) { - case afpLockingStyle: { - /* afp locking uses the file path so it needs to be included in - ** the afpLockingContext */ - int nFilename; - pNew->pMethod = &sqlite3AFPLockingUnixIoMethod; - pNew->lockingContext = - sqlite3_malloc(sizeof(afpLockingContext)); - nFilename = strlen(zFilename)+1; - ((afpLockingContext *)pNew->lockingContext)->filePath = - sqlite3_malloc(nFilename); - memcpy(((afpLockingContext *)pNew->lockingContext)->filePath, - zFilename, nFilename); - srandomdev(); - break; - } - case flockLockingStyle: - /* flock locking doesn't need additional lockingContext information */ - pNew->pMethod = &sqlite3FlockLockingUnixIoMethod; - break; - case dotlockLockingStyle: { - /* dotlock locking uses the file path so it needs to be included in - ** the dotlockLockingContext */ - int nFilename; - pNew->pMethod = &sqlite3DotlockLockingUnixIoMethod; - pNew->lockingContext = sqlite3_malloc( - sizeof(dotlockLockingContext)); - nFilename = strlen(zFilename) + 6; - ((dotlockLockingContext *)pNew->lockingContext)->lockPath = - sqlite3_malloc( nFilename ); - sqlite3_snprintf(nFilename, - ((dotlockLockingContext *)pNew->lockingContext)->lockPath, - "%s.lock", zFilename); - break; - } - case posixLockingStyle: - /* posix locking doesn't need additional lockingContext information */ - pNew->pMethod = &sqlite3UnixIoMethod; - break; - case noLockingStyle: - case unsupportedLockingStyle: - default: - pNew->pMethod = &sqlite3NolockLockingUnixIoMethod; - } - OpenCounter(+1); - return SQLITE_OK; - } -} -#else /* SQLITE_ENABLE_LOCKING_STYLE */ -static int fillInUnixFile( - int h, /* Open file descriptor on file being opened */ - int dirfd, - sqlite3_file *pId, /* Write to the unixFile structure here */ - const char *zFilename /* Name of the file being opened */ -){ - unixFile *pNew = (unixFile *)pId; - int rc; - -#ifdef FD_CLOEXEC - fcntl(h, F_SETFD, fcntl(h, F_GETFD, 0) | FD_CLOEXEC); -#endif - - enterMutex(); - rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen); - leaveMutex(); - if( rc ){ - close(h); - return SQLITE_NOMEM; - } - - OSTRACE3("OPEN %-3d %s\n", h, zFilename); - pNew->dirfd = -1; - pNew->h = h; - pNew->dirfd = dirfd; - SET_THREADID(pNew); - - pNew->pMethod = &sqlite3UnixIoMethod; - OpenCounter(+1); - return SQLITE_OK; -} -#endif /* SQLITE_ENABLE_LOCKING_STYLE */ - -/* -** Open a file descriptor to the directory containing file zFilename. -** If successful, *pFd is set to the opened file descriptor and -** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM -** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined -** value. -** -** If SQLITE_OK is returned, the caller is responsible for closing -** the file descriptor *pFd using close(). -*/ -static int openDirectory(const char *zFilename, int *pFd){ - int ii; - int fd = -1; - char zDirname[MAX_PATHNAME+1]; - - sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); - for(ii=strlen(zDirname); ii>=0 && zDirname[ii]!='/'; ii--); - if( ii>0 ){ - zDirname[ii] = '\0'; - fd = open(zDirname, O_RDONLY|O_BINARY, 0); - if( fd>=0 ){ -#ifdef FD_CLOEXEC - fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC); -#endif - OSTRACE3("OPENDIR %-3d %s\n", fd, zDirname); - } - } - *pFd = fd; - return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN); -} - -/* -** Open the file zPath. -** -** Previously, the SQLite OS layer used three functions in place of this -** one: -** -** sqlite3OsOpenReadWrite(); -** sqlite3OsOpenReadOnly(); -** sqlite3OsOpenExclusive(); -** -** These calls correspond to the following combinations of flags: -** -** ReadWrite() -> (READWRITE | CREATE) -** ReadOnly() -> (READONLY) -** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE) -** -** The old OpenExclusive() accepted a boolean argument - "delFlag". If -** true, the file was configured to be automatically deleted when the -** file handle closed. To achieve the same effect using this new -** interface, add the DELETEONCLOSE flag to those specified above for -** OpenExclusive(). -*/ -static int unixOpen( - sqlite3_vfs *pVfs, - const char *zPath, - sqlite3_file *pFile, - int flags, - int *pOutFlags -){ - int fd = 0; /* File descriptor returned by open() */ - int dirfd = -1; /* Directory file descriptor */ - int oflags = 0; /* Flags to pass to open() */ - int eType = flags&0xFFFFFF00; /* Type of file to open */ - - int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); - int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); - int isCreate = (flags & SQLITE_OPEN_CREATE); - int isReadonly = (flags & SQLITE_OPEN_READONLY); - int isReadWrite = (flags & SQLITE_OPEN_READWRITE); - - /* If creating a master or main-file journal, this function will open - ** a file-descriptor on the directory too. The first time unixSync() - ** is called the directory file descriptor will be fsync()ed and close()d. - */ - int isOpenDirectory = (isCreate && - (eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL) - ); - - /* Check the following statements are true: - ** - ** (a) Exactly one of the READWRITE and READONLY flags must be set, and - ** (b) if CREATE is set, then READWRITE must also be set, and - ** (c) if EXCLUSIVE is set, then CREATE must also be set. - ** (d) if DELETEONCLOSE is set, then CREATE must also be set. - */ - assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); - assert(isCreate==0 || isReadWrite); - assert(isExclusive==0 || isCreate); - assert(isDelete==0 || isCreate); - - - /* The main DB, main journal, and master journal are never automatically - ** deleted - */ - assert( eType!=SQLITE_OPEN_MAIN_DB || !isDelete ); - assert( eType!=SQLITE_OPEN_MAIN_JOURNAL || !isDelete ); - assert( eType!=SQLITE_OPEN_MASTER_JOURNAL || !isDelete ); - - /* Assert that the upper layer has set one of the "file-type" flags. */ - assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB - || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL - || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL - || eType==SQLITE_OPEN_TRANSIENT_DB - ); - - if( isReadonly ) oflags |= O_RDONLY; - if( isReadWrite ) oflags |= O_RDWR; - if( isCreate ) oflags |= O_CREAT; - if( isExclusive ) oflags |= (O_EXCL|O_NOFOLLOW); - oflags |= (O_LARGEFILE|O_BINARY); - - memset(pFile, 0, sizeof(unixFile)); - fd = open(zPath, oflags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS); - if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){ - /* Failed to open the file for read/write access. Try read-only. */ - flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); - flags |= SQLITE_OPEN_READONLY; - return unixOpen(pVfs, zPath, pFile, flags, pOutFlags); - } - if( fd<0 ){ - return SQLITE_CANTOPEN; - } - if( isDelete ){ - unlink(zPath); - } - if( pOutFlags ){ - *pOutFlags = flags; - } - - assert(fd!=0); - if( isOpenDirectory ){ - int rc = openDirectory(zPath, &dirfd); - if( rc!=SQLITE_OK ){ - close(fd); - return rc; - } - } - return fillInUnixFile(fd, dirfd, pFile, zPath); -} - -/* -** Delete the file at zPath. If the dirSync argument is true, fsync() -** the directory after deleting the file. -*/ -static int unixDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ - int rc = SQLITE_OK; - SimulateIOError(return SQLITE_IOERR_DELETE); - unlink(zPath); - if( dirSync ){ - int fd; - rc = openDirectory(zPath, &fd); - if( rc==SQLITE_OK ){ - if( fsync(fd) ){ - rc = SQLITE_IOERR_DIR_FSYNC; - } - close(fd); - } - } - return rc; -} - -/* -** Test the existance of or access permissions of file zPath. The -** test performed depends on the value of flags: -** -** SQLITE_ACCESS_EXISTS: Return 1 if the file exists -** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable. -** SQLITE_ACCESS_READONLY: Return 1 if the file is readable. -** -** Otherwise return 0. -*/ -static int unixAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ - int amode = 0; - switch( flags ){ - case SQLITE_ACCESS_EXISTS: - amode = F_OK; - break; - case SQLITE_ACCESS_READWRITE: - amode = W_OK|R_OK; - break; - case SQLITE_ACCESS_READ: - amode = R_OK; - break; - - default: - assert(!"Invalid flags argument"); - } - return (access(zPath, amode)==0); -} - -/* -** Create a temporary file name in zBuf. zBuf must be allocated -** by the calling process and must be big enough to hold at least -** pVfs->mxPathname bytes. -*/ -static int unixGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ - static const char *azDirs[] = { - 0, - "/var/tmp", - "/usr/tmp", - "/tmp", - ".", - }; - static const unsigned char zChars[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"; - int i, j; - struct stat buf; - const char *zDir = "."; - - /* It's odd to simulate an io-error here, but really this is just - ** using the io-error infrastructure to test that SQLite handles this - ** function failing. - */ - SimulateIOError( return SQLITE_ERROR ); - - azDirs[0] = sqlite3_temp_directory; - for(i=0; imxPathname==MAX_PATHNAME ); - assert( nBuf>=MAX_PATHNAME ); - sqlite3_snprintf(MAX_PATHNAME-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir); - j = strlen(zBuf); - sqlite3Randomness(15, &zBuf[j]); - for(i=0; i<15; i++, j++){ - zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; - } - zBuf[j] = 0; - }while( access(zBuf,0)==0 ); - return SQLITE_OK; -} - - -/* -** Turn a relative pathname into a full pathname. The relative path -** is stored as a nul-terminated string in the buffer pointed to by -** zPath. -** -** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes -** (in this case, MAX_PATHNAME bytes). The full-path is written to -** this buffer before returning. -*/ -static int unixFullPathname( - sqlite3_vfs *pVfs, /* Pointer to vfs object */ - const char *zPath, /* Possibly relative input path */ - int nOut, /* Size of output buffer in bytes */ - char *zOut /* Output buffer */ -){ - - /* It's odd to simulate an io-error here, but really this is just - ** using the io-error infrastructure to test that SQLite handles this - ** function failing. This function could fail if, for example, the - ** current working directly has been unlinked. - */ - SimulateIOError( return SQLITE_ERROR ); - - assert( pVfs->mxPathname==MAX_PATHNAME ); - zOut[MAX_PATHNAME-1] = '\0'; - if( zPath[0]=='/' ){ - sqlite3_snprintf(MAX_PATHNAME, zOut, "%s", zPath); - }else{ - int nCwd; - if( getcwd(zOut, MAX_PATHNAME-1)==0 ){ - return SQLITE_CANTOPEN; - } - nCwd = strlen(zOut); - sqlite3_snprintf(MAX_PATHNAME-nCwd, &zOut[nCwd], "/%s", zPath); - } - return SQLITE_OK; - -#if 0 - /* - ** Remove "/./" path elements and convert "/A/./" path elements - ** to just "/". - */ - if( zFull ){ - int i, j; - for(i=j=0; zFull[i]; i++){ - if( zFull[i]=='/' ){ - if( zFull[i+1]=='/' ) continue; - if( zFull[i+1]=='.' && zFull[i+2]=='/' ){ - i += 1; - continue; - } - if( zFull[i+1]=='.' && zFull[i+2]=='.' && zFull[i+3]=='/' ){ - while( j>0 && zFull[j-1]!='/' ){ j--; } - i += 3; - continue; - } - } - zFull[j++] = zFull[i]; - } - zFull[j] = 0; - } -#endif -} - - -#ifndef SQLITE_OMIT_LOAD_EXTENSION -/* -** Interfaces for opening a shared library, finding entry points -** within the shared library, and closing the shared library. -*/ -#include -static void *unixDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ - return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL); -} - -/* -** SQLite calls this function immediately after a call to unixDlSym() or -** unixDlOpen() fails (returns a null pointer). If a more detailed error -** message is available, it is written to zBufOut. If no error message -** is available, zBufOut is left unmodified and SQLite uses a default -** error message. -*/ -static void unixDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ - char *zErr; - enterMutex(); - zErr = dlerror(); - if( zErr ){ - sqlite3_snprintf(nBuf, zBufOut, "%s", zErr); - } - leaveMutex(); -} -static void *unixDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ - return dlsym(pHandle, zSymbol); -} -static void unixDlClose(sqlite3_vfs *pVfs, void *pHandle){ - dlclose(pHandle); -} -#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ - #define unixDlOpen 0 - #define unixDlError 0 - #define unixDlSym 0 - #define unixDlClose 0 -#endif - -/* -** Write nBuf bytes of random data to the supplied buffer zBuf. -*/ -static int unixRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ - - assert(nBuf>=(sizeof(time_t)+sizeof(int))); - - /* We have to initialize zBuf to prevent valgrind from reporting - ** errors. The reports issued by valgrind are incorrect - we would - ** prefer that the randomness be increased by making use of the - ** uninitialized space in zBuf - but valgrind errors tend to worry - ** some users. Rather than argue, it seems easier just to initialize - ** the whole array and silence valgrind, even if that means less randomness - ** in the random seed. - ** - ** When testing, initializing zBuf[] to zero is all we do. That means - ** that we always use the same random number sequence. This makes the - ** tests repeatable. - */ - memset(zBuf, 0, nBuf); -#if !defined(SQLITE_TEST) - { - int pid, fd; - fd = open("/dev/urandom", O_RDONLY); - if( fd<0 ){ - time_t t; - time(&t); - memcpy(zBuf, &t, sizeof(t)); - pid = getpid(); - memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid)); - }else{ - read(fd, zBuf, nBuf); - close(fd); - } - } -#endif - return SQLITE_OK; -} - - -/* -** Sleep for a little while. Return the amount of time slept. -** The argument is the number of microseconds we want to sleep. -** The return value is the number of microseconds of sleep actually -** requested from the underlying operating system, a number which -** might be greater than or equal to the argument, but not less -** than the argument. -*/ -static int unixSleep(sqlite3_vfs *pVfs, int microseconds){ -#if defined(HAVE_USLEEP) && HAVE_USLEEP - usleep(microseconds); - return microseconds; -#else - int seconds = (microseconds+999999)/1000000; - sleep(seconds); - return seconds*1000000; -#endif -} - -/* -** The following variable, if set to a non-zero value, becomes the result -** returned from sqlite3OsCurrentTime(). This is used for testing. -*/ -#ifdef SQLITE_TEST -int sqlite3_current_time = 0; -#endif - -/* -** Find the current time (in Universal Coordinated Time). Write the -** current time and date as a Julian Day number into *prNow and -** return 0. Return 1 if the time and date cannot be found. -*/ -static int unixCurrentTime(sqlite3_vfs *pVfs, double *prNow){ -#ifdef NO_GETTOD - time_t t; - time(&t); - *prNow = t/86400.0 + 2440587.5; -#else - struct timeval sNow; - gettimeofday(&sNow, 0); - *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_usec/86400000000.0; -#endif -#ifdef SQLITE_TEST - if( sqlite3_current_time ){ - *prNow = sqlite3_current_time/86400.0 + 2440587.5; - } -#endif - return 0; -} - -/* -** Return a pointer to the sqlite3DefaultVfs structure. We use -** a function rather than give the structure global scope because -** some compilers (MSVC) do not allow forward declarations of -** initialized structures. -*/ -sqlite3_vfs *sqlite3OsDefaultVfs(void){ - static sqlite3_vfs unixVfs = { - 1, /* iVersion */ - sizeof(unixFile), /* szOsFile */ - MAX_PATHNAME, /* mxPathname */ - 0, /* pNext */ - "unix", /* zName */ - 0, /* pAppData */ - - unixOpen, /* xOpen */ - unixDelete, /* xDelete */ - unixAccess, /* xAccess */ - unixGetTempname, /* xGetTempName */ - unixFullPathname, /* xFullPathname */ - unixDlOpen, /* xDlOpen */ - unixDlError, /* xDlError */ - unixDlSym, /* xDlSym */ - unixDlClose, /* xDlClose */ - unixRandomness, /* xRandomness */ - unixSleep, /* xSleep */ - unixCurrentTime /* xCurrentTime */ - }; - - return &unixVfs; -} - -#endif /* OS_UNIX */ diff --git a/extensions/sqlite/sqlite-source/os_win.c b/extensions/sqlite/sqlite-source/os_win.c deleted file mode 100644 index bcb1c6ec..00000000 --- a/extensions/sqlite/sqlite-source/os_win.c +++ /dev/null @@ -1,1545 +0,0 @@ -/* -** 2004 May 22 -** -** 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 file contains code that is specific to windows. -*/ -#include "sqliteInt.h" -#if OS_WIN /* This file is used for windows only */ - - -/* -** A Note About Memory Allocation: -** -** This driver uses malloc()/free() directly rather than going through -** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers -** are designed for use on embedded systems where memory is scarce and -** malloc failures happen frequently. Win32 does not typically run on -** embedded systems, and when it does the developers normally have bigger -** problems to worry about than running out of memory. So there is not -** a compelling need to use the wrappers. -** -** But there is a good reason to not use the wrappers. If we use the -** wrappers then we will get simulated malloc() failures within this -** driver. And that causes all kinds of problems for our tests. We -** could enhance SQLite to deal with simulated malloc failures within -** the OS driver, but the code to deal with those failure would not -** be exercised on Linux (which does not need to malloc() in the driver) -** and so we would have difficulty writing coverage tests for that -** code. Better to leave the code out, we think. -** -** The point of this discussion is as follows: When creating a new -** OS layer for an embedded system, if you use this file as an example, -** avoid the use of malloc()/free(). Those routines work ok on windows -** desktops but not so well in embedded systems. -*/ - -#include - -#ifdef __CYGWIN__ -# include -#endif - -/* -** Macros used to determine whether or not to use threads. -*/ -#if defined(THREADSAFE) && THREADSAFE -# define SQLITE_W32_THREADS 1 -#endif - -/* -** Include code that is common to all os_*.c files -*/ -#include "os_common.h" - -/* -** Determine if we are dealing with WindowsCE - which has a much -** reduced API. -*/ -#if defined(_WIN32_WCE) -# define OS_WINCE 1 -# define AreFileApisANSI() 1 -#else -# define OS_WINCE 0 -#endif - -/* -** WinCE lacks native support for file locking so we have to fake it -** with some code of our own. -*/ -#if OS_WINCE -typedef struct winceLock { - int nReaders; /* Number of reader locks obtained */ - BOOL bPending; /* Indicates a pending lock has been obtained */ - BOOL bReserved; /* Indicates a reserved lock has been obtained */ - BOOL bExclusive; /* Indicates an exclusive lock has been obtained */ -} winceLock; -#endif - -/* -** The winFile structure is a subclass of sqlite3_file* specific to the win32 -** portability layer. -*/ -typedef struct winFile winFile; -struct winFile { - const sqlite3_io_methods *pMethod;/* Must be first */ - HANDLE h; /* Handle for accessing the file */ - unsigned char locktype; /* Type of lock currently held on this file */ - short sharedLockByte; /* Randomly chosen byte used as a shared lock */ -#if OS_WINCE - WCHAR *zDeleteOnClose; /* Name of file to delete when closing */ - HANDLE hMutex; /* Mutex used to control access to shared lock */ - HANDLE hShared; /* Shared memory segment used for locking */ - winceLock local; /* Locks obtained by this instance of winFile */ - winceLock *shared; /* Global shared lock memory for the file */ -#endif -}; - - -/* -** The following variable is (normally) set once and never changes -** thereafter. It records whether the operating system is Win95 -** or WinNT. -** -** 0: Operating system unknown. -** 1: Operating system is Win95. -** 2: Operating system is WinNT. -** -** In order to facilitate testing on a WinNT system, the test fixture -** can manually set this value to 1 to emulate Win98 behavior. -*/ -#ifdef SQLITE_TEST -int sqlite3_os_type = 0; -#else -static int sqlite3_os_type = 0; -#endif - -/* -** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, -** or WinCE. Return false (zero) for Win95, Win98, or WinME. -** -** Here is an interesting observation: Win95, Win98, and WinME lack -** the LockFileEx() API. But we can still statically link against that -** API as long as we don't call it win running Win95/98/ME. A call to -** this routine is used to determine if the host is Win95/98/ME or -** WinNT/2K/XP so that we will know whether or not we can safely call -** the LockFileEx() API. -*/ -#if OS_WINCE -# define isNT() (1) -#else - static int isNT(void){ - if( sqlite3_os_type==0 ){ - OSVERSIONINFO sInfo; - sInfo.dwOSVersionInfoSize = sizeof(sInfo); - GetVersionEx(&sInfo); - sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; - } - return sqlite3_os_type==2; - } -#endif /* OS_WINCE */ - -/* -** Convert a UTF-8 string to microsoft unicode (UTF-16?). -** -** Space to hold the returned string is obtained from malloc. -*/ -static WCHAR *utf8ToUnicode(const char *zFilename){ - int nChar; - WCHAR *zWideFilename; - - nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); - zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) ); - if( zWideFilename==0 ){ - return 0; - } - nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar); - if( nChar==0 ){ - free(zWideFilename); - zWideFilename = 0; - } - return zWideFilename; -} - -/* -** Convert microsoft unicode to UTF-8. Space to hold the returned string is -** obtained from malloc(). -*/ -static char *unicodeToUtf8(const WCHAR *zWideFilename){ - int nByte; - char *zFilename; - - nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); - zFilename = malloc( nByte ); - if( zFilename==0 ){ - return 0; - } - nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, - 0, 0); - if( nByte == 0 ){ - free(zFilename); - zFilename = 0; - } - return zFilename; -} - -/* -** Convert an ansi string to microsoft unicode, based on the -** current codepage settings for file apis. -** -** Space to hold the returned string is obtained -** from malloc. -*/ -static WCHAR *mbcsToUnicode(const char *zFilename){ - int nByte; - WCHAR *zMbcsFilename; - int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; - - nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR); - zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) ); - if( zMbcsFilename==0 ){ - return 0; - } - nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte); - if( nByte==0 ){ - free(zMbcsFilename); - zMbcsFilename = 0; - } - return zMbcsFilename; -} - -/* -** Convert microsoft unicode to multibyte character string, based on the -** user's Ansi codepage. -** -** Space to hold the returned string is obtained from -** malloc(). -*/ -static char *unicodeToMbcs(const WCHAR *zWideFilename){ - int nByte; - char *zFilename; - int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; - - nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); - zFilename = malloc( nByte ); - if( zFilename==0 ){ - return 0; - } - nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte, - 0, 0); - if( nByte == 0 ){ - free(zFilename); - zFilename = 0; - } - return zFilename; -} - -/* -** Convert multibyte character string to UTF-8. Space to hold the -** returned string is obtained from malloc(). -*/ -static char *mbcsToUtf8(const char *zFilename){ - char *zFilenameUtf8; - WCHAR *zTmpWide; - - zTmpWide = mbcsToUnicode(zFilename); - if( zTmpWide==0 ){ - return 0; - } - zFilenameUtf8 = unicodeToUtf8(zTmpWide); - free(zTmpWide); - return zFilenameUtf8; -} - -/* -** Convert UTF-8 to multibyte character string. Space to hold the -** returned string is obtained from malloc(). -*/ -static char *utf8ToMbcs(const char *zFilename){ - char *zFilenameMbcs; - WCHAR *zTmpWide; - - zTmpWide = utf8ToUnicode(zFilename); - if( zTmpWide==0 ){ - return 0; - } - zFilenameMbcs = unicodeToMbcs(zTmpWide); - free(zTmpWide); - return zFilenameMbcs; -} - -#if OS_WINCE -/************************************************************************* -** This section contains code for WinCE only. -*/ -/* -** WindowsCE does not have a localtime() function. So create a -** substitute. -*/ -#include -struct tm *__cdecl localtime(const time_t *t) -{ - static struct tm y; - FILETIME uTm, lTm; - SYSTEMTIME pTm; - sqlite3_int64 t64; - t64 = *t; - t64 = (t64 + 11644473600)*10000000; - uTm.dwLowDateTime = t64 & 0xFFFFFFFF; - uTm.dwHighDateTime= t64 >> 32; - FileTimeToLocalFileTime(&uTm,&lTm); - FileTimeToSystemTime(&lTm,&pTm); - y.tm_year = pTm.wYear - 1900; - y.tm_mon = pTm.wMonth - 1; - y.tm_wday = pTm.wDayOfWeek; - y.tm_mday = pTm.wDay; - y.tm_hour = pTm.wHour; - y.tm_min = pTm.wMinute; - y.tm_sec = pTm.wSecond; - return &y; -} - -/* This will never be called, but defined to make the code compile */ -#define GetTempPathA(a,b) - -#define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e) -#define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e) -#define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f) - -#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)] - -/* -** Acquire a lock on the handle h -*/ -static void winceMutexAcquire(HANDLE h){ - DWORD dwErr; - do { - dwErr = WaitForSingleObject(h, INFINITE); - } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED); -} -/* -** Release a lock acquired by winceMutexAcquire() -*/ -#define winceMutexRelease(h) ReleaseMutex(h) - -/* -** Create the mutex and shared memory used for locking in the file -** descriptor pFile -*/ -static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ - WCHAR *zTok; - WCHAR *zName = utf8ToUnicode(zFilename); - BOOL bInit = TRUE; - - /* Initialize the local lockdata */ - ZeroMemory(&pFile->local, sizeof(pFile->local)); - - /* Replace the backslashes from the filename and lowercase it - ** to derive a mutex name. */ - zTok = CharLowerW(zName); - for (;*zTok;zTok++){ - if (*zTok == '\\') *zTok = '_'; - } - - /* Create/open the named mutex */ - pFile->hMutex = CreateMutexW(NULL, FALSE, zName); - if (!pFile->hMutex){ - free(zName); - return FALSE; - } - - /* Acquire the mutex before continuing */ - winceMutexAcquire(pFile->hMutex); - - /* Since the names of named mutexes, semaphores, file mappings etc are - ** case-sensitive, take advantage of that by uppercasing the mutex name - ** and using that as the shared filemapping name. - */ - CharUpperW(zName); - pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, - PAGE_READWRITE, 0, sizeof(winceLock), - zName); - - /* Set a flag that indicates we're the first to create the memory so it - ** must be zero-initialized */ - if (GetLastError() == ERROR_ALREADY_EXISTS){ - bInit = FALSE; - } - - free(zName); - - /* If we succeeded in making the shared memory handle, map it. */ - if (pFile->hShared){ - pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, - FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); - /* If mapping failed, close the shared memory handle and erase it */ - if (!pFile->shared){ - CloseHandle(pFile->hShared); - pFile->hShared = NULL; - } - } - - /* If shared memory could not be created, then close the mutex and fail */ - if (pFile->hShared == NULL){ - winceMutexRelease(pFile->hMutex); - CloseHandle(pFile->hMutex); - pFile->hMutex = NULL; - return FALSE; - } - - /* Initialize the shared memory if we're supposed to */ - if (bInit) { - ZeroMemory(pFile->shared, sizeof(winceLock)); - } - - winceMutexRelease(pFile->hMutex); - return TRUE; -} - -/* -** Destroy the part of winFile that deals with wince locks -*/ -static void winceDestroyLock(winFile *pFile){ - if (pFile->hMutex){ - /* Acquire the mutex */ - winceMutexAcquire(pFile->hMutex); - - /* The following blocks should probably assert in debug mode, but they - are to cleanup in case any locks remained open */ - if (pFile->local.nReaders){ - pFile->shared->nReaders --; - } - if (pFile->local.bReserved){ - pFile->shared->bReserved = FALSE; - } - if (pFile->local.bPending){ - pFile->shared->bPending = FALSE; - } - if (pFile->local.bExclusive){ - pFile->shared->bExclusive = FALSE; - } - - /* De-reference and close our copy of the shared memory handle */ - UnmapViewOfFile(pFile->shared); - CloseHandle(pFile->hShared); - - if( pFile->zDeleteOnClose ){ - DeleteFileW(pFile->zDeleteOnClose); - free(pFile->zDeleteOnClose); - pFile->zDeleteOnClose = 0; - } - - /* Done with the mutex */ - winceMutexRelease(pFile->hMutex); - CloseHandle(pFile->hMutex); - pFile->hMutex = NULL; - } -} - -/* -** An implementation of the LockFile() API of windows for wince -*/ -static BOOL winceLockFile( - HANDLE *phFile, - DWORD dwFileOffsetLow, - DWORD dwFileOffsetHigh, - DWORD nNumberOfBytesToLockLow, - DWORD nNumberOfBytesToLockHigh -){ - winFile *pFile = HANDLE_TO_WINFILE(phFile); - BOOL bReturn = FALSE; - - if (!pFile->hMutex) return TRUE; - winceMutexAcquire(pFile->hMutex); - - /* Wanting an exclusive lock? */ - if (dwFileOffsetLow == SHARED_FIRST - && nNumberOfBytesToLockLow == SHARED_SIZE){ - if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){ - pFile->shared->bExclusive = TRUE; - pFile->local.bExclusive = TRUE; - bReturn = TRUE; - } - } - - /* Want a read-only lock? */ - else if ((dwFileOffsetLow >= SHARED_FIRST && - dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) && - nNumberOfBytesToLockLow == 1){ - if (pFile->shared->bExclusive == 0){ - pFile->local.nReaders ++; - if (pFile->local.nReaders == 1){ - pFile->shared->nReaders ++; - } - bReturn = TRUE; - } - } - - /* Want a pending lock? */ - else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){ - /* If no pending lock has been acquired, then acquire it */ - if (pFile->shared->bPending == 0) { - pFile->shared->bPending = TRUE; - pFile->local.bPending = TRUE; - bReturn = TRUE; - } - } - /* Want a reserved lock? */ - else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){ - if (pFile->shared->bReserved == 0) { - pFile->shared->bReserved = TRUE; - pFile->local.bReserved = TRUE; - bReturn = TRUE; - } - } - - winceMutexRelease(pFile->hMutex); - return bReturn; -} - -/* -** An implementation of the UnlockFile API of windows for wince -*/ -static BOOL winceUnlockFile( - HANDLE *phFile, - DWORD dwFileOffsetLow, - DWORD dwFileOffsetHigh, - DWORD nNumberOfBytesToUnlockLow, - DWORD nNumberOfBytesToUnlockHigh -){ - winFile *pFile = HANDLE_TO_WINFILE(phFile); - BOOL bReturn = FALSE; - - if (!pFile->hMutex) return TRUE; - winceMutexAcquire(pFile->hMutex); - - /* Releasing a reader lock or an exclusive lock */ - if (dwFileOffsetLow >= SHARED_FIRST && - dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){ - /* Did we have an exclusive lock? */ - if (pFile->local.bExclusive){ - pFile->local.bExclusive = FALSE; - pFile->shared->bExclusive = FALSE; - bReturn = TRUE; - } - - /* Did we just have a reader lock? */ - else if (pFile->local.nReaders){ - pFile->local.nReaders --; - if (pFile->local.nReaders == 0) - { - pFile->shared->nReaders --; - } - bReturn = TRUE; - } - } - - /* Releasing a pending lock */ - else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){ - if (pFile->local.bPending){ - pFile->local.bPending = FALSE; - pFile->shared->bPending = FALSE; - bReturn = TRUE; - } - } - /* Releasing a reserved lock */ - else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){ - if (pFile->local.bReserved) { - pFile->local.bReserved = FALSE; - pFile->shared->bReserved = FALSE; - bReturn = TRUE; - } - } - - winceMutexRelease(pFile->hMutex); - return bReturn; -} - -/* -** An implementation of the LockFileEx() API of windows for wince -*/ -static BOOL winceLockFileEx( - HANDLE *phFile, - DWORD dwFlags, - DWORD dwReserved, - DWORD nNumberOfBytesToLockLow, - DWORD nNumberOfBytesToLockHigh, - LPOVERLAPPED lpOverlapped -){ - /* If the caller wants a shared read lock, forward this call - ** to winceLockFile */ - if (lpOverlapped->Offset == SHARED_FIRST && - dwFlags == 1 && - nNumberOfBytesToLockLow == SHARED_SIZE){ - return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0); - } - return FALSE; -} -/* -** End of the special code for wince -*****************************************************************************/ -#endif /* OS_WINCE */ - -/***************************************************************************** -** The next group of routines implement the I/O methods specified -** by the sqlite3_io_methods object. -******************************************************************************/ - -/* -** Close a file. -** -** It is reported that an attempt to close a handle might sometimes -** fail. This is a very unreasonable result, but windows is notorious -** for being unreasonable so I do not doubt that it might happen. If -** the close fails, we pause for 100 milliseconds and try again. As -** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before -** giving up and returning an error. -*/ -#define MX_CLOSE_ATTEMPT 3 -static int winClose(sqlite3_file *id){ - int rc, cnt = 0; - winFile *pFile = (winFile*)id; - OSTRACE2("CLOSE %d\n", pFile->h); - do{ - rc = CloseHandle(pFile->h); - }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); -#if OS_WINCE - winceDestroyLock(pFile); -#endif - OpenCounter(-1); - return rc ? SQLITE_OK : SQLITE_IOERR; -} - -/* -** Some microsoft compilers lack this definition. -*/ -#ifndef INVALID_SET_FILE_POINTER -# define INVALID_SET_FILE_POINTER ((DWORD)-1) -#endif - -/* -** Read data from a file into a buffer. Return SQLITE_OK if all -** bytes were read successfully and SQLITE_IOERR if anything goes -** wrong. -*/ -static int winRead( - sqlite3_file *id, /* File to read from */ - void *pBuf, /* Write content into this buffer */ - int amt, /* Number of bytes to read */ - sqlite3_int64 offset /* Begin reading at this offset */ -){ - LONG upperBits = (offset>>32) & 0x7fffffff; - LONG lowerBits = offset & 0xffffffff; - DWORD rc; - DWORD got; - winFile *pFile = (winFile*)id; - assert( id!=0 ); - SimulateIOError(return SQLITE_IOERR_READ); - OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype); - rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); - if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){ - return SQLITE_FULL; - } - if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){ - return SQLITE_IOERR_READ; - } - if( got==(DWORD)amt ){ - return SQLITE_OK; - }else{ - memset(&((char*)pBuf)[got], 0, amt-got); - return SQLITE_IOERR_SHORT_READ; - } -} - -/* -** Write data from a buffer into a file. Return SQLITE_OK on success -** or some other error code on failure. -*/ -static int winWrite( - sqlite3_file *id, /* File to write into */ - const void *pBuf, /* The bytes to be written */ - int amt, /* Number of bytes to write */ - sqlite3_int64 offset /* Offset into the file to begin writing at */ -){ - LONG upperBits = (offset>>32) & 0x7fffffff; - LONG lowerBits = offset & 0xffffffff; - DWORD rc; - DWORD wrote; - winFile *pFile = (winFile*)id; - assert( id!=0 ); - SimulateIOError(return SQLITE_IOERR_WRITE); - SimulateDiskfullError(return SQLITE_FULL); - OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype); - rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); - if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){ - return SQLITE_FULL; - } - assert( amt>0 ); - while( - amt>0 - && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0 - && wrote>0 - ){ - amt -= wrote; - pBuf = &((char*)pBuf)[wrote]; - } - if( !rc || amt>(int)wrote ){ - return SQLITE_FULL; - } - return SQLITE_OK; -} - -/* -** Truncate an open file to a specified size -*/ -static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ - LONG upperBits = (nByte>>32) & 0x7fffffff; - LONG lowerBits = nByte & 0xffffffff; - winFile *pFile = (winFile*)id; - OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte); - SimulateIOError(return SQLITE_IOERR_TRUNCATE); - SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); - SetEndOfFile(pFile->h); - return SQLITE_OK; -} - -#ifdef SQLITE_TEST -/* -** Count the number of fullsyncs and normal syncs. This is used to test -** that syncs and fullsyncs are occuring at the right times. -*/ -int sqlite3_sync_count = 0; -int sqlite3_fullsync_count = 0; -#endif - -/* -** Make sure all writes to a particular file are committed to disk. -*/ -static int winSync(sqlite3_file *id, int flags){ - winFile *pFile = (winFile*)id; - OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype); -#ifdef SQLITE_TEST - if( flags & SQLITE_SYNC_FULL ){ - sqlite3_fullsync_count++; - } - sqlite3_sync_count++; -#endif - if( FlushFileBuffers(pFile->h) ){ - return SQLITE_OK; - }else{ - return SQLITE_IOERR; - } -} - -/* -** Determine the current size of a file in bytes -*/ -static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ - winFile *pFile = (winFile*)id; - DWORD upperBits, lowerBits; - SimulateIOError(return SQLITE_IOERR_FSTAT); - lowerBits = GetFileSize(pFile->h, &upperBits); - *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; - return SQLITE_OK; -} - -/* -** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. -*/ -#ifndef LOCKFILE_FAIL_IMMEDIATELY -# define LOCKFILE_FAIL_IMMEDIATELY 1 -#endif - -/* -** Acquire a reader lock. -** Different API routines are called depending on whether or not this -** is Win95 or WinNT. -*/ -static int getReadLock(winFile *pFile){ - int res; - if( isNT() ){ - OVERLAPPED ovlp; - ovlp.Offset = SHARED_FIRST; - ovlp.OffsetHigh = 0; - ovlp.hEvent = 0; - res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, - 0, SHARED_SIZE, 0, &ovlp); - }else{ - int lk; - sqlite3Randomness(sizeof(lk), &lk); - pFile->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1); - res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); - } - return res; -} - -/* -** Undo a readlock -*/ -static int unlockReadLock(winFile *pFile){ - int res; - if( isNT() ){ - res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); - }else{ - res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); - } - return res; -} - -/* -** Lock the file with the lock specified by parameter locktype - one -** of the following: -** -** (1) SHARED_LOCK -** (2) RESERVED_LOCK -** (3) PENDING_LOCK -** (4) EXCLUSIVE_LOCK -** -** Sometimes when requesting one lock state, additional lock states -** are inserted in between. The locking might fail on one of the later -** transitions leaving the lock state different from what it started but -** still short of its goal. The following chart shows the allowed -** transitions and the inserted intermediate states: -** -** UNLOCKED -> SHARED -** SHARED -> RESERVED -** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> (PENDING) -> EXCLUSIVE -** PENDING -> EXCLUSIVE -** -** This routine will only increase a lock. The winUnlock() routine -** erases all locks at once and returns us immediately to locking level 0. -** It is not possible to lower the locking level one step at a time. You -** must go straight to locking level 0. -*/ -static int winLock(sqlite3_file *id, int locktype){ - int rc = SQLITE_OK; /* Return code from subroutines */ - int res = 1; /* Result of a windows lock call */ - int newLocktype; /* Set pFile->locktype to this value before exiting */ - int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ - winFile *pFile = (winFile*)id; - - assert( pFile!=0 ); - OSTRACE5("LOCK %d %d was %d(%d)\n", - pFile->h, locktype, pFile->locktype, pFile->sharedLockByte); - - /* If there is already a lock of this type or more restrictive on the - ** OsFile, do nothing. Don't use the end_lock: exit path, as - ** sqlite3OsEnterMutex() hasn't been called yet. - */ - if( pFile->locktype>=locktype ){ - return SQLITE_OK; - } - - /* Make sure the locking sequence is correct - */ - assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); - assert( locktype!=PENDING_LOCK ); - assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); - - /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or - ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of - ** the PENDING_LOCK byte is temporary. - */ - newLocktype = pFile->locktype; - if( pFile->locktype==NO_LOCK - || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) - ){ - int cnt = 3; - while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ - /* Try 3 times to get the pending lock. The pending lock might be - ** held by another reader process who will release it momentarily. - */ - OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt); - Sleep(1); - } - gotPendingLock = res; - } - - /* Acquire a shared lock - */ - if( locktype==SHARED_LOCK && res ){ - assert( pFile->locktype==NO_LOCK ); - res = getReadLock(pFile); - if( res ){ - newLocktype = SHARED_LOCK; - } - } - - /* Acquire a RESERVED lock - */ - if( locktype==RESERVED_LOCK && res ){ - assert( pFile->locktype==SHARED_LOCK ); - res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); - if( res ){ - newLocktype = RESERVED_LOCK; - } - } - - /* Acquire a PENDING lock - */ - if( locktype==EXCLUSIVE_LOCK && res ){ - newLocktype = PENDING_LOCK; - gotPendingLock = 0; - } - - /* Acquire an EXCLUSIVE lock - */ - if( locktype==EXCLUSIVE_LOCK && res ){ - assert( pFile->locktype>=SHARED_LOCK ); - res = unlockReadLock(pFile); - OSTRACE2("unreadlock = %d\n", res); - res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); - if( res ){ - newLocktype = EXCLUSIVE_LOCK; - }else{ - OSTRACE2("error-code = %d\n", GetLastError()); - getReadLock(pFile); - } - } - - /* If we are holding a PENDING lock that ought to be released, then - ** release it now. - */ - if( gotPendingLock && locktype==SHARED_LOCK ){ - UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); - } - - /* Update the state of the lock has held in the file descriptor then - ** return the appropriate result code. - */ - if( res ){ - rc = SQLITE_OK; - }else{ - OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h, - locktype, newLocktype); - rc = SQLITE_BUSY; - } - pFile->locktype = newLocktype; - return rc; -} - -/* -** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, return -** non-zero, otherwise zero. -*/ -static int winCheckReservedLock(sqlite3_file *id){ - int rc; - winFile *pFile = (winFile*)id; - assert( pFile!=0 ); - if( pFile->locktype>=RESERVED_LOCK ){ - rc = 1; - OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc); - }else{ - rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); - if( rc ){ - UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); - } - rc = !rc; - OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc); - } - return rc; -} - -/* -** Lower the locking level on file descriptor id to locktype. locktype -** must be either NO_LOCK or SHARED_LOCK. -** -** If the locking level of the file descriptor is already at or below -** the requested locking level, this routine is a no-op. -** -** It is not possible for this routine to fail if the second argument -** is NO_LOCK. If the second argument is SHARED_LOCK then this routine -** might return SQLITE_IOERR; -*/ -static int winUnlock(sqlite3_file *id, int locktype){ - int type; - winFile *pFile = (winFile*)id; - int rc = SQLITE_OK; - assert( pFile!=0 ); - assert( locktype<=SHARED_LOCK ); - OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype, - pFile->locktype, pFile->sharedLockByte); - type = pFile->locktype; - if( type>=EXCLUSIVE_LOCK ){ - UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); - if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ - /* This should never happen. We should always be able to - ** reacquire the read lock */ - rc = SQLITE_IOERR_UNLOCK; - } - } - if( type>=RESERVED_LOCK ){ - UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); - } - if( locktype==NO_LOCK && type>=SHARED_LOCK ){ - unlockReadLock(pFile); - } - if( type>=PENDING_LOCK ){ - UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); - } - pFile->locktype = locktype; - return rc; -} - -/* -** Control and query of the open file handle. -*/ -static int winFileControl(sqlite3_file *id, int op, void *pArg){ - switch( op ){ - case SQLITE_FCNTL_LOCKSTATE: { - *(int*)pArg = ((winFile*)id)->locktype; - return SQLITE_OK; - } - } - return SQLITE_ERROR; -} - -/* -** Return the sector size in bytes of the underlying block device for -** the specified file. This is almost always 512 bytes, but may be -** larger for some devices. -** -** SQLite code assumes this function cannot fail. It also assumes that -** if two files are created in the same file-system directory (i.e. -** a database and it's journal file) that the sector size will be the -** same for both. -*/ -static int winSectorSize(sqlite3_file *id){ - return SQLITE_DEFAULT_SECTOR_SIZE; -} - -/* -** Return a vector of device characteristics. -*/ -static int winDeviceCharacteristics(sqlite3_file *id){ - return 0; -} - -/* -** This vector defines all the methods that can operate on an -** sqlite3_file for win32. -*/ -static const sqlite3_io_methods winIoMethod = { - 1, /* iVersion */ - winClose, - winRead, - winWrite, - winTruncate, - winSync, - winFileSize, - winLock, - winUnlock, - winCheckReservedLock, - winFileControl, - winSectorSize, - winDeviceCharacteristics -}; - -/*************************************************************************** -** Here ends the I/O methods that form the sqlite3_io_methods object. -** -** The next block of code implements the VFS methods. -****************************************************************************/ - -/* -** Convert a UTF-8 filename into whatever form the underlying -** operating system wants filenames in. Space to hold the result -** is obtained from malloc and must be freed by the calling -** function. -*/ -static void *convertUtf8Filename(const char *zFilename){ - void *zConverted = 0; - if( isNT() ){ - zConverted = utf8ToUnicode(zFilename); - }else{ - zConverted = utf8ToMbcs(zFilename); - } - /* caller will handle out of memory */ - return zConverted; -} - -/* -** Open a file. -*/ -static int winOpen( - sqlite3_vfs *pVfs, /* Not used */ - const char *zName, /* Name of the file (UTF-8) */ - sqlite3_file *id, /* Write the SQLite file handle here */ - int flags, /* Open mode flags */ - int *pOutFlags /* Status return flags */ -){ - HANDLE h; - DWORD dwDesiredAccess; - DWORD dwShareMode; - DWORD dwCreationDisposition; - DWORD dwFlagsAndAttributes = 0; - winFile *pFile = (winFile*)id; - void *zConverted = convertUtf8Filename(zName); - if( zConverted==0 ){ - return SQLITE_NOMEM; - } - - if( flags & SQLITE_OPEN_READWRITE ){ - dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; - }else{ - dwDesiredAccess = GENERIC_READ; - } - if( flags & SQLITE_OPEN_CREATE ){ - dwCreationDisposition = OPEN_ALWAYS; - }else{ - dwCreationDisposition = OPEN_EXISTING; - } - if( flags & SQLITE_OPEN_MAIN_DB ){ - dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; - }else{ - dwShareMode = 0; - } - if( flags & (SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_TEMP_JOURNAL - | SQLITE_OPEN_SUBJOURNAL) ){ - dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY - | FILE_ATTRIBUTE_HIDDEN - | FILE_FLAG_DELETE_ON_CLOSE; - }else{ - dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; - } - if( flags & (SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_TEMP_DB) ){ - dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; - }else{ - dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; - } - if( isNT() ){ - h = CreateFileW((WCHAR*)zConverted, - dwDesiredAccess, - dwShareMode, - NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL - ); - }else{ -#if OS_WINCE - return SQLITE_NOMEM; -#else - h = CreateFileA((char*)zConverted, - dwDesiredAccess, - dwShareMode, - NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL - ); -#endif - } - if( h==INVALID_HANDLE_VALUE ){ - free(zConverted); - if( flags & SQLITE_OPEN_READWRITE ){ - return winOpen(0, zName, id, - ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags); - }else{ - return SQLITE_CANTOPEN; - } - } - if( pOutFlags ){ - if( flags & SQLITE_OPEN_READWRITE ){ - *pOutFlags = SQLITE_OPEN_READWRITE; - }else{ - *pOutFlags = SQLITE_OPEN_READONLY; - } - } - memset(pFile, 0, sizeof(*pFile)); - pFile->pMethod = &winIoMethod; - pFile->h = h; -#if OS_WINCE - if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) == - (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB) - && !winceCreateLock(zFilename, pFile) - ){ - CloseHandle(h); - free(zConverted); - return SQLITE_CANTOPEN; - } - if( dwFlagsAndAttributes & FILE_FLAG_DELETE_ON_CLOSE ){ - pFile->zDeleteOnClose = zConverted; - }else -#endif - { - free(zConverted); - } - OpenCounter(+1); - return SQLITE_OK; -} - -/* -** Delete the named file. -** -** Note that windows does not allow a file to be deleted if some other -** process has it open. Sometimes a virus scanner or indexing program -** will open a journal file shortly after it is created in order to do -** whatever it is it does. While this other process is holding the -** file open, we will be unable to delete it. To work around this -** problem, we delay 100 milliseconds and try to delete again. Up -** to MX_DELETION_ATTEMPTs deletion attempts are run before giving -** up and returning an error. -*/ -#define MX_DELETION_ATTEMPTS 3 -static int winDelete( - sqlite3_vfs *pVfs, /* Not used on win32 */ - const char *zFilename, /* Name of file to delete */ - int syncDir /* Not used on win32 */ -){ - int cnt = 0; - int rc; - void *zConverted = convertUtf8Filename(zFilename); - if( zConverted==0 ){ - return SQLITE_NOMEM; - } - SimulateIOError(return SQLITE_IOERR_DELETE); - if( isNT() ){ - do{ - rc = DeleteFileW(zConverted); - }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff - && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); - }else{ -#if OS_WINCE - return SQLITE_NOMEM; -#else - do{ - rc = DeleteFileA(zConverted); - }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff - && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); -#endif - } - free(zConverted); - OSTRACE2("DELETE \"%s\"\n", zFilename); - return rc!=0 ? SQLITE_OK : SQLITE_IOERR; -} - -/* -** Check the existance and status of a file. -*/ -static int winAccess( - sqlite3_vfs *pVfs, /* Not used on win32 */ - const char *zFilename, /* Name of file to check */ - int flags /* Type of test to make on this file */ -){ - DWORD attr; - int rc; - void *zConverted = convertUtf8Filename(zFilename); - if( zConverted==0 ){ - return SQLITE_NOMEM; - } - if( isNT() ){ - attr = GetFileAttributesW((WCHAR*)zConverted); - }else{ -#if OS_WINCE - return SQLITE_NOMEM; -#else - attr = GetFileAttributesA((char*)zConverted); -#endif - } - free(zConverted); - switch( flags ){ - case SQLITE_ACCESS_READ: - case SQLITE_ACCESS_EXISTS: - rc = attr!=0xffffffff; - break; - case SQLITE_ACCESS_READWRITE: - rc = (attr & FILE_ATTRIBUTE_READONLY)==0; - break; - default: - assert(!"Invalid flags argument"); - } - return rc; -} - - -/* -** Create a temporary file name in zBuf. zBuf must be big enough to -** hold at pVfs->mxPathname characters. -*/ -static int winGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ - static char zChars[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"; - int i, j; - char zTempPath[MAX_PATH+1]; - if( sqlite3_temp_directory ){ - sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); - }else if( isNT() ){ - char *zMulti; - WCHAR zWidePath[MAX_PATH]; - GetTempPathW(MAX_PATH-30, zWidePath); - zMulti = unicodeToUtf8(zWidePath); - if( zMulti ){ - sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); - free(zMulti); - }else{ - return SQLITE_NOMEM; - } - }else{ - char *zUtf8; - char zMbcsPath[MAX_PATH]; - GetTempPathA(MAX_PATH-30, zMbcsPath); - zUtf8 = mbcsToUtf8(zMbcsPath); - if( zUtf8 ){ - sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); - free(zUtf8); - }else{ - return SQLITE_NOMEM; - } - } - for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} - zTempPath[i] = 0; - sqlite3_snprintf(pVfs->mxPathname-30, zBuf, - "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); - j = strlen(zBuf); - sqlite3Randomness(20, &zBuf[j]); - for(i=0; i<20; i++, j++){ - zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; - } - zBuf[j] = 0; - OSTRACE2("TEMP FILENAME: %s\n", zBuf); - return SQLITE_OK; -} - -/* -** Turn a relative pathname into a full pathname. Write the full -** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname -** bytes in size. -*/ -static int winFullPathname( - sqlite3_vfs *pVfs, /* Pointer to vfs object */ - const char *zRelative, /* Possibly relative input path */ - int nFull, /* Size of output buffer in bytes */ - char *zFull /* Output buffer */ -){ - -#if defined(__CYGWIN__) - cygwin_conv_to_full_win32_path(zRelative, zFull); - return SQLITE_OK; -#endif - -#if OS_WINCE - /* WinCE has no concept of a relative pathname, or so I am told. */ - sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); -#endif - -#if !OS_WINCE && !defined(__CYGWIN__) - int nByte; - void *zConverted; - char *zOut; - zConverted = convertUtf8Filename(zRelative); - if( isNT() ){ - WCHAR *zTemp; - nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; - zTemp = malloc( nByte*sizeof(zTemp[0]) ); - if( zTemp==0 ){ - free(zConverted); - return SQLITE_NOMEM; - } - GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0); - free(zConverted); - zOut = unicodeToUtf8(zTemp); - free(zTemp); - }else{ - char *zTemp; - nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; - zTemp = malloc( nByte*sizeof(zTemp[0]) ); - if( zTemp==0 ){ - free(zConverted); - return SQLITE_NOMEM; - } - GetFullPathNameA((char*)zConverted, nByte, zTemp, 0); - free(zConverted); - zOut = mbcsToUtf8(zTemp); - free(zTemp); - } - if( zOut ){ - sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut); - free(zOut); - return SQLITE_OK; - }else{ - return SQLITE_NOMEM; - } -#endif -} - -#ifndef SQLITE_OMIT_LOAD_EXTENSION -/* -** Interfaces for opening a shared library, finding entry points -** within the shared library, and closing the shared library. -*/ -/* -** Interfaces for opening a shared library, finding entry points -** within the shared library, and closing the shared library. -*/ -static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ - HANDLE h; - void *zConverted = convertUtf8Filename(zFilename); - if( zConverted==0 ){ - return 0; - } - if( isNT() ){ - h = LoadLibraryW((WCHAR*)zConverted); - }else{ -#if OS_WINCE - return 0; -#else - h = LoadLibraryA((char*)zConverted); -#endif - } - free(zConverted); - return (void*)h; -} -static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ - FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - 0, - zBufOut, - nBuf-1, - 0 - ); -} -void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ -#if OS_WINCE - /* The GetProcAddressA() routine is only available on wince. */ - return GetProcAddressA((HANDLE)pHandle, zSymbol); -#else - /* All other windows platforms expect GetProcAddress() to take - ** an Ansi string regardless of the _UNICODE setting */ - return GetProcAddress((HANDLE)pHandle, zSymbol); -#endif -} -void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ - FreeLibrary((HANDLE)pHandle); -} -#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ - #define winDlOpen 0 - #define winDlError 0 - #define winDlSym 0 - #define winDlClose 0 -#endif - - -/* -** Write up to nBuf bytes of randomness into zBuf. -*/ -static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ - int n = 0; - if( sizeof(SYSTEMTIME)<=nBuf-n ){ - SYSTEMTIME x; - GetSystemTime(&x); - memcpy(&zBuf[n], &x, sizeof(x)); - n += sizeof(x); - } - if( sizeof(DWORD)<=nBuf-n ){ - DWORD pid = GetCurrentProcessId(); - memcpy(&zBuf[n], &pid, sizeof(pid)); - n += sizeof(pid); - } - if( sizeof(DWORD)<=nBuf-n ){ - DWORD cnt = GetTickCount(); - memcpy(&zBuf[n], &cnt, sizeof(cnt)); - n += sizeof(cnt); - } - if( sizeof(LARGE_INTEGER)<=nBuf-n ){ - LARGE_INTEGER i; - QueryPerformanceCounter(&i); - memcpy(&zBuf[n], &i, sizeof(i)); - n += sizeof(i); - } - return n; -} - - -/* -** Sleep for a little while. Return the amount of time slept. -*/ -static int winSleep(sqlite3_vfs *pVfs, int microsec){ - Sleep((microsec+999)/1000); - return ((microsec+999)/1000)*1000; -} - -/* -** The following variable, if set to a non-zero value, becomes the result -** returned from sqlite3OsCurrentTime(). This is used for testing. -*/ -#ifdef SQLITE_TEST -int sqlite3_current_time = 0; -#endif - -/* -** Find the current time (in Universal Coordinated Time). Write the -** current time and date as a Julian Day number into *prNow and -** return 0. Return 1 if the time and date cannot be found. -*/ -int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ - FILETIME ft; - /* FILETIME structure is a 64-bit value representing the number of - 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). - */ - double now; -#if OS_WINCE - SYSTEMTIME time; - GetSystemTime(&time); - SystemTimeToFileTime(&time,&ft); -#else - GetSystemTimeAsFileTime( &ft ); -#endif - now = ((double)ft.dwHighDateTime) * 4294967296.0; - *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5; -#ifdef SQLITE_TEST - if( sqlite3_current_time ){ - *prNow = sqlite3_current_time/86400.0 + 2440587.5; - } -#endif - return 0; -} - - -/* -** Return a pointer to the sqlite3DefaultVfs structure. We use -** a function rather than give the structure global scope because -** some compilers (MSVC) do not allow forward declarations of -** initialized structures. -*/ -sqlite3_vfs *sqlite3OsDefaultVfs(void){ - static sqlite3_vfs winVfs = { - 1, /* iVersion */ - sizeof(winFile), /* szOsFile */ - MAX_PATH, /* mxPathname */ - 0, /* pNext */ - "win32", /* zName */ - 0, /* pAppData */ - - winOpen, /* xOpen */ - winDelete, /* xDelete */ - winAccess, /* xAccess */ - winGetTempname, /* xGetTempName */ - winFullPathname, /* xFullPathname */ - winDlOpen, /* xDlOpen */ - winDlError, /* xDlError */ - winDlSym, /* xDlSym */ - winDlClose, /* xDlClose */ - winRandomness, /* xRandomness */ - winSleep, /* xSleep */ - winCurrentTime /* xCurrentTime */ - }; - - return &winVfs; -} - -#endif /* OS_WIN */ diff --git a/extensions/sqlite/sqlite-source/pager.c b/extensions/sqlite/sqlite-source/pager.c deleted file mode 100644 index a33b2f71..00000000 --- a/extensions/sqlite/sqlite-source/pager.c +++ /dev/null @@ -1,5104 +0,0 @@ -/* -** 2001 September 15 -** -** 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 is the implementation of the page cache subsystem or "pager". -** -** The pager is used to access a database disk file. It implements -** atomic commit and rollback through the use of a journal file that -** is separate from the database file. The pager also implements file -** locking to prevent two processes from writing the same database -** file simultaneously, or one process from reading the database while -** another is writing. -** -** @(#) $Id$ -*/ -#ifndef SQLITE_OMIT_DISKIO -#include "sqliteInt.h" -#include -#include - -/* -** Macros for troubleshooting. Normally turned off -*/ -#if 0 -#define sqlite3DebugPrintf printf -#define PAGERTRACE1(X) sqlite3DebugPrintf(X) -#define PAGERTRACE2(X,Y) sqlite3DebugPrintf(X,Y) -#define PAGERTRACE3(X,Y,Z) sqlite3DebugPrintf(X,Y,Z) -#define PAGERTRACE4(X,Y,Z,W) sqlite3DebugPrintf(X,Y,Z,W) -#define PAGERTRACE5(X,Y,Z,W,V) sqlite3DebugPrintf(X,Y,Z,W,V) -#else -#define PAGERTRACE1(X) -#define PAGERTRACE2(X,Y) -#define PAGERTRACE3(X,Y,Z) -#define PAGERTRACE4(X,Y,Z,W) -#define PAGERTRACE5(X,Y,Z,W,V) -#endif - -/* -** The following two macros are used within the PAGERTRACEX() macros above -** to print out file-descriptors. -** -** PAGERID() takes a pointer to a Pager struct as it's argument. The -** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file -** struct as it's argument. -*/ -#define PAGERID(p) ((int)(p->fd)) -#define FILEHANDLEID(fd) ((int)fd) - -/* -** The page cache as a whole is always in one of the following -** states: -** -** PAGER_UNLOCK The page cache is not currently reading or -** writing the database file. There is no -** data held in memory. This is the initial -** state. -** -** PAGER_SHARED The page cache is reading the database. -** Writing is not permitted. There can be -** multiple readers accessing the same database -** file at the same time. -** -** PAGER_RESERVED This process has reserved the database for writing -** but has not yet made any changes. Only one process -** at a time can reserve the database. The original -** database file has not been modified so other -** processes may still be reading the on-disk -** database file. -** -** PAGER_EXCLUSIVE The page cache is writing the database. -** Access is exclusive. No other processes or -** threads can be reading or writing while one -** process is writing. -** -** PAGER_SYNCED The pager moves to this state from PAGER_EXCLUSIVE -** after all dirty pages have been written to the -** database file and the file has been synced to -** disk. All that remains to do is to remove or -** truncate the journal file and the transaction -** will be committed. -** -** The page cache comes up in PAGER_UNLOCK. The first time a -** sqlite3PagerGet() occurs, the state transitions to PAGER_SHARED. -** After all pages have been released using sqlite_page_unref(), -** the state transitions back to PAGER_UNLOCK. The first time -** that sqlite3PagerWrite() is called, the state transitions to -** PAGER_RESERVED. (Note that sqlite3PagerWrite() can only be -** called on an outstanding page which means that the pager must -** be in PAGER_SHARED before it transitions to PAGER_RESERVED.) -** PAGER_RESERVED means that there is an open rollback journal. -** The transition to PAGER_EXCLUSIVE occurs before any changes -** are made to the database file, though writes to the rollback -** journal occurs with just PAGER_RESERVED. After an sqlite3PagerRollback() -** or sqlite3PagerCommitPhaseTwo(), the state can go back to PAGER_SHARED, -** or it can stay at PAGER_EXCLUSIVE if we are in exclusive access mode. -*/ -#define PAGER_UNLOCK 0 -#define PAGER_SHARED 1 /* same as SHARED_LOCK */ -#define PAGER_RESERVED 2 /* same as RESERVED_LOCK */ -#define PAGER_EXCLUSIVE 4 /* same as EXCLUSIVE_LOCK */ -#define PAGER_SYNCED 5 - -/* -** If the SQLITE_BUSY_RESERVED_LOCK macro is set to true at compile-time, -** then failed attempts to get a reserved lock will invoke the busy callback. -** This is off by default. To see why, consider the following scenario: -** -** Suppose thread A already has a shared lock and wants a reserved lock. -** Thread B already has a reserved lock and wants an exclusive lock. If -** both threads are using their busy callbacks, it might be a long time -** be for one of the threads give up and allows the other to proceed. -** But if the thread trying to get the reserved lock gives up quickly -** (if it never invokes its busy callback) then the contention will be -** resolved quickly. -*/ -#ifndef SQLITE_BUSY_RESERVED_LOCK -# define SQLITE_BUSY_RESERVED_LOCK 0 -#endif - -/* -** This macro rounds values up so that if the value is an address it -** is guaranteed to be an address that is aligned to an 8-byte boundary. -*/ -#define FORCE_ALIGNMENT(X) (((X)+7)&~7) - -typedef struct PgHdr PgHdr; - -/* -** Each pager stores all currently unreferenced pages in a list sorted -** in least-recently-used (LRU) order (i.e. the first item on the list has -** not been referenced in a long time, the last item has been recently -** used). An instance of this structure is included as part of each -** pager structure for this purpose (variable Pager.lru). -** -** Additionally, if memory-management is enabled, all unreferenced pages -** are stored in a global LRU list (global variable sqlite3LruPageList). -** -** In both cases, the PagerLruList.pFirstSynced variable points to -** the first page in the corresponding list that does not require an -** fsync() operation before it's memory can be reclaimed. If no such -** page exists, PagerLruList.pFirstSynced is set to NULL. -*/ -typedef struct PagerLruList PagerLruList; -struct PagerLruList { - PgHdr *pFirst; /* First page in LRU list */ - PgHdr *pLast; /* Last page in LRU list (the most recently used) */ - PgHdr *pFirstSynced; /* First page in list with PgHdr.needSync==0 */ -}; - -/* -** The following structure contains the next and previous pointers used -** to link a PgHdr structure into a PagerLruList linked list. -*/ -typedef struct PagerLruLink PagerLruLink; -struct PagerLruLink { - PgHdr *pNext; - PgHdr *pPrev; -}; - -/* -** Each in-memory image of a page begins with the following header. -** This header is only visible to this pager module. The client -** code that calls pager sees only the data that follows the header. -** -** Client code should call sqlite3PagerWrite() on a page prior to making -** any modifications to that page. The first time sqlite3PagerWrite() -** is called, the original page contents are written into the rollback -** journal and PgHdr.inJournal and PgHdr.needSync are set. Later, once -** the journal page has made it onto the disk surface, PgHdr.needSync -** is cleared. The modified page cannot be written back into the original -** database file until the journal pages has been synced to disk and the -** PgHdr.needSync has been cleared. -** -** The PgHdr.dirty flag is set when sqlite3PagerWrite() is called and -** is cleared again when the page content is written back to the original -** database file. -** -** Details of important structure elements: -** -** needSync -** -** If this is true, this means that it is not safe to write the page -** content to the database because the original content needed -** for rollback has not by synced to the main rollback journal. -** The original content may have been written to the rollback journal -** but it has not yet been synced. So we cannot write to the database -** file because power failure might cause the page in the journal file -** to never reach the disk. It is as if the write to the journal file -** does not occur until the journal file is synced. -** -** This flag is false if the page content exactly matches what -** currently exists in the database file. The needSync flag is also -** false if the original content has been written to the main rollback -** journal and synced. If the page represents a new page that has -** been added onto the end of the database during the current -** transaction, the needSync flag is true until the original database -** size in the journal header has been synced to disk. -** -** inJournal -** -** This is true if the original page has been written into the main -** rollback journal. This is always false for new pages added to -** the end of the database file during the current transaction. -** And this flag says nothing about whether or not the journal -** has been synced to disk. For pages that are in the original -** database file, the following expression should always be true: -** -** inJournal = (pPager->aInJournal[(pgno-1)/8] & (1<<((pgno-1)%8))!=0 -** -** The pPager->aInJournal[] array is only valid for the original -** pages of the database, not new pages that are added to the end -** of the database, so obviously the above expression cannot be -** valid for new pages. For new pages inJournal is always 0. -** -** dirty -** -** When true, this means that the content of the page has been -** modified and needs to be written back to the database file. -** If false, it means that either the content of the page is -** unchanged or else the content is unimportant and we do not -** care whether or not it is preserved. -** -** alwaysRollback -** -** This means that the sqlite3PagerDontRollback() API should be -** ignored for this page. The DontRollback() API attempts to say -** that the content of the page on disk is unimportant (it is an -** unused page on the freelist) so that it is unnecessary to -** rollback changes to this page because the content of the page -** can change without changing the meaning of the database. This -** flag overrides any DontRollback() attempt. This flag is set -** when a page that originally contained valid data is added to -** the freelist. Later in the same transaction, this page might -** be pulled from the freelist and reused for something different -** and at that point the DontRollback() API will be called because -** pages taken from the freelist do not need to be protected by -** the rollback journal. But this flag says that the page was -** not originally part of the freelist so that it still needs to -** be rolled back in spite of any subsequent DontRollback() calls. -** -** needRead -** -** This flag means (when true) that the content of the page has -** not yet been loaded from disk. The in-memory content is just -** garbage. (Actually, we zero the content, but you should not -** make any assumptions about the content nevertheless.) If the -** content is needed in the future, it should be read from the -** original database file. -*/ -struct PgHdr { - Pager *pPager; /* The pager to which this page belongs */ - Pgno pgno; /* The page number for this page */ - PgHdr *pNextHash, *pPrevHash; /* Hash collision chain for PgHdr.pgno */ - PagerLruLink free; /* Next and previous free pages */ - PgHdr *pNextAll; /* A list of all pages */ - u8 inJournal; /* TRUE if has been written to journal */ - u8 dirty; /* TRUE if we need to write back changes */ - u8 needSync; /* Sync journal before writing this page */ - u8 alwaysRollback; /* Disable DontRollback() for this page */ - u8 needRead; /* Read content if PagerWrite() is called */ - short int nRef; /* Number of users of this page */ - PgHdr *pDirty, *pPrevDirty; /* Dirty pages */ -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - PagerLruLink gfree; /* Global list of nRef==0 pages */ -#endif -#ifdef SQLITE_CHECK_PAGES - u32 pageHash; -#endif - void *pData; /* Page data */ - /* Pager.nExtra bytes of local data appended to this header */ -}; - -/* -** For an in-memory only database, some extra information is recorded about -** each page so that changes can be rolled back. (Journal files are not -** used for in-memory databases.) The following information is added to -** the end of every EXTRA block for in-memory databases. -** -** This information could have been added directly to the PgHdr structure. -** But then it would take up an extra 8 bytes of storage on every PgHdr -** even for disk-based databases. Splitting it out saves 8 bytes. This -** is only a savings of 0.8% but those percentages add up. -*/ -typedef struct PgHistory PgHistory; -struct PgHistory { - u8 *pOrig; /* Original page text. Restore to this on a full rollback */ - u8 *pStmt; /* Text as it was at the beginning of the current statement */ - PgHdr *pNextStmt, *pPrevStmt; /* List of pages in the statement journal */ - u8 inStmt; /* TRUE if in the statement subjournal */ -}; - -/* -** A macro used for invoking the codec if there is one -*/ -#ifdef SQLITE_HAS_CODEC -# define CODEC1(P,D,N,X) if( P->xCodec!=0 ){ P->xCodec(P->pCodecArg,D,N,X); } -# define CODEC2(P,D,N,X) ((char*)(P->xCodec!=0?P->xCodec(P->pCodecArg,D,N,X):D)) -#else -# define CODEC1(P,D,N,X) /* NO-OP */ -# define CODEC2(P,D,N,X) ((char*)D) -#endif - -/* -** Convert a pointer to a PgHdr into a pointer to its data -** and back again. -*/ -#define PGHDR_TO_DATA(P) ((P)->pData) -#define PGHDR_TO_EXTRA(G,P) ((void*)&((G)[1])) -#define PGHDR_TO_HIST(P,PGR) \ - ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->nExtra]) - -/* -** A open page cache is an instance of the following structure. -** -** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, or -** or SQLITE_FULL. Once one of the first three errors occurs, it persists -** and is returned as the result of every major pager API call. The -** SQLITE_FULL return code is slightly different. It persists only until the -** next successful rollback is performed on the pager cache. Also, -** SQLITE_FULL does not affect the sqlite3PagerGet() and sqlite3PagerLookup() -** APIs, they may still be used successfully. -*/ -struct Pager { - sqlite3_vfs *pVfs; /* OS functions to use for IO */ - u8 journalOpen; /* True if journal file descriptors is valid */ - u8 journalStarted; /* True if header of journal is synced */ - u8 useJournal; /* Use a rollback journal on this file */ - u8 noReadlock; /* Do not bother to obtain readlocks */ - u8 stmtOpen; /* True if the statement subjournal is open */ - u8 stmtInUse; /* True we are in a statement subtransaction */ - u8 stmtAutoopen; /* Open stmt journal when main journal is opened*/ - u8 noSync; /* Do not sync the journal if true */ - u8 fullSync; /* Do extra syncs of the journal for robustness */ - u8 sync_flags; /* One of SYNC_NORMAL or SYNC_FULL */ - u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */ - u8 tempFile; /* zFilename is a temporary file */ - u8 readOnly; /* True for a read-only database */ - u8 needSync; /* True if an fsync() is needed on the journal */ - u8 dirtyCache; /* True if cached pages have changed */ - u8 alwaysRollback; /* Disable DontRollback() for all pages */ - u8 memDb; /* True to inhibit all file I/O */ - u8 setMaster; /* True if a m-j name has been written to jrnl */ - u8 doNotSync; /* Boolean. While true, do not spill the cache */ - u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ - u8 changeCountDone; /* Set after incrementing the change-counter */ - u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ - int errCode; /* One of several kinds of errors */ - int dbSize; /* Number of pages in the file */ - int origDbSize; /* dbSize before the current change */ - int stmtSize; /* Size of database (in pages) at stmt_begin() */ - int nRec; /* Number of pages written to the journal */ - u32 cksumInit; /* Quasi-random value added to every checksum */ - int stmtNRec; /* Number of records in stmt subjournal */ - int nExtra; /* Add this many bytes to each in-memory page */ - int pageSize; /* Number of bytes in a page */ - int nPage; /* Total number of in-memory pages */ - int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */ - int mxPage; /* Maximum number of pages to hold in cache */ - Pgno mxPgno; /* Maximum allowed size of the database */ - u8 *aInJournal; /* One bit for each page in the database file */ - u8 *aInStmt; /* One bit for each page in the database */ - char *zFilename; /* Name of the database file */ - char *zJournal; /* Name of the journal file */ - char *zDirectory; /* Directory hold database and journal files */ - char *zStmtJrnl; /* Name of the statement journal file */ - sqlite3_file *fd, *jfd; /* File descriptors for database and journal */ - sqlite3_file *stfd; /* File descriptor for the statement subjournal*/ - BusyHandler *pBusyHandler; /* Pointer to sqlite.busyHandler */ - PagerLruList lru; /* LRU list of free pages */ - PgHdr *pAll; /* List of all pages */ - PgHdr *pStmt; /* List of pages in the statement subjournal */ - PgHdr *pDirty; /* List of all dirty pages */ - i64 journalOff; /* Current byte offset in the journal file */ - i64 journalHdr; /* Byte offset to previous journal header */ - i64 stmtHdrOff; /* First journal header written this statement */ - i64 stmtCksum; /* cksumInit when statement was started */ - i64 stmtJSize; /* Size of journal at stmt_begin() */ - int sectorSize; /* Assumed sector size during rollback */ -#ifdef SQLITE_TEST - int nHit, nMiss; /* Cache hits and missing */ - int nRead, nWrite; /* Database pages read/written */ -#endif - void (*xDestructor)(DbPage*,int); /* Call this routine when freeing pages */ - void (*xReiniter)(DbPage*,int); /* Call this routine when reloading pages */ -#ifdef SQLITE_HAS_CODEC - void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ - void *pCodecArg; /* First argument to xCodec() */ -#endif - int nHash; /* Size of the pager hash table */ - PgHdr **aHash; /* Hash table to map page number to PgHdr */ -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - Pager *pNext; /* Doubly linked list of pagers on which */ - Pager *pPrev; /* sqlite3_release_memory() will work */ - int iInUseMM; /* Non-zero if unavailable to MM */ - int iInUseDB; /* Non-zero if in sqlite3_release_memory() */ -#endif - char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ - char dbFileVers[16]; /* Changes whenever database file changes */ -}; - -/* -** The following global variables hold counters used for -** testing purposes only. These variables do not exist in -** a non-testing build. These variables are not thread-safe. -*/ -#ifdef SQLITE_TEST -int sqlite3_pager_readdb_count = 0; /* Number of full pages read from DB */ -int sqlite3_pager_writedb_count = 0; /* Number of full pages written to DB */ -int sqlite3_pager_writej_count = 0; /* Number of pages written to journal */ -int sqlite3_pager_pgfree_count = 0; /* Number of cache pages freed */ -# define PAGER_INCR(v) v++ -#else -# define PAGER_INCR(v) -#endif - -/* -** The following variable points to the head of a double-linked list -** of all pagers that are eligible for page stealing by the -** sqlite3_release_memory() interface. Access to this list is -** protected by the SQLITE_MUTEX_STATIC_MEM2 mutex. -*/ -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT -static Pager *sqlite3PagerList = 0; -static PagerLruList sqlite3LruPageList = {0, 0, 0}; -#endif - - -/* -** Journal files begin with the following magic string. The data -** was obtained from /dev/random. It is used only as a sanity check. -** -** Since version 2.8.0, the journal format contains additional sanity -** checking information. If the power fails while the journal is begin -** written, semi-random garbage data might appear in the journal -** file after power is restored. If an attempt is then made -** to roll the journal back, the database could be corrupted. The additional -** sanity checking data is an attempt to discover the garbage in the -** journal and ignore it. -** -** The sanity checking information for the new journal format consists -** of a 32-bit checksum on each page of data. The checksum covers both -** the page number and the pPager->pageSize bytes of data for the page. -** This cksum is initialized to a 32-bit random value that appears in the -** journal file right after the header. The random initializer is important, -** because garbage data that appears at the end of a journal is likely -** data that was once in other files that have now been deleted. If the -** garbage data came from an obsolete journal file, the checksums might -** be correct. But by initializing the checksum to random value which -** is different for every journal, we minimize that risk. -*/ -static const unsigned char aJournalMagic[] = { - 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7, -}; - -/* -** The size of the header and of each page in the journal is determined -** by the following macros. -*/ -#define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8) - -/* -** The journal header size for this pager. In the future, this could be -** set to some value read from the disk controller. The important -** characteristic is that it is the same size as a disk sector. -*/ -#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize) - -/* -** The macro MEMDB is true if we are dealing with an in-memory database. -** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set, -** the value of MEMDB will be a constant and the compiler will optimize -** out code that would never execute. -*/ -#ifdef SQLITE_OMIT_MEMORYDB -# define MEMDB 0 -#else -# define MEMDB pPager->memDb -#endif - -/* -** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is -** reserved for working around a windows/posix incompatibility). It is -** used in the journal to signify that the remainder of the journal file -** is devoted to storing a master journal name - there are no more pages to -** roll back. See comments for function writeMasterJournal() for details. -*/ -/* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */ -#define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1) - -/* -** The maximum legal page number is (2^31 - 1). -*/ -#define PAGER_MAX_PGNO 2147483647 - -/* -** The pagerEnter() and pagerLeave() routines acquire and release -** a mutex on each pager. The mutex is recursive. -** -** This is a special-purpose mutex. It only provides mutual exclusion -** between the Btree and the Memory Management sqlite3_release_memory() -** function. It does not prevent, for example, two Btrees from accessing -** the same pager at the same time. Other general-purpose mutexes in -** the btree layer handle that chore. -*/ -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - static void pagerEnter(Pager *p){ - p->iInUseDB++; - if( p->iInUseMM && p->iInUseDB==1 ){ - sqlite3_mutex *mutex; - mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2); - p->iInUseDB = 0; - sqlite3_mutex_enter(mutex); - p->iInUseDB = 1; - sqlite3_mutex_leave(mutex); - } - assert( p->iInUseMM==0 ); - } - static void pagerLeave(Pager *p){ - p->iInUseDB--; - assert( p->iInUseDB>=0 ); - } -#else -# define pagerEnter(X) -# define pagerLeave(X) -#endif - -/* -** Enable reference count tracking (for debugging) here: -*/ -#ifdef SQLITE_DEBUG - int pager3_refinfo_enable = 0; - static void pager_refinfo(PgHdr *p){ - static int cnt = 0; - if( !pager3_refinfo_enable ) return; - sqlite3DebugPrintf( - "REFCNT: %4d addr=%p nRef=%-3d total=%d\n", - p->pgno, PGHDR_TO_DATA(p), p->nRef, p->pPager->nRef - ); - cnt++; /* Something to set a breakpoint on */ - } -# define REFINFO(X) pager_refinfo(X) -#else -# define REFINFO(X) -#endif - -/* -** Add page pPg to the end of the linked list managed by structure -** pList (pPg becomes the last entry in the list - the most recently -** used). Argument pLink should point to either pPg->free or pPg->gfree, -** depending on whether pPg is being added to the pager-specific or -** global LRU list. -*/ -static void listAdd(PagerLruList *pList, PagerLruLink *pLink, PgHdr *pPg){ - pLink->pNext = 0; - pLink->pPrev = pList->pLast; - -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - assert(pLink==&pPg->free || pLink==&pPg->gfree); - assert(pLink==&pPg->gfree || pList!=&sqlite3LruPageList); -#endif - - if( pList->pLast ){ - int iOff = (char *)pLink - (char *)pPg; - PagerLruLink *pLastLink = (PagerLruLink *)(&((u8 *)pList->pLast)[iOff]); - pLastLink->pNext = pPg; - }else{ - assert(!pList->pFirst); - pList->pFirst = pPg; - } - - pList->pLast = pPg; - if( !pList->pFirstSynced && pPg->needSync==0 ){ - pList->pFirstSynced = pPg; - } -} - -/* -** Remove pPg from the list managed by the structure pointed to by pList. -** -** Argument pLink should point to either pPg->free or pPg->gfree, depending -** on whether pPg is being added to the pager-specific or global LRU list. -*/ -static void listRemove(PagerLruList *pList, PagerLruLink *pLink, PgHdr *pPg){ - int iOff = (char *)pLink - (char *)pPg; - -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - assert(pLink==&pPg->free || pLink==&pPg->gfree); - assert(pLink==&pPg->gfree || pList!=&sqlite3LruPageList); -#endif - - if( pPg==pList->pFirst ){ - pList->pFirst = pLink->pNext; - } - if( pPg==pList->pLast ){ - pList->pLast = pLink->pPrev; - } - if( pLink->pPrev ){ - PagerLruLink *pPrevLink = (PagerLruLink *)(&((u8 *)pLink->pPrev)[iOff]); - pPrevLink->pNext = pLink->pNext; - } - if( pLink->pNext ){ - PagerLruLink *pNextLink = (PagerLruLink *)(&((u8 *)pLink->pNext)[iOff]); - pNextLink->pPrev = pLink->pPrev; - } - if( pPg==pList->pFirstSynced ){ - PgHdr *p = pLink->pNext; - while( p && p->needSync ){ - PagerLruLink *pL = (PagerLruLink *)(&((u8 *)p)[iOff]); - p = pL->pNext; - } - pList->pFirstSynced = p; - } - - pLink->pNext = pLink->pPrev = 0; -} - -/* -** Add page pPg to the list of free pages for the pager. If -** memory-management is enabled, also add the page to the global -** list of free pages. -*/ -static void lruListAdd(PgHdr *pPg){ - listAdd(&pPg->pPager->lru, &pPg->free, pPg); -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - if( !pPg->pPager->memDb ){ - sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU)); - listAdd(&sqlite3LruPageList, &pPg->gfree, pPg); - sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU)); - } -#endif -} - -/* -** Remove page pPg from the list of free pages for the associated pager. -** If memory-management is enabled, also remove pPg from the global list -** of free pages. -*/ -static void lruListRemove(PgHdr *pPg){ - listRemove(&pPg->pPager->lru, &pPg->free, pPg); -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - if( !pPg->pPager->memDb ){ - sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU)); - listRemove(&sqlite3LruPageList, &pPg->gfree, pPg); - sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU)); - } -#endif -} - -/* -** This function is called just after the needSync flag has been cleared -** from all pages managed by pPager (usually because the journal file -** has just been synced). It updates the pPager->lru.pFirstSynced variable -** and, if memory-management is enabled, the sqlite3LruPageList.pFirstSynced -** variable also. -*/ -static void lruListSetFirstSynced(Pager *pPager){ - pPager->lru.pFirstSynced = pPager->lru.pFirst; -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - if( !pPager->memDb ){ - PgHdr *p; - sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU)); - for(p=sqlite3LruPageList.pFirst; p && p->needSync; p=p->gfree.pNext); - assert(p==pPager->lru.pFirstSynced || p==sqlite3LruPageList.pFirstSynced); - sqlite3LruPageList.pFirstSynced = p; - sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU)); - } -#endif -} - -/* -** Return true if page *pPg has already been written to the statement -** journal (or statement snapshot has been created, if *pPg is part -** of an in-memory database). -*/ -static int pageInStatement(PgHdr *pPg){ - Pager *pPager = pPg->pPager; - if( MEMDB ){ - return PGHDR_TO_HIST(pPg, pPager)->inStmt; - }else{ - Pgno pgno = pPg->pgno; - u8 *a = pPager->aInStmt; - return (a && (int)pgno<=pPager->stmtSize && (a[pgno/8] & (1<<(pgno&7)))); - } -} - -/* -** Change the size of the pager hash table to N. N must be a power -** of two. -*/ -static void pager_resize_hash_table(Pager *pPager, int N){ - PgHdr **aHash, *pPg; - assert( N>0 && (N&(N-1))==0 ); - pagerLeave(pPager); - sqlite3MallocBenignFailure((int)pPager->aHash); - aHash = sqlite3MallocZero( sizeof(aHash[0])*N ); - pagerEnter(pPager); - if( aHash==0 ){ - /* Failure to rehash is not an error. It is only a performance hit. */ - return; - } - sqlite3_free(pPager->aHash); - pPager->nHash = N; - pPager->aHash = aHash; - for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ - int h; - if( pPg->pgno==0 ){ - assert( pPg->pNextHash==0 && pPg->pPrevHash==0 ); - continue; - } - h = pPg->pgno & (N-1); - pPg->pNextHash = aHash[h]; - if( aHash[h] ){ - aHash[h]->pPrevHash = pPg; - } - aHash[h] = pPg; - pPg->pPrevHash = 0; - } -} - -/* -** Read a 32-bit integer from the given file descriptor. Store the integer -** that is read in *pRes. Return SQLITE_OK if everything worked, or an -** error code is something goes wrong. -** -** All values are stored on disk as big-endian. -*/ -static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){ - unsigned char ac[4]; - int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset); - if( rc==SQLITE_OK ){ - *pRes = sqlite3Get4byte(ac); - } - return rc; -} - -/* -** Write a 32-bit integer into a string buffer in big-endian byte order. -*/ -#define put32bits(A,B) sqlite3Put4byte((u8*)A,B) - -/* -** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK -** on success or an error code is something goes wrong. -*/ -static int write32bits(sqlite3_file *fd, i64 offset, u32 val){ - char ac[4]; - put32bits(ac, val); - return sqlite3OsWrite(fd, ac, 4, offset); -} - -/* -** If file pFd is open, call sqlite3OsUnlock() on it. -*/ -static int osUnlock(sqlite3_file *pFd, int eLock){ - if( !pFd->pMethods ){ - return SQLITE_OK; - } - return sqlite3OsUnlock(pFd, eLock); -} - -/* -** This function determines whether or not the atomic-write optimization -** can be used with this pager. The optimization can be used if: -** -** (a) the value returned by OsDeviceCharacteristics() indicates that -** a database page may be written atomically, and -** (b) the value returned by OsSectorSize() is less than or equal -** to the page size. -** -** If the optimization cannot be used, 0 is returned. If it can be used, -** then the value returned is the size of the journal file when it -** contains rollback data for exactly one page. -*/ -#ifdef SQLITE_ENABLE_ATOMIC_WRITE -static int jrnlBufferSize(Pager *pPager){ - int dc; /* Device characteristics */ - int nSector; /* Sector size */ - int nPage; /* Page size */ - sqlite3_file *fd = pPager->fd; - - if( fd->pMethods ){ - dc = sqlite3OsDeviceCharacteristics(fd); - nSector = sqlite3OsSectorSize(fd); - nPage = pPager->pageSize; - } - - assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); - assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); - - if( !fd->pMethods || (dc&(SQLITE_IOCAP_ATOMIC|(nPage>>8))&&nSector<=nPage) ){ - return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager); - } - return 0; -} -#endif - -/* -** This function should be called when an error occurs within the pager -** code. The first argument is a pointer to the pager structure, the -** second the error-code about to be returned by a pager API function. -** The value returned is a copy of the second argument to this function. -** -** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL -** the error becomes persistent. Until the persisten error is cleared, -** subsequent API calls on this Pager will immediately return the same -** error code. -** -** A persistent error indicates that the contents of the pager-cache -** cannot be trusted. This state can be cleared by completely discarding -** the contents of the pager-cache. If a transaction was active when -** the persistent error occured, then the rollback journal may need -** to be replayed. -*/ -static void pager_unlock(Pager *pPager); -static int pager_error(Pager *pPager, int rc){ - int rc2 = rc & 0xff; - assert( - pPager->errCode==SQLITE_FULL || - pPager->errCode==SQLITE_OK || - (pPager->errCode & 0xff)==SQLITE_IOERR - ); - if( - rc2==SQLITE_FULL || - rc2==SQLITE_IOERR || - rc2==SQLITE_CORRUPT - ){ - pPager->errCode = rc; - if( pPager->state==PAGER_UNLOCK && pPager->nRef==0 ){ - /* If the pager is already unlocked, call pager_unlock() now to - ** clear the error state and ensure that the pager-cache is - ** completely empty. - */ - pager_unlock(pPager); - } - } - return rc; -} - -/* -** If SQLITE_CHECK_PAGES is defined then we do some sanity checking -** on the cache using a hash function. This is used for testing -** and debugging only. -*/ -#ifdef SQLITE_CHECK_PAGES -/* -** Return a 32-bit hash of the page data for pPage. -*/ -static u32 pager_datahash(int nByte, unsigned char *pData){ - u32 hash = 0; - int i; - for(i=0; ipPager->pageSize, - (unsigned char *)PGHDR_TO_DATA(pPage)); -} - -/* -** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES -** is defined, and NDEBUG is not defined, an assert() statement checks -** that the page is either dirty or still matches the calculated page-hash. -*/ -#define CHECK_PAGE(x) checkPage(x) -static void checkPage(PgHdr *pPg){ - Pager *pPager = pPg->pPager; - assert( !pPg->pageHash || pPager->errCode || MEMDB || pPg->dirty || - pPg->pageHash==pager_pagehash(pPg) ); -} - -#else -#define pager_datahash(X,Y) 0 -#define pager_pagehash(X) 0 -#define CHECK_PAGE(x) -#endif - -/* -** When this is called the journal file for pager pPager must be open. -** The master journal file name is read from the end of the file and -** written into memory supplied by the caller. -** -** zMaster must point to a buffer of at least nMaster bytes allocated by -** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is -** enough space to write the master journal name). If the master journal -** name in the journal is longer than nMaster bytes (including a -** nul-terminator), then this is handled as if no master journal name -** were present in the journal. -** -** If no master journal file name is present zMaster[0] is set to 0 and -** SQLITE_OK returned. -*/ -static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, int nMaster){ - int rc; - u32 len; - i64 szJ; - u32 cksum; - int i; - unsigned char aMagic[8]; /* A buffer to hold the magic header */ - - zMaster[0] = '\0'; - - rc = sqlite3OsFileSize(pJrnl, &szJ); - if( rc!=SQLITE_OK || szJ<16 ) return rc; - - rc = read32bits(pJrnl, szJ-16, &len); - if( rc!=SQLITE_OK ) return rc; - - if( len>=nMaster ){ - return SQLITE_OK; - } - - rc = read32bits(pJrnl, szJ-12, &cksum); - if( rc!=SQLITE_OK ) return rc; - - rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8); - if( rc!=SQLITE_OK || memcmp(aMagic, aJournalMagic, 8) ) return rc; - - rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len); - if( rc!=SQLITE_OK ){ - return rc; - } - zMaster[len] = '\0'; - - /* See if the checksum matches the master journal name */ - for(i=0; ijournalOff; - if( c ){ - offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager); - } - assert( offset%JOURNAL_HDR_SZ(pPager)==0 ); - assert( offset>=c ); - assert( (offset-c)journalOff = offset; -} - -/* -** The journal file must be open when this routine is called. A journal -** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the -** current location. -** -** The format for the journal header is as follows: -** - 8 bytes: Magic identifying journal format. -** - 4 bytes: Number of records in journal, or -1 no-sync mode is on. -** - 4 bytes: Random number used for page hash. -** - 4 bytes: Initial database page count. -** - 4 bytes: Sector size used by the process that wrote this journal. -** -** Followed by (JOURNAL_HDR_SZ - 24) bytes of unused space. -*/ -static int writeJournalHdr(Pager *pPager){ - char zHeader[sizeof(aJournalMagic)+16]; - int rc; - - if( pPager->stmtHdrOff==0 ){ - pPager->stmtHdrOff = pPager->journalOff; - } - - seekJournalHdr(pPager); - pPager->journalHdr = pPager->journalOff; - - memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); - - /* - ** Write the nRec Field - the number of page records that follow this - ** journal header. Normally, zero is written to this value at this time. - ** After the records are added to the journal (and the journal synced, - ** if in full-sync mode), the zero is overwritten with the true number - ** of records (see syncJournal()). - ** - ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When - ** reading the journal this value tells SQLite to assume that the - ** rest of the journal file contains valid page records. This assumption - ** is dangerous, as if a failure occured whilst writing to the journal - ** file it may contain some garbage data. There are two scenarios - ** where this risk can be ignored: - ** - ** * When the pager is in no-sync mode. Corruption can follow a - ** power failure in this case anyway. - ** - ** * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees - ** that garbage data is never appended to the journal file. - */ - assert(pPager->fd->pMethods||pPager->noSync); - if( (pPager->noSync) - || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) - ){ - put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff); - }else{ - put32bits(&zHeader[sizeof(aJournalMagic)], 0); - } - - /* The random check-hash initialiser */ - sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); - put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); - /* The initial database size */ - put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbSize); - /* The assumed sector size for this process */ - put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize); - IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, sizeof(zHeader))) - rc = sqlite3OsWrite(pPager->jfd, zHeader, sizeof(zHeader),pPager->journalOff); - pPager->journalOff += JOURNAL_HDR_SZ(pPager); - - /* The journal header has been written successfully. Seek the journal - ** file descriptor to the end of the journal header sector. - */ - if( rc==SQLITE_OK ){ - IOTRACE(("JTAIL %p %lld\n", pPager, pPager->journalOff-1)) - rc = sqlite3OsWrite(pPager->jfd, "\000", 1, pPager->journalOff-1); - } - return rc; -} - -/* -** The journal file must be open when this is called. A journal header file -** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal -** file. See comments above function writeJournalHdr() for a description of -** the journal header format. -** -** If the header is read successfully, *nRec is set to the number of -** page records following this header and *dbSize is set to the size of the -** database before the transaction began, in pages. Also, pPager->cksumInit -** is set to the value read from the journal header. SQLITE_OK is returned -** in this case. -** -** If the journal header file appears to be corrupted, SQLITE_DONE is -** returned and *nRec and *dbSize are not set. If JOURNAL_HDR_SZ bytes -** cannot be read from the journal file an error code is returned. -*/ -static int readJournalHdr( - Pager *pPager, - i64 journalSize, - u32 *pNRec, - u32 *pDbSize -){ - int rc; - unsigned char aMagic[8]; /* A buffer to hold the magic header */ - i64 jrnlOff; - - seekJournalHdr(pPager); - if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){ - return SQLITE_DONE; - } - jrnlOff = pPager->journalOff; - - rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), jrnlOff); - if( rc ) return rc; - jrnlOff += sizeof(aMagic); - - if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ - return SQLITE_DONE; - } - - rc = read32bits(pPager->jfd, jrnlOff, pNRec); - if( rc ) return rc; - - rc = read32bits(pPager->jfd, jrnlOff+4, &pPager->cksumInit); - if( rc ) return rc; - - rc = read32bits(pPager->jfd, jrnlOff+8, pDbSize); - if( rc ) return rc; - - /* Update the assumed sector-size to match the value used by - ** the process that created this journal. If this journal was - ** created by a process other than this one, then this routine - ** is being called from within pager_playback(). The local value - ** of Pager.sectorSize is restored at the end of that routine. - */ - rc = read32bits(pPager->jfd, jrnlOff+12, (u32 *)&pPager->sectorSize); - if( rc ) return rc; - - pPager->journalOff += JOURNAL_HDR_SZ(pPager); - return SQLITE_OK; -} - - -/* -** Write the supplied master journal name into the journal file for pager -** pPager at the current location. The master journal name must be the last -** thing written to a journal file. If the pager is in full-sync mode, the -** journal file descriptor is advanced to the next sector boundary before -** anything is written. The format is: -** -** + 4 bytes: PAGER_MJ_PGNO. -** + N bytes: length of master journal name. -** + 4 bytes: N -** + 4 bytes: Master journal name checksum. -** + 8 bytes: aJournalMagic[]. -** -** The master journal page checksum is the sum of the bytes in the master -** journal name. -** -** If zMaster is a NULL pointer (occurs for a single database transaction), -** this call is a no-op. -*/ -static int writeMasterJournal(Pager *pPager, const char *zMaster){ - int rc; - int len; - int i; - i64 jrnlOff; - u32 cksum = 0; - char zBuf[sizeof(aJournalMagic)+2*4]; - - if( !zMaster || pPager->setMaster) return SQLITE_OK; - pPager->setMaster = 1; - - len = strlen(zMaster); - for(i=0; ifullSync ){ - seekJournalHdr(pPager); - } - jrnlOff = pPager->journalOff; - pPager->journalOff += (len+20); - - rc = write32bits(pPager->jfd, jrnlOff, PAGER_MJ_PGNO(pPager)); - if( rc!=SQLITE_OK ) return rc; - jrnlOff += 4; - - rc = sqlite3OsWrite(pPager->jfd, zMaster, len, jrnlOff); - if( rc!=SQLITE_OK ) return rc; - jrnlOff += len; - - put32bits(zBuf, len); - put32bits(&zBuf[4], cksum); - memcpy(&zBuf[8], aJournalMagic, sizeof(aJournalMagic)); - rc = sqlite3OsWrite(pPager->jfd, zBuf, 8+sizeof(aJournalMagic), jrnlOff); - pPager->needSync = !pPager->noSync; - return rc; -} - -/* -** Add or remove a page from the list of all pages that are in the -** statement journal. -** -** The Pager keeps a separate list of pages that are currently in -** the statement journal. This helps the sqlite3PagerStmtCommit() -** routine run MUCH faster for the common case where there are many -** pages in memory but only a few are in the statement journal. -*/ -static void page_add_to_stmt_list(PgHdr *pPg){ - Pager *pPager = pPg->pPager; - PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); - assert( MEMDB ); - if( !pHist->inStmt ){ - assert( pHist->pPrevStmt==0 && pHist->pNextStmt==0 ); - if( pPager->pStmt ){ - PGHDR_TO_HIST(pPager->pStmt, pPager)->pPrevStmt = pPg; - } - pHist->pNextStmt = pPager->pStmt; - pPager->pStmt = pPg; - pHist->inStmt = 1; - } -} - -/* -** Find a page in the hash table given its page number. Return -** a pointer to the page or NULL if not found. -*/ -static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){ - PgHdr *p; - if( pPager->aHash==0 ) return 0; - p = pPager->aHash[pgno & (pPager->nHash-1)]; - while( p && p->pgno!=pgno ){ - p = p->pNextHash; - } - return p; -} - -/* -** Clear the in-memory cache. This routine -** sets the state of the pager back to what it was when it was first -** opened. Any outstanding pages are invalidated and subsequent attempts -** to access those pages will likely result in a coredump. -*/ -static void pager_reset(Pager *pPager){ - PgHdr *pPg, *pNext; - if( pPager->errCode ) return; - for(pPg=pPager->pAll; pPg; pPg=pNext){ - IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno)); - PAGER_INCR(sqlite3_pager_pgfree_count); - pNext = pPg->pNextAll; - lruListRemove(pPg); - sqlite3_free(pPg->pData); - sqlite3_free(pPg); - } - assert(pPager->lru.pFirst==0); - assert(pPager->lru.pFirstSynced==0); - assert(pPager->lru.pLast==0); - pPager->pStmt = 0; - pPager->pAll = 0; - pPager->pDirty = 0; - pPager->nHash = 0; - sqlite3_free(pPager->aHash); - pPager->nPage = 0; - pPager->aHash = 0; - pPager->nRef = 0; -} - -/* -** Unlock the database file. -** -** If the pager is currently in error state, discard the contents of -** the cache and reset the Pager structure internal state. If there is -** an open journal-file, then the next time a shared-lock is obtained -** on the pager file (by this or any other process), it will be -** treated as a hot-journal and rolled back. -*/ -static void pager_unlock(Pager *pPager){ - if( !pPager->exclusiveMode ){ - if( !MEMDB ){ - if( pPager->fd->pMethods ){ - osUnlock(pPager->fd, NO_LOCK); - } - pPager->dbSize = -1; - IOTRACE(("UNLOCK %p\n", pPager)) - - /* If Pager.errCode is set, the contents of the pager cache cannot be - ** trusted. Now that the pager file is unlocked, the contents of the - ** cache can be discarded and the error code safely cleared. - */ - if( pPager->errCode ){ - pPager->errCode = SQLITE_OK; - pager_reset(pPager); - if( pPager->stmtOpen ){ - sqlite3OsClose(pPager->stfd); - sqlite3_free(pPager->aInStmt); - pPager->aInStmt = 0; - } - if( pPager->journalOpen ){ - sqlite3OsClose(pPager->jfd); - pPager->journalOpen = 0; - sqlite3_free(pPager->aInJournal); - pPager->aInJournal = 0; - } - pPager->stmtOpen = 0; - pPager->stmtInUse = 0; - pPager->journalOff = 0; - pPager->journalStarted = 0; - pPager->stmtAutoopen = 0; - pPager->origDbSize = 0; - } - } - - if( !MEMDB || pPager->errCode==SQLITE_OK ){ - pPager->state = PAGER_UNLOCK; - pPager->changeCountDone = 0; - } - } -} - -/* -** Execute a rollback if a transaction is active and unlock the -** database file. If the pager has already entered the error state, -** do not attempt the rollback. -*/ -static void pagerUnlockAndRollback(Pager *p){ - assert( p->state>=PAGER_RESERVED || p->journalOpen==0 ); - if( p->errCode==SQLITE_OK && p->state>=PAGER_RESERVED ){ - sqlite3PagerRollback(p); - } - pager_unlock(p); - assert( p->errCode || !p->journalOpen || (p->exclusiveMode&&!p->journalOff) ); - assert( p->errCode || !p->stmtOpen || p->exclusiveMode ); -} - -/* -** This routine ends a transaction. A transaction is ended by either -** a COMMIT or a ROLLBACK. -** -** When this routine is called, the pager has the journal file open and -** a RESERVED or EXCLUSIVE lock on the database. This routine will release -** the database lock and acquires a SHARED lock in its place if that is -** the appropriate thing to do. Release locks usually is appropriate, -** unless we are in exclusive access mode or unless this is a -** COMMIT AND BEGIN or ROLLBACK AND BEGIN operation. -** -** The journal file is either deleted or truncated. -** -** TODO: Consider keeping the journal file open for temporary databases. -** This might give a performance improvement on windows where opening -** a file is an expensive operation. -*/ -static int pager_end_transaction(Pager *pPager){ - PgHdr *pPg; - int rc = SQLITE_OK; - int rc2 = SQLITE_OK; - assert( !MEMDB ); - if( pPager->statestmtOpen && !pPager->exclusiveMode ){ - sqlite3OsClose(pPager->stfd); - pPager->stmtOpen = 0; - } - if( pPager->journalOpen ){ - if( pPager->exclusiveMode - && (rc = sqlite3OsTruncate(pPager->jfd, 0))==SQLITE_OK ){; - pPager->journalOff = 0; - pPager->journalStarted = 0; - }else{ - sqlite3OsClose(pPager->jfd); - pPager->journalOpen = 0; - if( rc==SQLITE_OK ){ - rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); - } - } - sqlite3_free( pPager->aInJournal ); - pPager->aInJournal = 0; - for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ - pPg->inJournal = 0; - pPg->dirty = 0; - pPg->needSync = 0; - pPg->alwaysRollback = 0; -#ifdef SQLITE_CHECK_PAGES - pPg->pageHash = pager_pagehash(pPg); -#endif - } - pPager->pDirty = 0; - pPager->dirtyCache = 0; - pPager->nRec = 0; - }else{ - assert( pPager->aInJournal==0 ); - assert( pPager->dirtyCache==0 || pPager->useJournal==0 ); - } - - if( !pPager->exclusiveMode ){ - rc2 = osUnlock(pPager->fd, SHARED_LOCK); - pPager->state = PAGER_SHARED; - }else if( pPager->state==PAGER_SYNCED ){ - pPager->state = PAGER_EXCLUSIVE; - } - pPager->origDbSize = 0; - pPager->setMaster = 0; - pPager->needSync = 0; - lruListSetFirstSynced(pPager); - pPager->dbSize = -1; - - return (rc==SQLITE_OK?rc2:rc); -} - -/* -** Compute and return a checksum for the page of data. -** -** This is not a real checksum. It is really just the sum of the -** random initial value and the page number. We experimented with -** a checksum of the entire data, but that was found to be too slow. -** -** Note that the page number is stored at the beginning of data and -** the checksum is stored at the end. This is important. If journal -** corruption occurs due to a power failure, the most likely scenario -** is that one end or the other of the record will be changed. It is -** much less likely that the two ends of the journal record will be -** correct and the middle be corrupt. Thus, this "checksum" scheme, -** though fast and simple, catches the mostly likely kind of corruption. -** -** FIX ME: Consider adding every 200th (or so) byte of the data to the -** checksum. That way if a single page spans 3 or more disk sectors and -** only the middle sector is corrupt, we will still have a reasonable -** chance of failing the checksum and thus detecting the problem. -*/ -static u32 pager_cksum(Pager *pPager, const u8 *aData){ - u32 cksum = pPager->cksumInit; - int i = pPager->pageSize-200; - while( i>0 ){ - cksum += aData[i]; - i -= 200; - } - return cksum; -} - -/* Forward declaration */ -static void makeClean(PgHdr*); - -/* -** Read a single page from the journal file opened on file descriptor -** jfd. Playback this one page. -** -** If useCksum==0 it means this journal does not use checksums. Checksums -** are not used in statement journals because statement journals do not -** need to survive power failures. -*/ -static int pager_playback_one_page( - Pager *pPager, - sqlite3_file *jfd, - i64 offset, - int useCksum -){ - int rc; - PgHdr *pPg; /* An existing page in the cache */ - Pgno pgno; /* The page number of a page in journal */ - u32 cksum; /* Checksum used for sanity checking */ - u8 *aData = (u8 *)pPager->pTmpSpace; /* Temp storage for a page */ - - /* useCksum should be true for the main journal and false for - ** statement journals. Verify that this is always the case - */ - assert( jfd == (useCksum ? pPager->jfd : pPager->stfd) ); - assert( aData ); - - rc = read32bits(jfd, offset, &pgno); - if( rc!=SQLITE_OK ) return rc; - rc = sqlite3OsRead(jfd, aData, pPager->pageSize, offset+4); - if( rc!=SQLITE_OK ) return rc; - pPager->journalOff += pPager->pageSize + 4; - - /* Sanity checking on the page. This is more important that I originally - ** thought. If a power failure occurs while the journal is being written, - ** it could cause invalid data to be written into the journal. We need to - ** detect this invalid data (with high probability) and ignore it. - */ - if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){ - return SQLITE_DONE; - } - if( pgno>(unsigned)pPager->dbSize ){ - return SQLITE_OK; - } - if( useCksum ){ - rc = read32bits(jfd, offset+pPager->pageSize+4, &cksum); - if( rc ) return rc; - pPager->journalOff += 4; - if( pager_cksum(pPager, aData)!=cksum ){ - return SQLITE_DONE; - } - } - - assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE ); - - /* If the pager is in RESERVED state, then there must be a copy of this - ** page in the pager cache. In this case just update the pager cache, - ** not the database file. The page is left marked dirty in this case. - ** - ** An exception to the above rule: If the database is in no-sync mode - ** and a page is moved during an incremental vacuum then the page may - ** not be in the pager cache. Later: if a malloc() or IO error occurs - ** during a Movepage() call, then the page may not be in the cache - ** either. So the condition described in the above paragraph is not - ** assert()able. - ** - ** If in EXCLUSIVE state, then we update the pager cache if it exists - ** and the main file. The page is then marked not dirty. - ** - ** Ticket #1171: The statement journal might contain page content that is - ** different from the page content at the start of the transaction. - ** This occurs when a page is changed prior to the start of a statement - ** then changed again within the statement. When rolling back such a - ** statement we must not write to the original database unless we know - ** for certain that original page contents are synced into the main rollback - ** journal. Otherwise, a power loss might leave modified data in the - ** database file without an entry in the rollback journal that can - ** restore the database to its original form. Two conditions must be - ** met before writing to the database files. (1) the database must be - ** locked. (2) we know that the original page content is fully synced - ** in the main journal either because the page is not in cache or else - ** the page is marked as needSync==0. - */ - pPg = pager_lookup(pPager, pgno); - PAGERTRACE4("PLAYBACK %d page %d hash(%08x)\n", - PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, aData)); - if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){ - i64 offset = (pgno-1)*(i64)pPager->pageSize; - rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize, offset); - if( pPg ){ - makeClean(pPg); - } - } - if( pPg ){ - /* No page should ever be explicitly rolled back that is in use, except - ** for page 1 which is held in use in order to keep the lock on the - ** database active. However such a page may be rolled back as a result - ** of an internal error resulting in an automatic call to - ** sqlite3PagerRollback(). - */ - void *pData; - /* assert( pPg->nRef==0 || pPg->pgno==1 ); */ - pData = PGHDR_TO_DATA(pPg); - memcpy(pData, aData, pPager->pageSize); - if( pPager->xReiniter ){ - pPager->xReiniter(pPg, pPager->pageSize); - } -#ifdef SQLITE_CHECK_PAGES - pPg->pageHash = pager_pagehash(pPg); -#endif - /* If this was page 1, then restore the value of Pager.dbFileVers. - ** Do this before any decoding. */ - if( pgno==1 ){ - memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers)); - } - - /* Decode the page just read from disk */ - CODEC1(pPager, pData, pPg->pgno, 3); - } - return rc; -} - -/* -** Parameter zMaster is the name of a master journal file. A single journal -** file that referred to the master journal file has just been rolled back. -** This routine checks if it is possible to delete the master journal file, -** and does so if it is. -** -** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not -** available for use within this function. -** -** -** The master journal file contains the names of all child journals. -** To tell if a master journal can be deleted, check to each of the -** children. If all children are either missing or do not refer to -** a different master journal, then this master journal can be deleted. -*/ -static int pager_delmaster(Pager *pPager, const char *zMaster){ - sqlite3_vfs *pVfs = pPager->pVfs; - int rc; - int master_open = 0; - sqlite3_file *pMaster; - sqlite3_file *pJournal; - char *zMasterJournal = 0; /* Contents of master journal file */ - i64 nMasterJournal; /* Size of master journal file */ - - /* Open the master journal file exclusively in case some other process - ** is running this routine also. Not that it makes too much difference. - */ - pMaster = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile * 2); - pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); - if( !pMaster ){ - rc = SQLITE_NOMEM; - }else{ - int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL); - rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0); - } - if( rc!=SQLITE_OK ) goto delmaster_out; - master_open = 1; - - rc = sqlite3OsFileSize(pMaster, &nMasterJournal); - if( rc!=SQLITE_OK ) goto delmaster_out; - - if( nMasterJournal>0 ){ - char *zJournal; - char *zMasterPtr = 0; - int nMasterPtr = pPager->pVfs->mxPathname+1; - - /* Load the entire master journal file into space obtained from - ** sqlite3_malloc() and pointed to by zMasterJournal. - */ - zMasterJournal = (char *)sqlite3_malloc(nMasterJournal + nMasterPtr); - if( !zMasterJournal ){ - rc = SQLITE_NOMEM; - goto delmaster_out; - } - zMasterPtr = &zMasterJournal[nMasterJournal]; - rc = sqlite3OsRead(pMaster, zMasterJournal, nMasterJournal, 0); - if( rc!=SQLITE_OK ) goto delmaster_out; - - zJournal = zMasterJournal; - while( (zJournal-zMasterJournal)state>=PAGER_EXCLUSIVE && pPager->fd->pMethods ){ - rc = sqlite3OsTruncate(pPager->fd, pPager->pageSize*(i64)nPage); - } - if( rc==SQLITE_OK ){ - pPager->dbSize = nPage; - pager_truncate_cache(pPager); - } - return rc; -} - -/* -** Set the sectorSize for the given pager. -** -** The sector size is the larger of the sector size reported -** by sqlite3OsSectorSize() and the pageSize. -*/ -static void setSectorSize(Pager *pPager){ - assert(pPager->fd->pMethods||pPager->tempFile); - if( !pPager->tempFile ){ - /* Sector size doesn't matter for temporary files. Also, the file - ** may not have been opened yet, in whcih case the OsSectorSize() - ** call will segfault. - */ - pPager->sectorSize = sqlite3OsSectorSize(pPager->fd); - } - if( pPager->sectorSizepageSize ){ - pPager->sectorSize = pPager->pageSize; - } -} - -/* -** Playback the journal and thus restore the database file to -** the state it was in before we started making changes. -** -** The journal file format is as follows: -** -** (1) 8 byte prefix. A copy of aJournalMagic[]. -** (2) 4 byte big-endian integer which is the number of valid page records -** in the journal. If this value is 0xffffffff, then compute the -** number of page records from the journal size. -** (3) 4 byte big-endian integer which is the initial value for the -** sanity checksum. -** (4) 4 byte integer which is the number of pages to truncate the -** database to during a rollback. -** (5) 4 byte integer which is the number of bytes in the master journal -** name. The value may be zero (indicate that there is no master -** journal.) -** (6) N bytes of the master journal name. The name will be nul-terminated -** and might be shorter than the value read from (5). If the first byte -** of the name is \000 then there is no master journal. The master -** journal name is stored in UTF-8. -** (7) Zero or more pages instances, each as follows: -** + 4 byte page number. -** + pPager->pageSize bytes of data. -** + 4 byte checksum -** -** When we speak of the journal header, we mean the first 6 items above. -** Each entry in the journal is an instance of the 7th item. -** -** Call the value from the second bullet "nRec". nRec is the number of -** valid page entries in the journal. In most cases, you can compute the -** value of nRec from the size of the journal file. But if a power -** failure occurred while the journal was being written, it could be the -** case that the size of the journal file had already been increased but -** the extra entries had not yet made it safely to disk. In such a case, -** the value of nRec computed from the file size would be too large. For -** that reason, we always use the nRec value in the header. -** -** If the nRec value is 0xffffffff it means that nRec should be computed -** from the file size. This value is used when the user selects the -** no-sync option for the journal. A power failure could lead to corruption -** in this case. But for things like temporary table (which will be -** deleted when the power is restored) we don't care. -** -** If the file opened as the journal file is not a well-formed -** journal file then all pages up to the first corrupted page are rolled -** back (or no pages if the journal header is corrupted). The journal file -** is then deleted and SQLITE_OK returned, just as if no corruption had -** been encountered. -** -** If an I/O or malloc() error occurs, the journal-file is not deleted -** and an error code is returned. -*/ -static int pager_playback(Pager *pPager, int isHot){ - sqlite3_vfs *pVfs = pPager->pVfs; - i64 szJ; /* Size of the journal file in bytes */ - u32 nRec; /* Number of Records in the journal */ - int i; /* Loop counter */ - Pgno mxPg = 0; /* Size of the original file in pages */ - int rc; /* Result code of a subroutine */ - char *zMaster = 0; /* Name of master journal file if any */ - - /* Figure out how many records are in the journal. Abort early if - ** the journal is empty. - */ - assert( pPager->journalOpen ); - rc = sqlite3OsFileSize(pPager->jfd, &szJ); - if( rc!=SQLITE_OK || szJ==0 ){ - goto end_playback; - } - - /* Read the master journal name from the journal, if it is present. - ** If a master journal file name is specified, but the file is not - ** present on disk, then the journal is not hot and does not need to be - ** played back. - */ - zMaster = pPager->pTmpSpace; - rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); - assert( rc!=SQLITE_DONE ); - if( rc!=SQLITE_OK - || (zMaster[0] && !sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS)) - ){ - zMaster = 0; - if( rc==SQLITE_DONE ) rc = SQLITE_OK; - goto end_playback; - } - pPager->journalOff = 0; - zMaster = 0; - - /* This loop terminates either when the readJournalHdr() call returns - ** SQLITE_DONE or an IO error occurs. */ - while( 1 ){ - - /* Read the next journal header from the journal file. If there are - ** not enough bytes left in the journal file for a complete header, or - ** it is corrupted, then a process must of failed while writing it. - ** This indicates nothing more needs to be rolled back. - */ - rc = readJournalHdr(pPager, szJ, &nRec, &mxPg); - if( rc!=SQLITE_OK ){ - if( rc==SQLITE_DONE ){ - rc = SQLITE_OK; - } - goto end_playback; - } - - /* If nRec is 0xffffffff, then this journal was created by a process - ** working in no-sync mode. This means that the rest of the journal - ** file consists of pages, there are no more journal headers. Compute - ** the value of nRec based on this assumption. - */ - if( nRec==0xffffffff ){ - assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ); - nRec = (szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager); - } - - /* If nRec is 0 and this rollback is of a transaction created by this - ** process and if this is the final header in the journal, then it means - ** that this part of the journal was being filled but has not yet been - ** synced to disk. Compute the number of pages based on the remaining - ** size of the file. - ** - ** The third term of the test was added to fix ticket #2565. - */ - if( nRec==0 && !isHot && - pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){ - nRec = (szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager); - } - - /* If this is the first header read from the journal, truncate the - ** database file back to it's original size. - */ - if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ - rc = pager_truncate(pPager, mxPg); - if( rc!=SQLITE_OK ){ - goto end_playback; - } - } - - /* Copy original pages out of the journal and back into the database file. - */ - for(i=0; ijfd, pPager->journalOff, 1); - if( rc!=SQLITE_OK ){ - if( rc==SQLITE_DONE ){ - rc = SQLITE_OK; - pPager->journalOff = szJ; - break; - }else{ - goto end_playback; - } - } - } - } - /*NOTREACHED*/ - assert( 0 ); - -end_playback: - if( rc==SQLITE_OK ){ - zMaster = pPager->pTmpSpace; - rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); - } - if( rc==SQLITE_OK ){ - rc = pager_end_transaction(pPager); - } - if( rc==SQLITE_OK && zMaster[0] ){ - /* If there was a master journal and this routine will return success, - ** see if it is possible to delete the master journal. - */ - rc = pager_delmaster(pPager, zMaster); - } - - /* The Pager.sectorSize variable may have been updated while rolling - ** back a journal created by a process with a different sector size - ** value. Reset it to the correct value for this process. - */ - setSectorSize(pPager); - return rc; -} - -/* -** Playback the statement journal. -** -** This is similar to playing back the transaction journal but with -** a few extra twists. -** -** (1) The number of pages in the database file at the start of -** the statement is stored in pPager->stmtSize, not in the -** journal file itself. -** -** (2) In addition to playing back the statement journal, also -** playback all pages of the transaction journal beginning -** at offset pPager->stmtJSize. -*/ -static int pager_stmt_playback(Pager *pPager){ - i64 szJ; /* Size of the full journal */ - i64 hdrOff; - int nRec; /* Number of Records */ - int i; /* Loop counter */ - int rc; - - szJ = pPager->journalOff; -#ifndef NDEBUG - { - i64 os_szJ; - rc = sqlite3OsFileSize(pPager->jfd, &os_szJ); - if( rc!=SQLITE_OK ) return rc; - assert( szJ==os_szJ ); - } -#endif - - /* Set hdrOff to be the offset just after the end of the last journal - ** page written before the first journal-header for this statement - ** transaction was written, or the end of the file if no journal - ** header was written. - */ - hdrOff = pPager->stmtHdrOff; - assert( pPager->fullSync || !hdrOff ); - if( !hdrOff ){ - hdrOff = szJ; - } - - /* Truncate the database back to its original size. - */ - rc = pager_truncate(pPager, pPager->stmtSize); - assert( pPager->state>=PAGER_SHARED ); - - /* Figure out how many records are in the statement journal. - */ - assert( pPager->stmtInUse && pPager->journalOpen ); - nRec = pPager->stmtNRec; - - /* Copy original pages out of the statement journal and back into the - ** database file. Note that the statement journal omits checksums from - ** each record since power-failure recovery is not important to statement - ** journals. - */ - for(i=0; ipageSize); - rc = pager_playback_one_page(pPager, pPager->stfd, offset, 0); - assert( rc!=SQLITE_DONE ); - if( rc!=SQLITE_OK ) goto end_stmt_playback; - } - - /* Now roll some pages back from the transaction journal. Pager.stmtJSize - ** was the size of the journal file when this statement was started, so - ** everything after that needs to be rolled back, either into the - ** database, the memory cache, or both. - ** - ** If it is not zero, then Pager.stmtHdrOff is the offset to the start - ** of the first journal header written during this statement transaction. - */ - pPager->journalOff = pPager->stmtJSize; - pPager->cksumInit = pPager->stmtCksum; - while( pPager->journalOff < hdrOff ){ - rc = pager_playback_one_page(pPager, pPager->jfd, pPager->journalOff, 1); - assert( rc!=SQLITE_DONE ); - if( rc!=SQLITE_OK ) goto end_stmt_playback; - } - - while( pPager->journalOff < szJ ){ - u32 nJRec; /* Number of Journal Records */ - u32 dummy; - rc = readJournalHdr(pPager, szJ, &nJRec, &dummy); - if( rc!=SQLITE_OK ){ - assert( rc!=SQLITE_DONE ); - goto end_stmt_playback; - } - if( nJRec==0 ){ - nJRec = (szJ - pPager->journalOff) / (pPager->pageSize+8); - } - for(i=nJRec-1; i>=0 && pPager->journalOff < szJ; i--){ - rc = pager_playback_one_page(pPager, pPager->jfd, pPager->journalOff, 1); - assert( rc!=SQLITE_DONE ); - if( rc!=SQLITE_OK ) goto end_stmt_playback; - } - } - - pPager->journalOff = szJ; - -end_stmt_playback: - if( rc==SQLITE_OK) { - pPager->journalOff = szJ; - /* pager_reload_cache(pPager); */ - } - return rc; -} - -/* -** Change the maximum number of in-memory pages that are allowed. -*/ -void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ - if( mxPage>10 ){ - pPager->mxPage = mxPage; - }else{ - pPager->mxPage = 10; - } -} - -/* -** Adjust the robustness of the database to damage due to OS crashes -** or power failures by changing the number of syncs()s when writing -** the rollback journal. There are three levels: -** -** OFF sqlite3OsSync() is never called. This is the default -** for temporary and transient files. -** -** NORMAL The journal is synced once before writes begin on the -** database. This is normally adequate protection, but -** it is theoretically possible, though very unlikely, -** that an inopertune power failure could leave the journal -** in a state which would cause damage to the database -** when it is rolled back. -** -** FULL The journal is synced twice before writes begin on the -** database (with some additional information - the nRec field -** of the journal header - being written in between the two -** syncs). If we assume that writing a -** single disk sector is atomic, then this mode provides -** assurance that the journal will not be corrupted to the -** point of causing damage to the database during rollback. -** -** Numeric values associated with these states are OFF==1, NORMAL=2, -** and FULL=3. -*/ -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -void sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int full_fsync){ - pPager->noSync = level==1 || pPager->tempFile; - pPager->fullSync = level==3 && !pPager->tempFile; - pPager->sync_flags = (full_fsync?SQLITE_SYNC_FULL:SQLITE_SYNC_NORMAL); - if( pPager->noSync ) pPager->needSync = 0; -} -#endif - -/* -** The following global variable is incremented whenever the library -** attempts to open a temporary file. This information is used for -** testing and analysis only. -*/ -#ifdef SQLITE_TEST -int sqlite3_opentemp_count = 0; -#endif - -/* -** Open a temporary file. -** -** Write the file descriptor into *fd. Return SQLITE_OK on success or some -** other error code if we fail. The OS will automatically delete the temporary -** file when it is closed. -*/ -static int sqlite3PagerOpentemp( - sqlite3_vfs *pVfs, /* The virtual file system layer */ - sqlite3_file *pFile, /* Write the file descriptor here */ - char *zFilename, /* Name of the file. Might be NULL */ - int vfsFlags /* Flags passed through to the VFS */ -){ - int rc; - assert( zFilename!=0 ); - -#ifdef SQLITE_TEST - sqlite3_opentemp_count++; /* Used for testing and analysis only */ -#endif - - vfsFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | - SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE; - rc = sqlite3OsOpen(pVfs, zFilename, pFile, vfsFlags, 0); - assert( rc!=SQLITE_OK || pFile->pMethods ); - return rc; -} - -/* -** Create a new page cache and put a pointer to the page cache in *ppPager. -** The file to be cached need not exist. The file is not locked until -** the first call to sqlite3PagerGet() and is only held open until the -** last page is released using sqlite3PagerUnref(). -** -** If zFilename is NULL then a randomly-named temporary file is created -** and used as the file to be cached. The file will be deleted -** automatically when it is closed. -** -** If zFilename is ":memory:" then all information is held in cache. -** It is never written to disk. This can be used to implement an -** in-memory database. -*/ -int sqlite3PagerOpen( - sqlite3_vfs *pVfs, /* The virtual file system to use */ - Pager **ppPager, /* Return the Pager structure here */ - const char *zFilename, /* Name of the database file to open */ - int nExtra, /* Extra bytes append to each in-memory page */ - int flags, /* flags controlling this file */ - int vfsFlags /* flags passed through to sqlite3_vfs.xOpen() */ -){ - u8 *pPtr; - Pager *pPager = 0; - int rc = SQLITE_OK; - int i; - int tempFile = 0; - int memDb = 0; - int readOnly = 0; - int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; - int noReadlock = (flags & PAGER_NO_READLOCK)!=0; - int journalFileSize = sqlite3JournalSize(pVfs); - int nDefaultPage = SQLITE_DEFAULT_PAGE_SIZE; - char *zPathname; - int nPathname; - - /* The default return is a NULL pointer */ - *ppPager = 0; - - /* Compute the full pathname */ - nPathname = pVfs->mxPathname+1; - zPathname = sqlite3_malloc(nPathname); - if( zPathname==0 ){ - return SQLITE_NOMEM; - } - if( zFilename && zFilename[0] ){ -#ifndef SQLITE_OMIT_MEMORYDB - if( strcmp(zFilename,":memory:")==0 ){ - memDb = 1; - zPathname[0] = 0; - }else -#endif - { - rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); - } - }else{ - rc = sqlite3OsGetTempname(pVfs, nPathname, zPathname); - } - if( rc!=SQLITE_OK ){ - sqlite3_free(zPathname); - return rc; - } - nPathname = strlen(zPathname); - - /* Allocate memory for the pager structure */ - pPager = sqlite3MallocZero( - sizeof(*pPager) + /* Pager structure */ - journalFileSize + /* The journal file structure */ - pVfs->szOsFile * 2 + /* The db and stmt journal files */ - 4*nPathname + 40 /* zFilename, zDirectory, zJournal, zStmtJrnl */ - ); - if( !pPager ){ - sqlite3_free(zPathname); - return SQLITE_NOMEM; - } - pPtr = (u8 *)&pPager[1]; - pPager->vfsFlags = vfsFlags; - pPager->fd = (sqlite3_file*)&pPtr[pVfs->szOsFile*0]; - pPager->stfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*1]; - pPager->jfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*2]; - pPager->zFilename = (char*)&pPtr[pVfs->szOsFile*2+journalFileSize]; - pPager->zDirectory = &pPager->zFilename[nPathname+1]; - pPager->zJournal = &pPager->zDirectory[nPathname+1]; - pPager->zStmtJrnl = &pPager->zJournal[nPathname+10]; - pPager->pVfs = pVfs; - memcpy(pPager->zFilename, zPathname, nPathname+1); - sqlite3_free(zPathname); - - /* Open the pager file. - */ - if( zFilename && zFilename[0] && !memDb ){ - if( nPathname>(pVfs->mxPathname - sizeof("-journal")) ){ - rc = SQLITE_CANTOPEN; - }else{ - int fout = 0; - rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, - pPager->vfsFlags, &fout); - readOnly = (fout&SQLITE_OPEN_READONLY); - - /* If the file was successfully opened for read/write access, - ** choose a default page size in case we have to create the - ** database file. The default page size is the maximum of: - ** - ** + SQLITE_DEFAULT_PAGE_SIZE, - ** + The value returned by sqlite3OsSectorSize() - ** + The largest page size that can be written atomically. - */ - if( rc==SQLITE_OK && !readOnly ){ - int iSectorSize = sqlite3OsSectorSize(pPager->fd); - if( nDefaultPagefd); - int ii; - assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); - assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); - assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); - for(ii=nDefaultPage; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ - if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ) nDefaultPage = ii; - } - } -#endif - if( nDefaultPage>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ - nDefaultPage = SQLITE_MAX_DEFAULT_PAGE_SIZE; - } - } - } - }else if( !memDb ){ - /* If a temporary file is requested, it is not opened immediately. - ** In this case we accept the default page size and delay actually - ** opening the file until the first call to OsWrite(). - */ - tempFile = 1; - pPager->state = PAGER_EXCLUSIVE; - } - - if( pPager && rc==SQLITE_OK ){ - pPager->pTmpSpace = (char *)sqlite3_malloc(nDefaultPage); - } - - /* If an error occured in either of the blocks above. - ** Free the Pager structure and close the file. - ** Since the pager is not allocated there is no need to set - ** any Pager.errMask variables. - */ - if( !pPager || !pPager->pTmpSpace ){ - sqlite3OsClose(pPager->fd); - sqlite3_free(pPager); - return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc); - } - - PAGERTRACE3("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename); - IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename)) - - /* Fill in Pager.zDirectory[] */ - memcpy(pPager->zDirectory, pPager->zFilename, nPathname+1); - for(i=strlen(pPager->zDirectory); i>0 && pPager->zDirectory[i-1]!='/'; i--){} - if( i>0 ) pPager->zDirectory[i-1] = 0; - - /* Fill in Pager.zJournal[] and Pager.zStmtJrnl[] */ - memcpy(pPager->zJournal, pPager->zFilename, nPathname); - memcpy(&pPager->zJournal[nPathname], "-journal", 9); - memcpy(pPager->zStmtJrnl, pPager->zFilename, nPathname); - memcpy(&pPager->zStmtJrnl[nPathname], "-stmtjrnl", 10); - - /* pPager->journalOpen = 0; */ - pPager->useJournal = useJournal && !memDb; - pPager->noReadlock = noReadlock && readOnly; - /* pPager->stmtOpen = 0; */ - /* pPager->stmtInUse = 0; */ - /* pPager->nRef = 0; */ - pPager->dbSize = memDb-1; - pPager->pageSize = nDefaultPage; - /* pPager->stmtSize = 0; */ - /* pPager->stmtJSize = 0; */ - /* pPager->nPage = 0; */ - pPager->mxPage = 100; - pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; - /* pPager->state = PAGER_UNLOCK; */ - assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) ); - /* pPager->errMask = 0; */ - pPager->tempFile = tempFile; - assert( tempFile==PAGER_LOCKINGMODE_NORMAL - || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); - assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); - pPager->exclusiveMode = tempFile; - pPager->memDb = memDb; - pPager->readOnly = readOnly; - /* pPager->needSync = 0; */ - pPager->noSync = pPager->tempFile || !useJournal; - pPager->fullSync = (pPager->noSync?0:1); - pPager->sync_flags = SQLITE_SYNC_NORMAL; - /* pPager->pFirst = 0; */ - /* pPager->pFirstSynced = 0; */ - /* pPager->pLast = 0; */ - pPager->nExtra = FORCE_ALIGNMENT(nExtra); - assert(pPager->fd->pMethods||memDb||tempFile); - if( !memDb ){ - setSectorSize(pPager); - } - /* pPager->pBusyHandler = 0; */ - /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ - *ppPager = pPager; -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - pPager->iInUseMM = 0; - pPager->iInUseDB = 0; - if( !memDb ){ - sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2); - sqlite3_mutex_enter(mutex); - pPager->pNext = sqlite3PagerList; - if( sqlite3PagerList ){ - assert( sqlite3PagerList->pPrev==0 ); - sqlite3PagerList->pPrev = pPager; - } - pPager->pPrev = 0; - sqlite3PagerList = pPager; - sqlite3_mutex_leave(mutex); - } -#endif - return SQLITE_OK; -} - -/* -** Set the busy handler function. -*/ -void sqlite3PagerSetBusyhandler(Pager *pPager, BusyHandler *pBusyHandler){ - pPager->pBusyHandler = pBusyHandler; -} - -/* -** Set the destructor for this pager. If not NULL, the destructor is called -** when the reference count on each page reaches zero. The destructor can -** be used to clean up information in the extra segment appended to each page. -** -** The destructor is not called as a result sqlite3PagerClose(). -** Destructors are only called by sqlite3PagerUnref(). -*/ -void sqlite3PagerSetDestructor(Pager *pPager, void (*xDesc)(DbPage*,int)){ - pPager->xDestructor = xDesc; -} - -/* -** Set the reinitializer for this pager. If not NULL, the reinitializer -** is called when the content of a page in cache is restored to its original -** value as a result of a rollback. The callback gives higher-level code -** an opportunity to restore the EXTRA section to agree with the restored -** page data. -*/ -void sqlite3PagerSetReiniter(Pager *pPager, void (*xReinit)(DbPage*,int)){ - pPager->xReiniter = xReinit; -} - -/* -** Set the page size to *pPageSize. If the suggest new page size is -** inappropriate, then an alternative page size is set to that -** value before returning. -*/ -int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize){ - int rc = SQLITE_OK; - u16 pageSize = *pPageSize; - assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); - if( pageSize && pageSize!=pPager->pageSize - && !pPager->memDb && pPager->nRef==0 - ){ - char *pNew = (char *)sqlite3_malloc(pageSize); - if( !pNew ){ - rc = SQLITE_NOMEM; - }else{ - pagerEnter(pPager); - pager_reset(pPager); - pPager->pageSize = pageSize; - setSectorSize(pPager); - sqlite3_free(pPager->pTmpSpace); - pPager->pTmpSpace = pNew; - pagerLeave(pPager); - } - } - *pPageSize = pPager->pageSize; - return rc; -} - -/* -** Attempt to set the maximum database page count if mxPage is positive. -** Make no changes if mxPage is zero or negative. And never reduce the -** maximum page count below the current size of the database. -** -** Regardless of mxPage, return the current maximum page count. -*/ -int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){ - if( mxPage>0 ){ - pPager->mxPgno = mxPage; - } - sqlite3PagerPagecount(pPager); - return pPager->mxPgno; -} - -/* -** The following set of routines are used to disable the simulated -** I/O error mechanism. These routines are used to avoid simulated -** errors in places where we do not care about errors. -** -** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops -** and generate no code. -*/ -#ifdef SQLITE_TEST -extern int sqlite3_io_error_pending; -extern int sqlite3_io_error_hit; -static int saved_cnt; -void disable_simulated_io_errors(void){ - saved_cnt = sqlite3_io_error_pending; - sqlite3_io_error_pending = -1; -} -void enable_simulated_io_errors(void){ - sqlite3_io_error_pending = saved_cnt; -} -#else -# define disable_simulated_io_errors() -# define enable_simulated_io_errors() -#endif - -/* -** Read the first N bytes from the beginning of the file into memory -** that pDest points to. -** -** No error checking is done. The rational for this is that this function -** may be called even if the file does not exist or contain a header. In -** these cases sqlite3OsRead() will return an error, to which the correct -** response is to zero the memory at pDest and continue. A real IO error -** will presumably recur and be picked up later (Todo: Think about this). -*/ -int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){ - int rc = SQLITE_OK; - memset(pDest, 0, N); - assert(MEMDB||pPager->fd->pMethods||pPager->tempFile); - if( pPager->fd->pMethods ){ - IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) - rc = sqlite3OsRead(pPager->fd, pDest, N, 0); - if( rc==SQLITE_IOERR_SHORT_READ ){ - rc = SQLITE_OK; - } - } - return rc; -} - -/* -** Return the total number of pages in the disk file associated with -** pPager. -** -** If the PENDING_BYTE lies on the page directly after the end of the -** file, then consider this page part of the file too. For example, if -** PENDING_BYTE is byte 4096 (the first byte of page 5) and the size of the -** file is 4096 bytes, 5 is returned instead of 4. -*/ -int sqlite3PagerPagecount(Pager *pPager){ - i64 n = 0; - int rc; - assert( pPager!=0 ); - if( pPager->errCode ){ - return 0; - } - if( pPager->dbSize>=0 ){ - n = pPager->dbSize; - } else { - assert(pPager->fd->pMethods||pPager->tempFile); - if( (pPager->fd->pMethods) - && (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){ - pPager->nRef++; - pager_error(pPager, rc); - pPager->nRef--; - return 0; - } - if( n>0 && npageSize ){ - n = 1; - }else{ - n /= pPager->pageSize; - } - if( pPager->state!=PAGER_UNLOCK ){ - pPager->dbSize = n; - } - } - if( n==(PENDING_BYTE/pPager->pageSize) ){ - n++; - } - if( n>pPager->mxPgno ){ - pPager->mxPgno = n; - } - return n; -} - - -#ifndef SQLITE_OMIT_MEMORYDB -/* -** Clear a PgHistory block -*/ -static void clearHistory(PgHistory *pHist){ - sqlite3_free(pHist->pOrig); - sqlite3_free(pHist->pStmt); - pHist->pOrig = 0; - pHist->pStmt = 0; -} -#else -#define clearHistory(x) -#endif - -/* -** Forward declaration -*/ -static int syncJournal(Pager*); - -/* -** Unlink pPg from it's hash chain. Also set the page number to 0 to indicate -** that the page is not part of any hash chain. This is required because the -** sqlite3PagerMovepage() routine can leave a page in the -** pNextFree/pPrevFree list that is not a part of any hash-chain. -*/ -static void unlinkHashChain(Pager *pPager, PgHdr *pPg){ - if( pPg->pgno==0 ){ - assert( pPg->pNextHash==0 && pPg->pPrevHash==0 ); - return; - } - if( pPg->pNextHash ){ - pPg->pNextHash->pPrevHash = pPg->pPrevHash; - } - if( pPg->pPrevHash ){ - assert( pPager->aHash[pPg->pgno & (pPager->nHash-1)]!=pPg ); - pPg->pPrevHash->pNextHash = pPg->pNextHash; - }else{ - int h = pPg->pgno & (pPager->nHash-1); - pPager->aHash[h] = pPg->pNextHash; - } - if( MEMDB ){ - clearHistory(PGHDR_TO_HIST(pPg, pPager)); - } - pPg->pgno = 0; - pPg->pNextHash = pPg->pPrevHash = 0; -} - -/* -** Unlink a page from the free list (the list of all pages where nRef==0) -** and from its hash collision chain. -*/ -static void unlinkPage(PgHdr *pPg){ - Pager *pPager = pPg->pPager; - - /* Unlink from free page list */ - lruListRemove(pPg); - - /* Unlink from the pgno hash table */ - unlinkHashChain(pPager, pPg); -} - -/* -** This routine is used to truncate the cache when a database -** is truncated. Drop from the cache all pages whose pgno is -** larger than pPager->dbSize and is unreferenced. -** -** Referenced pages larger than pPager->dbSize are zeroed. -** -** Actually, at the point this routine is called, it would be -** an error to have a referenced page. But rather than delete -** that page and guarantee a subsequent segfault, it seems better -** to zero it and hope that we error out sanely. -*/ -static void pager_truncate_cache(Pager *pPager){ - PgHdr *pPg; - PgHdr **ppPg; - int dbSize = pPager->dbSize; - - ppPg = &pPager->pAll; - while( (pPg = *ppPg)!=0 ){ - if( pPg->pgno<=dbSize ){ - ppPg = &pPg->pNextAll; - }else if( pPg->nRef>0 ){ - memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); - ppPg = &pPg->pNextAll; - }else{ - *ppPg = pPg->pNextAll; - IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno)); - PAGER_INCR(sqlite3_pager_pgfree_count); - unlinkPage(pPg); - makeClean(pPg); - sqlite3_free(pPg->pData); - sqlite3_free(pPg); - pPager->nPage--; - } - } -} - -/* -** Try to obtain a lock on a file. Invoke the busy callback if the lock -** is currently not available. Repeat until the busy callback returns -** false or until the lock succeeds. -** -** Return SQLITE_OK on success and an error code if we cannot obtain -** the lock. -*/ -static int pager_wait_on_lock(Pager *pPager, int locktype){ - int rc; - - /* The OS lock values must be the same as the Pager lock values */ - assert( PAGER_SHARED==SHARED_LOCK ); - assert( PAGER_RESERVED==RESERVED_LOCK ); - assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK ); - - /* If the file is currently unlocked then the size must be unknown */ - assert( pPager->state>=PAGER_SHARED || pPager->dbSize<0 || MEMDB ); - - if( pPager->state>=locktype ){ - rc = SQLITE_OK; - }else{ - do { - rc = sqlite3OsLock(pPager->fd, locktype); - }while( rc==SQLITE_BUSY && sqlite3InvokeBusyHandler(pPager->pBusyHandler) ); - if( rc==SQLITE_OK ){ - pPager->state = locktype; - IOTRACE(("LOCK %p %d\n", pPager, locktype)) - } - } - return rc; -} - -/* -** Truncate the file to the number of pages specified. -*/ -int sqlite3PagerTruncate(Pager *pPager, Pgno nPage){ - int rc; - assert( pPager->state>=PAGER_SHARED || MEMDB ); - sqlite3PagerPagecount(pPager); - if( pPager->errCode ){ - rc = pPager->errCode; - return rc; - } - if( nPage>=(unsigned)pPager->dbSize ){ - return SQLITE_OK; - } - if( MEMDB ){ - pPager->dbSize = nPage; - pager_truncate_cache(pPager); - return SQLITE_OK; - } - pagerEnter(pPager); - rc = syncJournal(pPager); - pagerLeave(pPager); - if( rc!=SQLITE_OK ){ - return rc; - } - - /* Get an exclusive lock on the database before truncating. */ - pagerEnter(pPager); - rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); - pagerLeave(pPager); - if( rc!=SQLITE_OK ){ - return rc; - } - - rc = pager_truncate(pPager, nPage); - return rc; -} - -/* -** Shutdown the page cache. Free all memory and close all files. -** -** If a transaction was in progress when this routine is called, that -** transaction is rolled back. All outstanding pages are invalidated -** and their memory is freed. Any attempt to use a page associated -** with this page cache after this function returns will likely -** result in a coredump. -** -** This function always succeeds. If a transaction is active an attempt -** is made to roll it back. If an error occurs during the rollback -** a hot journal may be left in the filesystem but no error is returned -** to the caller. -*/ -int sqlite3PagerClose(Pager *pPager){ -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - if( !MEMDB ){ - sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2); - sqlite3_mutex_enter(mutex); - if( pPager->pPrev ){ - pPager->pPrev->pNext = pPager->pNext; - }else{ - sqlite3PagerList = pPager->pNext; - } - if( pPager->pNext ){ - pPager->pNext->pPrev = pPager->pPrev; - } - sqlite3_mutex_leave(mutex); - } -#endif - - disable_simulated_io_errors(); - pPager->errCode = 0; - pPager->exclusiveMode = 0; - pager_reset(pPager); - pagerUnlockAndRollback(pPager); - enable_simulated_io_errors(); - PAGERTRACE2("CLOSE %d\n", PAGERID(pPager)); - IOTRACE(("CLOSE %p\n", pPager)) - assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) ); - if( pPager->journalOpen ){ - sqlite3OsClose(pPager->jfd); - } - sqlite3_free(pPager->aInJournal); - if( pPager->stmtOpen ){ - sqlite3OsClose(pPager->stfd); - } - sqlite3OsClose(pPager->fd); - /* Temp files are automatically deleted by the OS - ** if( pPager->tempFile ){ - ** sqlite3OsDelete(pPager->zFilename); - ** } - */ - - sqlite3_free(pPager->aHash); - sqlite3_free(pPager->pTmpSpace); - sqlite3_free(pPager); - return SQLITE_OK; -} - -#if !defined(NDEBUG) || defined(SQLITE_TEST) -/* -** Return the page number for the given page data. -*/ -Pgno sqlite3PagerPagenumber(DbPage *p){ - return p->pgno; -} -#endif - -/* -** The page_ref() function increments the reference count for a page. -** If the page is currently on the freelist (the reference count is zero) then -** remove it from the freelist. -** -** For non-test systems, page_ref() is a macro that calls _page_ref() -** online of the reference count is zero. For test systems, page_ref() -** is a real function so that we can set breakpoints and trace it. -*/ -static void _page_ref(PgHdr *pPg){ - if( pPg->nRef==0 ){ - /* The page is currently on the freelist. Remove it. */ - lruListRemove(pPg); - pPg->pPager->nRef++; - } - pPg->nRef++; - REFINFO(pPg); -} -#ifdef SQLITE_DEBUG - static void page_ref(PgHdr *pPg){ - if( pPg->nRef==0 ){ - _page_ref(pPg); - }else{ - pPg->nRef++; - REFINFO(pPg); - } - } -#else -# define page_ref(P) ((P)->nRef==0?_page_ref(P):(void)(P)->nRef++) -#endif - -/* -** Increment the reference count for a page. The input pointer is -** a reference to the page data. -*/ -int sqlite3PagerRef(DbPage *pPg){ - pagerEnter(pPg->pPager); - page_ref(pPg); - pagerLeave(pPg->pPager); - return SQLITE_OK; -} - -/* -** Sync the journal. In other words, make sure all the pages that have -** been written to the journal have actually reached the surface of the -** disk. It is not safe to modify the original database file until after -** the journal has been synced. If the original database is modified before -** the journal is synced and a power failure occurs, the unsynced journal -** data would be lost and we would be unable to completely rollback the -** database changes. Database corruption would occur. -** -** This routine also updates the nRec field in the header of the journal. -** (See comments on the pager_playback() routine for additional information.) -** If the sync mode is FULL, two syncs will occur. First the whole journal -** is synced, then the nRec field is updated, then a second sync occurs. -** -** For temporary databases, we do not care if we are able to rollback -** after a power failure, so no sync occurs. -** -** If the IOCAP_SEQUENTIAL flag is set for the persistent media on which -** the database is stored, then OsSync() is never called on the journal -** file. In this case all that is required is to update the nRec field in -** the journal header. -** -** This routine clears the needSync field of every page current held in -** memory. -*/ -static int syncJournal(Pager *pPager){ - PgHdr *pPg; - int rc = SQLITE_OK; - - - /* Sync the journal before modifying the main database - ** (assuming there is a journal and it needs to be synced.) - */ - if( pPager->needSync ){ - if( !pPager->tempFile ){ - int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); - assert( pPager->journalOpen ); - - /* assert( !pPager->noSync ); // noSync might be set if synchronous - ** was turned off after the transaction was started. Ticket #615 */ -#ifndef NDEBUG - { - /* Make sure the pPager->nRec counter we are keeping agrees - ** with the nRec computed from the size of the journal file. - */ - i64 jSz; - rc = sqlite3OsFileSize(pPager->jfd, &jSz); - if( rc!=0 ) return rc; - assert( pPager->journalOff==jSz ); - } -#endif - if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ - /* Write the nRec value into the journal file header. If in - ** full-synchronous mode, sync the journal first. This ensures that - ** all data has really hit the disk before nRec is updated to mark - ** it as a candidate for rollback. - ** - ** This is not required if the persistent media supports the - ** SAFE_APPEND property. Because in this case it is not possible - ** for garbage data to be appended to the file, the nRec field - ** is populated with 0xFFFFFFFF when the journal header is written - ** and never needs to be updated. - */ - i64 jrnlOff; - if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ - PAGERTRACE2("SYNC journal of %d\n", PAGERID(pPager)); - IOTRACE(("JSYNC %p\n", pPager)) - rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags); - if( rc!=0 ) return rc; - } - - jrnlOff = pPager->journalHdr + sizeof(aJournalMagic); - IOTRACE(("JHDR %p %lld %d\n", pPager, jrnlOff, 4)); - rc = write32bits(pPager->jfd, jrnlOff, pPager->nRec); - if( rc ) return rc; - } - if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ - PAGERTRACE2("SYNC journal of %d\n", PAGERID(pPager)); - IOTRACE(("JSYNC %p\n", pPager)) - rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags| - (pPager->sync_flags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0) - ); - if( rc!=0 ) return rc; - } - pPager->journalStarted = 1; - } - pPager->needSync = 0; - - /* Erase the needSync flag from every page. - */ - for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ - pPg->needSync = 0; - } - lruListSetFirstSynced(pPager); - } - -#ifndef NDEBUG - /* If the Pager.needSync flag is clear then the PgHdr.needSync - ** flag must also be clear for all pages. Verify that this - ** invariant is true. - */ - else{ - for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ - assert( pPg->needSync==0 ); - } - assert( pPager->lru.pFirstSynced==pPager->lru.pFirst ); - } -#endif - - return rc; -} - -/* -** Merge two lists of pages connected by pDirty and in pgno order. -** Do not both fixing the pPrevDirty pointers. -*/ -static PgHdr *merge_pagelist(PgHdr *pA, PgHdr *pB){ - PgHdr result, *pTail; - pTail = &result; - while( pA && pB ){ - if( pA->pgnopgno ){ - pTail->pDirty = pA; - pTail = pA; - pA = pA->pDirty; - }else{ - pTail->pDirty = pB; - pTail = pB; - pB = pB->pDirty; - } - } - if( pA ){ - pTail->pDirty = pA; - }else if( pB ){ - pTail->pDirty = pB; - }else{ - pTail->pDirty = 0; - } - return result.pDirty; -} - -/* -** Sort the list of pages in accending order by pgno. Pages are -** connected by pDirty pointers. The pPrevDirty pointers are -** corrupted by this sort. -*/ -#define N_SORT_BUCKET_ALLOC 25 -#define N_SORT_BUCKET 25 -#ifdef SQLITE_TEST - int sqlite3_pager_n_sort_bucket = 0; - #undef N_SORT_BUCKET - #define N_SORT_BUCKET \ - (sqlite3_pager_n_sort_bucket?sqlite3_pager_n_sort_bucket:N_SORT_BUCKET_ALLOC) -#endif -static PgHdr *sort_pagelist(PgHdr *pIn){ - PgHdr *a[N_SORT_BUCKET_ALLOC], *p; - int i; - memset(a, 0, sizeof(a)); - while( pIn ){ - p = pIn; - pIn = p->pDirty; - p->pDirty = 0; - for(i=0; ipPager; - - /* At this point there may be either a RESERVED or EXCLUSIVE lock on the - ** database file. If there is already an EXCLUSIVE lock, the following - ** calls to sqlite3OsLock() are no-ops. - ** - ** Moving the lock from RESERVED to EXCLUSIVE actually involves going - ** through an intermediate state PENDING. A PENDING lock prevents new - ** readers from attaching to the database but is unsufficient for us to - ** write. The idea of a PENDING lock is to prevent new readers from - ** coming in while we wait for existing readers to clear. - ** - ** While the pager is in the RESERVED state, the original database file - ** is unchanged and we can rollback without having to playback the - ** journal into the original database file. Once we transition to - ** EXCLUSIVE, it means the database file has been changed and any rollback - ** will require a journal playback. - */ - rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); - if( rc!=SQLITE_OK ){ - return rc; - } - - pList = sort_pagelist(pList); - for(p=pList; p; p=p->pDirty){ - assert( p->dirty ); - p->dirty = 0; - } - while( pList ){ - - /* If the file has not yet been opened, open it now. */ - if( !pPager->fd->pMethods ){ - assert(pPager->tempFile); - rc = sqlite3PagerOpentemp(pPager->pVfs, pPager->fd, pPager->zFilename, - pPager->vfsFlags); - if( rc ) return rc; - } - - /* If there are dirty pages in the page cache with page numbers greater - ** than Pager.dbSize, this means sqlite3PagerTruncate() was called to - ** make the file smaller (presumably by auto-vacuum code). Do not write - ** any such pages to the file. - */ - if( pList->pgno<=pPager->dbSize ){ - i64 offset = (pList->pgno-1)*(i64)pPager->pageSize; - char *pData = CODEC2(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6); - PAGERTRACE4("STORE %d page %d hash(%08x)\n", - PAGERID(pPager), pList->pgno, pager_pagehash(pList)); - IOTRACE(("PGOUT %p %d\n", pPager, pList->pgno)); - rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); - PAGER_INCR(sqlite3_pager_writedb_count); - PAGER_INCR(pPager->nWrite); - if( pList->pgno==1 ){ - memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers)); - } - } -#ifndef NDEBUG - else{ - PAGERTRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno); - } -#endif - if( rc ) return rc; -#ifdef SQLITE_CHECK_PAGES - pList->pageHash = pager_pagehash(pList); -#endif - pList = pList->pDirty; - } - return SQLITE_OK; -} - -/* -** Collect every dirty page into a dirty list and -** return a pointer to the head of that list. All pages are -** collected even if they are still in use. -*/ -static PgHdr *pager_get_all_dirty_pages(Pager *pPager){ - return pPager->pDirty; -} - -/* -** Return TRUE if there is a hot journal on the given pager. -** A hot journal is one that needs to be played back. -** -** If the current size of the database file is 0 but a journal file -** exists, that is probably an old journal left over from a prior -** database with the same name. Just delete the journal. -*/ -static int hasHotJournal(Pager *pPager){ - sqlite3_vfs *pVfs = pPager->pVfs; - if( !pPager->useJournal ) return 0; - if( !sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ - return 0; - } - if( sqlite3OsCheckReservedLock(pPager->fd) ){ - return 0; - } - if( sqlite3PagerPagecount(pPager)==0 ){ - sqlite3OsDelete(pVfs, pPager->zJournal, 0); - return 0; - }else{ - return 1; - } -} - -/* -** Try to find a page in the cache that can be recycled. -** -** This routine may return SQLITE_IOERR, SQLITE_FULL or SQLITE_OK. It -** does not set the pPager->errCode variable. -*/ -static int pager_recycle(Pager *pPager, PgHdr **ppPg){ - PgHdr *pPg; - *ppPg = 0; - - /* It is illegal to call this function unless the pager object - ** pointed to by pPager has at least one free page (page with nRef==0). - */ - assert(!MEMDB); - assert(pPager->lru.pFirst); - - /* Find a page to recycle. Try to locate a page that does not - ** require us to do an fsync() on the journal. - */ - pPg = pPager->lru.pFirstSynced; - - /* If we could not find a page that does not require an fsync() - ** on the journal file then fsync the journal file. This is a - ** very slow operation, so we work hard to avoid it. But sometimes - ** it can't be helped. - */ - if( pPg==0 && pPager->lru.pFirst){ - int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); - int rc = syncJournal(pPager); - if( rc!=0 ){ - return rc; - } - if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ - /* If in full-sync mode, write a new journal header into the - ** journal file. This is done to avoid ever modifying a journal - ** header that is involved in the rollback of pages that have - ** already been written to the database (in case the header is - ** trashed when the nRec field is updated). - */ - pPager->nRec = 0; - assert( pPager->journalOff > 0 ); - assert( pPager->doNotSync==0 ); - rc = writeJournalHdr(pPager); - if( rc!=0 ){ - return rc; - } - } - pPg = pPager->lru.pFirst; - } - - assert( pPg->nRef==0 ); - - /* Write the page to the database file if it is dirty. - */ - if( pPg->dirty ){ - int rc; - assert( pPg->needSync==0 ); - makeClean(pPg); - pPg->dirty = 1; - pPg->pDirty = 0; - rc = pager_write_pagelist( pPg ); - pPg->dirty = 0; - if( rc!=SQLITE_OK ){ - return rc; - } - } - assert( pPg->dirty==0 ); - - /* If the page we are recycling is marked as alwaysRollback, then - ** set the global alwaysRollback flag, thus disabling the - ** sqlite3PagerDontRollback() optimization for the rest of this transaction. - ** It is necessary to do this because the page marked alwaysRollback - ** might be reloaded at a later time but at that point we won't remember - ** that is was marked alwaysRollback. This means that all pages must - ** be marked as alwaysRollback from here on out. - */ - if( pPg->alwaysRollback ){ - IOTRACE(("ALWAYS_ROLLBACK %p\n", pPager)) - pPager->alwaysRollback = 1; - } - - /* Unlink the old page from the free list and the hash table - */ - unlinkPage(pPg); - assert( pPg->pgno==0 ); - - *ppPg = pPg; - return SQLITE_OK; -} - -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT -/* -** This function is called to free superfluous dynamically allocated memory -** held by the pager system. Memory in use by any SQLite pager allocated -** by the current thread may be sqlite3_free()ed. -** -** nReq is the number of bytes of memory required. Once this much has -** been released, the function returns. The return value is the total number -** of bytes of memory released. -*/ -int sqlite3PagerReleaseMemory(int nReq){ - int nReleased = 0; /* Bytes of memory released so far */ - sqlite3_mutex *mutex; /* The MEM2 mutex */ - Pager *pPager; /* For looping over pagers */ - int rc = SQLITE_OK; - - /* Acquire the memory-management mutex - */ - mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2); - sqlite3_mutex_enter(mutex); - - /* Signal all database connections that memory management wants - ** to have access to the pagers. - */ - for(pPager=sqlite3PagerList; pPager; pPager=pPager->pNext){ - pPager->iInUseMM = 1; - } - - while( rc==SQLITE_OK && (nReq<0 || nReleasedneedSync || pPg->pPager->iInUseDB) ){ - pPg = pPg->gfree.pNext; - } - if( !pPg ){ - pPg = sqlite3LruPageList.pFirst; - while( pPg && pPg->pPager->iInUseDB ){ - pPg = pPg->gfree.pNext; - } - } - sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU)); - - /* If pPg==0, then the block above has failed to find a page to - ** recycle. In this case return early - no further memory will - ** be released. - */ - if( !pPg ) break; - - pPager = pPg->pPager; - assert(!pPg->needSync || pPg==pPager->lru.pFirst); - assert(pPg->needSync || pPg==pPager->lru.pFirstSynced); - - rc = pager_recycle(pPager, &pRecycled); - assert(pRecycled==pPg || rc!=SQLITE_OK); - if( rc==SQLITE_OK ){ - /* We've found a page to free. At this point the page has been - ** removed from the page hash-table, free-list and synced-list - ** (pFirstSynced). It is still in the all pages (pAll) list. - ** Remove it from this list before freeing. - ** - ** Todo: Check the Pager.pStmt list to make sure this is Ok. It - ** probably is though. - */ - PgHdr *pTmp; - assert( pPg ); - if( pPg==pPager->pAll ){ - pPager->pAll = pPg->pNextAll; - }else{ - for( pTmp=pPager->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll ){} - pTmp->pNextAll = pPg->pNextAll; - } - nReleased += ( - sizeof(*pPg) + pPager->pageSize - + sizeof(u32) + pPager->nExtra - + MEMDB*sizeof(PgHistory) - ); - IOTRACE(("PGFREE %p %d *\n", pPager, pPg->pgno)); - PAGER_INCR(sqlite3_pager_pgfree_count); - sqlite3_free(pPg->pData); - sqlite3_free(pPg); - pPager->nPage--; - }else{ - /* An error occured whilst writing to the database file or - ** journal in pager_recycle(). The error is not returned to the - ** caller of this function. Instead, set the Pager.errCode variable. - ** The error will be returned to the user (or users, in the case - ** of a shared pager cache) of the pager for which the error occured. - */ - assert( - (rc&0xff)==SQLITE_IOERR || - rc==SQLITE_FULL || - rc==SQLITE_BUSY - ); - assert( pPager->state>=PAGER_RESERVED ); - pager_error(pPager, rc); - } - } - - /* Clear the memory management flags and release the mutex - */ - for(pPager=sqlite3PagerList; pPager; pPager=pPager->pNext){ - pPager->iInUseMM = 0; - } - sqlite3_mutex_leave(mutex); - - /* Return the number of bytes released - */ - return nReleased; -} -#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */ - -/* -** Read the content of page pPg out of the database file. -*/ -static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){ - int rc; - i64 offset; - assert( MEMDB==0 ); - assert(pPager->fd->pMethods||pPager->tempFile); - if( !pPager->fd->pMethods ){ - return SQLITE_IOERR_SHORT_READ; - } - offset = (pgno-1)*(i64)pPager->pageSize; - rc = sqlite3OsRead(pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize, offset); - PAGER_INCR(sqlite3_pager_readdb_count); - PAGER_INCR(pPager->nRead); - IOTRACE(("PGIN %p %d\n", pPager, pgno)); - if( pgno==1 ){ - memcpy(&pPager->dbFileVers, &((u8*)PGHDR_TO_DATA(pPg))[24], - sizeof(pPager->dbFileVers)); - } - CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3); - PAGERTRACE4("FETCH %d page %d hash(%08x)\n", - PAGERID(pPager), pPg->pgno, pager_pagehash(pPg)); - return rc; -} - - -/* -** This function is called to obtain the shared lock required before -** data may be read from the pager cache. If the shared lock has already -** been obtained, this function is a no-op. -** -** Immediately after obtaining the shared lock (if required), this function -** checks for a hot-journal file. If one is found, an emergency rollback -** is performed immediately. -*/ -static int pagerSharedLock(Pager *pPager){ - int rc = SQLITE_OK; - int isHot = 0; - - /* If this database is opened for exclusive access, has no outstanding - ** page references and is in an error-state, now is the chance to clear - ** the error. Discard the contents of the pager-cache and treat any - ** open journal file as a hot-journal. - */ - if( !MEMDB && pPager->exclusiveMode && pPager->nRef==0 && pPager->errCode ){ - if( pPager->journalOpen ){ - isHot = 1; - } - pager_reset(pPager); - pPager->errCode = SQLITE_OK; - } - - /* If the pager is still in an error state, do not proceed. The error - ** state will be cleared at some point in the future when all page - ** references are dropped and the cache can be discarded. - */ - if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){ - return pPager->errCode; - } - - if( pPager->state==PAGER_UNLOCK || isHot ){ - sqlite3_vfs *pVfs = pPager->pVfs; - if( !MEMDB ){ - assert( pPager->nRef==0 ); - if( !pPager->noReadlock ){ - rc = pager_wait_on_lock(pPager, SHARED_LOCK); - if( rc!=SQLITE_OK ){ - return pager_error(pPager, rc); - } - assert( pPager->state>=SHARED_LOCK ); - } - - /* If a journal file exists, and there is no RESERVED lock on the - ** database file, then it either needs to be played back or deleted. - */ - if( hasHotJournal(pPager) || isHot ){ - /* Get an EXCLUSIVE lock on the database file. At this point it is - ** important that a RESERVED lock is not obtained on the way to the - ** EXCLUSIVE lock. If it were, another process might open the - ** database file, detect the RESERVED lock, and conclude that the - ** database is safe to read while this process is still rolling it - ** back. - ** - ** Because the intermediate RESERVED lock is not requested, the - ** second process will get to this point in the code and fail to - ** obtain it's own EXCLUSIVE lock on the database file. - */ - if( pPager->statefd, EXCLUSIVE_LOCK); - if( rc!=SQLITE_OK ){ - pager_unlock(pPager); - return pager_error(pPager, rc); - } - pPager->state = PAGER_EXCLUSIVE; - } - - /* Open the journal for reading only. Return SQLITE_BUSY if - ** we are unable to open the journal file. - ** - ** The journal file does not need to be locked itself. The - ** journal file is never open unless the main database file holds - ** a write lock, so there is never any chance of two or more - ** processes opening the journal at the same time. - ** - ** Open the journal for read/write access. This is because in - ** exclusive-access mode the file descriptor will be kept open and - ** possibly used for a transaction later on. On some systems, the - ** OsTruncate() call used in exclusive-access mode also requires - ** a read/write file handle. - */ - if( !isHot ){ - rc = SQLITE_BUSY; - if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ - int fout = 0; - int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; - assert( !pPager->tempFile ); - rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); - assert( rc!=SQLITE_OK || pPager->jfd->pMethods ); - if( fout&SQLITE_OPEN_READONLY ){ - rc = SQLITE_BUSY; - sqlite3OsClose(pPager->jfd); - } - } - } - if( rc!=SQLITE_OK ){ - pager_unlock(pPager); - return ((rc==SQLITE_NOMEM||rc==SQLITE_IOERR_NOMEM)?rc:SQLITE_BUSY); - } - pPager->journalOpen = 1; - pPager->journalStarted = 0; - pPager->journalOff = 0; - pPager->setMaster = 0; - pPager->journalHdr = 0; - - /* Playback and delete the journal. Drop the database write - ** lock and reacquire the read lock. - */ - rc = pager_playback(pPager, 1); - if( rc!=SQLITE_OK ){ - return pager_error(pPager, rc); - } - assert(pPager->state==PAGER_SHARED || - (pPager->exclusiveMode && pPager->state>PAGER_SHARED) - ); - } - - if( pPager->pAll ){ - /* The shared-lock has just been acquired on the database file - ** and there are already pages in the cache (from a previous - ** read or write transaction). Check to see if the database - ** has been modified. If the database has changed, flush the - ** cache. - ** - ** Database changes is detected by looking at 15 bytes beginning - ** at offset 24 into the file. The first 4 of these 16 bytes are - ** a 32-bit counter that is incremented with each change. The - ** other bytes change randomly with each file change when - ** a codec is in use. - ** - ** There is a vanishingly small chance that a change will not be - ** detected. The chance of an undetected change is so small that - ** it can be neglected. - */ - char dbFileVers[sizeof(pPager->dbFileVers)]; - sqlite3PagerPagecount(pPager); - - if( pPager->errCode ){ - return pPager->errCode; - } - - if( pPager->dbSize>0 ){ - IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); - rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24); - if( rc!=SQLITE_OK ){ - return rc; - } - }else{ - memset(dbFileVers, 0, sizeof(dbFileVers)); - } - - if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){ - pager_reset(pPager); - } - } - } - assert( pPager->exclusiveMode || pPager->state<=PAGER_SHARED ); - if( pPager->state==PAGER_UNLOCK ){ - pPager->state = PAGER_SHARED; - } - } - - return rc; -} - -/* -** Allocate a PgHdr object. Either create a new one or reuse -** an existing one that is not otherwise in use. -** -** A new PgHdr structure is created if any of the following are -** true: -** -** (1) We have not exceeded our maximum allocated cache size -** as set by the "PRAGMA cache_size" command. -** -** (2) There are no unused PgHdr objects available at this time. -** -** (3) This is an in-memory database. -** -** (4) There are no PgHdr objects that do not require a journal -** file sync and a sync of the journal file is currently -** prohibited. -** -** Otherwise, reuse an existing PgHdr. In other words, reuse an -** existing PgHdr if all of the following are true: -** -** (1) We have reached or exceeded the maximum cache size -** allowed by "PRAGMA cache_size". -** -** (2) There is a PgHdr available with PgHdr->nRef==0 -** -** (3) We are not in an in-memory database -** -** (4) Either there is an available PgHdr that does not need -** to be synced to disk or else disk syncing is currently -** allowed. -*/ -static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){ - int rc = SQLITE_OK; - PgHdr *pPg; - void *pData; - - /* Create a new PgHdr if any of the four conditions defined - ** above are met: */ - if( pPager->nPagemxPage - || pPager->lru.pFirst==0 - || MEMDB - || (pPager->lru.pFirstSynced==0 && pPager->doNotSync) - ){ - if( pPager->nPage>=pPager->nHash ){ - pager_resize_hash_table(pPager, - pPager->nHash<256 ? 256 : pPager->nHash*2); - if( pPager->nHash==0 ){ - rc = SQLITE_NOMEM; - goto pager_allocate_out; - } - } - pagerLeave(pPager); - pPg = sqlite3_malloc( sizeof(*pPg) + sizeof(u32) + pPager->nExtra - + MEMDB*sizeof(PgHistory) ); - if( pPg ){ - pData = sqlite3_malloc( pPager->pageSize ); - if( pData==0 ){ - sqlite3_free(pPg); - pPg = 0; - } - } - pagerEnter(pPager); - if( pPg==0 ){ - rc = SQLITE_NOMEM; - goto pager_allocate_out; - } - memset(pPg, 0, sizeof(*pPg)); - if( MEMDB ){ - memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory)); - } - pPg->pData = pData; - pPg->pPager = pPager; - pPg->pNextAll = pPager->pAll; - pPager->pAll = pPg; - pPager->nPage++; - }else{ - /* Recycle an existing page with a zero ref-count. */ - rc = pager_recycle(pPager, &pPg); - if( rc==SQLITE_BUSY ){ - rc = SQLITE_IOERR_BLOCKED; - } - if( rc!=SQLITE_OK ){ - goto pager_allocate_out; - } - assert( pPager->state>=SHARED_LOCK ); - assert(pPg); - } - *ppPg = pPg; - -pager_allocate_out: - return rc; -} - -/* -** Make sure we have the content for a page. If the page was -** previously acquired with noContent==1, then the content was -** just initialized to zeros instead of being read from disk. -** But now we need the real data off of disk. So make sure we -** have it. Read it in if we do not have it already. -*/ -static int pager_get_content(PgHdr *pPg){ - if( pPg->needRead ){ - int rc = readDbPage(pPg->pPager, pPg, pPg->pgno); - if( rc==SQLITE_OK ){ - pPg->needRead = 0; - }else{ - return rc; - } - } - return SQLITE_OK; -} - -/* -** Acquire a page. -** -** A read lock on the disk file is obtained when the first page is acquired. -** This read lock is dropped when the last page is released. -** -** This routine works for any page number greater than 0. If the database -** file is smaller than the requested page, then no actual disk -** read occurs and the memory image of the page is initialized to -** all zeros. The extra data appended to a page is always initialized -** to zeros the first time a page is loaded into memory. -** -** The acquisition might fail for several reasons. In all cases, -** an appropriate error code is returned and *ppPage is set to NULL. -** -** See also sqlite3PagerLookup(). Both this routine and Lookup() attempt -** to find a page in the in-memory cache first. If the page is not already -** in memory, this routine goes to disk to read it in whereas Lookup() -** just returns 0. This routine acquires a read-lock the first time it -** has to go to disk, and could also playback an old journal if necessary. -** Since Lookup() never goes to disk, it never has to deal with locks -** or journal files. -** -** If noContent is false, the page contents are actually read from disk. -** If noContent is true, it means that we do not care about the contents -** of the page at this time, so do not do a disk read. Just fill in the -** page content with zeros. But mark the fact that we have not read the -** content by setting the PgHdr.needRead flag. Later on, if -** sqlite3PagerWrite() is called on this page or if this routine is -** called again with noContent==0, that means that the content is needed -** and the disk read should occur at that point. -*/ -static int pagerAcquire( - Pager *pPager, /* The pager open on the database file */ - Pgno pgno, /* Page number to fetch */ - DbPage **ppPage, /* Write a pointer to the page here */ - int noContent /* Do not bother reading content from disk if true */ -){ - PgHdr *pPg; - int rc; - - assert( pPager->state==PAGER_UNLOCK || pPager->nRef>0 || pgno==1 ); - - /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page - ** number greater than this, or zero, is requested. - */ - if( pgno>PAGER_MAX_PGNO || pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){ - return SQLITE_CORRUPT_BKPT; - } - - /* Make sure we have not hit any critical errors. - */ - assert( pPager!=0 ); - *ppPage = 0; - - /* If this is the first page accessed, then get a SHARED lock - ** on the database file. pagerSharedLock() is a no-op if - ** a database lock is already held. - */ - rc = pagerSharedLock(pPager); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( pPager->state!=PAGER_UNLOCK ); - - pPg = pager_lookup(pPager, pgno); - if( pPg==0 ){ - /* The requested page is not in the page cache. */ - int nMax; - int h; - PAGER_INCR(pPager->nMiss); - rc = pagerAllocatePage(pPager, &pPg); - if( rc!=SQLITE_OK ){ - return rc; - } - - pPg->pgno = pgno; - assert( !MEMDB || pgno>pPager->stmtSize ); - if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){ -#if 0 - sqlite3CheckMemory(pPager->aInJournal, pgno/8); -#endif - assert( pPager->journalOpen ); - pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0; - pPg->needSync = 0; - }else{ - pPg->inJournal = 0; - pPg->needSync = 0; - } - - makeClean(pPg); - pPg->nRef = 1; - REFINFO(pPg); - - pPager->nRef++; - if( pPager->nExtra>0 ){ - memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra); - } - nMax = sqlite3PagerPagecount(pPager); - if( pPager->errCode ){ - rc = pPager->errCode; - sqlite3PagerUnref(pPg); - return rc; - } - - /* Populate the page with data, either by reading from the database - ** file, or by setting the entire page to zero. - */ - if( nMax<(int)pgno || MEMDB || (noContent && !pPager->alwaysRollback) ){ - if( pgno>pPager->mxPgno ){ - sqlite3PagerUnref(pPg); - return SQLITE_FULL; - } - memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); - pPg->needRead = noContent && !pPager->alwaysRollback; - IOTRACE(("ZERO %p %d\n", pPager, pgno)); - }else{ - rc = readDbPage(pPager, pPg, pgno); - if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){ - pPg->pgno = 0; - sqlite3PagerUnref(pPg); - return rc; - } - pPg->needRead = 0; - } - - /* Link the page into the page hash table */ - h = pgno & (pPager->nHash-1); - assert( pgno!=0 ); - pPg->pNextHash = pPager->aHash[h]; - pPager->aHash[h] = pPg; - if( pPg->pNextHash ){ - assert( pPg->pNextHash->pPrevHash==0 ); - pPg->pNextHash->pPrevHash = pPg; - } - -#ifdef SQLITE_CHECK_PAGES - pPg->pageHash = pager_pagehash(pPg); -#endif - }else{ - /* The requested page is in the page cache. */ - assert(pPager->nRef>0 || pgno==1); - PAGER_INCR(pPager->nHit); - if( !noContent ){ - rc = pager_get_content(pPg); - if( rc ){ - return rc; - } - } - page_ref(pPg); - } - *ppPage = pPg; - return SQLITE_OK; -} -int sqlite3PagerAcquire( - Pager *pPager, /* The pager open on the database file */ - Pgno pgno, /* Page number to fetch */ - DbPage **ppPage, /* Write a pointer to the page here */ - int noContent /* Do not bother reading content from disk if true */ -){ - int rc; - pagerEnter(pPager); - rc = pagerAcquire(pPager, pgno, ppPage, noContent); - pagerLeave(pPager); - return rc; -} - - -/* -** Acquire a page if it is already in the in-memory cache. Do -** not read the page from disk. Return a pointer to the page, -** or 0 if the page is not in cache. -** -** See also sqlite3PagerGet(). The difference between this routine -** and sqlite3PagerGet() is that _get() will go to the disk and read -** in the page if the page is not already in cache. This routine -** returns NULL if the page is not in cache or if a disk I/O error -** has ever happened. -*/ -DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ - PgHdr *pPg = 0; - - assert( pPager!=0 ); - assert( pgno!=0 ); - - pagerEnter(pPager); - if( pPager->state==PAGER_UNLOCK ){ - assert( !pPager->pAll || pPager->exclusiveMode ); - }else if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){ - /* Do nothing */ - }else if( (pPg = pager_lookup(pPager, pgno))!=0 ){ - page_ref(pPg); - } - pagerLeave(pPager); - return pPg; -} - -/* -** Release a page. -** -** If the number of references to the page drop to zero, then the -** page is added to the LRU list. When all references to all pages -** are released, a rollback occurs and the lock on the database is -** removed. -*/ -int sqlite3PagerUnref(DbPage *pPg){ - Pager *pPager = pPg->pPager; - - /* Decrement the reference count for this page - */ - assert( pPg->nRef>0 ); - pagerEnter(pPg->pPager); - pPg->nRef--; - REFINFO(pPg); - - CHECK_PAGE(pPg); - - /* When the number of references to a page reach 0, call the - ** destructor and add the page to the freelist. - */ - if( pPg->nRef==0 ){ - - lruListAdd(pPg); - if( pPager->xDestructor ){ - pPager->xDestructor(pPg, pPager->pageSize); - } - - /* When all pages reach the freelist, drop the read lock from - ** the database file. - */ - pPager->nRef--; - assert( pPager->nRef>=0 ); - if( pPager->nRef==0 && (!pPager->exclusiveMode || pPager->journalOff>0) ){ - pagerUnlockAndRollback(pPager); - } - } - pagerLeave(pPager); - return SQLITE_OK; -} - -/* -** Create a journal file for pPager. There should already be a RESERVED -** or EXCLUSIVE lock on the database file when this routine is called. -** -** Return SQLITE_OK if everything. Return an error code and release the -** write lock if anything goes wrong. -*/ -static int pager_open_journal(Pager *pPager){ - sqlite3_vfs *pVfs = pPager->pVfs; - int flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_CREATE); - - int rc; - assert( !MEMDB ); - assert( pPager->state>=PAGER_RESERVED ); - assert( pPager->journalOpen==0 ); - assert( pPager->useJournal ); - assert( pPager->aInJournal==0 ); - sqlite3PagerPagecount(pPager); - pagerLeave(pPager); - pPager->aInJournal = sqlite3MallocZero( pPager->dbSize/8 + 1 ); - pagerEnter(pPager); - if( pPager->aInJournal==0 ){ - rc = SQLITE_NOMEM; - goto failed_to_open_journal; - } - - if( pPager->tempFile ){ - flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); - }else{ - flags |= (SQLITE_OPEN_MAIN_JOURNAL); - } -#ifdef SQLITE_ENABLE_ATOMIC_WRITE - rc = sqlite3JournalOpen( - pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) - ); -#else - rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); -#endif - assert( rc!=SQLITE_OK || pPager->jfd->pMethods ); - pPager->journalOff = 0; - pPager->setMaster = 0; - pPager->journalHdr = 0; - if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM ){ - sqlite3OsDelete(pVfs, pPager->zJournal, 0); - } - goto failed_to_open_journal; - } - pPager->journalOpen = 1; - pPager->journalStarted = 0; - pPager->needSync = 0; - pPager->alwaysRollback = 0; - pPager->nRec = 0; - if( pPager->errCode ){ - rc = pPager->errCode; - goto failed_to_open_journal; - } - pPager->origDbSize = pPager->dbSize; - - rc = writeJournalHdr(pPager); - - if( pPager->stmtAutoopen && rc==SQLITE_OK ){ - rc = sqlite3PagerStmtBegin(pPager); - } - if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && rc!=SQLITE_IOERR_NOMEM ){ - rc = pager_end_transaction(pPager); - if( rc==SQLITE_OK ){ - rc = SQLITE_FULL; - } - } - return rc; - -failed_to_open_journal: - sqlite3_free(pPager->aInJournal); - pPager->aInJournal = 0; - return rc; -} - -/* -** Acquire a write-lock on the database. The lock is removed when -** the any of the following happen: -** -** * sqlite3PagerCommitPhaseTwo() is called. -** * sqlite3PagerRollback() is called. -** * sqlite3PagerClose() is called. -** * sqlite3PagerUnref() is called to on every outstanding page. -** -** The first parameter to this routine is a pointer to any open page of the -** database file. Nothing changes about the page - it is used merely to -** acquire a pointer to the Pager structure and as proof that there is -** already a read-lock on the database. -** -** The second parameter indicates how much space in bytes to reserve for a -** master journal file-name at the start of the journal when it is created. -** -** A journal file is opened if this is not a temporary file. For temporary -** files, the opening of the journal file is deferred until there is an -** actual need to write to the journal. -** -** If the database is already reserved for writing, this routine is a no-op. -** -** If exFlag is true, go ahead and get an EXCLUSIVE lock on the file -** immediately instead of waiting until we try to flush the cache. The -** exFlag is ignored if a transaction is already active. -*/ -int sqlite3PagerBegin(DbPage *pPg, int exFlag){ - Pager *pPager = pPg->pPager; - int rc = SQLITE_OK; - pagerEnter(pPager); - assert( pPg->nRef>0 ); - assert( pPager->state!=PAGER_UNLOCK ); - if( pPager->state==PAGER_SHARED ){ - assert( pPager->aInJournal==0 ); - if( MEMDB ){ - pPager->state = PAGER_EXCLUSIVE; - pPager->origDbSize = pPager->dbSize; - }else{ - rc = sqlite3OsLock(pPager->fd, RESERVED_LOCK); - if( rc==SQLITE_OK ){ - pPager->state = PAGER_RESERVED; - if( exFlag ){ - rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); - } - } - if( rc!=SQLITE_OK ){ - pagerLeave(pPager); - return rc; - } - pPager->dirtyCache = 0; - PAGERTRACE2("TRANSACTION %d\n", PAGERID(pPager)); - if( pPager->useJournal && !pPager->tempFile ){ - rc = pager_open_journal(pPager); - } - } - }else if( pPager->journalOpen && pPager->journalOff==0 ){ - /* This happens when the pager was in exclusive-access mode last - ** time a (read or write) transaction was successfully concluded - ** by this connection. Instead of deleting the journal file it was - ** kept open and truncated to 0 bytes. - */ - assert( pPager->nRec==0 ); - assert( pPager->origDbSize==0 ); - assert( pPager->aInJournal==0 ); - sqlite3PagerPagecount(pPager); - pagerLeave(pPager); - pPager->aInJournal = sqlite3MallocZero( pPager->dbSize/8 + 1 ); - pagerEnter(pPager); - if( !pPager->aInJournal ){ - rc = SQLITE_NOMEM; - }else{ - pPager->origDbSize = pPager->dbSize; - rc = writeJournalHdr(pPager); - } - } - assert( !pPager->journalOpen || pPager->journalOff>0 || rc!=SQLITE_OK ); - pagerLeave(pPager); - return rc; -} - -/* -** Make a page dirty. Set its dirty flag and add it to the dirty -** page list. -*/ -static void makeDirty(PgHdr *pPg){ - if( pPg->dirty==0 ){ - Pager *pPager = pPg->pPager; - pPg->dirty = 1; - pPg->pDirty = pPager->pDirty; - if( pPager->pDirty ){ - pPager->pDirty->pPrevDirty = pPg; - } - pPg->pPrevDirty = 0; - pPager->pDirty = pPg; - } -} - -/* -** Make a page clean. Clear its dirty bit and remove it from the -** dirty page list. -*/ -static void makeClean(PgHdr *pPg){ - if( pPg->dirty ){ - pPg->dirty = 0; - if( pPg->pDirty ){ - assert( pPg->pDirty->pPrevDirty==pPg ); - pPg->pDirty->pPrevDirty = pPg->pPrevDirty; - } - if( pPg->pPrevDirty ){ - assert( pPg->pPrevDirty->pDirty==pPg ); - pPg->pPrevDirty->pDirty = pPg->pDirty; - }else{ - assert( pPg->pPager->pDirty==pPg ); - pPg->pPager->pDirty = pPg->pDirty; - } - } -} - - -/* -** Mark a data page as writeable. The page is written into the journal -** if it is not there already. This routine must be called before making -** changes to a page. -** -** The first time this routine is called, the pager creates a new -** journal and acquires a RESERVED lock on the database. If the RESERVED -** lock could not be acquired, this routine returns SQLITE_BUSY. The -** calling routine must check for that return value and be careful not to -** change any page data until this routine returns SQLITE_OK. -** -** If the journal file could not be written because the disk is full, -** then this routine returns SQLITE_FULL and does an immediate rollback. -** All subsequent write attempts also return SQLITE_FULL until there -** is a call to sqlite3PagerCommit() or sqlite3PagerRollback() to -** reset. -*/ -static int pager_write(PgHdr *pPg){ - void *pData = PGHDR_TO_DATA(pPg); - Pager *pPager = pPg->pPager; - int rc = SQLITE_OK; - - /* Check for errors - */ - if( pPager->errCode ){ - return pPager->errCode; - } - if( pPager->readOnly ){ - return SQLITE_PERM; - } - - assert( !pPager->setMaster ); - - CHECK_PAGE(pPg); - - /* If this page was previously acquired with noContent==1, that means - ** we didn't really read in the content of the page. This can happen - ** (for example) when the page is being moved to the freelist. But - ** now we are (perhaps) moving the page off of the freelist for - ** reuse and we need to know its original content so that content - ** can be stored in the rollback journal. So do the read at this - ** time. - */ - rc = pager_get_content(pPg); - if( rc ){ - return rc; - } - - /* Mark the page as dirty. If the page has already been written - ** to the journal then we can return right away. - */ - makeDirty(pPg); - if( pPg->inJournal && (pageInStatement(pPg) || pPager->stmtInUse==0) ){ - pPager->dirtyCache = 1; - }else{ - - /* If we get this far, it means that the page needs to be - ** written to the transaction journal or the ckeckpoint journal - ** or both. - ** - ** First check to see that the transaction journal exists and - ** create it if it does not. - */ - assert( pPager->state!=PAGER_UNLOCK ); - rc = sqlite3PagerBegin(pPg, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( pPager->state>=PAGER_RESERVED ); - if( !pPager->journalOpen && pPager->useJournal ){ - rc = pager_open_journal(pPager); - if( rc!=SQLITE_OK ) return rc; - } - assert( pPager->journalOpen || !pPager->useJournal ); - pPager->dirtyCache = 1; - - /* The transaction journal now exists and we have a RESERVED or an - ** EXCLUSIVE lock on the main database file. Write the current page to - ** the transaction journal if it is not there already. - */ - if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){ - if( (int)pPg->pgno <= pPager->origDbSize ){ - if( MEMDB ){ - PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); - PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); - assert( pHist->pOrig==0 ); - pHist->pOrig = sqlite3_malloc( pPager->pageSize ); - if( pHist->pOrig ){ - memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize); - } - }else{ - u32 cksum; - char *pData2; - - /* We should never write to the journal file the page that - ** contains the database locks. The following assert verifies - ** that we do not. */ - assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) ); - pData2 = CODEC2(pPager, pData, pPg->pgno, 7); - cksum = pager_cksum(pPager, (u8*)pData2); - rc = write32bits(pPager->jfd, pPager->journalOff, pPg->pgno); - if( rc==SQLITE_OK ){ - rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, - pPager->journalOff + 4); - pPager->journalOff += pPager->pageSize+4; - } - if( rc==SQLITE_OK ){ - rc = write32bits(pPager->jfd, pPager->journalOff, cksum); - pPager->journalOff += 4; - } - IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, - pPager->journalOff, pPager->pageSize)); - PAGER_INCR(sqlite3_pager_writej_count); - PAGERTRACE5("JOURNAL %d page %d needSync=%d hash(%08x)\n", - PAGERID(pPager), pPg->pgno, pPg->needSync, pager_pagehash(pPg)); - - /* An error has occured writing to the journal file. The - ** transaction will be rolled back by the layer above. - */ - if( rc!=SQLITE_OK ){ - return rc; - } - - pPager->nRec++; - assert( pPager->aInJournal!=0 ); - pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); - pPg->needSync = !pPager->noSync; - if( pPager->stmtInUse ){ - pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); - } - } - }else{ - pPg->needSync = !pPager->journalStarted && !pPager->noSync; - PAGERTRACE4("APPEND %d page %d needSync=%d\n", - PAGERID(pPager), pPg->pgno, pPg->needSync); - } - if( pPg->needSync ){ - pPager->needSync = 1; - } - pPg->inJournal = 1; - } - - /* If the statement journal is open and the page is not in it, - ** then write the current page to the statement journal. Note that - ** the statement journal format differs from the standard journal format - ** in that it omits the checksums and the header. - */ - if( pPager->stmtInUse - && !pageInStatement(pPg) - && (int)pPg->pgno<=pPager->stmtSize - ){ - assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); - if( MEMDB ){ - PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); - assert( pHist->pStmt==0 ); - pHist->pStmt = sqlite3_malloc( pPager->pageSize ); - if( pHist->pStmt ){ - memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize); - } - PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); - page_add_to_stmt_list(pPg); - }else{ - i64 offset = pPager->stmtNRec*(4+pPager->pageSize); - char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7); - rc = write32bits(pPager->stfd, offset, pPg->pgno); - if( rc==SQLITE_OK ){ - rc = sqlite3OsWrite(pPager->stfd, pData2, pPager->pageSize, offset+4); - } - PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); - if( rc!=SQLITE_OK ){ - return rc; - } - pPager->stmtNRec++; - assert( pPager->aInStmt!=0 ); - pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); - } - } - } - - /* Update the database size and return. - */ - assert( pPager->state>=PAGER_SHARED ); - if( pPager->dbSize<(int)pPg->pgno ){ - pPager->dbSize = pPg->pgno; - if( !MEMDB && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){ - pPager->dbSize++; - } - } - return rc; -} - -/* -** This function is used to mark a data-page as writable. It uses -** pager_write() to open a journal file (if it is not already open) -** and write the page *pData to the journal. -** -** The difference between this function and pager_write() is that this -** function also deals with the special case where 2 or more pages -** fit on a single disk sector. In this case all co-resident pages -** must have been written to the journal file before returning. -*/ -int sqlite3PagerWrite(DbPage *pDbPage){ - int rc = SQLITE_OK; - - PgHdr *pPg = pDbPage; - Pager *pPager = pPg->pPager; - Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); - - pagerEnter(pPager); - if( !MEMDB && nPagePerSector>1 ){ - Pgno nPageCount; /* Total number of pages in database file */ - Pgno pg1; /* First page of the sector pPg is located on. */ - int nPage; /* Number of pages starting at pg1 to journal */ - int ii; - int needSync = 0; - - /* Set the doNotSync flag to 1. This is because we cannot allow a journal - ** header to be written between the pages journaled by this function. - */ - assert( pPager->doNotSync==0 ); - pPager->doNotSync = 1; - - /* This trick assumes that both the page-size and sector-size are - ** an integer power of 2. It sets variable pg1 to the identifier - ** of the first page of the sector pPg is located on. - */ - pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; - - nPageCount = sqlite3PagerPagecount(pPager); - if( pPg->pgno>nPageCount ){ - nPage = (pPg->pgno - pg1)+1; - }else if( (pg1+nPagePerSector-1)>nPageCount ){ - nPage = nPageCount+1-pg1; - }else{ - nPage = nPagePerSector; - } - assert(nPage>0); - assert(pg1<=pPg->pgno); - assert((pg1+nPage)>pPg->pgno); - - for(ii=0; iiaInJournal || pg==pPg->pgno || - pg>pPager->origDbSize || !(pPager->aInJournal[pg/8]&(1<<(pg&7))) - ) { - if( pg!=PAGER_MJ_PGNO(pPager) ){ - rc = sqlite3PagerGet(pPager, pg, &pPage); - if( rc==SQLITE_OK ){ - rc = pager_write(pPage); - if( pPage->needSync ){ - needSync = 1; - } - sqlite3PagerUnref(pPage); - } - } - }else if( (pPage = pager_lookup(pPager, pg)) ){ - if( pPage->needSync ){ - needSync = 1; - } - } - } - - /* If the PgHdr.needSync flag is set for any of the nPage pages - ** starting at pg1, then it needs to be set for all of them. Because - ** writing to any of these nPage pages may damage the others, the - ** journal file must contain sync()ed copies of all of them - ** before any of them can be written out to the database file. - */ - if( needSync ){ - for(ii=0; iineedSync = 1; - } - assert(pPager->needSync); - } - - assert( pPager->doNotSync==1 ); - pPager->doNotSync = 0; - }else{ - rc = pager_write(pDbPage); - } - pagerLeave(pPager); - return rc; -} - -/* -** Return TRUE if the page given in the argument was previously passed -** to sqlite3PagerWrite(). In other words, return TRUE if it is ok -** to change the content of the page. -*/ -#ifndef NDEBUG -int sqlite3PagerIswriteable(DbPage *pPg){ - return pPg->dirty; -} -#endif - -#ifndef SQLITE_OMIT_VACUUM -/* -** Replace the content of a single page with the information in the third -** argument. -*/ -int sqlite3PagerOverwrite(Pager *pPager, Pgno pgno, void *pData){ - PgHdr *pPg; - int rc; - - pagerEnter(pPager); - rc = sqlite3PagerGet(pPager, pgno, &pPg); - if( rc==SQLITE_OK ){ - rc = sqlite3PagerWrite(pPg); - if( rc==SQLITE_OK ){ - memcpy(sqlite3PagerGetData(pPg), pData, pPager->pageSize); - } - sqlite3PagerUnref(pPg); - } - pagerLeave(pPager); - return rc; -} -#endif - -/* -** A call to this routine tells the pager that it is not necessary to -** write the information on page pPg back to the disk, even though -** that page might be marked as dirty. -** -** The overlying software layer calls this routine when all of the data -** on the given page is unused. The pager marks the page as clean so -** that it does not get written to disk. -** -** Tests show that this optimization, together with the -** sqlite3PagerDontRollback() below, more than double the speed -** of large INSERT operations and quadruple the speed of large DELETEs. -** -** When this routine is called, set the alwaysRollback flag to true. -** Subsequent calls to sqlite3PagerDontRollback() for the same page -** will thereafter be ignored. This is necessary to avoid a problem -** where a page with data is added to the freelist during one part of -** a transaction then removed from the freelist during a later part -** of the same transaction and reused for some other purpose. When it -** is first added to the freelist, this routine is called. When reused, -** the sqlite3PagerDontRollback() routine is called. But because the -** page contains critical data, we still need to be sure it gets -** rolled back in spite of the sqlite3PagerDontRollback() call. -*/ -void sqlite3PagerDontWrite(DbPage *pDbPage){ - PgHdr *pPg = pDbPage; - Pager *pPager = pPg->pPager; - - if( MEMDB ) return; - pagerEnter(pPager); - pPg->alwaysRollback = 1; - if( pPg->dirty && !pPager->stmtInUse ){ - assert( pPager->state>=PAGER_SHARED ); - if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSizedbSize ){ - /* If this pages is the last page in the file and the file has grown - ** during the current transaction, then do NOT mark the page as clean. - ** When the database file grows, we must make sure that the last page - ** gets written at least once so that the disk file will be the correct - ** size. If you do not write this page and the size of the file - ** on the disk ends up being too small, that can lead to database - ** corruption during the next transaction. - */ - }else{ - PAGERTRACE3("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)); - IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno)) - makeClean(pPg); -#ifdef SQLITE_CHECK_PAGES - pPg->pageHash = pager_pagehash(pPg); -#endif - } - } - pagerLeave(pPager); -} - -/* -** A call to this routine tells the pager that if a rollback occurs, -** it is not necessary to restore the data on the given page. This -** means that the pager does not have to record the given page in the -** rollback journal. -** -** If we have not yet actually read the content of this page (if -** the PgHdr.needRead flag is set) then this routine acts as a promise -** that we will never need to read the page content in the future. -** so the needRead flag can be cleared at this point. -*/ -void sqlite3PagerDontRollback(DbPage *pPg){ - Pager *pPager = pPg->pPager; - - pagerEnter(pPager); - assert( pPager->state>=PAGER_RESERVED ); - if( pPager->journalOpen==0 ) return; - if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return; - if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){ - assert( pPager->aInJournal!=0 ); - pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); - pPg->inJournal = 1; - pPg->needRead = 0; - if( pPager->stmtInUse ){ - pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); - } - PAGERTRACE3("DONT_ROLLBACK page %d of %d\n", pPg->pgno, PAGERID(pPager)); - IOTRACE(("GARBAGE %p %d\n", pPager, pPg->pgno)) - } - if( pPager->stmtInUse - && !pageInStatement(pPg) - && (int)pPg->pgno<=pPager->stmtSize - ){ - assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); - assert( pPager->aInStmt!=0 ); - pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); - } - pagerLeave(pPager); -} - - -/* -** This routine is called to increment the database file change-counter, -** stored at byte 24 of the pager file. -*/ -static int pager_incr_changecounter(Pager *pPager, int isDirect){ - PgHdr *pPgHdr; - u32 change_counter; - int rc = SQLITE_OK; - - if( !pPager->changeCountDone ){ - /* Open page 1 of the file for writing. */ - rc = sqlite3PagerGet(pPager, 1, &pPgHdr); - if( rc!=SQLITE_OK ) return rc; - - if( !isDirect ){ - rc = sqlite3PagerWrite(pPgHdr); - if( rc!=SQLITE_OK ){ - sqlite3PagerUnref(pPgHdr); - return rc; - } - } - - /* Increment the value just read and write it back to byte 24. */ - change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers); - change_counter++; - put32bits(((char*)PGHDR_TO_DATA(pPgHdr))+24, change_counter); - - if( isDirect && pPager->fd->pMethods ){ - const void *zBuf = PGHDR_TO_DATA(pPgHdr); - rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); - } - - /* Release the page reference. */ - sqlite3PagerUnref(pPgHdr); - pPager->changeCountDone = 1; - } - return rc; -} - -/* -** Sync the database file for the pager pPager. zMaster points to the name -** of a master journal file that should be written into the individual -** journal file. zMaster may be NULL, which is interpreted as no master -** journal (a single database transaction). -** -** This routine ensures that the journal is synced, all dirty pages written -** to the database file and the database file synced. The only thing that -** remains to commit the transaction is to delete the journal file (or -** master journal file if specified). -** -** Note that if zMaster==NULL, this does not overwrite a previous value -** passed to an sqlite3PagerCommitPhaseOne() call. -** -** If parameter nTrunc is non-zero, then the pager file is truncated to -** nTrunc pages (this is used by auto-vacuum databases). -*/ -int sqlite3PagerCommitPhaseOne(Pager *pPager, const char *zMaster, Pgno nTrunc){ - int rc = SQLITE_OK; - - PAGERTRACE4("DATABASE SYNC: File=%s zMaster=%s nTrunc=%d\n", - pPager->zFilename, zMaster, nTrunc); - pagerEnter(pPager); - - /* If this is an in-memory db, or no pages have been written to, or this - ** function has already been called, it is a no-op. - */ - if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){ - PgHdr *pPg; - -#ifdef SQLITE_ENABLE_ATOMIC_WRITE - /* The atomic-write optimization can be used if all of the - ** following are true: - ** - ** + The file-system supports the atomic-write property for - ** blocks of size page-size, and - ** + This commit is not part of a multi-file transaction, and - ** + Exactly one page has been modified and store in the journal file. - ** - ** If the optimization can be used, then the journal file will never - ** be created for this transaction. - */ - int useAtomicWrite = ( - !zMaster && - pPager->journalOff==jrnlBufferSize(pPager) && - nTrunc==0 && - (0==pPager->pDirty || 0==pPager->pDirty->pDirty) - ); - if( useAtomicWrite ){ - /* Update the nRec field in the journal file. */ - int offset = pPager->journalHdr + sizeof(aJournalMagic); - assert(pPager->nRec==1); - rc = write32bits(pPager->jfd, offset, pPager->nRec); - - /* Update the db file change counter. The following call will modify - ** the in-memory representation of page 1 to include the updated - ** change counter and then write page 1 directly to the database - ** file. Because of the atomic-write property of the host file-system, - ** this is safe. - */ - if( rc==SQLITE_OK ){ - rc = pager_incr_changecounter(pPager, 1); - } - }else{ - rc = sqlite3JournalCreate(pPager->jfd); - } - - if( !useAtomicWrite && rc==SQLITE_OK ) -#endif - - /* If a master journal file name has already been written to the - ** journal file, then no sync is required. This happens when it is - ** written, then the process fails to upgrade from a RESERVED to an - ** EXCLUSIVE lock. The next time the process tries to commit the - ** transaction the m-j name will have already been written. - */ - if( !pPager->setMaster ){ - assert( pPager->journalOpen ); - rc = pager_incr_changecounter(pPager, 0); - if( rc!=SQLITE_OK ) goto sync_exit; -#ifndef SQLITE_OMIT_AUTOVACUUM - if( nTrunc!=0 ){ - /* If this transaction has made the database smaller, then all pages - ** being discarded by the truncation must be written to the journal - ** file. - */ - Pgno i; - int iSkip = PAGER_MJ_PGNO(pPager); - for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){ - if( !(pPager->aInJournal[i/8] & (1<<(i&7))) && i!=iSkip ){ - rc = sqlite3PagerGet(pPager, i, &pPg); - if( rc!=SQLITE_OK ) goto sync_exit; - rc = sqlite3PagerWrite(pPg); - sqlite3PagerUnref(pPg); - if( rc!=SQLITE_OK ) goto sync_exit; - } - } - } -#endif - rc = writeMasterJournal(pPager, zMaster); - if( rc!=SQLITE_OK ) goto sync_exit; - rc = syncJournal(pPager); - } - if( rc!=SQLITE_OK ) goto sync_exit; - -#ifndef SQLITE_OMIT_AUTOVACUUM - if( nTrunc!=0 ){ - rc = sqlite3PagerTruncate(pPager, nTrunc); - if( rc!=SQLITE_OK ) goto sync_exit; - } -#endif - - /* Write all dirty pages to the database file */ - pPg = pager_get_all_dirty_pages(pPager); - rc = pager_write_pagelist(pPg); - if( rc!=SQLITE_OK ){ - while( pPg && !pPg->dirty ){ pPg = pPg->pDirty; } - pPager->pDirty = pPg; - goto sync_exit; - } - pPager->pDirty = 0; - - /* Sync the database file. */ - if( !pPager->noSync ){ - rc = sqlite3OsSync(pPager->fd, pPager->sync_flags); - } - IOTRACE(("DBSYNC %p\n", pPager)) - - pPager->state = PAGER_SYNCED; - }else if( MEMDB && nTrunc!=0 ){ - rc = sqlite3PagerTruncate(pPager, nTrunc); - } - -sync_exit: - if( rc==SQLITE_IOERR_BLOCKED ){ - /* pager_incr_changecounter() may attempt to obtain an exclusive - * lock to spill the cache and return IOERR_BLOCKED. But since - * there is no chance the cache is inconsistent, it's - * better to return SQLITE_BUSY. - */ - rc = SQLITE_BUSY; - } - pagerLeave(pPager); - return rc; -} - - -/* -** Commit all changes to the database and release the write lock. -** -** If the commit fails for any reason, a rollback attempt is made -** and an error code is returned. If the commit worked, SQLITE_OK -** is returned. -*/ -int sqlite3PagerCommitPhaseTwo(Pager *pPager){ - int rc; - PgHdr *pPg; - - if( pPager->errCode ){ - return pPager->errCode; - } - if( pPager->statedirty = 0; - pPg->inJournal = 0; - pHist->inStmt = 0; - pPg->needSync = 0; - pHist->pPrevStmt = pHist->pNextStmt = 0; - pPg = pPg->pDirty; - } - pPager->pDirty = 0; -#ifndef NDEBUG - for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ - PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); - assert( !pPg->alwaysRollback ); - assert( !pHist->pOrig ); - assert( !pHist->pStmt ); - } -#endif - pPager->pStmt = 0; - pPager->state = PAGER_SHARED; - return SQLITE_OK; - } - assert( pPager->journalOpen || !pPager->dirtyCache ); - assert( pPager->state==PAGER_SYNCED || !pPager->dirtyCache ); - rc = pager_end_transaction(pPager); - rc = pager_error(pPager, rc); - pagerLeave(pPager); - return rc; -} - -/* -** Rollback all changes. The database falls back to PAGER_SHARED mode. -** All in-memory cache pages revert to their original data contents. -** The journal is deleted. -** -** This routine cannot fail unless some other process is not following -** the correct locking protocol or unless some other -** process is writing trash into the journal file (SQLITE_CORRUPT) or -** unless a prior malloc() failed (SQLITE_NOMEM). Appropriate error -** codes are returned for all these occasions. Otherwise, -** SQLITE_OK is returned. -*/ -int sqlite3PagerRollback(Pager *pPager){ - int rc; - PAGERTRACE2("ROLLBACK %d\n", PAGERID(pPager)); - if( MEMDB ){ - PgHdr *p; - for(p=pPager->pAll; p; p=p->pNextAll){ - PgHistory *pHist; - assert( !p->alwaysRollback ); - if( !p->dirty ){ - assert( !((PgHistory *)PGHDR_TO_HIST(p, pPager))->pOrig ); - assert( !((PgHistory *)PGHDR_TO_HIST(p, pPager))->pStmt ); - continue; - } - - pHist = PGHDR_TO_HIST(p, pPager); - if( pHist->pOrig ){ - memcpy(PGHDR_TO_DATA(p), pHist->pOrig, pPager->pageSize); - PAGERTRACE3("ROLLBACK-PAGE %d of %d\n", p->pgno, PAGERID(pPager)); - }else{ - PAGERTRACE3("PAGE %d is clean on %d\n", p->pgno, PAGERID(pPager)); - } - clearHistory(pHist); - p->dirty = 0; - p->inJournal = 0; - pHist->inStmt = 0; - pHist->pPrevStmt = pHist->pNextStmt = 0; - if( pPager->xReiniter ){ - pPager->xReiniter(p, pPager->pageSize); - } - } - pPager->pDirty = 0; - pPager->pStmt = 0; - pPager->dbSize = pPager->origDbSize; - pager_truncate_cache(pPager); - pPager->stmtInUse = 0; - pPager->state = PAGER_SHARED; - return SQLITE_OK; - } - - pagerEnter(pPager); - if( !pPager->dirtyCache || !pPager->journalOpen ){ - rc = pager_end_transaction(pPager); - pagerLeave(pPager); - return rc; - } - - if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){ - if( pPager->state>=PAGER_EXCLUSIVE ){ - pager_playback(pPager, 0); - } - pagerLeave(pPager); - return pPager->errCode; - } - if( pPager->state==PAGER_RESERVED ){ - int rc2; - rc = pager_playback(pPager, 0); - rc2 = pager_end_transaction(pPager); - if( rc==SQLITE_OK ){ - rc = rc2; - } - }else{ - rc = pager_playback(pPager, 0); - } - /* pager_reset(pPager); */ - pPager->dbSize = -1; - - /* If an error occurs during a ROLLBACK, we can no longer trust the pager - ** cache. So call pager_error() on the way out to make any error - ** persistent. - */ - rc = pager_error(pPager, rc); - pagerLeave(pPager); - return rc; -} - -/* -** Return TRUE if the database file is opened read-only. Return FALSE -** if the database is (in theory) writable. -*/ -int sqlite3PagerIsreadonly(Pager *pPager){ - return pPager->readOnly; -} - -/* -** Return the number of references to the pager. -*/ -int sqlite3PagerRefcount(Pager *pPager){ - return pPager->nRef; -} - -#ifdef SQLITE_TEST -/* -** This routine is used for testing and analysis only. -*/ -int *sqlite3PagerStats(Pager *pPager){ - static int a[11]; - a[0] = pPager->nRef; - a[1] = pPager->nPage; - a[2] = pPager->mxPage; - a[3] = pPager->dbSize; - a[4] = pPager->state; - a[5] = pPager->errCode; - a[6] = pPager->nHit; - a[7] = pPager->nMiss; - a[8] = 0; /* Used to be pPager->nOvfl */ - a[9] = pPager->nRead; - a[10] = pPager->nWrite; - return a; -} -#endif - -/* -** Set the statement rollback point. -** -** This routine should be called with the transaction journal already -** open. A new statement journal is created that can be used to rollback -** changes of a single SQL command within a larger transaction. -*/ -static int pagerStmtBegin(Pager *pPager){ - int rc; - assert( !pPager->stmtInUse ); - assert( pPager->state>=PAGER_SHARED ); - assert( pPager->dbSize>=0 ); - PAGERTRACE2("STMT-BEGIN %d\n", PAGERID(pPager)); - if( MEMDB ){ - pPager->stmtInUse = 1; - pPager->stmtSize = pPager->dbSize; - return SQLITE_OK; - } - if( !pPager->journalOpen ){ - pPager->stmtAutoopen = 1; - return SQLITE_OK; - } - assert( pPager->journalOpen ); - pagerLeave(pPager); - assert( pPager->aInStmt==0 ); - pPager->aInStmt = sqlite3MallocZero( pPager->dbSize/8 + 1 ); - pagerEnter(pPager); - if( pPager->aInStmt==0 ){ - /* sqlite3OsLock(pPager->fd, SHARED_LOCK); */ - return SQLITE_NOMEM; - } -#ifndef NDEBUG - rc = sqlite3OsFileSize(pPager->jfd, &pPager->stmtJSize); - if( rc ) goto stmt_begin_failed; - assert( pPager->stmtJSize == pPager->journalOff ); -#endif - pPager->stmtJSize = pPager->journalOff; - pPager->stmtSize = pPager->dbSize; - pPager->stmtHdrOff = 0; - pPager->stmtCksum = pPager->cksumInit; - if( !pPager->stmtOpen ){ - rc = sqlite3PagerOpentemp(pPager->pVfs, pPager->stfd, pPager->zStmtJrnl, - SQLITE_OPEN_SUBJOURNAL); - if( rc ){ - goto stmt_begin_failed; - } - pPager->stmtOpen = 1; - pPager->stmtNRec = 0; - } - pPager->stmtInUse = 1; - return SQLITE_OK; - -stmt_begin_failed: - if( pPager->aInStmt ){ - sqlite3_free(pPager->aInStmt); - pPager->aInStmt = 0; - } - return rc; -} -int sqlite3PagerStmtBegin(Pager *pPager){ - int rc; - pagerEnter(pPager); - rc = pagerStmtBegin(pPager); - pagerLeave(pPager); - return rc; -} - -/* -** Commit a statement. -*/ -int sqlite3PagerStmtCommit(Pager *pPager){ - pagerEnter(pPager); - if( pPager->stmtInUse ){ - PgHdr *pPg, *pNext; - PAGERTRACE2("STMT-COMMIT %d\n", PAGERID(pPager)); - if( !MEMDB ){ - /* sqlite3OsTruncate(pPager->stfd, 0); */ - sqlite3_free( pPager->aInStmt ); - pPager->aInStmt = 0; - }else{ - for(pPg=pPager->pStmt; pPg; pPg=pNext){ - PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); - pNext = pHist->pNextStmt; - assert( pHist->inStmt ); - pHist->inStmt = 0; - pHist->pPrevStmt = pHist->pNextStmt = 0; - sqlite3_free(pHist->pStmt); - pHist->pStmt = 0; - } - } - pPager->stmtNRec = 0; - pPager->stmtInUse = 0; - pPager->pStmt = 0; - } - pPager->stmtAutoopen = 0; - pagerLeave(pPager); - return SQLITE_OK; -} - -/* -** Rollback a statement. -*/ -int sqlite3PagerStmtRollback(Pager *pPager){ - int rc; - pagerEnter(pPager); - if( pPager->stmtInUse ){ - PAGERTRACE2("STMT-ROLLBACK %d\n", PAGERID(pPager)); - if( MEMDB ){ - PgHdr *pPg; - PgHistory *pHist; - for(pPg=pPager->pStmt; pPg; pPg=pHist->pNextStmt){ - pHist = PGHDR_TO_HIST(pPg, pPager); - if( pHist->pStmt ){ - memcpy(PGHDR_TO_DATA(pPg), pHist->pStmt, pPager->pageSize); - sqlite3_free(pHist->pStmt); - pHist->pStmt = 0; - } - } - pPager->dbSize = pPager->stmtSize; - pager_truncate_cache(pPager); - rc = SQLITE_OK; - }else{ - rc = pager_stmt_playback(pPager); - } - sqlite3PagerStmtCommit(pPager); - }else{ - rc = SQLITE_OK; - } - pPager->stmtAutoopen = 0; - pagerLeave(pPager); - return rc; -} - -/* -** Return the full pathname of the database file. -*/ -const char *sqlite3PagerFilename(Pager *pPager){ - return pPager->zFilename; -} - -/* -** Return the VFS structure for the pager. -*/ -const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){ - return pPager->pVfs; -} - -/* -** Return the file handle for the database file associated -** with the pager. This might return NULL if the file has -** not yet been opened. -*/ -sqlite3_file *sqlite3PagerFile(Pager *pPager){ - return pPager->fd; -} - -/* -** Return the directory of the database file. -*/ -const char *sqlite3PagerDirname(Pager *pPager){ - return pPager->zDirectory; -} - -/* -** Return the full pathname of the journal file. -*/ -const char *sqlite3PagerJournalname(Pager *pPager){ - return pPager->zJournal; -} - -/* -** Return true if fsync() calls are disabled for this pager. Return FALSE -** if fsync()s are executed normally. -*/ -int sqlite3PagerNosync(Pager *pPager){ - return pPager->noSync; -} - -#ifdef SQLITE_HAS_CODEC -/* -** Set the codec for this pager -*/ -void sqlite3PagerSetCodec( - Pager *pPager, - void *(*xCodec)(void*,void*,Pgno,int), - void *pCodecArg -){ - pPager->xCodec = xCodec; - pPager->pCodecArg = pCodecArg; -} -#endif - -#ifndef SQLITE_OMIT_AUTOVACUUM -/* -** Move the page pPg to location pgno in the file. -** -** There must be no references to the page previously located at -** pgno (which we call pPgOld) though that page is allowed to be -** in cache. If the page previous located at pgno is not already -** in the rollback journal, it is not put there by by this routine. -** -** References to the page pPg remain valid. Updating any -** meta-data associated with pPg (i.e. data stored in the nExtra bytes -** allocated along with the page) is the responsibility of the caller. -** -** A transaction must be active when this routine is called. It used to be -** required that a statement transaction was not active, but this restriction -** has been removed (CREATE INDEX needs to move a page when a statement -** transaction is active). -*/ -int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){ - PgHdr *pPgOld; /* The page being overwritten. */ - int h; - Pgno needSyncPgno = 0; - - pagerEnter(pPager); - assert( pPg->nRef>0 ); - - PAGERTRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", - PAGERID(pPager), pPg->pgno, pPg->needSync, pgno); - IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno)) - - pager_get_content(pPg); - if( pPg->needSync ){ - needSyncPgno = pPg->pgno; - assert( pPg->inJournal || (int)pgno>pPager->origDbSize ); - assert( pPg->dirty ); - assert( pPager->needSync ); - } - - /* Unlink pPg from it's hash-chain */ - unlinkHashChain(pPager, pPg); - - /* If the cache contains a page with page-number pgno, remove it - ** from it's hash chain. Also, if the PgHdr.needSync was set for - ** page pgno before the 'move' operation, it needs to be retained - ** for the page moved there. - */ - pPg->needSync = 0; - pPgOld = pager_lookup(pPager, pgno); - if( pPgOld ){ - assert( pPgOld->nRef==0 ); - unlinkHashChain(pPager, pPgOld); - makeClean(pPgOld); - pPg->needSync = pPgOld->needSync; - }else{ - pPg->needSync = 0; - } - if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){ - pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0; - }else{ - pPg->inJournal = 0; - assert( pPg->needSync==0 || (int)pgno>pPager->origDbSize ); - } - - /* Change the page number for pPg and insert it into the new hash-chain. */ - assert( pgno!=0 ); - pPg->pgno = pgno; - h = pgno & (pPager->nHash-1); - if( pPager->aHash[h] ){ - assert( pPager->aHash[h]->pPrevHash==0 ); - pPager->aHash[h]->pPrevHash = pPg; - } - pPg->pNextHash = pPager->aHash[h]; - pPager->aHash[h] = pPg; - pPg->pPrevHash = 0; - - makeDirty(pPg); - pPager->dirtyCache = 1; - - if( needSyncPgno ){ - /* If needSyncPgno is non-zero, then the journal file needs to be - ** sync()ed before any data is written to database file page needSyncPgno. - ** Currently, no such page exists in the page-cache and the - ** Pager.aInJournal bit has been set. This needs to be remedied by loading - ** the page into the pager-cache and setting the PgHdr.needSync flag. - ** - ** The sqlite3PagerGet() call may cause the journal to sync. So make - ** sure the Pager.needSync flag is set too. - */ - int rc; - PgHdr *pPgHdr; - assert( pPager->needSync ); - rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr); - if( rc!=SQLITE_OK ) return rc; - pPager->needSync = 1; - pPgHdr->needSync = 1; - pPgHdr->inJournal = 1; - makeDirty(pPgHdr); - sqlite3PagerUnref(pPgHdr); - } - - pagerLeave(pPager); - return SQLITE_OK; -} -#endif - -/* -** Return a pointer to the data for the specified page. -*/ -void *sqlite3PagerGetData(DbPage *pPg){ - return PGHDR_TO_DATA(pPg); -} - -/* -** Return a pointer to the Pager.nExtra bytes of "extra" space -** allocated along with the specified page. -*/ -void *sqlite3PagerGetExtra(DbPage *pPg){ - Pager *pPager = pPg->pPager; - return (pPager?PGHDR_TO_EXTRA(pPg, pPager):0); -} - -/* -** Get/set the locking-mode for this pager. Parameter eMode must be one -** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or -** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then -** the locking-mode is set to the value specified. -** -** The returned value is either PAGER_LOCKINGMODE_NORMAL or -** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated) -** locking-mode. -*/ -int sqlite3PagerLockingMode(Pager *pPager, int eMode){ - assert( eMode==PAGER_LOCKINGMODE_QUERY - || eMode==PAGER_LOCKINGMODE_NORMAL - || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); - assert( PAGER_LOCKINGMODE_QUERY<0 ); - assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 ); - if( eMode>=0 && !pPager->tempFile ){ - pPager->exclusiveMode = eMode; - } - return (int)pPager->exclusiveMode; -} - -#ifdef SQLITE_DEBUG -/* -** Print a listing of all referenced pages and their ref count. -*/ -void sqlite3PagerRefdump(Pager *pPager){ - PgHdr *pPg; - for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ - if( pPg->nRef<=0 ) continue; - sqlite3DebugPrintf("PAGE %3d addr=%p nRef=%d\n", - pPg->pgno, PGHDR_TO_DATA(pPg), pPg->nRef); - } -} -#endif - -#endif /* SQLITE_OMIT_DISKIO */ diff --git a/extensions/sqlite/sqlite-source/pager.h b/extensions/sqlite/sqlite-source/pager.h deleted file mode 100644 index 731efdeb..00000000 --- a/extensions/sqlite/sqlite-source/pager.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -** 2001 September 15 -** -** 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 interface that the sqlite page cache -** subsystem. The page cache subsystem reads and writes a file a page -** at a time and provides a journal for rollback. -** -** @(#) $Id$ -*/ - -#ifndef _PAGER_H_ -#define _PAGER_H_ - -/* -** The type used to represent a page number. The first page in a file -** is called page 1. 0 is used to represent "not a page". -*/ -typedef unsigned int Pgno; - -/* -** Each open file is managed by a separate instance of the "Pager" structure. -*/ -typedef struct Pager Pager; - -/* -** Handle type for pages. -*/ -typedef struct PgHdr DbPage; - -/* -** Allowed values for the flags parameter to sqlite3PagerOpen(). -** -** NOTE: This values must match the corresponding BTREE_ values in btree.h. -*/ -#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ -#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ - -/* -** Valid values for the second argument to sqlite3PagerLockingMode(). -*/ -#define PAGER_LOCKINGMODE_QUERY -1 -#define PAGER_LOCKINGMODE_NORMAL 0 -#define PAGER_LOCKINGMODE_EXCLUSIVE 1 - -/* -** See source code comments for a detailed description of the following -** routines: -*/ -int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char*, int,int,int); -void sqlite3PagerSetBusyhandler(Pager*, BusyHandler *pBusyHandler); -void sqlite3PagerSetDestructor(Pager*, void(*)(DbPage*,int)); -void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*,int)); -int sqlite3PagerSetPagesize(Pager*, u16*); -int sqlite3PagerMaxPageCount(Pager*, int); -int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); -void sqlite3PagerSetCachesize(Pager*, int); -int sqlite3PagerClose(Pager *pPager); -int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); -#define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0) -DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); -int sqlite3PagerRef(DbPage*); -int sqlite3PagerUnref(DbPage*); -int sqlite3PagerWrite(DbPage*); -int sqlite3PagerOverwrite(Pager *pPager, Pgno pgno, void*); -int sqlite3PagerPagecount(Pager*); -int sqlite3PagerTruncate(Pager*,Pgno); -int sqlite3PagerBegin(DbPage*, int exFlag); -int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, Pgno); -int sqlite3PagerCommitPhaseTwo(Pager*); -int sqlite3PagerRollback(Pager*); -int sqlite3PagerIsreadonly(Pager*); -int sqlite3PagerStmtBegin(Pager*); -int sqlite3PagerStmtCommit(Pager*); -int sqlite3PagerStmtRollback(Pager*); -void sqlite3PagerDontRollback(DbPage*); -void sqlite3PagerDontWrite(DbPage*); -int sqlite3PagerRefcount(Pager*); -void sqlite3PagerSetSafetyLevel(Pager*,int,int); -const char *sqlite3PagerFilename(Pager*); -const sqlite3_vfs *sqlite3PagerVfs(Pager*); -sqlite3_file *sqlite3PagerFile(Pager*); -const char *sqlite3PagerDirname(Pager*); -const char *sqlite3PagerJournalname(Pager*); -int sqlite3PagerNosync(Pager*); -int sqlite3PagerMovepage(Pager*,DbPage*,Pgno); -void *sqlite3PagerGetData(DbPage *); -void *sqlite3PagerGetExtra(DbPage *); -int sqlite3PagerLockingMode(Pager *, int); - -#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO) - int sqlite3PagerReleaseMemory(int); -#endif - -#ifdef SQLITE_HAS_CODEC - void sqlite3PagerSetCodec(Pager*,void*(*)(void*,void*,Pgno,int),void*); -#endif - -#if !defined(NDEBUG) || defined(SQLITE_TEST) - Pgno sqlite3PagerPagenumber(DbPage*); - int sqlite3PagerIswriteable(DbPage*); -#endif - -#ifdef SQLITE_TEST - int *sqlite3PagerStats(Pager*); - void sqlite3PagerRefdump(Pager*); - int pager3_refinfo_enable; -#endif - -#ifdef SQLITE_TEST -void disable_simulated_io_errors(void); -void enable_simulated_io_errors(void); -#else -# define disable_simulated_io_errors() -# define enable_simulated_io_errors() -#endif - -#endif /* _PAGER_H_ */ diff --git a/extensions/sqlite/sqlite-source/parse.c b/extensions/sqlite/sqlite-source/parse.c deleted file mode 100644 index 4fb4866a..00000000 --- a/extensions/sqlite/sqlite-source/parse.c +++ /dev/null @@ -1,3505 +0,0 @@ -/* Driver template for the LEMON parser generator. -** The author disclaims copyright to this source code. -*/ -/* First off, code is include which follows the "include" declaration -** in the input file. */ -#include -#line 56 "parse.y" - -#include "sqliteInt.h" - -/* -** An instance of this structure holds information about the -** LIMIT clause of a SELECT statement. -*/ -struct LimitVal { - Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */ - Expr *pOffset; /* The OFFSET expression. NULL if there is none */ -}; - -/* -** An instance of this structure is used to store the LIKE, -** GLOB, NOT LIKE, and NOT GLOB operators. -*/ -struct LikeOp { - Token eOperator; /* "like" or "glob" or "regexp" */ - int not; /* True if the NOT keyword is present */ -}; - -/* -** An instance of the following structure describes the event of a -** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, -** TK_DELETE, or TK_INSTEAD. If the event is of the form -** -** UPDATE ON (a,b,c) -** -** Then the "b" IdList records the list "a,b,c". -*/ -struct TrigEvent { int a; IdList * b; }; - -/* -** An instance of this structure holds the ATTACH key and the key type. -*/ -struct AttachKey { int type; Token key; }; - -#line 47 "parse.c" -/* Next is all token values, in a form suitable for use by makeheaders. -** This section will be null unless lemon is run with the -m switch. -*/ -/* -** These constants (all generated automatically by the parser generator) -** specify the various kinds of tokens (terminals) that the parser -** understands. -** -** Each symbol here is a terminal symbol in the grammar. -*/ -/* Make sure the INTERFACE macro is defined. -*/ -#ifndef INTERFACE -# define INTERFACE 1 -#endif -/* The next thing included is series of defines which control -** various aspects of the generated parser. -** YYCODETYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 terminals -** and nonterminals. "int" is used otherwise. -** YYNOCODE is a number of type YYCODETYPE which corresponds -** to no legal terminal or nonterminal number. This -** number is used to fill in empty slots of the hash -** table. -** YYFALLBACK If defined, this indicates that one or more tokens -** have fall-back values which should be used if the -** original value of the token will not parse. -** YYACTIONTYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 rules and -** states combined. "int" is used otherwise. -** sqlite3ParserTOKENTYPE is the data type used for minor tokens given -** directly to the parser from the tokenizer. -** YYMINORTYPE is the data type used for all minor tokens. -** This is typically a union of many types, one of -** which is sqlite3ParserTOKENTYPE. The entry in the union -** for base tokens is called "yy0". -** YYSTACKDEPTH is the maximum depth of the parser's stack. If -** zero the stack is dynamically sized using realloc() -** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument -** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument -** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser -** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser -** YYNSTATE the combined number of states. -** YYNRULE the number of rules in the grammar -** YYERRORSYMBOL is the code number of the error symbol. If not -** defined, then do no error processing. -*/ -#define YYCODETYPE unsigned char -#define YYNOCODE 248 -#define YYACTIONTYPE unsigned short int -#define YYWILDCARD 59 -#define sqlite3ParserTOKENTYPE Token -typedef union { - sqlite3ParserTOKENTYPE yy0; - int yy46; - struct LikeOp yy72; - Expr* yy172; - ExprList* yy174; - Select* yy219; - struct LimitVal yy234; - TriggerStep* yy243; - struct TrigEvent yy370; - SrcList* yy373; - Expr * yy386; - struct {int value; int mask;} yy405; - Token yy410; - IdList* yy432; - int yy495; -} YYMINORTYPE; -#ifndef YYSTACKDEPTH -#define YYSTACKDEPTH 100 -#endif -#define sqlite3ParserARG_SDECL Parse *pParse; -#define sqlite3ParserARG_PDECL ,Parse *pParse -#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse -#define sqlite3ParserARG_STORE yypParser->pParse = pParse -#define YYNSTATE 586 -#define YYNRULE 311 -#define YYERRORSYMBOL 138 -#define YYERRSYMDT yy495 -#define YYFALLBACK 1 -#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) -#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) -#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) - -/* Next are that tables used to determine what action to take based on the -** current state and lookahead token. These tables are used to implement -** functions that take a state number and lookahead value and return an -** action integer. -** -** Suppose the action integer is N. Then the action is determined as -** follows -** -** 0 <= N < YYNSTATE Shift N. That is, push the lookahead -** token onto the stack and goto state N. -** -** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. -** -** N == YYNSTATE+YYNRULE A syntax error has occurred. -** -** N == YYNSTATE+YYNRULE+1 The parser accepts its input. -** -** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused -** slots in the yy_action[] table. -** -** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as -** -** yy_action[ yy_shift_ofst[S] + X ] -** -** If the index value yy_shift_ofst[S]+X is out of range or if the value -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] -** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. -** -** The formula above is for computing the action when the lookahead is -** a terminal symbol. If the lookahead is a non-terminal (as occurs after -** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of -** YY_SHIFT_USE_DFLT. -** -** The following are the tables generated in this section: -** -** yy_action[] A single table containing all actions. -** yy_lookahead[] A table containing the lookahead for each entry in -** yy_action. Used to detect hash collisions. -** yy_shift_ofst[] For each state, the offset into yy_action for -** shifting terminals. -** yy_reduce_ofst[] For each state, the offset into yy_action for -** shifting non-terminals after a reduce. -** yy_default[] Default action for each state. -*/ -static const YYACTIONTYPE yy_action[] = { - /* 0 */ 290, 898, 122, 585, 407, 170, 2, 437, 61, 61, - /* 10 */ 61, 61, 517, 63, 63, 63, 63, 64, 64, 65, - /* 20 */ 65, 65, 66, 231, 445, 209, 422, 428, 68, 63, - /* 30 */ 63, 63, 63, 64, 64, 65, 65, 65, 66, 231, - /* 40 */ 389, 386, 394, 449, 60, 59, 295, 432, 433, 429, - /* 50 */ 429, 62, 62, 61, 61, 61, 61, 261, 63, 63, - /* 60 */ 63, 63, 64, 64, 65, 65, 65, 66, 231, 290, - /* 70 */ 491, 492, 437, 487, 206, 81, 67, 417, 69, 152, - /* 80 */ 63, 63, 63, 63, 64, 64, 65, 65, 65, 66, - /* 90 */ 231, 67, 460, 69, 152, 422, 428, 571, 262, 58, - /* 100 */ 64, 64, 65, 65, 65, 66, 231, 395, 396, 419, - /* 110 */ 419, 419, 290, 60, 59, 295, 432, 433, 429, 429, - /* 120 */ 62, 62, 61, 61, 61, 61, 315, 63, 63, 63, - /* 130 */ 63, 64, 64, 65, 65, 65, 66, 231, 422, 428, - /* 140 */ 93, 65, 65, 65, 66, 231, 394, 231, 412, 34, - /* 150 */ 56, 296, 440, 441, 408, 486, 60, 59, 295, 432, - /* 160 */ 433, 429, 429, 62, 62, 61, 61, 61, 61, 488, - /* 170 */ 63, 63, 63, 63, 64, 64, 65, 65, 65, 66, - /* 180 */ 231, 290, 255, 522, 293, 569, 112, 406, 520, 449, - /* 190 */ 329, 315, 405, 20, 437, 338, 517, 394, 530, 529, - /* 200 */ 503, 445, 209, 568, 567, 206, 528, 422, 428, 147, - /* 210 */ 148, 395, 396, 412, 41, 208, 149, 531, 370, 487, - /* 220 */ 259, 566, 257, 417, 290, 60, 59, 295, 432, 433, - /* 230 */ 429, 429, 62, 62, 61, 61, 61, 61, 315, 63, - /* 240 */ 63, 63, 63, 64, 64, 65, 65, 65, 66, 231, - /* 250 */ 422, 428, 445, 331, 212, 419, 419, 419, 361, 437, - /* 260 */ 412, 41, 395, 396, 364, 565, 208, 290, 60, 59, - /* 270 */ 295, 432, 433, 429, 429, 62, 62, 61, 61, 61, - /* 280 */ 61, 394, 63, 63, 63, 63, 64, 64, 65, 65, - /* 290 */ 65, 66, 231, 422, 428, 489, 298, 522, 472, 66, - /* 300 */ 231, 211, 472, 224, 409, 284, 532, 20, 447, 521, - /* 310 */ 166, 60, 59, 295, 432, 433, 429, 429, 62, 62, - /* 320 */ 61, 61, 61, 61, 472, 63, 63, 63, 63, 64, - /* 330 */ 64, 65, 65, 65, 66, 231, 207, 478, 315, 76, - /* 340 */ 290, 235, 298, 55, 482, 225, 395, 396, 179, 545, - /* 350 */ 492, 343, 346, 347, 67, 150, 69, 152, 337, 522, - /* 360 */ 412, 35, 348, 237, 249, 368, 422, 428, 576, 20, - /* 370 */ 162, 116, 239, 341, 244, 342, 174, 320, 440, 441, - /* 380 */ 412, 3, 79, 250, 60, 59, 295, 432, 433, 429, - /* 390 */ 429, 62, 62, 61, 61, 61, 61, 172, 63, 63, - /* 400 */ 63, 63, 64, 64, 65, 65, 65, 66, 231, 290, - /* 410 */ 249, 548, 232, 485, 508, 351, 315, 116, 239, 341, - /* 420 */ 244, 342, 174, 179, 315, 523, 343, 346, 347, 250, - /* 430 */ 218, 413, 153, 462, 509, 422, 428, 348, 412, 34, - /* 440 */ 463, 208, 175, 173, 158, 233, 412, 34, 336, 547, - /* 450 */ 447, 321, 166, 60, 59, 295, 432, 433, 429, 429, - /* 460 */ 62, 62, 61, 61, 61, 61, 413, 63, 63, 63, - /* 470 */ 63, 64, 64, 65, 65, 65, 66, 231, 290, 540, - /* 480 */ 333, 515, 502, 539, 454, 569, 300, 19, 329, 142, - /* 490 */ 315, 388, 315, 328, 2, 360, 455, 292, 481, 371, - /* 500 */ 267, 266, 250, 568, 422, 428, 586, 389, 386, 456, - /* 510 */ 206, 493, 412, 49, 412, 49, 301, 583, 889, 157, - /* 520 */ 889, 494, 60, 59, 295, 432, 433, 429, 429, 62, - /* 530 */ 62, 61, 61, 61, 61, 199, 63, 63, 63, 63, - /* 540 */ 64, 64, 65, 65, 65, 66, 231, 290, 315, 179, - /* 550 */ 436, 253, 343, 346, 347, 368, 151, 580, 306, 248, - /* 560 */ 307, 450, 75, 348, 77, 380, 208, 423, 424, 413, - /* 570 */ 412, 27, 317, 422, 428, 438, 1, 22, 583, 888, - /* 580 */ 394, 888, 542, 476, 318, 261, 435, 435, 426, 427, - /* 590 */ 413, 60, 59, 295, 432, 433, 429, 429, 62, 62, - /* 600 */ 61, 61, 61, 61, 326, 63, 63, 63, 63, 64, - /* 610 */ 64, 65, 65, 65, 66, 231, 290, 425, 580, 372, - /* 620 */ 219, 92, 515, 9, 334, 394, 555, 394, 454, 67, - /* 630 */ 394, 69, 152, 397, 398, 399, 318, 234, 435, 435, - /* 640 */ 455, 316, 422, 428, 297, 395, 396, 318, 430, 435, - /* 650 */ 435, 579, 289, 456, 220, 325, 5, 217, 544, 290, - /* 660 */ 60, 59, 295, 432, 433, 429, 429, 62, 62, 61, - /* 670 */ 61, 61, 61, 393, 63, 63, 63, 63, 64, 64, - /* 680 */ 65, 65, 65, 66, 231, 422, 428, 480, 311, 390, - /* 690 */ 395, 396, 395, 396, 205, 395, 396, 821, 271, 515, - /* 700 */ 248, 198, 290, 60, 59, 295, 432, 433, 429, 429, - /* 710 */ 62, 62, 61, 61, 61, 61, 468, 63, 63, 63, - /* 720 */ 63, 64, 64, 65, 65, 65, 66, 231, 422, 428, - /* 730 */ 169, 158, 261, 261, 302, 413, 274, 117, 272, 261, - /* 740 */ 515, 515, 261, 515, 190, 290, 60, 70, 295, 432, - /* 750 */ 433, 429, 429, 62, 62, 61, 61, 61, 61, 377, - /* 760 */ 63, 63, 63, 63, 64, 64, 65, 65, 65, 66, - /* 770 */ 231, 422, 428, 382, 557, 303, 304, 248, 413, 318, - /* 780 */ 558, 435, 435, 559, 538, 358, 538, 385, 290, 194, - /* 790 */ 59, 295, 432, 433, 429, 429, 62, 62, 61, 61, - /* 800 */ 61, 61, 369, 63, 63, 63, 63, 64, 64, 65, - /* 810 */ 65, 65, 66, 231, 422, 428, 394, 273, 248, 248, - /* 820 */ 170, 246, 437, 413, 384, 365, 176, 177, 178, 467, - /* 830 */ 309, 121, 154, 126, 295, 432, 433, 429, 429, 62, - /* 840 */ 62, 61, 61, 61, 61, 315, 63, 63, 63, 63, - /* 850 */ 64, 64, 65, 65, 65, 66, 231, 72, 322, 175, - /* 860 */ 4, 315, 261, 315, 294, 261, 413, 412, 28, 315, - /* 870 */ 261, 315, 319, 72, 322, 315, 4, 418, 443, 443, - /* 880 */ 294, 395, 396, 412, 23, 412, 32, 437, 319, 324, - /* 890 */ 327, 412, 53, 412, 52, 315, 156, 412, 97, 449, - /* 900 */ 315, 192, 315, 275, 315, 324, 376, 469, 500, 315, - /* 910 */ 476, 277, 476, 163, 292, 449, 315, 412, 95, 74, - /* 920 */ 73, 467, 412, 100, 412, 101, 412, 111, 72, 313, - /* 930 */ 314, 412, 113, 417, 446, 74, 73, 479, 412, 16, - /* 940 */ 379, 315, 181, 465, 72, 313, 314, 72, 322, 417, - /* 950 */ 4, 206, 315, 184, 294, 315, 497, 498, 474, 206, - /* 960 */ 171, 339, 319, 412, 98, 419, 419, 419, 420, 421, - /* 970 */ 11, 359, 378, 305, 412, 33, 413, 412, 96, 324, - /* 980 */ 458, 419, 419, 419, 420, 421, 11, 413, 411, 449, - /* 990 */ 411, 160, 410, 315, 410, 466, 221, 222, 223, 103, - /* 1000 */ 83, 471, 315, 507, 506, 315, 620, 475, 315, 74, - /* 1010 */ 73, 245, 203, 21, 279, 412, 24, 437, 72, 313, - /* 1020 */ 314, 280, 315, 417, 412, 54, 505, 412, 114, 315, - /* 1030 */ 412, 115, 504, 201, 145, 547, 240, 510, 524, 200, - /* 1040 */ 315, 511, 202, 315, 412, 25, 315, 241, 315, 18, - /* 1050 */ 315, 412, 36, 315, 254, 419, 419, 419, 420, 421, - /* 1060 */ 11, 256, 412, 37, 258, 412, 26, 315, 412, 38, - /* 1070 */ 412, 39, 412, 40, 260, 412, 42, 315, 512, 315, - /* 1080 */ 126, 315, 437, 315, 187, 375, 276, 266, 265, 412, - /* 1090 */ 43, 291, 315, 252, 315, 126, 206, 581, 8, 412, - /* 1100 */ 44, 412, 29, 412, 30, 412, 45, 350, 363, 126, - /* 1110 */ 315, 543, 315, 126, 412, 46, 412, 47, 315, 355, - /* 1120 */ 381, 551, 315, 171, 552, 315, 90, 562, 578, 90, - /* 1130 */ 288, 366, 412, 48, 412, 31, 582, 367, 268, 269, - /* 1140 */ 412, 10, 270, 554, 412, 50, 564, 412, 51, 278, - /* 1150 */ 281, 282, 575, 144, 442, 403, 323, 226, 444, 461, - /* 1160 */ 464, 242, 503, 550, 561, 513, 161, 392, 400, 516, - /* 1170 */ 401, 345, 402, 7, 312, 83, 227, 332, 228, 82, - /* 1180 */ 330, 57, 408, 416, 168, 78, 459, 123, 210, 414, - /* 1190 */ 84, 335, 340, 299, 496, 500, 490, 229, 495, 243, - /* 1200 */ 104, 247, 499, 501, 230, 285, 415, 215, 514, 518, - /* 1210 */ 525, 526, 519, 236, 527, 473, 238, 352, 477, 286, - /* 1220 */ 182, 356, 533, 354, 119, 183, 185, 87, 546, 130, - /* 1230 */ 186, 535, 188, 140, 362, 191, 553, 216, 373, 374, - /* 1240 */ 131, 560, 308, 132, 133, 572, 577, 136, 263, 134, - /* 1250 */ 139, 536, 573, 391, 91, 94, 404, 574, 99, 214, - /* 1260 */ 102, 621, 622, 431, 164, 434, 165, 71, 141, 17, - /* 1270 */ 439, 448, 451, 155, 6, 452, 470, 110, 167, 453, - /* 1280 */ 457, 124, 13, 213, 120, 80, 12, 125, 159, 483, - /* 1290 */ 484, 85, 310, 105, 180, 251, 106, 118, 86, 107, - /* 1300 */ 241, 344, 349, 353, 143, 534, 127, 357, 171, 189, - /* 1310 */ 264, 108, 287, 128, 549, 129, 193, 537, 541, 14, - /* 1320 */ 195, 88, 196, 556, 197, 137, 138, 135, 15, 563, - /* 1330 */ 570, 109, 283, 146, 204, 383, 387, 899, 584, 899, - /* 1340 */ 899, 899, 899, 899, 89, -}; -static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 16, 139, 140, 141, 168, 21, 144, 23, 69, 70, - /* 10 */ 71, 72, 176, 74, 75, 76, 77, 78, 79, 80, - /* 20 */ 81, 82, 83, 84, 78, 79, 42, 43, 73, 74, - /* 30 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - /* 40 */ 1, 2, 23, 58, 60, 61, 62, 63, 64, 65, - /* 50 */ 66, 67, 68, 69, 70, 71, 72, 147, 74, 75, - /* 60 */ 76, 77, 78, 79, 80, 81, 82, 83, 84, 16, - /* 70 */ 185, 186, 88, 88, 110, 22, 217, 92, 219, 220, - /* 80 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - /* 90 */ 84, 217, 218, 219, 220, 42, 43, 238, 188, 46, - /* 100 */ 78, 79, 80, 81, 82, 83, 84, 88, 89, 124, - /* 110 */ 125, 126, 16, 60, 61, 62, 63, 64, 65, 66, - /* 120 */ 67, 68, 69, 70, 71, 72, 147, 74, 75, 76, - /* 130 */ 77, 78, 79, 80, 81, 82, 83, 84, 42, 43, - /* 140 */ 44, 80, 81, 82, 83, 84, 23, 84, 169, 170, - /* 150 */ 19, 164, 165, 166, 23, 169, 60, 61, 62, 63, - /* 160 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 169, - /* 170 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - /* 180 */ 84, 16, 14, 147, 150, 147, 21, 167, 168, 58, - /* 190 */ 211, 147, 156, 157, 23, 216, 176, 23, 181, 176, - /* 200 */ 177, 78, 79, 165, 166, 110, 183, 42, 43, 78, - /* 210 */ 79, 88, 89, 169, 170, 228, 180, 181, 123, 88, - /* 220 */ 52, 98, 54, 92, 16, 60, 61, 62, 63, 64, - /* 230 */ 65, 66, 67, 68, 69, 70, 71, 72, 147, 74, - /* 240 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - /* 250 */ 42, 43, 78, 209, 210, 124, 125, 126, 224, 88, - /* 260 */ 169, 170, 88, 89, 230, 227, 228, 16, 60, 61, - /* 270 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 280 */ 72, 23, 74, 75, 76, 77, 78, 79, 80, 81, - /* 290 */ 82, 83, 84, 42, 43, 160, 16, 147, 161, 83, - /* 300 */ 84, 210, 161, 153, 169, 158, 156, 157, 161, 162, - /* 310 */ 163, 60, 61, 62, 63, 64, 65, 66, 67, 68, - /* 320 */ 69, 70, 71, 72, 161, 74, 75, 76, 77, 78, - /* 330 */ 79, 80, 81, 82, 83, 84, 192, 200, 147, 131, - /* 340 */ 16, 200, 16, 199, 20, 190, 88, 89, 90, 185, - /* 350 */ 186, 93, 94, 95, 217, 22, 219, 220, 147, 147, - /* 360 */ 169, 170, 104, 200, 84, 147, 42, 43, 156, 157, - /* 370 */ 90, 91, 92, 93, 94, 95, 96, 164, 165, 166, - /* 380 */ 169, 170, 131, 103, 60, 61, 62, 63, 64, 65, - /* 390 */ 66, 67, 68, 69, 70, 71, 72, 155, 74, 75, - /* 400 */ 76, 77, 78, 79, 80, 81, 82, 83, 84, 16, - /* 410 */ 84, 11, 221, 20, 30, 16, 147, 91, 92, 93, - /* 420 */ 94, 95, 96, 90, 147, 181, 93, 94, 95, 103, - /* 430 */ 212, 189, 155, 27, 50, 42, 43, 104, 169, 170, - /* 440 */ 34, 228, 43, 201, 202, 147, 169, 170, 206, 49, - /* 450 */ 161, 162, 163, 60, 61, 62, 63, 64, 65, 66, - /* 460 */ 67, 68, 69, 70, 71, 72, 189, 74, 75, 76, - /* 470 */ 77, 78, 79, 80, 81, 82, 83, 84, 16, 25, - /* 480 */ 211, 147, 20, 29, 12, 147, 102, 19, 211, 21, - /* 490 */ 147, 141, 147, 216, 144, 41, 24, 98, 20, 99, - /* 500 */ 100, 101, 103, 165, 42, 43, 0, 1, 2, 37, - /* 510 */ 110, 39, 169, 170, 169, 170, 182, 19, 20, 147, - /* 520 */ 22, 49, 60, 61, 62, 63, 64, 65, 66, 67, - /* 530 */ 68, 69, 70, 71, 72, 155, 74, 75, 76, 77, - /* 540 */ 78, 79, 80, 81, 82, 83, 84, 16, 147, 90, - /* 550 */ 20, 20, 93, 94, 95, 147, 155, 59, 215, 225, - /* 560 */ 215, 20, 130, 104, 132, 227, 228, 42, 43, 189, - /* 570 */ 169, 170, 16, 42, 43, 20, 19, 22, 19, 20, - /* 580 */ 23, 22, 18, 147, 106, 147, 108, 109, 63, 64, - /* 590 */ 189, 60, 61, 62, 63, 64, 65, 66, 67, 68, - /* 600 */ 69, 70, 71, 72, 186, 74, 75, 76, 77, 78, - /* 610 */ 79, 80, 81, 82, 83, 84, 16, 92, 59, 55, - /* 620 */ 212, 21, 147, 19, 147, 23, 188, 23, 12, 217, - /* 630 */ 23, 219, 220, 7, 8, 9, 106, 147, 108, 109, - /* 640 */ 24, 147, 42, 43, 208, 88, 89, 106, 92, 108, - /* 650 */ 109, 244, 245, 37, 145, 39, 191, 182, 94, 16, - /* 660 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - /* 670 */ 70, 71, 72, 147, 74, 75, 76, 77, 78, 79, - /* 680 */ 80, 81, 82, 83, 84, 42, 43, 80, 142, 143, - /* 690 */ 88, 89, 88, 89, 148, 88, 89, 133, 14, 147, - /* 700 */ 225, 155, 16, 60, 61, 62, 63, 64, 65, 66, - /* 710 */ 67, 68, 69, 70, 71, 72, 114, 74, 75, 76, - /* 720 */ 77, 78, 79, 80, 81, 82, 83, 84, 42, 43, - /* 730 */ 201, 202, 147, 147, 182, 189, 52, 147, 54, 147, - /* 740 */ 147, 147, 147, 147, 155, 16, 60, 61, 62, 63, - /* 750 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 213, - /* 760 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - /* 770 */ 84, 42, 43, 188, 188, 182, 182, 225, 189, 106, - /* 780 */ 188, 108, 109, 188, 99, 100, 101, 241, 16, 155, - /* 790 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - /* 800 */ 71, 72, 213, 74, 75, 76, 77, 78, 79, 80, - /* 810 */ 81, 82, 83, 84, 42, 43, 23, 133, 225, 225, - /* 820 */ 21, 225, 23, 189, 239, 236, 99, 100, 101, 22, - /* 830 */ 242, 243, 155, 22, 62, 63, 64, 65, 66, 67, - /* 840 */ 68, 69, 70, 71, 72, 147, 74, 75, 76, 77, - /* 850 */ 78, 79, 80, 81, 82, 83, 84, 16, 17, 43, - /* 860 */ 19, 147, 147, 147, 23, 147, 189, 169, 170, 147, - /* 870 */ 147, 147, 31, 16, 17, 147, 19, 147, 124, 125, - /* 880 */ 23, 88, 89, 169, 170, 169, 170, 88, 31, 48, - /* 890 */ 147, 169, 170, 169, 170, 147, 89, 169, 170, 58, - /* 900 */ 147, 22, 147, 188, 147, 48, 188, 114, 97, 147, - /* 910 */ 147, 188, 147, 19, 98, 58, 147, 169, 170, 78, - /* 920 */ 79, 114, 169, 170, 169, 170, 169, 170, 87, 88, - /* 930 */ 89, 169, 170, 92, 161, 78, 79, 80, 169, 170, - /* 940 */ 91, 147, 155, 22, 87, 88, 89, 16, 17, 92, - /* 950 */ 19, 110, 147, 155, 23, 147, 7, 8, 20, 110, - /* 960 */ 22, 80, 31, 169, 170, 124, 125, 126, 127, 128, - /* 970 */ 129, 208, 123, 208, 169, 170, 189, 169, 170, 48, - /* 980 */ 147, 124, 125, 126, 127, 128, 129, 189, 107, 58, - /* 990 */ 107, 5, 111, 147, 111, 203, 10, 11, 12, 13, - /* 1000 */ 121, 147, 147, 91, 92, 147, 112, 147, 147, 78, - /* 1010 */ 79, 147, 26, 19, 28, 169, 170, 23, 87, 88, - /* 1020 */ 89, 35, 147, 92, 169, 170, 178, 169, 170, 147, - /* 1030 */ 169, 170, 147, 47, 113, 49, 92, 178, 147, 53, - /* 1040 */ 147, 178, 56, 147, 169, 170, 147, 103, 147, 19, - /* 1050 */ 147, 169, 170, 147, 147, 124, 125, 126, 127, 128, - /* 1060 */ 129, 147, 169, 170, 147, 169, 170, 147, 169, 170, - /* 1070 */ 169, 170, 169, 170, 147, 169, 170, 147, 20, 147, - /* 1080 */ 22, 147, 88, 147, 232, 99, 100, 101, 147, 169, - /* 1090 */ 170, 105, 147, 20, 147, 22, 110, 20, 68, 169, - /* 1100 */ 170, 169, 170, 169, 170, 169, 170, 20, 147, 22, - /* 1110 */ 147, 20, 147, 22, 169, 170, 169, 170, 147, 233, - /* 1120 */ 134, 20, 147, 22, 20, 147, 22, 20, 20, 22, - /* 1130 */ 22, 147, 169, 170, 169, 170, 59, 147, 147, 147, - /* 1140 */ 169, 170, 147, 147, 169, 170, 147, 169, 170, 147, - /* 1150 */ 147, 147, 147, 191, 229, 149, 223, 193, 229, 172, - /* 1160 */ 172, 172, 177, 194, 194, 172, 6, 146, 146, 172, - /* 1170 */ 146, 173, 146, 22, 154, 121, 194, 118, 195, 119, - /* 1180 */ 116, 120, 23, 160, 112, 130, 152, 152, 222, 189, - /* 1190 */ 98, 115, 98, 40, 179, 97, 171, 196, 171, 171, - /* 1200 */ 19, 84, 173, 171, 197, 174, 198, 226, 160, 160, - /* 1210 */ 171, 171, 179, 204, 171, 205, 204, 15, 205, 174, - /* 1220 */ 151, 38, 152, 152, 60, 151, 151, 130, 184, 19, - /* 1230 */ 152, 152, 151, 214, 152, 184, 194, 226, 152, 15, - /* 1240 */ 187, 194, 152, 187, 187, 33, 137, 184, 234, 187, - /* 1250 */ 214, 235, 152, 1, 237, 237, 20, 152, 159, 175, - /* 1260 */ 175, 112, 112, 92, 112, 107, 112, 19, 19, 231, - /* 1270 */ 20, 20, 11, 19, 117, 20, 114, 240, 22, 20, - /* 1280 */ 20, 19, 117, 44, 243, 22, 22, 20, 112, 20, - /* 1290 */ 20, 19, 246, 19, 96, 20, 19, 32, 19, 19, - /* 1300 */ 103, 44, 44, 16, 21, 17, 98, 36, 22, 98, - /* 1310 */ 133, 19, 5, 45, 1, 102, 122, 51, 45, 19, - /* 1320 */ 113, 68, 14, 17, 115, 102, 122, 113, 19, 123, - /* 1330 */ 20, 14, 136, 19, 135, 57, 3, 247, 4, 247, - /* 1340 */ 247, 247, 247, 247, 68, -}; -#define YY_SHIFT_USE_DFLT (-62) -#define YY_SHIFT_MAX 387 -static const short yy_shift_ofst[] = { - /* 0 */ 39, 841, 986, -16, 841, 931, 931, 258, 123, -36, - /* 10 */ 96, 931, 931, 931, 931, 931, -45, 400, 174, 19, - /* 20 */ 171, -54, -54, 53, 165, 208, 251, 324, 393, 462, - /* 30 */ 531, 600, 643, 686, 643, 643, 643, 643, 643, 643, - /* 40 */ 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, - /* 50 */ 643, 643, 729, 772, 772, 857, 931, 931, 931, 931, - /* 60 */ 931, 931, 931, 931, 931, 931, 931, 931, 931, 931, - /* 70 */ 931, 931, 931, 931, 931, 931, 931, 931, 931, 931, - /* 80 */ 931, 931, 931, 931, 931, 931, 931, 931, 931, 931, - /* 90 */ 931, 931, 931, 931, 931, -61, -61, 6, 6, 280, - /* 100 */ 22, 61, 399, 564, 19, 19, 19, 19, 19, 19, - /* 110 */ 19, 216, 171, 63, -62, -62, 131, 326, 472, 472, - /* 120 */ 498, 559, 506, 799, 19, 799, 19, 19, 19, 19, - /* 130 */ 19, 19, 19, 19, 19, 19, 19, 19, 19, 849, - /* 140 */ 95, -36, -36, -36, -62, -62, -62, -15, -15, 333, - /* 150 */ 459, 478, 557, 530, 541, 616, 602, 793, 604, 607, - /* 160 */ 626, 19, 19, 881, 19, 19, 994, 19, 19, 807, - /* 170 */ 19, 19, 673, 807, 19, 19, 384, 384, 384, 19, - /* 180 */ 19, 673, 19, 19, 673, 19, 454, 685, 19, 19, - /* 190 */ 673, 19, 19, 19, 673, 19, 19, 19, 673, 673, - /* 200 */ 19, 19, 19, 19, 19, 468, 883, 921, 754, 754, - /* 210 */ 432, 406, 406, 406, 816, 406, 406, 811, 879, 879, - /* 220 */ 1160, 1160, 1160, 1160, 1151, -36, 1054, 1059, 1060, 1064, - /* 230 */ 1061, 1159, 1055, 1072, 1072, 1092, 1076, 1092, 1076, 1094, - /* 240 */ 1094, 1153, 1094, 1098, 1094, 1181, 1117, 1159, 1117, 1159, - /* 250 */ 1153, 1094, 1094, 1094, 1181, 1202, 1072, 1202, 1072, 1202, - /* 260 */ 1072, 1072, 1183, 1097, 1202, 1072, 1164, 1164, 1210, 1054, - /* 270 */ 1072, 1224, 1224, 1224, 1224, 1054, 1164, 1210, 1072, 1212, - /* 280 */ 1212, 1072, 1072, 1109, -62, -62, -62, -62, -62, -62, - /* 290 */ 525, 684, 727, 168, 894, 556, 555, 938, 944, 949, - /* 300 */ 912, 1058, 1073, 1087, 1091, 1101, 1104, 1107, 1030, 1108, - /* 310 */ 1077, 1252, 1236, 1149, 1150, 1152, 1154, 1171, 1158, 1248, - /* 320 */ 1250, 1251, 1249, 1261, 1254, 1255, 1256, 1259, 1260, 1263, - /* 330 */ 1157, 1264, 1165, 1263, 1162, 1262, 1267, 1176, 1269, 1270, - /* 340 */ 1265, 1239, 1272, 1257, 1274, 1275, 1277, 1279, 1258, 1280, - /* 350 */ 1198, 1197, 1287, 1288, 1283, 1208, 1271, 1266, 1268, 1286, - /* 360 */ 1273, 1177, 1211, 1292, 1307, 1313, 1213, 1253, 1276, 1194, - /* 370 */ 1300, 1207, 1308, 1209, 1306, 1214, 1223, 1204, 1309, 1206, - /* 380 */ 1310, 1317, 1278, 1199, 1196, 1314, 1333, 1334, -}; -#define YY_REDUCE_USE_DFLT (-165) -#define YY_REDUCE_MAX 289 -static const short yy_reduce_ofst[] = { - /* 0 */ -138, 277, 546, 137, 401, -21, 44, 36, 38, 242, - /* 10 */ -141, 191, 91, 269, 343, 345, -126, 589, 338, 150, - /* 20 */ 147, -13, 213, 412, 412, 412, 412, 412, 412, 412, - /* 30 */ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, - /* 40 */ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, - /* 50 */ 412, 412, 412, 412, 412, 211, 698, 714, 716, 722, - /* 60 */ 724, 728, 748, 753, 755, 757, 762, 769, 794, 805, - /* 70 */ 808, 846, 855, 858, 861, 875, 882, 893, 896, 899, - /* 80 */ 901, 903, 906, 920, 930, 932, 934, 936, 945, 947, - /* 90 */ 963, 965, 971, 975, 978, 412, 412, 412, 412, 20, - /* 100 */ 412, 412, 23, 34, 334, 475, 552, 593, 594, 585, - /* 110 */ 212, 412, 289, 412, 412, 412, 135, -164, -115, 164, - /* 120 */ 407, 407, 350, 141, 436, 163, 596, -90, 763, 218, - /* 130 */ 765, 438, 586, 592, 595, 715, 718, 408, 723, 380, - /* 140 */ 634, 677, 787, 798, 144, 529, 588, -14, 0, 17, - /* 150 */ 244, 155, 298, 155, 155, 418, 372, 477, 490, 494, - /* 160 */ 509, 526, 590, 465, 494, 730, 773, 743, 833, 792, - /* 170 */ 854, 860, 155, 792, 864, 885, 848, 859, 863, 891, - /* 180 */ 907, 155, 914, 917, 155, 927, 852, 886, 941, 961, - /* 190 */ 155, 984, 990, 991, 155, 992, 995, 996, 155, 155, - /* 200 */ 999, 1002, 1003, 1004, 1005, 1006, 962, 964, 925, 929, - /* 210 */ 933, 987, 988, 989, 985, 993, 997, 998, 969, 970, - /* 220 */ 1021, 1022, 1024, 1026, 1020, 1000, 982, 983, 1001, 1007, - /* 230 */ 1008, 1023, 966, 1034, 1035, 1009, 1010, 1012, 1013, 1025, - /* 240 */ 1027, 1015, 1028, 1029, 1032, 1031, 981, 1048, 1011, 1049, - /* 250 */ 1033, 1039, 1040, 1043, 1045, 1069, 1070, 1074, 1071, 1075, - /* 260 */ 1078, 1079, 1014, 1016, 1081, 1082, 1044, 1051, 1019, 1042, - /* 270 */ 1086, 1053, 1056, 1057, 1062, 1047, 1063, 1036, 1090, 1017, - /* 280 */ 1018, 1100, 1105, 1037, 1099, 1084, 1085, 1038, 1041, 1046, -}; -static const YYACTIONTYPE yy_default[] = { - /* 0 */ 592, 816, 897, 707, 897, 816, 897, 897, 843, 711, - /* 10 */ 872, 814, 897, 897, 897, 897, 789, 897, 843, 897, - /* 20 */ 623, 843, 843, 740, 897, 897, 897, 897, 897, 897, - /* 30 */ 897, 897, 741, 897, 818, 813, 809, 811, 810, 817, - /* 40 */ 742, 731, 738, 745, 723, 856, 747, 748, 754, 755, - /* 50 */ 873, 871, 777, 776, 795, 897, 897, 897, 897, 897, - /* 60 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 70 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 80 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 90 */ 897, 897, 897, 897, 897, 779, 800, 778, 788, 616, - /* 100 */ 780, 781, 676, 611, 897, 897, 897, 897, 897, 897, - /* 110 */ 897, 782, 897, 783, 796, 797, 897, 897, 897, 897, - /* 120 */ 897, 897, 592, 707, 897, 707, 897, 897, 897, 897, - /* 130 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 140 */ 897, 897, 897, 897, 701, 711, 890, 897, 897, 667, - /* 150 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 160 */ 599, 597, 897, 699, 897, 897, 625, 897, 897, 709, - /* 170 */ 897, 897, 714, 715, 897, 897, 897, 897, 897, 897, - /* 180 */ 897, 613, 897, 897, 688, 897, 849, 897, 897, 897, - /* 190 */ 863, 897, 897, 897, 861, 897, 897, 897, 690, 750, - /* 200 */ 830, 897, 876, 878, 897, 897, 699, 708, 897, 897, - /* 210 */ 812, 734, 734, 734, 646, 734, 734, 649, 744, 744, - /* 220 */ 596, 596, 596, 596, 666, 897, 744, 735, 737, 727, - /* 230 */ 739, 897, 897, 716, 716, 724, 726, 724, 726, 678, - /* 240 */ 678, 663, 678, 649, 678, 822, 827, 897, 827, 897, - /* 250 */ 663, 678, 678, 678, 822, 608, 716, 608, 716, 608, - /* 260 */ 716, 716, 853, 855, 608, 716, 680, 680, 756, 744, - /* 270 */ 716, 687, 687, 687, 687, 744, 680, 756, 716, 875, - /* 280 */ 875, 716, 716, 883, 633, 651, 651, 858, 890, 895, - /* 290 */ 897, 897, 897, 897, 763, 897, 897, 897, 897, 897, - /* 300 */ 897, 897, 897, 897, 897, 897, 897, 897, 836, 897, - /* 310 */ 897, 897, 897, 768, 764, 897, 765, 897, 693, 897, - /* 320 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 815, - /* 330 */ 897, 728, 897, 736, 897, 897, 897, 897, 897, 897, - /* 340 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 350 */ 897, 897, 897, 897, 897, 897, 897, 897, 851, 852, - /* 360 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 370 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 380 */ 897, 897, 882, 897, 897, 885, 593, 897, 587, 590, - /* 390 */ 589, 591, 595, 598, 620, 621, 622, 600, 601, 602, - /* 400 */ 603, 604, 605, 606, 612, 614, 632, 634, 618, 636, - /* 410 */ 697, 698, 760, 691, 692, 696, 771, 762, 766, 767, - /* 420 */ 769, 770, 784, 785, 787, 793, 799, 802, 786, 791, - /* 430 */ 792, 794, 798, 801, 694, 695, 805, 619, 626, 627, - /* 440 */ 630, 631, 839, 841, 840, 842, 629, 628, 772, 775, - /* 450 */ 807, 808, 864, 865, 866, 867, 868, 803, 717, 806, - /* 460 */ 790, 729, 732, 733, 730, 700, 710, 719, 720, 721, - /* 470 */ 722, 705, 706, 712, 725, 758, 759, 713, 702, 703, - /* 480 */ 704, 804, 761, 773, 774, 637, 638, 768, 639, 640, - /* 490 */ 641, 679, 682, 683, 684, 642, 661, 664, 665, 643, - /* 500 */ 650, 644, 645, 652, 653, 654, 657, 658, 659, 660, - /* 510 */ 655, 656, 823, 824, 828, 826, 825, 647, 648, 662, - /* 520 */ 635, 624, 617, 668, 671, 672, 673, 674, 675, 677, - /* 530 */ 669, 670, 615, 607, 609, 718, 845, 854, 850, 846, - /* 540 */ 847, 848, 610, 819, 820, 681, 752, 753, 844, 857, - /* 550 */ 859, 757, 860, 862, 887, 685, 686, 689, 829, 869, - /* 560 */ 743, 746, 749, 751, 831, 832, 833, 834, 837, 838, - /* 570 */ 835, 870, 874, 877, 879, 880, 881, 884, 886, 891, - /* 580 */ 892, 893, 896, 894, 594, 588, -}; -#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) - -/* The next table maps tokens into fallback tokens. If a construct -** like the following: -** -** %fallback ID X Y Z. -** -** appears in the grammer, then ID becomes a fallback token for X, Y, -** and Z. Whenever one of the tokens X, Y, or Z is input to the parser -** but it does not parse, the type of the token is changed to ID and -** the parse is retried before an error is thrown. -*/ -#ifdef YYFALLBACK -static const YYCODETYPE yyFallback[] = { - 0, /* $ => nothing */ - 0, /* SEMI => nothing */ - 23, /* EXPLAIN => ID */ - 23, /* QUERY => ID */ - 23, /* PLAN => ID */ - 23, /* BEGIN => ID */ - 0, /* TRANSACTION => nothing */ - 23, /* DEFERRED => ID */ - 23, /* IMMEDIATE => ID */ - 23, /* EXCLUSIVE => ID */ - 0, /* COMMIT => nothing */ - 23, /* END => ID */ - 0, /* ROLLBACK => nothing */ - 0, /* CREATE => nothing */ - 0, /* TABLE => nothing */ - 23, /* IF => ID */ - 0, /* NOT => nothing */ - 0, /* EXISTS => nothing */ - 23, /* TEMP => ID */ - 0, /* LP => nothing */ - 0, /* RP => nothing */ - 0, /* AS => nothing */ - 0, /* COMMA => nothing */ - 0, /* ID => nothing */ - 23, /* ABORT => ID */ - 23, /* AFTER => ID */ - 23, /* ANALYZE => ID */ - 23, /* ASC => ID */ - 23, /* ATTACH => ID */ - 23, /* BEFORE => ID */ - 23, /* CASCADE => ID */ - 23, /* CAST => ID */ - 23, /* CONFLICT => ID */ - 23, /* DATABASE => ID */ - 23, /* DESC => ID */ - 23, /* DETACH => ID */ - 23, /* EACH => ID */ - 23, /* FAIL => ID */ - 23, /* FOR => ID */ - 23, /* IGNORE => ID */ - 23, /* INITIALLY => ID */ - 23, /* INSTEAD => ID */ - 23, /* LIKE_KW => ID */ - 23, /* MATCH => ID */ - 23, /* KEY => ID */ - 23, /* OF => ID */ - 23, /* OFFSET => ID */ - 23, /* PRAGMA => ID */ - 23, /* RAISE => ID */ - 23, /* REPLACE => ID */ - 23, /* RESTRICT => ID */ - 23, /* ROW => ID */ - 23, /* TRIGGER => ID */ - 23, /* VACUUM => ID */ - 23, /* VIEW => ID */ - 23, /* VIRTUAL => ID */ - 23, /* REINDEX => ID */ - 23, /* RENAME => ID */ - 23, /* CTIME_KW => ID */ - 0, /* ANY => nothing */ - 0, /* OR => nothing */ - 0, /* AND => nothing */ - 0, /* IS => nothing */ - 0, /* BETWEEN => nothing */ - 0, /* IN => nothing */ - 0, /* ISNULL => nothing */ - 0, /* NOTNULL => nothing */ - 0, /* NE => nothing */ - 0, /* EQ => nothing */ - 0, /* GT => nothing */ - 0, /* LE => nothing */ - 0, /* LT => nothing */ - 0, /* GE => nothing */ - 0, /* ESCAPE => nothing */ - 0, /* BITAND => nothing */ - 0, /* BITOR => nothing */ - 0, /* LSHIFT => nothing */ - 0, /* RSHIFT => nothing */ - 0, /* PLUS => nothing */ - 0, /* MINUS => nothing */ - 0, /* STAR => nothing */ - 0, /* SLASH => nothing */ - 0, /* REM => nothing */ - 0, /* CONCAT => nothing */ - 0, /* COLLATE => nothing */ - 0, /* UMINUS => nothing */ - 0, /* UPLUS => nothing */ - 0, /* BITNOT => nothing */ - 0, /* STRING => nothing */ - 0, /* JOIN_KW => nothing */ - 0, /* CONSTRAINT => nothing */ - 0, /* DEFAULT => nothing */ - 0, /* NULL => nothing */ - 0, /* PRIMARY => nothing */ - 0, /* UNIQUE => nothing */ - 0, /* CHECK => nothing */ - 0, /* REFERENCES => nothing */ - 0, /* AUTOINCR => nothing */ - 0, /* ON => nothing */ - 0, /* DELETE => nothing */ - 0, /* UPDATE => nothing */ - 0, /* INSERT => nothing */ - 0, /* SET => nothing */ - 0, /* DEFERRABLE => nothing */ - 0, /* FOREIGN => nothing */ - 0, /* DROP => nothing */ - 0, /* UNION => nothing */ - 0, /* ALL => nothing */ - 0, /* EXCEPT => nothing */ - 0, /* INTERSECT => nothing */ - 0, /* SELECT => nothing */ - 0, /* DISTINCT => nothing */ - 0, /* DOT => nothing */ - 0, /* FROM => nothing */ - 0, /* JOIN => nothing */ - 0, /* USING => nothing */ - 0, /* ORDER => nothing */ - 0, /* BY => nothing */ - 0, /* GROUP => nothing */ - 0, /* HAVING => nothing */ - 0, /* LIMIT => nothing */ - 0, /* WHERE => nothing */ - 0, /* INTO => nothing */ - 0, /* VALUES => nothing */ - 0, /* INTEGER => nothing */ - 0, /* FLOAT => nothing */ - 0, /* BLOB => nothing */ - 0, /* REGISTER => nothing */ - 0, /* VARIABLE => nothing */ - 0, /* CASE => nothing */ - 0, /* WHEN => nothing */ - 0, /* THEN => nothing */ - 0, /* ELSE => nothing */ - 0, /* INDEX => nothing */ - 0, /* ALTER => nothing */ - 0, /* TO => nothing */ - 0, /* ADD => nothing */ - 0, /* COLUMNKW => nothing */ -}; -#endif /* YYFALLBACK */ - -/* The following structure represents a single element of the -** parser's stack. Information stored includes: -** -** + The state number for the parser at this level of the stack. -** -** + The value of the token stored at this level of the stack. -** (In other words, the "major" token.) -** -** + The semantic value stored at this level of the stack. This is -** the information used by the action routines in the grammar. -** It is sometimes called the "minor" token. -*/ -struct yyStackEntry { - int stateno; /* The state-number */ - int major; /* The major token value. This is the code - ** number for the token at this stack level */ - YYMINORTYPE minor; /* The user-supplied minor token value. This - ** is the value of the token */ -}; -typedef struct yyStackEntry yyStackEntry; - -/* The state of the parser is completely contained in an instance of -** the following structure */ -struct yyParser { - int yyidx; /* Index of top element in stack */ - int yyerrcnt; /* Shifts left before out of the error */ - sqlite3ParserARG_SDECL /* A place to hold %extra_argument */ -#if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ -#else - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ -#endif -}; -typedef struct yyParser yyParser; - -#ifndef NDEBUG -#include -static FILE *yyTraceFILE = 0; -static char *yyTracePrompt = 0; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* -** Turn parser tracing on by giving a stream to which to write the trace -** and a prompt to preface each trace message. Tracing is turned off -** by making either argument NULL -** -** Inputs: -**
    -**
  • A FILE* to which trace output should be written. -** If NULL, then tracing is turned off. -**
  • A prefix string written at the beginning of every -** line of trace output. If NULL, then tracing is -** turned off. -**
-** -** Outputs: -** None. -*/ -void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){ - yyTraceFILE = TraceFILE; - yyTracePrompt = zTracePrompt; - if( yyTraceFILE==0 ) yyTracePrompt = 0; - else if( yyTracePrompt==0 ) yyTraceFILE = 0; -} -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing shifts, the names of all terminals and nonterminals -** are required. The following table supplies these names */ -static const char *const yyTokenName[] = { - "$", "SEMI", "EXPLAIN", "QUERY", - "PLAN", "BEGIN", "TRANSACTION", "DEFERRED", - "IMMEDIATE", "EXCLUSIVE", "COMMIT", "END", - "ROLLBACK", "CREATE", "TABLE", "IF", - "NOT", "EXISTS", "TEMP", "LP", - "RP", "AS", "COMMA", "ID", - "ABORT", "AFTER", "ANALYZE", "ASC", - "ATTACH", "BEFORE", "CASCADE", "CAST", - "CONFLICT", "DATABASE", "DESC", "DETACH", - "EACH", "FAIL", "FOR", "IGNORE", - "INITIALLY", "INSTEAD", "LIKE_KW", "MATCH", - "KEY", "OF", "OFFSET", "PRAGMA", - "RAISE", "REPLACE", "RESTRICT", "ROW", - "TRIGGER", "VACUUM", "VIEW", "VIRTUAL", - "REINDEX", "RENAME", "CTIME_KW", "ANY", - "OR", "AND", "IS", "BETWEEN", - "IN", "ISNULL", "NOTNULL", "NE", - "EQ", "GT", "LE", "LT", - "GE", "ESCAPE", "BITAND", "BITOR", - "LSHIFT", "RSHIFT", "PLUS", "MINUS", - "STAR", "SLASH", "REM", "CONCAT", - "COLLATE", "UMINUS", "UPLUS", "BITNOT", - "STRING", "JOIN_KW", "CONSTRAINT", "DEFAULT", - "NULL", "PRIMARY", "UNIQUE", "CHECK", - "REFERENCES", "AUTOINCR", "ON", "DELETE", - "UPDATE", "INSERT", "SET", "DEFERRABLE", - "FOREIGN", "DROP", "UNION", "ALL", - "EXCEPT", "INTERSECT", "SELECT", "DISTINCT", - "DOT", "FROM", "JOIN", "USING", - "ORDER", "BY", "GROUP", "HAVING", - "LIMIT", "WHERE", "INTO", "VALUES", - "INTEGER", "FLOAT", "BLOB", "REGISTER", - "VARIABLE", "CASE", "WHEN", "THEN", - "ELSE", "INDEX", "ALTER", "TO", - "ADD", "COLUMNKW", "error", "input", - "cmdlist", "ecmd", "cmdx", "cmd", - "explain", "transtype", "trans_opt", "nm", - "create_table", "create_table_args", "temp", "ifnotexists", - "dbnm", "columnlist", "conslist_opt", "select", - "column", "columnid", "type", "carglist", - "id", "ids", "typetoken", "typename", - "signed", "plus_num", "minus_num", "carg", - "ccons", "term", "expr", "onconf", - "sortorder", "autoinc", "idxlist_opt", "refargs", - "defer_subclause", "refarg", "refact", "init_deferred_pred_opt", - "conslist", "tcons", "idxlist", "defer_subclause_opt", - "orconf", "resolvetype", "raisetype", "ifexists", - "fullname", "oneselect", "multiselect_op", "distinct", - "selcollist", "from", "where_opt", "groupby_opt", - "having_opt", "orderby_opt", "limit_opt", "sclp", - "as", "seltablist", "stl_prefix", "joinop", - "on_opt", "using_opt", "seltablist_paren", "joinop2", - "inscollist", "sortlist", "sortitem", "nexprlist", - "setlist", "insert_cmd", "inscollist_opt", "itemlist", - "exprlist", "likeop", "escape", "between_op", - "in_op", "case_operand", "case_exprlist", "case_else", - "uniqueflag", "idxitem", "collate", "nmnum", - "plus_opt", "number", "trigger_decl", "trigger_cmd_list", - "trigger_time", "trigger_event", "foreach_clause", "when_clause", - "trigger_cmd", "database_kw_opt", "key_opt", "add_column_fullname", - "kwcolumn_opt", "create_vtab", "vtabarglist", "vtabarg", - "vtabargtoken", "lp", "anylist", -}; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing reduce actions, the names of all rules are required. -*/ -static const char *const yyRuleName[] = { - /* 0 */ "input ::= cmdlist", - /* 1 */ "cmdlist ::= cmdlist ecmd", - /* 2 */ "cmdlist ::= ecmd", - /* 3 */ "cmdx ::= cmd", - /* 4 */ "ecmd ::= SEMI", - /* 5 */ "ecmd ::= explain cmdx SEMI", - /* 6 */ "explain ::=", - /* 7 */ "explain ::= EXPLAIN", - /* 8 */ "explain ::= EXPLAIN QUERY PLAN", - /* 9 */ "cmd ::= BEGIN transtype trans_opt", - /* 10 */ "trans_opt ::=", - /* 11 */ "trans_opt ::= TRANSACTION", - /* 12 */ "trans_opt ::= TRANSACTION nm", - /* 13 */ "transtype ::=", - /* 14 */ "transtype ::= DEFERRED", - /* 15 */ "transtype ::= IMMEDIATE", - /* 16 */ "transtype ::= EXCLUSIVE", - /* 17 */ "cmd ::= COMMIT trans_opt", - /* 18 */ "cmd ::= END trans_opt", - /* 19 */ "cmd ::= ROLLBACK trans_opt", - /* 20 */ "cmd ::= create_table create_table_args", - /* 21 */ "create_table ::= CREATE temp TABLE ifnotexists nm dbnm", - /* 22 */ "ifnotexists ::=", - /* 23 */ "ifnotexists ::= IF NOT EXISTS", - /* 24 */ "temp ::= TEMP", - /* 25 */ "temp ::=", - /* 26 */ "create_table_args ::= LP columnlist conslist_opt RP", - /* 27 */ "create_table_args ::= AS select", - /* 28 */ "columnlist ::= columnlist COMMA column", - /* 29 */ "columnlist ::= column", - /* 30 */ "column ::= columnid type carglist", - /* 31 */ "columnid ::= nm", - /* 32 */ "id ::= ID", - /* 33 */ "ids ::= ID|STRING", - /* 34 */ "nm ::= ID", - /* 35 */ "nm ::= STRING", - /* 36 */ "nm ::= JOIN_KW", - /* 37 */ "type ::=", - /* 38 */ "type ::= typetoken", - /* 39 */ "typetoken ::= typename", - /* 40 */ "typetoken ::= typename LP signed RP", - /* 41 */ "typetoken ::= typename LP signed COMMA signed RP", - /* 42 */ "typename ::= ids", - /* 43 */ "typename ::= typename ids", - /* 44 */ "signed ::= plus_num", - /* 45 */ "signed ::= minus_num", - /* 46 */ "carglist ::= carglist carg", - /* 47 */ "carglist ::=", - /* 48 */ "carg ::= CONSTRAINT nm ccons", - /* 49 */ "carg ::= ccons", - /* 50 */ "ccons ::= DEFAULT term", - /* 51 */ "ccons ::= DEFAULT LP expr RP", - /* 52 */ "ccons ::= DEFAULT PLUS term", - /* 53 */ "ccons ::= DEFAULT MINUS term", - /* 54 */ "ccons ::= DEFAULT id", - /* 55 */ "ccons ::= NULL onconf", - /* 56 */ "ccons ::= NOT NULL onconf", - /* 57 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", - /* 58 */ "ccons ::= UNIQUE onconf", - /* 59 */ "ccons ::= CHECK LP expr RP", - /* 60 */ "ccons ::= REFERENCES nm idxlist_opt refargs", - /* 61 */ "ccons ::= defer_subclause", - /* 62 */ "ccons ::= COLLATE id", - /* 63 */ "autoinc ::=", - /* 64 */ "autoinc ::= AUTOINCR", - /* 65 */ "refargs ::=", - /* 66 */ "refargs ::= refargs refarg", - /* 67 */ "refarg ::= MATCH nm", - /* 68 */ "refarg ::= ON DELETE refact", - /* 69 */ "refarg ::= ON UPDATE refact", - /* 70 */ "refarg ::= ON INSERT refact", - /* 71 */ "refact ::= SET NULL", - /* 72 */ "refact ::= SET DEFAULT", - /* 73 */ "refact ::= CASCADE", - /* 74 */ "refact ::= RESTRICT", - /* 75 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", - /* 76 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", - /* 77 */ "init_deferred_pred_opt ::=", - /* 78 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", - /* 79 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", - /* 80 */ "conslist_opt ::=", - /* 81 */ "conslist_opt ::= COMMA conslist", - /* 82 */ "conslist ::= conslist COMMA tcons", - /* 83 */ "conslist ::= conslist tcons", - /* 84 */ "conslist ::= tcons", - /* 85 */ "tcons ::= CONSTRAINT nm", - /* 86 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf", - /* 87 */ "tcons ::= UNIQUE LP idxlist RP onconf", - /* 88 */ "tcons ::= CHECK LP expr RP onconf", - /* 89 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt", - /* 90 */ "defer_subclause_opt ::=", - /* 91 */ "defer_subclause_opt ::= defer_subclause", - /* 92 */ "onconf ::=", - /* 93 */ "onconf ::= ON CONFLICT resolvetype", - /* 94 */ "orconf ::=", - /* 95 */ "orconf ::= OR resolvetype", - /* 96 */ "resolvetype ::= raisetype", - /* 97 */ "resolvetype ::= IGNORE", - /* 98 */ "resolvetype ::= REPLACE", - /* 99 */ "cmd ::= DROP TABLE ifexists fullname", - /* 100 */ "ifexists ::= IF EXISTS", - /* 101 */ "ifexists ::=", - /* 102 */ "cmd ::= CREATE temp VIEW ifnotexists nm dbnm AS select", - /* 103 */ "cmd ::= DROP VIEW ifexists fullname", - /* 104 */ "cmd ::= select", - /* 105 */ "select ::= oneselect", - /* 106 */ "select ::= select multiselect_op oneselect", - /* 107 */ "multiselect_op ::= UNION", - /* 108 */ "multiselect_op ::= UNION ALL", - /* 109 */ "multiselect_op ::= EXCEPT|INTERSECT", - /* 110 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", - /* 111 */ "distinct ::= DISTINCT", - /* 112 */ "distinct ::= ALL", - /* 113 */ "distinct ::=", - /* 114 */ "sclp ::= selcollist COMMA", - /* 115 */ "sclp ::=", - /* 116 */ "selcollist ::= sclp expr as", - /* 117 */ "selcollist ::= sclp STAR", - /* 118 */ "selcollist ::= sclp nm DOT STAR", - /* 119 */ "as ::= AS nm", - /* 120 */ "as ::= ids", - /* 121 */ "as ::=", - /* 122 */ "from ::=", - /* 123 */ "from ::= FROM seltablist", - /* 124 */ "stl_prefix ::= seltablist joinop", - /* 125 */ "stl_prefix ::=", - /* 126 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt", - /* 127 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt", - /* 128 */ "seltablist_paren ::= select", - /* 129 */ "seltablist_paren ::= seltablist", - /* 130 */ "dbnm ::=", - /* 131 */ "dbnm ::= DOT nm", - /* 132 */ "fullname ::= nm dbnm", - /* 133 */ "joinop ::= COMMA|JOIN", - /* 134 */ "joinop ::= JOIN_KW JOIN", - /* 135 */ "joinop ::= JOIN_KW nm JOIN", - /* 136 */ "joinop ::= JOIN_KW nm nm JOIN", - /* 137 */ "on_opt ::= ON expr", - /* 138 */ "on_opt ::=", - /* 139 */ "using_opt ::= USING LP inscollist RP", - /* 140 */ "using_opt ::=", - /* 141 */ "orderby_opt ::=", - /* 142 */ "orderby_opt ::= ORDER BY sortlist", - /* 143 */ "sortlist ::= sortlist COMMA sortitem sortorder", - /* 144 */ "sortlist ::= sortitem sortorder", - /* 145 */ "sortitem ::= expr", - /* 146 */ "sortorder ::= ASC", - /* 147 */ "sortorder ::= DESC", - /* 148 */ "sortorder ::=", - /* 149 */ "groupby_opt ::=", - /* 150 */ "groupby_opt ::= GROUP BY nexprlist", - /* 151 */ "having_opt ::=", - /* 152 */ "having_opt ::= HAVING expr", - /* 153 */ "limit_opt ::=", - /* 154 */ "limit_opt ::= LIMIT expr", - /* 155 */ "limit_opt ::= LIMIT expr OFFSET expr", - /* 156 */ "limit_opt ::= LIMIT expr COMMA expr", - /* 157 */ "cmd ::= DELETE FROM fullname where_opt", - /* 158 */ "where_opt ::=", - /* 159 */ "where_opt ::= WHERE expr", - /* 160 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt", - /* 161 */ "setlist ::= setlist COMMA nm EQ expr", - /* 162 */ "setlist ::= nm EQ expr", - /* 163 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP", - /* 164 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", - /* 165 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES", - /* 166 */ "insert_cmd ::= INSERT orconf", - /* 167 */ "insert_cmd ::= REPLACE", - /* 168 */ "itemlist ::= itemlist COMMA expr", - /* 169 */ "itemlist ::= expr", - /* 170 */ "inscollist_opt ::=", - /* 171 */ "inscollist_opt ::= LP inscollist RP", - /* 172 */ "inscollist ::= inscollist COMMA nm", - /* 173 */ "inscollist ::= nm", - /* 174 */ "expr ::= term", - /* 175 */ "expr ::= LP expr RP", - /* 176 */ "term ::= NULL", - /* 177 */ "expr ::= ID", - /* 178 */ "expr ::= JOIN_KW", - /* 179 */ "expr ::= nm DOT nm", - /* 180 */ "expr ::= nm DOT nm DOT nm", - /* 181 */ "term ::= INTEGER|FLOAT|BLOB", - /* 182 */ "term ::= STRING", - /* 183 */ "expr ::= REGISTER", - /* 184 */ "expr ::= VARIABLE", - /* 185 */ "expr ::= expr COLLATE id", - /* 186 */ "expr ::= CAST LP expr AS typetoken RP", - /* 187 */ "expr ::= ID LP distinct exprlist RP", - /* 188 */ "expr ::= ID LP STAR RP", - /* 189 */ "term ::= CTIME_KW", - /* 190 */ "expr ::= expr AND expr", - /* 191 */ "expr ::= expr OR expr", - /* 192 */ "expr ::= expr LT|GT|GE|LE expr", - /* 193 */ "expr ::= expr EQ|NE expr", - /* 194 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 195 */ "expr ::= expr PLUS|MINUS expr", - /* 196 */ "expr ::= expr STAR|SLASH|REM expr", - /* 197 */ "expr ::= expr CONCAT expr", - /* 198 */ "likeop ::= LIKE_KW", - /* 199 */ "likeop ::= NOT LIKE_KW", - /* 200 */ "likeop ::= MATCH", - /* 201 */ "likeop ::= NOT MATCH", - /* 202 */ "escape ::= ESCAPE expr", - /* 203 */ "escape ::=", - /* 204 */ "expr ::= expr likeop expr escape", - /* 205 */ "expr ::= expr ISNULL|NOTNULL", - /* 206 */ "expr ::= expr IS NULL", - /* 207 */ "expr ::= expr NOT NULL", - /* 208 */ "expr ::= expr IS NOT NULL", - /* 209 */ "expr ::= NOT|BITNOT expr", - /* 210 */ "expr ::= MINUS expr", - /* 211 */ "expr ::= PLUS expr", - /* 212 */ "between_op ::= BETWEEN", - /* 213 */ "between_op ::= NOT BETWEEN", - /* 214 */ "expr ::= expr between_op expr AND expr", - /* 215 */ "in_op ::= IN", - /* 216 */ "in_op ::= NOT IN", - /* 217 */ "expr ::= expr in_op LP exprlist RP", - /* 218 */ "expr ::= LP select RP", - /* 219 */ "expr ::= expr in_op LP select RP", - /* 220 */ "expr ::= expr in_op nm dbnm", - /* 221 */ "expr ::= EXISTS LP select RP", - /* 222 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 223 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 224 */ "case_exprlist ::= WHEN expr THEN expr", - /* 225 */ "case_else ::= ELSE expr", - /* 226 */ "case_else ::=", - /* 227 */ "case_operand ::= expr", - /* 228 */ "case_operand ::=", - /* 229 */ "exprlist ::= nexprlist", - /* 230 */ "exprlist ::=", - /* 231 */ "nexprlist ::= nexprlist COMMA expr", - /* 232 */ "nexprlist ::= expr", - /* 233 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP", - /* 234 */ "uniqueflag ::= UNIQUE", - /* 235 */ "uniqueflag ::=", - /* 236 */ "idxlist_opt ::=", - /* 237 */ "idxlist_opt ::= LP idxlist RP", - /* 238 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", - /* 239 */ "idxlist ::= idxitem collate sortorder", - /* 240 */ "idxitem ::= nm", - /* 241 */ "collate ::=", - /* 242 */ "collate ::= COLLATE id", - /* 243 */ "cmd ::= DROP INDEX ifexists fullname", - /* 244 */ "cmd ::= VACUUM", - /* 245 */ "cmd ::= VACUUM nm", - /* 246 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 247 */ "cmd ::= PRAGMA nm dbnm EQ ON", - /* 248 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 249 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 250 */ "cmd ::= PRAGMA nm dbnm", - /* 251 */ "nmnum ::= plus_num", - /* 252 */ "nmnum ::= nm", - /* 253 */ "plus_num ::= plus_opt number", - /* 254 */ "minus_num ::= MINUS number", - /* 255 */ "number ::= INTEGER|FLOAT", - /* 256 */ "plus_opt ::= PLUS", - /* 257 */ "plus_opt ::=", - /* 258 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", - /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 260 */ "trigger_time ::= BEFORE", - /* 261 */ "trigger_time ::= AFTER", - /* 262 */ "trigger_time ::= INSTEAD OF", - /* 263 */ "trigger_time ::=", - /* 264 */ "trigger_event ::= DELETE|INSERT", - /* 265 */ "trigger_event ::= UPDATE", - /* 266 */ "trigger_event ::= UPDATE OF inscollist", - /* 267 */ "foreach_clause ::=", - /* 268 */ "foreach_clause ::= FOR EACH ROW", - /* 269 */ "when_clause ::=", - /* 270 */ "when_clause ::= WHEN expr", - /* 271 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 272 */ "trigger_cmd_list ::=", - /* 273 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", - /* 274 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", - /* 275 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", - /* 276 */ "trigger_cmd ::= DELETE FROM nm where_opt", - /* 277 */ "trigger_cmd ::= select", - /* 278 */ "expr ::= RAISE LP IGNORE RP", - /* 279 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 280 */ "raisetype ::= ROLLBACK", - /* 281 */ "raisetype ::= ABORT", - /* 282 */ "raisetype ::= FAIL", - /* 283 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 284 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 285 */ "cmd ::= DETACH database_kw_opt expr", - /* 286 */ "key_opt ::=", - /* 287 */ "key_opt ::= KEY expr", - /* 288 */ "database_kw_opt ::= DATABASE", - /* 289 */ "database_kw_opt ::=", - /* 290 */ "cmd ::= REINDEX", - /* 291 */ "cmd ::= REINDEX nm dbnm", - /* 292 */ "cmd ::= ANALYZE", - /* 293 */ "cmd ::= ANALYZE nm dbnm", - /* 294 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 295 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", - /* 296 */ "add_column_fullname ::= fullname", - /* 297 */ "kwcolumn_opt ::=", - /* 298 */ "kwcolumn_opt ::= COLUMNKW", - /* 299 */ "cmd ::= create_vtab", - /* 300 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 301 */ "create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm", - /* 302 */ "vtabarglist ::= vtabarg", - /* 303 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 304 */ "vtabarg ::=", - /* 305 */ "vtabarg ::= vtabarg vtabargtoken", - /* 306 */ "vtabargtoken ::= ANY", - /* 307 */ "vtabargtoken ::= lp anylist RP", - /* 308 */ "lp ::= LP", - /* 309 */ "anylist ::=", - /* 310 */ "anylist ::= anylist ANY", -}; -#endif /* NDEBUG */ - - -#if YYSTACKDEPTH<=0 -/* -** Try to increase the size of the parser stack. -*/ -static void yyGrowStack(yyParser *p){ - int newSize; - yyStackEntry *pNew; - - newSize = p->yystksz*2 + 100; - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); - if( pNew ){ - p->yystack = pNew; - p->yystksz = newSize; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", - yyTracePrompt, p->yystksz); - } -#endif - } -} -#endif - -/* -** This function allocates a new parser. -** The only argument is a pointer to a function which works like -** malloc. -** -** Inputs: -** A pointer to the function used to allocate memory. -** -** Outputs: -** A pointer to a parser. This pointer is used in subsequent calls -** to sqlite3Parser and sqlite3ParserFree. -*/ -void *sqlite3ParserAlloc(void *(*mallocProc)(size_t)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); - if( pParser ){ - pParser->yyidx = -1; -#if YYSTACKDEPTH<=0 - yyGrowStack(pParser); -#endif - } - return pParser; -} - -/* The following function deletes the value associated with a -** symbol. The symbol can be either a terminal or nonterminal. -** "yymajor" is the symbol code, and "yypminor" is a pointer to -** the value. -*/ -static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){ - switch( yymajor ){ - /* Here is inserted the actions which take place when a - ** terminal or non-terminal is destroyed. This can happen - ** when the symbol is popped from the stack during a - ** reduce or during error processing or when a parser is - ** being destroyed before it is finished parsing. - ** - ** Note: during a reduce, the only symbols destroyed are those - ** which appear on the RHS of the rule, but which are not used - ** inside the C code. - */ - case 155: - case 189: - case 206: -#line 373 "parse.y" -{sqlite3SelectDelete((yypminor->yy219));} -#line 1273 "parse.c" - break; - case 169: - case 170: - case 194: - case 196: - case 204: - case 210: - case 218: - case 221: - case 223: - case 235: -#line 633 "parse.y" -{sqlite3ExprDelete((yypminor->yy172));} -#line 1287 "parse.c" - break; - case 174: - case 182: - case 192: - case 195: - case 197: - case 199: - case 209: - case 211: - case 212: - case 215: - case 216: - case 222: -#line 887 "parse.y" -{sqlite3ExprListDelete((yypminor->yy174));} -#line 1303 "parse.c" - break; - case 188: - case 193: - case 201: - case 202: -#line 490 "parse.y" -{sqlite3SrcListDelete((yypminor->yy373));} -#line 1311 "parse.c" - break; - case 205: - case 208: - case 214: -#line 507 "parse.y" -{sqlite3IdListDelete((yypminor->yy432));} -#line 1318 "parse.c" - break; - case 231: - case 236: -#line 990 "parse.y" -{sqlite3DeleteTriggerStep((yypminor->yy243));} -#line 1324 "parse.c" - break; - case 233: -#line 976 "parse.y" -{sqlite3IdListDelete((yypminor->yy370).b);} -#line 1329 "parse.c" - break; - case 238: -#line 1063 "parse.y" -{sqlite3ExprDelete((yypminor->yy386));} -#line 1334 "parse.c" - break; - default: break; /* If no destructor action specified: do nothing */ - } -} - -/* -** Pop the parser's stack once. -** -** If there is a destructor routine associated with the token which -** is popped from the stack, then call it. -** -** Return the major token number for the symbol popped. -*/ -static int yy_pop_parser_stack(yyParser *pParser){ - YYCODETYPE yymajor; - yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; - - if( pParser->yyidx<0 ) return 0; -#ifndef NDEBUG - if( yyTraceFILE && pParser->yyidx>=0 ){ - fprintf(yyTraceFILE,"%sPopping %s\n", - yyTracePrompt, - yyTokenName[yytos->major]); - } -#endif - yymajor = yytos->major; - yy_destructor( yymajor, &yytos->minor); - pParser->yyidx--; - return yymajor; -} - -/* -** Deallocate and destroy a parser. Destructors are all called for -** all stack elements before shutting the parser down. -** -** Inputs: -**
    -**
  • A pointer to the parser. This should be a pointer -** obtained from sqlite3ParserAlloc. -**
  • A pointer to a function used to reclaim memory obtained -** from malloc. -**
-*/ -void sqlite3ParserFree( - void *p, /* The parser to be deleted */ - void (*freeProc)(void*) /* Function used to reclaim memory */ -){ - yyParser *pParser = (yyParser*)p; - if( pParser==0 ) return; - while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - free(pParser->yystack); -#endif - (*freeProc)((void*)pParser); -} - -/* -** Find the appropriate action for a parser given the terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_shift_action( - yyParser *pParser, /* The parser */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; - - if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ - return yy_default[stateno]; - } - if( iLookAhead==YYNOCODE ){ - return YY_NO_ACTION; - } - i += iLookAhead; - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - if( iLookAhead>0 ){ -#ifdef YYFALLBACK - int iFallback; /* Fallback token */ - if( iLookAhead %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - return yy_find_shift_action(pParser, iFallback); - } -#endif -#ifdef YYWILDCARD - { - int j = i - iLookAhead + YYWILDCARD; - if( j>=0 && j %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); - } -#endif /* NDEBUG */ - return yy_action[j]; - } - } -#endif /* YYWILDCARD */ - } - return yy_default[stateno]; - }else{ - return yy_action[i]; - } -} - -/* -** Find the appropriate action for a parser given the non-terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_reduce_action( - int stateno, /* Current state number */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - /* int stateno = pParser->yystack[pParser->yyidx].stateno; */ - - if( stateno>YY_REDUCE_MAX || - (i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){ - return yy_default[stateno]; - } - if( iLookAhead==YYNOCODE ){ - return YY_NO_ACTION; - } - i += iLookAhead; - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - return yy_default[stateno]; - }else{ - return yy_action[i]; - } -} - -/* -** The following routine is called if the stack overflows. -*/ -static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){ - sqlite3ParserARG_FETCH; - yypParser->yyidx--; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will execute if the parser - ** stack every overflows */ -#line 44 "parse.y" - - sqlite3ErrorMsg(pParse, "parser stack overflow"); - pParse->parseError = 1; -#line 1498 "parse.c" - sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */ -} - -/* -** Perform a shift action. -*/ -static void yy_shift( - yyParser *yypParser, /* The parser to be shifted */ - int yyNewState, /* The new state to shift in */ - int yyMajor, /* The major token to shift in */ - YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */ -){ - yyStackEntry *yytos; - yypParser->yyidx++; -#if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH ){ - yyStackOverflow(yypParser, yypMinor); - return; - } -#else - if( yypParser->yyidx>=yypParser->yystksz ){ - yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz ){ - yyStackOverflow(yypParser, yypMinor); - return; - } - } -#endif - yytos = &yypParser->yystack[yypParser->yyidx]; - yytos->stateno = yyNewState; - yytos->major = yyMajor; - yytos->minor = *yypMinor; -#ifndef NDEBUG - if( yyTraceFILE && yypParser->yyidx>0 ){ - int i; - fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); - fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); - for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); - fprintf(yyTraceFILE,"\n"); - } -#endif -} - -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - unsigned char nrhs; /* Number of right-hand side symbols in the rule */ -} yyRuleInfo[] = { - { 139, 1 }, - { 140, 2 }, - { 140, 1 }, - { 142, 1 }, - { 141, 1 }, - { 141, 3 }, - { 144, 0 }, - { 144, 1 }, - { 144, 3 }, - { 143, 3 }, - { 146, 0 }, - { 146, 1 }, - { 146, 2 }, - { 145, 0 }, - { 145, 1 }, - { 145, 1 }, - { 145, 1 }, - { 143, 2 }, - { 143, 2 }, - { 143, 2 }, - { 143, 2 }, - { 148, 6 }, - { 151, 0 }, - { 151, 3 }, - { 150, 1 }, - { 150, 0 }, - { 149, 4 }, - { 149, 2 }, - { 153, 3 }, - { 153, 1 }, - { 156, 3 }, - { 157, 1 }, - { 160, 1 }, - { 161, 1 }, - { 147, 1 }, - { 147, 1 }, - { 147, 1 }, - { 158, 0 }, - { 158, 1 }, - { 162, 1 }, - { 162, 4 }, - { 162, 6 }, - { 163, 1 }, - { 163, 2 }, - { 164, 1 }, - { 164, 1 }, - { 159, 2 }, - { 159, 0 }, - { 167, 3 }, - { 167, 1 }, - { 168, 2 }, - { 168, 4 }, - { 168, 3 }, - { 168, 3 }, - { 168, 2 }, - { 168, 2 }, - { 168, 3 }, - { 168, 5 }, - { 168, 2 }, - { 168, 4 }, - { 168, 4 }, - { 168, 1 }, - { 168, 2 }, - { 173, 0 }, - { 173, 1 }, - { 175, 0 }, - { 175, 2 }, - { 177, 2 }, - { 177, 3 }, - { 177, 3 }, - { 177, 3 }, - { 178, 2 }, - { 178, 2 }, - { 178, 1 }, - { 178, 1 }, - { 176, 3 }, - { 176, 2 }, - { 179, 0 }, - { 179, 2 }, - { 179, 2 }, - { 154, 0 }, - { 154, 2 }, - { 180, 3 }, - { 180, 2 }, - { 180, 1 }, - { 181, 2 }, - { 181, 7 }, - { 181, 5 }, - { 181, 5 }, - { 181, 10 }, - { 183, 0 }, - { 183, 1 }, - { 171, 0 }, - { 171, 3 }, - { 184, 0 }, - { 184, 2 }, - { 185, 1 }, - { 185, 1 }, - { 185, 1 }, - { 143, 4 }, - { 187, 2 }, - { 187, 0 }, - { 143, 8 }, - { 143, 4 }, - { 143, 1 }, - { 155, 1 }, - { 155, 3 }, - { 190, 1 }, - { 190, 2 }, - { 190, 1 }, - { 189, 9 }, - { 191, 1 }, - { 191, 1 }, - { 191, 0 }, - { 199, 2 }, - { 199, 0 }, - { 192, 3 }, - { 192, 2 }, - { 192, 4 }, - { 200, 2 }, - { 200, 1 }, - { 200, 0 }, - { 193, 0 }, - { 193, 2 }, - { 202, 2 }, - { 202, 0 }, - { 201, 6 }, - { 201, 7 }, - { 206, 1 }, - { 206, 1 }, - { 152, 0 }, - { 152, 2 }, - { 188, 2 }, - { 203, 1 }, - { 203, 2 }, - { 203, 3 }, - { 203, 4 }, - { 204, 2 }, - { 204, 0 }, - { 205, 4 }, - { 205, 0 }, - { 197, 0 }, - { 197, 3 }, - { 209, 4 }, - { 209, 2 }, - { 210, 1 }, - { 172, 1 }, - { 172, 1 }, - { 172, 0 }, - { 195, 0 }, - { 195, 3 }, - { 196, 0 }, - { 196, 2 }, - { 198, 0 }, - { 198, 2 }, - { 198, 4 }, - { 198, 4 }, - { 143, 4 }, - { 194, 0 }, - { 194, 2 }, - { 143, 6 }, - { 212, 5 }, - { 212, 3 }, - { 143, 8 }, - { 143, 5 }, - { 143, 6 }, - { 213, 2 }, - { 213, 1 }, - { 215, 3 }, - { 215, 1 }, - { 214, 0 }, - { 214, 3 }, - { 208, 3 }, - { 208, 1 }, - { 170, 1 }, - { 170, 3 }, - { 169, 1 }, - { 170, 1 }, - { 170, 1 }, - { 170, 3 }, - { 170, 5 }, - { 169, 1 }, - { 169, 1 }, - { 170, 1 }, - { 170, 1 }, - { 170, 3 }, - { 170, 6 }, - { 170, 5 }, - { 170, 4 }, - { 169, 1 }, - { 170, 3 }, - { 170, 3 }, - { 170, 3 }, - { 170, 3 }, - { 170, 3 }, - { 170, 3 }, - { 170, 3 }, - { 170, 3 }, - { 217, 1 }, - { 217, 2 }, - { 217, 1 }, - { 217, 2 }, - { 218, 2 }, - { 218, 0 }, - { 170, 4 }, - { 170, 2 }, - { 170, 3 }, - { 170, 3 }, - { 170, 4 }, - { 170, 2 }, - { 170, 2 }, - { 170, 2 }, - { 219, 1 }, - { 219, 2 }, - { 170, 5 }, - { 220, 1 }, - { 220, 2 }, - { 170, 5 }, - { 170, 3 }, - { 170, 5 }, - { 170, 4 }, - { 170, 4 }, - { 170, 5 }, - { 222, 5 }, - { 222, 4 }, - { 223, 2 }, - { 223, 0 }, - { 221, 1 }, - { 221, 0 }, - { 216, 1 }, - { 216, 0 }, - { 211, 3 }, - { 211, 1 }, - { 143, 11 }, - { 224, 1 }, - { 224, 0 }, - { 174, 0 }, - { 174, 3 }, - { 182, 5 }, - { 182, 3 }, - { 225, 1 }, - { 226, 0 }, - { 226, 2 }, - { 143, 4 }, - { 143, 1 }, - { 143, 2 }, - { 143, 5 }, - { 143, 5 }, - { 143, 5 }, - { 143, 6 }, - { 143, 3 }, - { 227, 1 }, - { 227, 1 }, - { 165, 2 }, - { 166, 2 }, - { 229, 1 }, - { 228, 1 }, - { 228, 0 }, - { 143, 5 }, - { 230, 11 }, - { 232, 1 }, - { 232, 1 }, - { 232, 2 }, - { 232, 0 }, - { 233, 1 }, - { 233, 1 }, - { 233, 3 }, - { 234, 0 }, - { 234, 3 }, - { 235, 0 }, - { 235, 2 }, - { 231, 3 }, - { 231, 0 }, - { 236, 6 }, - { 236, 8 }, - { 236, 5 }, - { 236, 4 }, - { 236, 1 }, - { 170, 4 }, - { 170, 6 }, - { 186, 1 }, - { 186, 1 }, - { 186, 1 }, - { 143, 4 }, - { 143, 6 }, - { 143, 3 }, - { 238, 0 }, - { 238, 2 }, - { 237, 1 }, - { 237, 0 }, - { 143, 1 }, - { 143, 3 }, - { 143, 1 }, - { 143, 3 }, - { 143, 6 }, - { 143, 6 }, - { 239, 1 }, - { 240, 0 }, - { 240, 1 }, - { 143, 1 }, - { 143, 4 }, - { 241, 7 }, - { 242, 1 }, - { 242, 3 }, - { 243, 0 }, - { 243, 2 }, - { 244, 1 }, - { 244, 3 }, - { 245, 1 }, - { 246, 0 }, - { 246, 2 }, -}; - -static void yy_accept(yyParser*); /* Forward Declaration */ - -/* -** Perform a reduce action and the shift that must immediately -** follow the reduce. -*/ -static void yy_reduce( - yyParser *yypParser, /* The parser */ - int yyruleno /* Number of the rule by which to reduce */ -){ - int yygoto; /* The next state */ - int yyact; /* The next action */ - YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ - yyStackEntry *yymsp; /* The top of the parser's stack */ - int yysize; /* Amount to pop the stack */ - sqlite3ParserARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 - && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, - yyRuleName[yyruleno]); - } -#endif /* NDEBUG */ - - /* Silence complaints from purify about yygotominor being uninitialized - ** in some cases when it is copied into the stack after the following - ** switch. yygotominor is uninitialized when a rule reduces that does - ** not set the value of its left-hand side nonterminal. Leaving the - ** value of the nonterminal uninitialized is utterly harmless as long - ** as the value is never used. So really the only thing this code - ** accomplishes is to quieten purify. - ** - ** 2007-01-16: The wireshark project (www.wireshark.org) reports that - ** without this code, their parser segfaults. I'm not sure what there - ** parser is doing to make this happen. This is the second bug report - ** from wireshark this week. Clearly they are stressing Lemon in ways - ** that it has not been previously stressed... (SQLite ticket #2172) - */ - memset(&yygotominor, 0, sizeof(yygotominor)); - - - switch( yyruleno ){ - /* Beginning here are the reduction cases. A typical example - ** follows: - ** case 0: - ** #line - ** { ... } // User supplied code - ** #line - ** break; - */ - case 0: - case 1: - case 2: - case 4: - case 5: - case 10: - case 11: - case 12: - case 20: - case 28: - case 29: - case 37: - case 44: - case 45: - case 46: - case 47: - case 48: - case 49: - case 55: - case 82: - case 83: - case 84: - case 85: - case 256: - case 257: - case 267: - case 268: - case 288: - case 289: - case 297: - case 298: - case 302: - case 303: - case 305: - case 309: -#line 96 "parse.y" -{ -} -#line 1952 "parse.c" - break; - case 3: -#line 99 "parse.y" -{ sqlite3FinishCoding(pParse); } -#line 1957 "parse.c" - break; - case 6: -#line 102 "parse.y" -{ sqlite3BeginParse(pParse, 0); } -#line 1962 "parse.c" - break; - case 7: -#line 104 "parse.y" -{ sqlite3BeginParse(pParse, 1); } -#line 1967 "parse.c" - break; - case 8: -#line 105 "parse.y" -{ sqlite3BeginParse(pParse, 2); } -#line 1972 "parse.c" - break; - case 9: -#line 111 "parse.y" -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy46);} -#line 1977 "parse.c" - break; - case 13: -#line 116 "parse.y" -{yygotominor.yy46 = TK_DEFERRED;} -#line 1982 "parse.c" - break; - case 14: - case 15: - case 16: - case 107: - case 109: -#line 117 "parse.y" -{yygotominor.yy46 = yymsp[0].major;} -#line 1991 "parse.c" - break; - case 17: - case 18: -#line 120 "parse.y" -{sqlite3CommitTransaction(pParse);} -#line 1997 "parse.c" - break; - case 19: -#line 122 "parse.y" -{sqlite3RollbackTransaction(pParse);} -#line 2002 "parse.c" - break; - case 21: -#line 127 "parse.y" -{ - sqlite3StartTable(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410,yymsp[-4].minor.yy46,0,0,yymsp[-2].minor.yy46); -} -#line 2009 "parse.c" - break; - case 22: - case 25: - case 63: - case 77: - case 79: - case 90: - case 101: - case 112: - case 113: - case 212: - case 215: -#line 131 "parse.y" -{yygotominor.yy46 = 0;} -#line 2024 "parse.c" - break; - case 23: - case 24: - case 64: - case 78: - case 100: - case 111: - case 213: - case 216: -#line 132 "parse.y" -{yygotominor.yy46 = 1;} -#line 2036 "parse.c" - break; - case 26: -#line 138 "parse.y" -{ - sqlite3EndTable(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy0,0); -} -#line 2043 "parse.c" - break; - case 27: -#line 141 "parse.y" -{ - sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy219); - sqlite3SelectDelete(yymsp[0].minor.yy219); -} -#line 2051 "parse.c" - break; - case 30: -#line 153 "parse.y" -{ - yygotominor.yy410.z = yymsp[-2].minor.yy410.z; - yygotominor.yy410.n = (pParse->sLastToken.z-yymsp[-2].minor.yy410.z) + pParse->sLastToken.n; -} -#line 2059 "parse.c" - break; - case 31: -#line 157 "parse.y" -{ - sqlite3AddColumn(pParse,&yymsp[0].minor.yy410); - yygotominor.yy410 = yymsp[0].minor.yy410; -} -#line 2067 "parse.c" - break; - case 32: - case 33: - case 34: - case 35: - case 36: - case 255: -#line 167 "parse.y" -{yygotominor.yy410 = yymsp[0].minor.yy0;} -#line 2077 "parse.c" - break; - case 38: -#line 228 "parse.y" -{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy410);} -#line 2082 "parse.c" - break; - case 39: - case 42: - case 119: - case 120: - case 131: - case 240: - case 242: - case 251: - case 252: - case 253: - case 254: -#line 229 "parse.y" -{yygotominor.yy410 = yymsp[0].minor.yy410;} -#line 2097 "parse.c" - break; - case 40: -#line 230 "parse.y" -{ - yygotominor.yy410.z = yymsp[-3].minor.yy410.z; - yygotominor.yy410.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy410.z; -} -#line 2105 "parse.c" - break; - case 41: -#line 234 "parse.y" -{ - yygotominor.yy410.z = yymsp[-5].minor.yy410.z; - yygotominor.yy410.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy410.z; -} -#line 2113 "parse.c" - break; - case 43: -#line 240 "parse.y" -{yygotominor.yy410.z=yymsp[-1].minor.yy410.z; yygotominor.yy410.n=yymsp[0].minor.yy410.n+(yymsp[0].minor.yy410.z-yymsp[-1].minor.yy410.z);} -#line 2118 "parse.c" - break; - case 50: - case 52: -#line 251 "parse.y" -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy172);} -#line 2124 "parse.c" - break; - case 51: -#line 252 "parse.y" -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy172);} -#line 2129 "parse.c" - break; - case 53: -#line 254 "parse.y" -{ - Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy172, 0, 0); - sqlite3AddDefaultValue(pParse,p); -} -#line 2137 "parse.c" - break; - case 54: -#line 258 "parse.y" -{ - Expr *p = sqlite3PExpr(pParse, TK_STRING, 0, 0, &yymsp[0].minor.yy410); - sqlite3AddDefaultValue(pParse,p); -} -#line 2145 "parse.c" - break; - case 56: -#line 267 "parse.y" -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy46);} -#line 2150 "parse.c" - break; - case 57: -#line 269 "parse.y" -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy46,yymsp[0].minor.yy46,yymsp[-2].minor.yy46);} -#line 2155 "parse.c" - break; - case 58: -#line 270 "parse.y" -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy46,0,0,0,0);} -#line 2160 "parse.c" - break; - case 59: -#line 271 "parse.y" -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy172);} -#line 2165 "parse.c" - break; - case 60: -#line 273 "parse.y" -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy410,yymsp[-1].minor.yy174,yymsp[0].minor.yy46);} -#line 2170 "parse.c" - break; - case 61: -#line 274 "parse.y" -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy46);} -#line 2175 "parse.c" - break; - case 62: -#line 275 "parse.y" -{sqlite3AddCollateType(pParse, (char*)yymsp[0].minor.yy410.z, yymsp[0].minor.yy410.n);} -#line 2180 "parse.c" - break; - case 65: -#line 288 "parse.y" -{ yygotominor.yy46 = OE_Restrict * 0x010101; } -#line 2185 "parse.c" - break; - case 66: -#line 289 "parse.y" -{ yygotominor.yy46 = (yymsp[-1].minor.yy46 & yymsp[0].minor.yy405.mask) | yymsp[0].minor.yy405.value; } -#line 2190 "parse.c" - break; - case 67: -#line 291 "parse.y" -{ yygotominor.yy405.value = 0; yygotominor.yy405.mask = 0x000000; } -#line 2195 "parse.c" - break; - case 68: -#line 292 "parse.y" -{ yygotominor.yy405.value = yymsp[0].minor.yy46; yygotominor.yy405.mask = 0x0000ff; } -#line 2200 "parse.c" - break; - case 69: -#line 293 "parse.y" -{ yygotominor.yy405.value = yymsp[0].minor.yy46<<8; yygotominor.yy405.mask = 0x00ff00; } -#line 2205 "parse.c" - break; - case 70: -#line 294 "parse.y" -{ yygotominor.yy405.value = yymsp[0].minor.yy46<<16; yygotominor.yy405.mask = 0xff0000; } -#line 2210 "parse.c" - break; - case 71: -#line 296 "parse.y" -{ yygotominor.yy46 = OE_SetNull; } -#line 2215 "parse.c" - break; - case 72: -#line 297 "parse.y" -{ yygotominor.yy46 = OE_SetDflt; } -#line 2220 "parse.c" - break; - case 73: -#line 298 "parse.y" -{ yygotominor.yy46 = OE_Cascade; } -#line 2225 "parse.c" - break; - case 74: -#line 299 "parse.y" -{ yygotominor.yy46 = OE_Restrict; } -#line 2230 "parse.c" - break; - case 75: - case 76: - case 91: - case 93: - case 95: - case 96: - case 166: -#line 301 "parse.y" -{yygotominor.yy46 = yymsp[0].minor.yy46;} -#line 2241 "parse.c" - break; - case 80: -#line 311 "parse.y" -{yygotominor.yy410.n = 0; yygotominor.yy410.z = 0;} -#line 2246 "parse.c" - break; - case 81: -#line 312 "parse.y" -{yygotominor.yy410 = yymsp[-1].minor.yy0;} -#line 2251 "parse.c" - break; - case 86: -#line 318 "parse.y" -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy174,yymsp[0].minor.yy46,yymsp[-2].minor.yy46,0);} -#line 2256 "parse.c" - break; - case 87: -#line 320 "parse.y" -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy174,yymsp[0].minor.yy46,0,0,0,0);} -#line 2261 "parse.c" - break; - case 88: -#line 321 "parse.y" -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy172);} -#line 2266 "parse.c" - break; - case 89: -#line 323 "parse.y" -{ - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy174, &yymsp[-3].minor.yy410, yymsp[-2].minor.yy174, yymsp[-1].minor.yy46); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy46); -} -#line 2274 "parse.c" - break; - case 92: - case 94: -#line 337 "parse.y" -{yygotominor.yy46 = OE_Default;} -#line 2280 "parse.c" - break; - case 97: -#line 342 "parse.y" -{yygotominor.yy46 = OE_Ignore;} -#line 2285 "parse.c" - break; - case 98: - case 167: -#line 343 "parse.y" -{yygotominor.yy46 = OE_Replace;} -#line 2291 "parse.c" - break; - case 99: -#line 347 "parse.y" -{ - sqlite3DropTable(pParse, yymsp[0].minor.yy373, 0, yymsp[-1].minor.yy46); -} -#line 2298 "parse.c" - break; - case 102: -#line 357 "parse.y" -{ - sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy410, &yymsp[-2].minor.yy410, yymsp[0].minor.yy219, yymsp[-6].minor.yy46, yymsp[-4].minor.yy46); -} -#line 2305 "parse.c" - break; - case 103: -#line 360 "parse.y" -{ - sqlite3DropTable(pParse, yymsp[0].minor.yy373, 1, yymsp[-1].minor.yy46); -} -#line 2312 "parse.c" - break; - case 104: -#line 367 "parse.y" -{ - sqlite3Select(pParse, yymsp[0].minor.yy219, SRT_Callback, 0, 0, 0, 0, 0); - sqlite3SelectDelete(yymsp[0].minor.yy219); -} -#line 2320 "parse.c" - break; - case 105: - case 128: -#line 377 "parse.y" -{yygotominor.yy219 = yymsp[0].minor.yy219;} -#line 2326 "parse.c" - break; - case 106: -#line 379 "parse.y" -{ - if( yymsp[0].minor.yy219 ){ - yymsp[0].minor.yy219->op = yymsp[-1].minor.yy46; - yymsp[0].minor.yy219->pPrior = yymsp[-2].minor.yy219; - }else{ - sqlite3SelectDelete(yymsp[-2].minor.yy219); - } - yygotominor.yy219 = yymsp[0].minor.yy219; -} -#line 2339 "parse.c" - break; - case 108: -#line 390 "parse.y" -{yygotominor.yy46 = TK_ALL;} -#line 2344 "parse.c" - break; - case 110: -#line 394 "parse.y" -{ - yygotominor.yy219 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy174,yymsp[-5].minor.yy373,yymsp[-4].minor.yy172,yymsp[-3].minor.yy174,yymsp[-2].minor.yy172,yymsp[-1].minor.yy174,yymsp[-7].minor.yy46,yymsp[0].minor.yy234.pLimit,yymsp[0].minor.yy234.pOffset); -} -#line 2351 "parse.c" - break; - case 114: - case 237: -#line 415 "parse.y" -{yygotominor.yy174 = yymsp[-1].minor.yy174;} -#line 2357 "parse.c" - break; - case 115: - case 141: - case 149: - case 230: - case 236: -#line 416 "parse.y" -{yygotominor.yy174 = 0;} -#line 2366 "parse.c" - break; - case 116: -#line 417 "parse.y" -{ - yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy174,yymsp[-1].minor.yy172,yymsp[0].minor.yy410.n?&yymsp[0].minor.yy410:0); -} -#line 2373 "parse.c" - break; - case 117: -#line 420 "parse.y" -{ - Expr *p = sqlite3PExpr(pParse, TK_ALL, 0, 0, 0); - yygotominor.yy174 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy174, p, 0); -} -#line 2381 "parse.c" - break; - case 118: -#line 424 "parse.y" -{ - Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, 0); - Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy410); - Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); - yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy174, pDot, 0); -} -#line 2391 "parse.c" - break; - case 121: -#line 437 "parse.y" -{yygotominor.yy410.n = 0;} -#line 2396 "parse.c" - break; - case 122: -#line 449 "parse.y" -{yygotominor.yy373 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy373));} -#line 2401 "parse.c" - break; - case 123: -#line 450 "parse.y" -{ - yygotominor.yy373 = yymsp[0].minor.yy373; - sqlite3SrcListShiftJoinType(yygotominor.yy373); -} -#line 2409 "parse.c" - break; - case 124: -#line 458 "parse.y" -{ - yygotominor.yy373 = yymsp[-1].minor.yy373; - if( yygotominor.yy373 && yygotominor.yy373->nSrc>0 ) yygotominor.yy373->a[yygotominor.yy373->nSrc-1].jointype = yymsp[0].minor.yy46; -} -#line 2417 "parse.c" - break; - case 125: -#line 462 "parse.y" -{yygotominor.yy373 = 0;} -#line 2422 "parse.c" - break; - case 126: -#line 463 "parse.y" -{ - yygotominor.yy373 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy373,&yymsp[-4].minor.yy410,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,0,yymsp[-1].minor.yy172,yymsp[0].minor.yy432); -} -#line 2429 "parse.c" - break; - case 127: -#line 468 "parse.y" -{ - yygotominor.yy373 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy373,0,0,&yymsp[-2].minor.yy410,yymsp[-4].minor.yy219,yymsp[-1].minor.yy172,yymsp[0].minor.yy432); - } -#line 2436 "parse.c" - break; - case 129: -#line 479 "parse.y" -{ - sqlite3SrcListShiftJoinType(yymsp[0].minor.yy373); - yygotominor.yy219 = sqlite3SelectNew(pParse,0,yymsp[0].minor.yy373,0,0,0,0,0,0,0); - } -#line 2444 "parse.c" - break; - case 130: -#line 486 "parse.y" -{yygotominor.yy410.z=0; yygotominor.yy410.n=0;} -#line 2449 "parse.c" - break; - case 132: -#line 491 "parse.y" -{yygotominor.yy373 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410);} -#line 2454 "parse.c" - break; - case 133: -#line 495 "parse.y" -{ yygotominor.yy46 = JT_INNER; } -#line 2459 "parse.c" - break; - case 134: -#line 496 "parse.y" -{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } -#line 2464 "parse.c" - break; - case 135: -#line 497 "parse.y" -{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy410,0); } -#line 2469 "parse.c" - break; - case 136: -#line 499 "parse.y" -{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy410,&yymsp[-1].minor.yy410); } -#line 2474 "parse.c" - break; - case 137: - case 145: - case 152: - case 159: - case 174: - case 202: - case 225: - case 227: -#line 503 "parse.y" -{yygotominor.yy172 = yymsp[0].minor.yy172;} -#line 2486 "parse.c" - break; - case 138: - case 151: - case 158: - case 203: - case 226: - case 228: -#line 504 "parse.y" -{yygotominor.yy172 = 0;} -#line 2496 "parse.c" - break; - case 139: - case 171: -#line 508 "parse.y" -{yygotominor.yy432 = yymsp[-1].minor.yy432;} -#line 2502 "parse.c" - break; - case 140: - case 170: -#line 509 "parse.y" -{yygotominor.yy432 = 0;} -#line 2508 "parse.c" - break; - case 142: - case 150: - case 229: -#line 520 "parse.y" -{yygotominor.yy174 = yymsp[0].minor.yy174;} -#line 2515 "parse.c" - break; - case 143: -#line 521 "parse.y" -{ - yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy174,yymsp[-1].minor.yy172,0); - if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46; -} -#line 2523 "parse.c" - break; - case 144: -#line 525 "parse.y" -{ - yygotominor.yy174 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy172,0); - if( yygotominor.yy174 && yygotominor.yy174->a ) yygotominor.yy174->a[0].sortOrder = yymsp[0].minor.yy46; -} -#line 2531 "parse.c" - break; - case 146: - case 148: -#line 533 "parse.y" -{yygotominor.yy46 = SQLITE_SO_ASC;} -#line 2537 "parse.c" - break; - case 147: -#line 534 "parse.y" -{yygotominor.yy46 = SQLITE_SO_DESC;} -#line 2542 "parse.c" - break; - case 153: -#line 560 "parse.y" -{yygotominor.yy234.pLimit = 0; yygotominor.yy234.pOffset = 0;} -#line 2547 "parse.c" - break; - case 154: -#line 561 "parse.y" -{yygotominor.yy234.pLimit = yymsp[0].minor.yy172; yygotominor.yy234.pOffset = 0;} -#line 2552 "parse.c" - break; - case 155: -#line 563 "parse.y" -{yygotominor.yy234.pLimit = yymsp[-2].minor.yy172; yygotominor.yy234.pOffset = yymsp[0].minor.yy172;} -#line 2557 "parse.c" - break; - case 156: -#line 565 "parse.y" -{yygotominor.yy234.pOffset = yymsp[-2].minor.yy172; yygotominor.yy234.pLimit = yymsp[0].minor.yy172;} -#line 2562 "parse.c" - break; - case 157: -#line 569 "parse.y" -{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy373,yymsp[0].minor.yy172);} -#line 2567 "parse.c" - break; - case 160: -#line 579 "parse.y" -{ - sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy174,SQLITE_MAX_COLUMN,"set list"); - sqlite3Update(pParse,yymsp[-3].minor.yy373,yymsp[-1].minor.yy174,yymsp[0].minor.yy172,yymsp[-4].minor.yy46); -} -#line 2575 "parse.c" - break; - case 161: -#line 588 "parse.y" -{yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174,yymsp[0].minor.yy172,&yymsp[-2].minor.yy410);} -#line 2580 "parse.c" - break; - case 162: -#line 590 "parse.y" -{yygotominor.yy174 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy172,&yymsp[-2].minor.yy410);} -#line 2585 "parse.c" - break; - case 163: -#line 596 "parse.y" -{sqlite3Insert(pParse, yymsp[-5].minor.yy373, yymsp[-1].minor.yy174, 0, yymsp[-4].minor.yy432, yymsp[-7].minor.yy46);} -#line 2590 "parse.c" - break; - case 164: -#line 598 "parse.y" -{sqlite3Insert(pParse, yymsp[-2].minor.yy373, 0, yymsp[0].minor.yy219, yymsp[-1].minor.yy432, yymsp[-4].minor.yy46);} -#line 2595 "parse.c" - break; - case 165: -#line 600 "parse.y" -{sqlite3Insert(pParse, yymsp[-3].minor.yy373, 0, 0, yymsp[-2].minor.yy432, yymsp[-5].minor.yy46);} -#line 2600 "parse.c" - break; - case 168: - case 231: -#line 611 "parse.y" -{yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy174,yymsp[0].minor.yy172,0);} -#line 2606 "parse.c" - break; - case 169: - case 232: -#line 613 "parse.y" -{yygotominor.yy174 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy172,0);} -#line 2612 "parse.c" - break; - case 172: -#line 623 "parse.y" -{yygotominor.yy432 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy432,&yymsp[0].minor.yy410);} -#line 2617 "parse.c" - break; - case 173: -#line 625 "parse.y" -{yygotominor.yy432 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy410);} -#line 2622 "parse.c" - break; - case 175: -#line 636 "parse.y" -{yygotominor.yy172 = yymsp[-1].minor.yy172; sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } -#line 2627 "parse.c" - break; - case 176: - case 181: - case 182: -#line 637 "parse.y" -{yygotominor.yy172 = sqlite3PExpr(pParse, yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);} -#line 2634 "parse.c" - break; - case 177: - case 178: -#line 638 "parse.y" -{yygotominor.yy172 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);} -#line 2640 "parse.c" - break; - case 179: -#line 640 "parse.y" -{ - Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy410); - Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy410); - yygotominor.yy172 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); -} -#line 2649 "parse.c" - break; - case 180: -#line 645 "parse.y" -{ - Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy410); - Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy410); - Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy410); - Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0); - yygotominor.yy172 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); -} -#line 2660 "parse.c" - break; - case 183: -#line 654 "parse.y" -{yygotominor.yy172 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);} -#line 2665 "parse.c" - break; - case 184: -#line 655 "parse.y" -{ - Token *pToken = &yymsp[0].minor.yy0; - Expr *pExpr = yygotominor.yy172 = sqlite3PExpr(pParse, TK_VARIABLE, 0, 0, pToken); - sqlite3ExprAssignVarNumber(pParse, pExpr); -} -#line 2674 "parse.c" - break; - case 185: -#line 660 "parse.y" -{ - yygotominor.yy172 = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy172, &yymsp[0].minor.yy410); -} -#line 2681 "parse.c" - break; - case 186: -#line 664 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy172, 0, &yymsp[-1].minor.yy410); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); -} -#line 2689 "parse.c" - break; - case 187: -#line 669 "parse.y" -{ - if( yymsp[-1].minor.yy174 && yymsp[-1].minor.yy174->nExpr>SQLITE_MAX_FUNCTION_ARG ){ - sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0); - } - yygotominor.yy172 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy174, &yymsp[-4].minor.yy0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); - if( yymsp[-2].minor.yy46 && yygotominor.yy172 ){ - yygotominor.yy172->flags |= EP_Distinct; - } -} -#line 2703 "parse.c" - break; - case 188: -#line 679 "parse.y" -{ - yygotominor.yy172 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); -} -#line 2711 "parse.c" - break; - case 189: -#line 683 "parse.y" -{ - /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are - ** treated as functions that return constants */ - yygotominor.yy172 = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0); - if( yygotominor.yy172 ){ - yygotominor.yy172->op = TK_CONST_FUNC; - yygotominor.yy172->span = yymsp[0].minor.yy0; - } -} -#line 2724 "parse.c" - break; - case 190: - case 191: - case 192: - case 193: - case 194: - case 195: - case 196: - case 197: -#line 692 "parse.y" -{yygotominor.yy172 = sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy172,yymsp[0].minor.yy172,0);} -#line 2736 "parse.c" - break; - case 198: - case 200: -#line 704 "parse.y" -{yygotominor.yy72.eOperator = yymsp[0].minor.yy0; yygotominor.yy72.not = 0;} -#line 2742 "parse.c" - break; - case 199: - case 201: -#line 705 "parse.y" -{yygotominor.yy72.eOperator = yymsp[0].minor.yy0; yygotominor.yy72.not = 1;} -#line 2748 "parse.c" - break; - case 204: -#line 712 "parse.y" -{ - ExprList *pList; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy172, 0); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy172, 0); - if( yymsp[0].minor.yy172 ){ - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy172, 0); - } - yygotominor.yy172 = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy72.eOperator); - if( yymsp[-2].minor.yy72.not ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0); - sqlite3ExprSpan(yygotominor.yy172, &yymsp[-3].minor.yy172->span, &yymsp[-1].minor.yy172->span); - if( yygotominor.yy172 ) yygotominor.yy172->flags |= EP_InfixFunc; -} -#line 2764 "parse.c" - break; - case 205: -#line 725 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, yymsp[0].major, yymsp[-1].minor.yy172, 0, 0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy172->span,&yymsp[0].minor.yy0); -} -#line 2772 "parse.c" - break; - case 206: -#line 729 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, TK_ISNULL, yymsp[-2].minor.yy172, 0, 0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy172->span,&yymsp[0].minor.yy0); -} -#line 2780 "parse.c" - break; - case 207: -#line 733 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-2].minor.yy172, 0, 0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy172->span,&yymsp[0].minor.yy0); -} -#line 2788 "parse.c" - break; - case 208: -#line 737 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-3].minor.yy172, 0, 0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,&yymsp[0].minor.yy0); -} -#line 2796 "parse.c" - break; - case 209: -#line 741 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy172, 0, 0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span); -} -#line 2804 "parse.c" - break; - case 210: -#line 745 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy172, 0, 0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span); -} -#line 2812 "parse.c" - break; - case 211: -#line 749 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, TK_UPLUS, yymsp[0].minor.yy172, 0, 0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span); -} -#line 2820 "parse.c" - break; - case 214: -#line 756 "parse.y" -{ - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy172, 0); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy172, 0); - yygotominor.yy172 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy172, 0, 0); - if( yygotominor.yy172 ){ - yygotominor.yy172->pList = pList; - }else{ - sqlite3ExprListDelete(pList); - } - if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy172->span); -} -#line 2836 "parse.c" - break; - case 217: -#line 772 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy172, 0, 0); - if( yygotominor.yy172 ){ - yygotominor.yy172->pList = yymsp[-1].minor.yy174; - sqlite3ExprSetHeight(yygotominor.yy172); - }else{ - sqlite3ExprListDelete(yymsp[-1].minor.yy174); - } - if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy0); - } -#line 2851 "parse.c" - break; - case 218: -#line 783 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); - if( yygotominor.yy172 ){ - yygotominor.yy172->pSelect = yymsp[-1].minor.yy219; - sqlite3ExprSetHeight(yygotominor.yy172); - }else{ - sqlite3SelectDelete(yymsp[-1].minor.yy219); - } - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); - } -#line 2865 "parse.c" - break; - case 219: -#line 793 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy172, 0, 0); - if( yygotominor.yy172 ){ - yygotominor.yy172->pSelect = yymsp[-1].minor.yy219; - sqlite3ExprSetHeight(yygotominor.yy172); - }else{ - sqlite3SelectDelete(yymsp[-1].minor.yy219); - } - if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy0); - } -#line 2880 "parse.c" - break; - case 220: -#line 804 "parse.y" -{ - SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410); - yygotominor.yy172 = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy172, 0, 0); - if( yygotominor.yy172 ){ - yygotominor.yy172->pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); - sqlite3ExprSetHeight(yygotominor.yy172); - }else{ - sqlite3SrcListDelete(pSrc); - } - if( yymsp[-2].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0); - sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,yymsp[0].minor.yy410.z?&yymsp[0].minor.yy410:&yymsp[-1].minor.yy410); - } -#line 2896 "parse.c" - break; - case 221: -#line 816 "parse.y" -{ - Expr *p = yygotominor.yy172 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); - if( p ){ - p->pSelect = yymsp[-1].minor.yy219; - sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); - sqlite3ExprSetHeight(yygotominor.yy172); - }else{ - sqlite3SelectDelete(yymsp[-1].minor.yy219); - } - } -#line 2910 "parse.c" - break; - case 222: -#line 829 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, 0); - if( yygotominor.yy172 ){ - yygotominor.yy172->pList = yymsp[-2].minor.yy174; - sqlite3ExprSetHeight(yygotominor.yy172); - }else{ - sqlite3ExprListDelete(yymsp[-2].minor.yy174); - } - sqlite3ExprSpan(yygotominor.yy172, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); -} -#line 2924 "parse.c" - break; - case 223: -#line 841 "parse.y" -{ - yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174, yymsp[-2].minor.yy172, 0); - yygotominor.yy174 = sqlite3ExprListAppend(pParse,yygotominor.yy174, yymsp[0].minor.yy172, 0); -} -#line 2932 "parse.c" - break; - case 224: -#line 845 "parse.y" -{ - yygotominor.yy174 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy172, 0); - yygotominor.yy174 = sqlite3ExprListAppend(pParse,yygotominor.yy174, yymsp[0].minor.yy172, 0); -} -#line 2940 "parse.c" - break; - case 233: -#line 874 "parse.y" -{ - sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy410, &yymsp[-5].minor.yy410, - sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy410,0), yymsp[-1].minor.yy174, yymsp[-9].minor.yy46, - &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy46); -} -#line 2949 "parse.c" - break; - case 234: - case 281: -#line 881 "parse.y" -{yygotominor.yy46 = OE_Abort;} -#line 2955 "parse.c" - break; - case 235: -#line 882 "parse.y" -{yygotominor.yy46 = OE_None;} -#line 2960 "parse.c" - break; - case 238: -#line 892 "parse.y" -{ - Expr *p = 0; - if( yymsp[-1].minor.yy410.n>0 ){ - p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy410.z, yymsp[-1].minor.yy410.n); - } - yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174, p, &yymsp[-2].minor.yy410); - sqlite3ExprListCheckLength(pParse, yygotominor.yy174, SQLITE_MAX_COLUMN, "index"); - if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46; -} -#line 2974 "parse.c" - break; - case 239: -#line 902 "parse.y" -{ - Expr *p = 0; - if( yymsp[-1].minor.yy410.n>0 ){ - p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy410.z, yymsp[-1].minor.yy410.n); - } - yygotominor.yy174 = sqlite3ExprListAppend(pParse,0, p, &yymsp[-2].minor.yy410); - sqlite3ExprListCheckLength(pParse, yygotominor.yy174, SQLITE_MAX_COLUMN, "index"); - if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46; -} -#line 2988 "parse.c" - break; - case 241: -#line 915 "parse.y" -{yygotominor.yy410.z = 0; yygotominor.yy410.n = 0;} -#line 2993 "parse.c" - break; - case 243: -#line 921 "parse.y" -{sqlite3DropIndex(pParse, yymsp[0].minor.yy373, yymsp[-1].minor.yy46);} -#line 2998 "parse.c" - break; - case 244: - case 245: -#line 927 "parse.y" -{sqlite3Vacuum(pParse);} -#line 3004 "parse.c" - break; - case 246: -#line 935 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy410,0);} -#line 3009 "parse.c" - break; - case 247: -#line 936 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy0,0);} -#line 3014 "parse.c" - break; - case 248: -#line 937 "parse.y" -{ - sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy410,1); -} -#line 3021 "parse.c" - break; - case 249: -#line 940 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-4].minor.yy410,&yymsp[-3].minor.yy410,&yymsp[-1].minor.yy410,0);} -#line 3026 "parse.c" - break; - case 250: -#line 941 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410,0,0);} -#line 3031 "parse.c" - break; - case 258: -#line 955 "parse.y" -{ - Token all; - all.z = yymsp[-3].minor.yy410.z; - all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy410.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy243, &all); -} -#line 3041 "parse.c" - break; - case 259: -#line 964 "parse.y" -{ - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy410, &yymsp[-6].minor.yy410, yymsp[-5].minor.yy46, yymsp[-4].minor.yy370.a, yymsp[-4].minor.yy370.b, yymsp[-2].minor.yy373, yymsp[0].minor.yy172, yymsp[-10].minor.yy46, yymsp[-8].minor.yy46); - yygotominor.yy410 = (yymsp[-6].minor.yy410.n==0?yymsp[-7].minor.yy410:yymsp[-6].minor.yy410); -} -#line 3049 "parse.c" - break; - case 260: - case 263: -#line 970 "parse.y" -{ yygotominor.yy46 = TK_BEFORE; } -#line 3055 "parse.c" - break; - case 261: -#line 971 "parse.y" -{ yygotominor.yy46 = TK_AFTER; } -#line 3060 "parse.c" - break; - case 262: -#line 972 "parse.y" -{ yygotominor.yy46 = TK_INSTEAD;} -#line 3065 "parse.c" - break; - case 264: - case 265: -#line 977 "parse.y" -{yygotominor.yy370.a = yymsp[0].major; yygotominor.yy370.b = 0;} -#line 3071 "parse.c" - break; - case 266: -#line 979 "parse.y" -{yygotominor.yy370.a = TK_UPDATE; yygotominor.yy370.b = yymsp[0].minor.yy432;} -#line 3076 "parse.c" - break; - case 269: -#line 986 "parse.y" -{ yygotominor.yy172 = 0; } -#line 3081 "parse.c" - break; - case 270: -#line 987 "parse.y" -{ yygotominor.yy172 = yymsp[0].minor.yy172; } -#line 3086 "parse.c" - break; - case 271: -#line 991 "parse.y" -{ - if( yymsp[-2].minor.yy243 ){ - yymsp[-2].minor.yy243->pLast->pNext = yymsp[-1].minor.yy243; - }else{ - yymsp[-2].minor.yy243 = yymsp[-1].minor.yy243; - } - yymsp[-2].minor.yy243->pLast = yymsp[-1].minor.yy243; - yygotominor.yy243 = yymsp[-2].minor.yy243; -} -#line 3099 "parse.c" - break; - case 272: -#line 1000 "parse.y" -{ yygotominor.yy243 = 0; } -#line 3104 "parse.c" - break; - case 273: -#line 1006 "parse.y" -{ yygotominor.yy243 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-3].minor.yy410, yymsp[-1].minor.yy174, yymsp[0].minor.yy172, yymsp[-4].minor.yy46); } -#line 3109 "parse.c" - break; - case 274: -#line 1011 "parse.y" -{yygotominor.yy243 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy410, yymsp[-4].minor.yy432, yymsp[-1].minor.yy174, 0, yymsp[-7].minor.yy46);} -#line 3114 "parse.c" - break; - case 275: -#line 1014 "parse.y" -{yygotominor.yy243 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy410, yymsp[-1].minor.yy432, 0, yymsp[0].minor.yy219, yymsp[-4].minor.yy46);} -#line 3119 "parse.c" - break; - case 276: -#line 1018 "parse.y" -{yygotominor.yy243 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-1].minor.yy410, yymsp[0].minor.yy172);} -#line 3124 "parse.c" - break; - case 277: -#line 1021 "parse.y" -{yygotominor.yy243 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy219); } -#line 3129 "parse.c" - break; - case 278: -#line 1024 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); - if( yygotominor.yy172 ){ - yygotominor.yy172->iColumn = OE_Ignore; - sqlite3ExprSpan(yygotominor.yy172, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); - } -} -#line 3140 "parse.c" - break; - case 279: -#line 1031 "parse.y" -{ - yygotominor.yy172 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy410); - if( yygotominor.yy172 ) { - yygotominor.yy172->iColumn = yymsp[-3].minor.yy46; - sqlite3ExprSpan(yygotominor.yy172, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); - } -} -#line 3151 "parse.c" - break; - case 280: -#line 1041 "parse.y" -{yygotominor.yy46 = OE_Rollback;} -#line 3156 "parse.c" - break; - case 282: -#line 1043 "parse.y" -{yygotominor.yy46 = OE_Fail;} -#line 3161 "parse.c" - break; - case 283: -#line 1048 "parse.y" -{ - sqlite3DropTrigger(pParse,yymsp[0].minor.yy373,yymsp[-1].minor.yy46); -} -#line 3168 "parse.c" - break; - case 284: -#line 1055 "parse.y" -{ - sqlite3Attach(pParse, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, yymsp[0].minor.yy386); -} -#line 3175 "parse.c" - break; - case 285: -#line 1058 "parse.y" -{ - sqlite3Detach(pParse, yymsp[0].minor.yy172); -} -#line 3182 "parse.c" - break; - case 286: -#line 1064 "parse.y" -{ yygotominor.yy386 = 0; } -#line 3187 "parse.c" - break; - case 287: -#line 1065 "parse.y" -{ yygotominor.yy386 = yymsp[0].minor.yy172; } -#line 3192 "parse.c" - break; - case 290: -#line 1073 "parse.y" -{sqlite3Reindex(pParse, 0, 0);} -#line 3197 "parse.c" - break; - case 291: -#line 1074 "parse.y" -{sqlite3Reindex(pParse, &yymsp[-1].minor.yy410, &yymsp[0].minor.yy410);} -#line 3202 "parse.c" - break; - case 292: -#line 1079 "parse.y" -{sqlite3Analyze(pParse, 0, 0);} -#line 3207 "parse.c" - break; - case 293: -#line 1080 "parse.y" -{sqlite3Analyze(pParse, &yymsp[-1].minor.yy410, &yymsp[0].minor.yy410);} -#line 3212 "parse.c" - break; - case 294: -#line 1085 "parse.y" -{ - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy373,&yymsp[0].minor.yy410); -} -#line 3219 "parse.c" - break; - case 295: -#line 1088 "parse.y" -{ - sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy410); -} -#line 3226 "parse.c" - break; - case 296: -#line 1091 "parse.y" -{ - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy373); -} -#line 3233 "parse.c" - break; - case 299: -#line 1100 "parse.y" -{sqlite3VtabFinishParse(pParse,0);} -#line 3238 "parse.c" - break; - case 300: -#line 1101 "parse.y" -{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} -#line 3243 "parse.c" - break; - case 301: -#line 1102 "parse.y" -{ - sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy410, &yymsp[-2].minor.yy410, &yymsp[0].minor.yy410); -} -#line 3250 "parse.c" - break; - case 304: -#line 1107 "parse.y" -{sqlite3VtabArgInit(pParse);} -#line 3255 "parse.c" - break; - case 306: - case 307: - case 308: - case 310: -#line 1109 "parse.y" -{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} -#line 3263 "parse.c" - break; - }; - yygoto = yyRuleInfo[yyruleno].lhs; - yysize = yyRuleInfo[yyruleno].nrhs; - yypParser->yyidx -= yysize; - yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto); - if( yyact < YYNSTATE ){ -#ifdef NDEBUG - /* If we are not debugging and the reduce action popped at least - ** one element off the stack, then we can push the new element back - ** onto the stack here, and skip the stack overflow test in yy_shift(). - ** That gives a significant speed improvement. */ - if( yysize ){ - yypParser->yyidx++; - yymsp -= yysize-1; - yymsp->stateno = yyact; - yymsp->major = yygoto; - yymsp->minor = yygotominor; - }else -#endif - { - yy_shift(yypParser,yyact,yygoto,&yygotominor); - } - }else if( yyact == YYNSTATE + YYNRULE + 1 ){ - yy_accept(yypParser); - } -} - -/* -** The following code executes when the parse fails -*/ -static void yy_parse_failed( - yyParser *yypParser /* The parser */ -){ - sqlite3ParserARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser fails */ - sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following code executes when a syntax error first occurs. -*/ -static void yy_syntax_error( - yyParser *yypParser, /* The parser */ - int yymajor, /* The major type of the error token */ - YYMINORTYPE yyminor /* The minor type of the error token */ -){ - sqlite3ParserARG_FETCH; -#define TOKEN (yyminor.yy0) -#line 34 "parse.y" - - if( !pParse->parseError ){ - if( TOKEN.z[0] ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); - }else{ - sqlite3ErrorMsg(pParse, "incomplete SQL statement"); - } - pParse->parseError = 1; - } -#line 3331 "parse.c" - sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following is executed when the parser accepts -*/ -static void yy_accept( - yyParser *yypParser /* The parser */ -){ - sqlite3ParserARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser accepts */ - sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* The main parser program. -** The first argument is a pointer to a structure obtained from -** "sqlite3ParserAlloc" which describes the current state of the parser. -** The second argument is the major token number. The third is -** the minor token. The fourth optional argument is whatever the -** user wants (and specified in the grammar) and is available for -** use by the action routines. -** -** Inputs: -**
    -**
  • A pointer to the parser (an opaque structure.) -**
  • The major token number. -**
  • The minor token number. -**
  • An option argument of a grammar-specified type. -**
-** -** Outputs: -** None. -*/ -void sqlite3Parser( - void *yyp, /* The parser */ - int yymajor, /* The major token code number */ - sqlite3ParserTOKENTYPE yyminor /* The value for the token */ - sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */ -){ - YYMINORTYPE yyminorunion; - int yyact; /* The parser action. */ - int yyendofinput; /* True if we are at the end of input */ - int yyerrorhit = 0; /* True if yymajor has invoked an error */ - yyParser *yypParser; /* The parser */ - - /* (re)initialize the parser, if necessary */ - yypParser = (yyParser*)yyp; - if( yypParser->yyidx<0 ){ -#if YYSTACKDEPTH<=0 - if( yypParser->yystksz <=0 ){ - memset(&yyminorunion, 0, sizeof(yyminorunion)); - yyStackOverflow(yypParser, &yyminorunion); - return; - } -#endif - yypParser->yyidx = 0; - yypParser->yyerrcnt = -1; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; - } - yyminorunion.yy0 = yyminor; - yyendofinput = (yymajor==0); - sqlite3ParserARG_STORE; - -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); - } -#endif - - do{ - yyact = yy_find_shift_action(yypParser,yymajor); - if( yyactyyerrcnt--; - if( yyendofinput && yypParser->yyidx>=0 ){ - yymajor = 0; - }else{ - yymajor = YYNOCODE; - } - }else if( yyact < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); - }else if( yyact == YY_ERROR_ACTION ){ - int yymx; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); - } -#endif -#ifdef YYERRORSYMBOL - /* A syntax error has occurred. - ** The response to an error depends upon whether or not the - ** grammar defines an error token "ERROR". - ** - ** This is what we do if the grammar does define ERROR: - ** - ** * Call the %syntax_error function. - ** - ** * Begin popping the stack until we enter a state where - ** it is legal to shift the error symbol, then shift - ** the error symbol. - ** - ** * Set the error count to three. - ** - ** * Begin accepting and shifting new tokens. No new error - ** processing will occur until three tokens have been - ** shifted successfully. - ** - */ - if( yypParser->yyerrcnt<0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yymx = yypParser->yystack[yypParser->yyidx].major; - if( yymx==YYERRORSYMBOL || yyerrorhit ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sDiscard input token %s\n", - yyTracePrompt,yyTokenName[yymajor]); - } -#endif - yy_destructor(yymajor,&yyminorunion); - yymajor = YYNOCODE; - }else{ - while( - yypParser->yyidx >= 0 && - yymx != YYERRORSYMBOL && - (yyact = yy_find_reduce_action( - yypParser->yystack[yypParser->yyidx].stateno, - YYERRORSYMBOL)) >= YYNSTATE - ){ - yy_pop_parser_stack(yypParser); - } - if( yypParser->yyidx < 0 || yymajor==0 ){ - yy_destructor(yymajor,&yyminorunion); - yy_parse_failed(yypParser); - yymajor = YYNOCODE; - }else if( yymx!=YYERRORSYMBOL ){ - YYMINORTYPE u2; - u2.YYERRSYMDT = 0; - yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); - } - } - yypParser->yyerrcnt = 3; - yyerrorhit = 1; -#else /* YYERRORSYMBOL is not defined */ - /* This is what we do if the grammar does not define ERROR: - ** - ** * Report an error message, and throw away the input token. - ** - ** * If the input token is $, then fail the parse. - ** - ** As before, subsequent error messages are suppressed until - ** three input tokens have been successfully shifted. - */ - if( yypParser->yyerrcnt<=0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yypParser->yyerrcnt = 3; - yy_destructor(yymajor,&yyminorunion); - if( yyendofinput ){ - yy_parse_failed(yypParser); - } - yymajor = YYNOCODE; -#endif - }else{ - yy_accept(yypParser); - yymajor = YYNOCODE; - } - }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); - return; -} diff --git a/extensions/sqlite/sqlite-source/parse.h b/extensions/sqlite/sqlite-source/parse.h deleted file mode 100644 index ed848ec5..00000000 --- a/extensions/sqlite/sqlite-source/parse.h +++ /dev/null @@ -1,152 +0,0 @@ -#define TK_SEMI 1 -#define TK_EXPLAIN 2 -#define TK_QUERY 3 -#define TK_PLAN 4 -#define TK_BEGIN 5 -#define TK_TRANSACTION 6 -#define TK_DEFERRED 7 -#define TK_IMMEDIATE 8 -#define TK_EXCLUSIVE 9 -#define TK_COMMIT 10 -#define TK_END 11 -#define TK_ROLLBACK 12 -#define TK_CREATE 13 -#define TK_TABLE 14 -#define TK_IF 15 -#define TK_NOT 16 -#define TK_EXISTS 17 -#define TK_TEMP 18 -#define TK_LP 19 -#define TK_RP 20 -#define TK_AS 21 -#define TK_COMMA 22 -#define TK_ID 23 -#define TK_ABORT 24 -#define TK_AFTER 25 -#define TK_ANALYZE 26 -#define TK_ASC 27 -#define TK_ATTACH 28 -#define TK_BEFORE 29 -#define TK_CASCADE 30 -#define TK_CAST 31 -#define TK_CONFLICT 32 -#define TK_DATABASE 33 -#define TK_DESC 34 -#define TK_DETACH 35 -#define TK_EACH 36 -#define TK_FAIL 37 -#define TK_FOR 38 -#define TK_IGNORE 39 -#define TK_INITIALLY 40 -#define TK_INSTEAD 41 -#define TK_LIKE_KW 42 -#define TK_MATCH 43 -#define TK_KEY 44 -#define TK_OF 45 -#define TK_OFFSET 46 -#define TK_PRAGMA 47 -#define TK_RAISE 48 -#define TK_REPLACE 49 -#define TK_RESTRICT 50 -#define TK_ROW 51 -#define TK_TRIGGER 52 -#define TK_VACUUM 53 -#define TK_VIEW 54 -#define TK_VIRTUAL 55 -#define TK_REINDEX 56 -#define TK_RENAME 57 -#define TK_CTIME_KW 58 -#define TK_ANY 59 -#define TK_OR 60 -#define TK_AND 61 -#define TK_IS 62 -#define TK_BETWEEN 63 -#define TK_IN 64 -#define TK_ISNULL 65 -#define TK_NOTNULL 66 -#define TK_NE 67 -#define TK_EQ 68 -#define TK_GT 69 -#define TK_LE 70 -#define TK_LT 71 -#define TK_GE 72 -#define TK_ESCAPE 73 -#define TK_BITAND 74 -#define TK_BITOR 75 -#define TK_LSHIFT 76 -#define TK_RSHIFT 77 -#define TK_PLUS 78 -#define TK_MINUS 79 -#define TK_STAR 80 -#define TK_SLASH 81 -#define TK_REM 82 -#define TK_CONCAT 83 -#define TK_COLLATE 84 -#define TK_UMINUS 85 -#define TK_UPLUS 86 -#define TK_BITNOT 87 -#define TK_STRING 88 -#define TK_JOIN_KW 89 -#define TK_CONSTRAINT 90 -#define TK_DEFAULT 91 -#define TK_NULL 92 -#define TK_PRIMARY 93 -#define TK_UNIQUE 94 -#define TK_CHECK 95 -#define TK_REFERENCES 96 -#define TK_AUTOINCR 97 -#define TK_ON 98 -#define TK_DELETE 99 -#define TK_UPDATE 100 -#define TK_INSERT 101 -#define TK_SET 102 -#define TK_DEFERRABLE 103 -#define TK_FOREIGN 104 -#define TK_DROP 105 -#define TK_UNION 106 -#define TK_ALL 107 -#define TK_EXCEPT 108 -#define TK_INTERSECT 109 -#define TK_SELECT 110 -#define TK_DISTINCT 111 -#define TK_DOT 112 -#define TK_FROM 113 -#define TK_JOIN 114 -#define TK_USING 115 -#define TK_ORDER 116 -#define TK_BY 117 -#define TK_GROUP 118 -#define TK_HAVING 119 -#define TK_LIMIT 120 -#define TK_WHERE 121 -#define TK_INTO 122 -#define TK_VALUES 123 -#define TK_INTEGER 124 -#define TK_FLOAT 125 -#define TK_BLOB 126 -#define TK_REGISTER 127 -#define TK_VARIABLE 128 -#define TK_CASE 129 -#define TK_WHEN 130 -#define TK_THEN 131 -#define TK_ELSE 132 -#define TK_INDEX 133 -#define TK_ALTER 134 -#define TK_TO 135 -#define TK_ADD 136 -#define TK_COLUMNKW 137 -#define TK_TO_TEXT 138 -#define TK_TO_BLOB 139 -#define TK_TO_NUMERIC 140 -#define TK_TO_INT 141 -#define TK_TO_REAL 142 -#define TK_END_OF_FILE 143 -#define TK_ILLEGAL 144 -#define TK_SPACE 145 -#define TK_UNCLOSED_STRING 146 -#define TK_COMMENT 147 -#define TK_FUNCTION 148 -#define TK_COLUMN 149 -#define TK_AGG_FUNCTION 150 -#define TK_AGG_COLUMN 151 -#define TK_CONST_FUNC 152 diff --git a/extensions/sqlite/sqlite-source/pragma.c b/extensions/sqlite/sqlite-source/pragma.c deleted file mode 100644 index fe3a5acd..00000000 --- a/extensions/sqlite/sqlite-source/pragma.c +++ /dev/null @@ -1,1186 +0,0 @@ -/* -** 2003 April 6 -** -** 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 file contains code used to implement the PRAGMA command. -** -** $Id$ -*/ -#include "sqliteInt.h" -#include - -/* Ignore this whole file if pragmas are disabled -*/ -#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER) - -/* -** Interpret the given string as a safety level. Return 0 for OFF, -** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or -** unrecognized string argument. -** -** Note that the values returned are one less that the values that -** should be passed into sqlite3BtreeSetSafetyLevel(). The is done -** to support legacy SQL code. The safety level used to be boolean -** and older scripts may have used numbers 0 for OFF and 1 for ON. -*/ -static int getSafetyLevel(const char *z){ - /* 123456789 123456789 */ - static const char zText[] = "onoffalseyestruefull"; - static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16}; - static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4}; - static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2}; - int i, n; - if( isdigit(*z) ){ - return atoi(z); - } - n = strlen(z); - for(i=0; i=0&&i<=2)?i:0); -} -#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */ - -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -/* -** Interpret the given string as a temp db location. Return 1 for file -** backed temporary databases, 2 for the Red-Black tree in memory database -** and 0 to use the compile-time default. -*/ -static int getTempStore(const char *z){ - if( z[0]>='0' && z[0]<='2' ){ - return z[0] - '0'; - }else if( sqlite3StrICmp(z, "file")==0 ){ - return 1; - }else if( sqlite3StrICmp(z, "memory")==0 ){ - return 2; - }else{ - return 0; - } -} -#endif /* SQLITE_PAGER_PRAGMAS */ - -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -/* -** Invalidate temp storage, either when the temp storage is changed -** from default, or when 'file' and the temp_store_directory has changed -*/ -static int invalidateTempStorage(Parse *pParse){ - sqlite3 *db = pParse->db; - if( db->aDb[1].pBt!=0 ){ - if( !db->autoCommit ){ - sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " - "from within a transaction"); - return SQLITE_ERROR; - } - sqlite3BtreeClose(db->aDb[1].pBt); - db->aDb[1].pBt = 0; - sqlite3ResetInternalSchema(db, 0); - } - return SQLITE_OK; -} -#endif /* SQLITE_PAGER_PRAGMAS */ - -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -/* -** If the TEMP database is open, close it and mark the database schema -** as needing reloading. This must be done when using the TEMP_STORE -** or DEFAULT_TEMP_STORE pragmas. -*/ -static int changeTempStorage(Parse *pParse, const char *zStorageType){ - int ts = getTempStore(zStorageType); - sqlite3 *db = pParse->db; - if( db->temp_store==ts ) return SQLITE_OK; - if( invalidateTempStorage( pParse ) != SQLITE_OK ){ - return SQLITE_ERROR; - } - db->temp_store = ts; - return SQLITE_OK; -} -#endif /* SQLITE_PAGER_PRAGMAS */ - -/* -** Generate code to return a single integer value. -*/ -static void returnSingleInt(Parse *pParse, const char *zLabel, int value){ - Vdbe *v = sqlite3GetVdbe(pParse); - sqlite3VdbeAddOp(v, OP_Integer, value, 0); - if( pParse->explain==0 ){ - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P3_STATIC); - } - sqlite3VdbeAddOp(v, OP_Callback, 1, 0); -} - -#ifndef SQLITE_OMIT_FLAG_PRAGMAS -/* -** Check to see if zRight and zLeft refer to a pragma that queries -** or changes one of the flags in db->flags. Return 1 if so and 0 if not. -** Also, implement the pragma. -*/ -static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ - static const struct sPragmaType { - const char *zName; /* Name of the pragma */ - int mask; /* Mask for the db->flags value */ - } aPragma[] = { - { "full_column_names", SQLITE_FullColNames }, - { "short_column_names", SQLITE_ShortColNames }, - { "count_changes", SQLITE_CountRows }, - { "empty_result_callbacks", SQLITE_NullCallback }, - { "legacy_file_format", SQLITE_LegacyFileFmt }, - { "fullfsync", SQLITE_FullFSync }, -#ifdef SQLITE_DEBUG - { "sql_trace", SQLITE_SqlTrace }, - { "vdbe_listing", SQLITE_VdbeListing }, - { "vdbe_trace", SQLITE_VdbeTrace }, -#endif -#ifndef SQLITE_OMIT_CHECK - { "ignore_check_constraints", SQLITE_IgnoreChecks }, -#endif - /* The following is VERY experimental */ - { "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode }, - { "omit_readlock", SQLITE_NoReadlock }, - - /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted - ** flag if there are any active statements. */ - { "read_uncommitted", SQLITE_ReadUncommitted }, - }; - int i; - const struct sPragmaType *p; - for(i=0, p=aPragma; izName)==0 ){ - sqlite3 *db = pParse->db; - Vdbe *v; - v = sqlite3GetVdbe(pParse); - if( v ){ - if( zRight==0 ){ - returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 ); - }else{ - if( getBoolean(zRight) ){ - db->flags |= p->mask; - }else{ - db->flags &= ~p->mask; - } - } - } - return 1; - } - } - return 0; -} -#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ - -/* -** Process a pragma statement. -** -** Pragmas are of this form: -** -** PRAGMA [database.]id [= value] -** -** The identifier might also be a string. The value is a string, and -** identifier, or a number. If minusFlag is true, then the value is -** a number that was preceded by a minus sign. -** -** If the left side is "database.id" then pId1 is the database name -** and pId2 is the id. If the left side is just "id" then pId1 is the -** id and pId2 is any empty string. -*/ -void sqlite3Pragma( - Parse *pParse, - Token *pId1, /* First part of [database.]id field */ - Token *pId2, /* Second part of [database.]id field, or NULL */ - Token *pValue, /* Token for , or NULL */ - int minusFlag /* True if a '-' sign preceded */ -){ - char *zLeft = 0; /* Nul-terminated UTF-8 string */ - char *zRight = 0; /* Nul-terminated UTF-8 string , or NULL */ - const char *zDb = 0; /* The database name */ - Token *pId; /* Pointer to token */ - int iDb; /* Database index for */ - sqlite3 *db = pParse->db; - Db *pDb; - Vdbe *v = sqlite3GetVdbe(pParse); - if( v==0 ) return; - - /* Interpret the [database.] part of the pragma statement. iDb is the - ** index of the database this pragma is being applied to in db.aDb[]. */ - iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); - if( iDb<0 ) return; - pDb = &db->aDb[iDb]; - - /* If the temp database has been explicitly named as part of the - ** pragma, make sure it is open. - */ - if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){ - return; - } - - zLeft = sqlite3NameFromToken(db, pId); - if( !zLeft ) return; - if( minusFlag ){ - zRight = sqlite3MPrintf(db, "-%T", pValue); - }else{ - zRight = sqlite3NameFromToken(db, pValue); - } - - zDb = ((iDb>0)?pDb->zName:0); - if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ - goto pragma_out; - } - -#ifndef SQLITE_OMIT_PAGER_PRAGMAS - /* - ** PRAGMA [database.]default_cache_size - ** PRAGMA [database.]default_cache_size=N - ** - ** The first form reports the current persistent setting for the - ** page cache size. The value returned is the maximum number of - ** pages in the page cache. The second form sets both the current - ** page cache size value and the persistent page cache size value - ** stored in the database file. - ** - ** The default cache size is stored in meta-value 2 of page 1 of the - ** database file. The cache size is actually the absolute value of - ** this memory location. The sign of meta-value 2 determines the - ** synchronous setting. A negative value means synchronous is off - ** and a positive value means synchronous is on. - */ - if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ - static const VdbeOpList getCacheSize[] = { - { OP_ReadCookie, 0, 2, 0}, /* 0 */ - { OP_AbsValue, 0, 0, 0}, - { OP_Dup, 0, 0, 0}, - { OP_Integer, 0, 0, 0}, - { OP_Ne, 0, 6, 0}, - { OP_Integer, 0, 0, 0}, /* 5 */ - { OP_Callback, 1, 0, 0}, - }; - int addr; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - sqlite3VdbeUsesBtree(v, iDb); - if( !zRight ){ - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P3_STATIC); - addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); - sqlite3VdbeChangeP1(v, addr, iDb); - sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE); - }else{ - int size = atoi(zRight); - if( size<0 ) size = -size; - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3VdbeAddOp(v, OP_Integer, size, 0); - sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2); - addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0); - sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3); - sqlite3VdbeAddOp(v, OP_Negative, 0, 0); - sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2); - pDb->pSchema->cache_size = size; - sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); - } - }else - - /* - ** PRAGMA [database.]page_size - ** PRAGMA [database.]page_size=N - ** - ** The first form reports the current setting for the - ** database page size in bytes. The second form sets the - ** database page size value. The value can only be set if - ** the database has not yet been created. - */ - if( sqlite3StrICmp(zLeft,"page_size")==0 ){ - Btree *pBt = pDb->pBt; - if( !zRight ){ - int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0; - returnSingleInt(pParse, "page_size", size); - }else{ - /* Malloc may fail when setting the page-size, as there is an internal - ** buffer that the pager module resizes using sqlite3_realloc(). - */ - if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1) ){ - db->mallocFailed = 1; - } - } - }else - - /* - ** PRAGMA [database.]max_page_count - ** PRAGMA [database.]max_page_count=N - ** - ** The first form reports the current setting for the - ** maximum number of pages in the database file. The - ** second form attempts to change this setting. Both - ** forms return the current setting. - */ - if( sqlite3StrICmp(zLeft,"max_page_count")==0 ){ - Btree *pBt = pDb->pBt; - int newMax = 0; - if( zRight ){ - newMax = atoi(zRight); - } - if( pBt ){ - newMax = sqlite3BtreeMaxPageCount(pBt, newMax); - } - returnSingleInt(pParse, "max_page_count", newMax); - }else - - /* - ** PRAGMA [database.]locking_mode - ** PRAGMA [database.]locking_mode = (normal|exclusive) - */ - if( sqlite3StrICmp(zLeft,"locking_mode")==0 ){ - const char *zRet = "normal"; - int eMode = getLockingMode(zRight); - - if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){ - /* Simple "PRAGMA locking_mode;" statement. This is a query for - ** the current default locking mode (which may be different to - ** the locking-mode of the main database). - */ - eMode = db->dfltLockMode; - }else{ - Pager *pPager; - if( pId2->n==0 ){ - /* This indicates that no database name was specified as part - ** of the PRAGMA command. In this case the locking-mode must be - ** set on all attached databases, as well as the main db file. - ** - ** Also, the sqlite3.dfltLockMode variable is set so that - ** any subsequently attached databases also use the specified - ** locking mode. - */ - int ii; - assert(pDb==&db->aDb[0]); - for(ii=2; iinDb; ii++){ - pPager = sqlite3BtreePager(db->aDb[ii].pBt); - sqlite3PagerLockingMode(pPager, eMode); - } - db->dfltLockMode = eMode; - } - pPager = sqlite3BtreePager(pDb->pBt); - eMode = sqlite3PagerLockingMode(pPager, eMode); - } - - assert(eMode==PAGER_LOCKINGMODE_NORMAL||eMode==PAGER_LOCKINGMODE_EXCLUSIVE); - if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){ - zRet = "exclusive"; - } - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", P3_STATIC); - sqlite3VdbeOp3(v, OP_String8, 0, 0, zRet, 0); - sqlite3VdbeAddOp(v, OP_Callback, 1, 0); - }else -#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ - - /* - ** PRAGMA [database.]auto_vacuum - ** PRAGMA [database.]auto_vacuum=N - ** - ** Get or set the (boolean) value of the database 'auto-vacuum' parameter. - */ -#ifndef SQLITE_OMIT_AUTOVACUUM - if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){ - Btree *pBt = pDb->pBt; - if( sqlite3ReadSchema(pParse) ){ - goto pragma_out; - } - if( !zRight ){ - int auto_vacuum = - pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM; - returnSingleInt(pParse, "auto_vacuum", auto_vacuum); - }else{ - int eAuto = getAutoVacuum(zRight); - if( eAuto>=0 ){ - /* Call SetAutoVacuum() to set initialize the internal auto and - ** incr-vacuum flags. This is required in case this connection - ** creates the database file. It is important that it is created - ** as an auto-vacuum capable db. - */ - int rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); - if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ - /* When setting the auto_vacuum mode to either "full" or - ** "incremental", write the value of meta[6] in the database - ** file. Before writing to meta[6], check that meta[3] indicates - ** that this really is an auto-vacuum capable database. - */ - static const VdbeOpList setMeta6[] = { - { OP_Transaction, 0, 1, 0}, /* 0 */ - { OP_ReadCookie, 0, 3, 0}, /* 1 */ - { OP_If, 0, 0, 0}, /* 2 */ - { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ - { OP_Integer, 0, 0, 0}, /* 4 */ - { OP_SetCookie, 0, 6, 0}, /* 5 */ - }; - int iAddr; - iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6); - sqlite3VdbeChangeP1(v, iAddr, iDb); - sqlite3VdbeChangeP1(v, iAddr+1, iDb); - sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); - sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); - sqlite3VdbeChangeP1(v, iAddr+5, iDb); - sqlite3VdbeUsesBtree(v, iDb); - } - } - } - }else -#endif - - /* - ** PRAGMA [database.]incremental_vacuum(N) - ** - ** Do N steps of incremental vacuuming on a database. - */ -#ifndef SQLITE_OMIT_AUTOVACUUM - if( sqlite3StrICmp(zLeft,"incremental_vacuum")==0 ){ - int iLimit, addr; - if( sqlite3ReadSchema(pParse) ){ - goto pragma_out; - } - if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ - iLimit = 0x7fffffff; - } - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3VdbeAddOp(v, OP_MemInt, iLimit, 0); - addr = sqlite3VdbeAddOp(v, OP_IncrVacuum, iDb, 0); - sqlite3VdbeAddOp(v, OP_Callback, 0, 0); - sqlite3VdbeAddOp(v, OP_MemIncr, -1, 0); - sqlite3VdbeAddOp(v, OP_IfMemPos, 0, addr); - sqlite3VdbeJumpHere(v, addr); - }else -#endif - -#ifndef SQLITE_OMIT_PAGER_PRAGMAS - /* - ** PRAGMA [database.]cache_size - ** PRAGMA [database.]cache_size=N - ** - ** The first form reports the current local setting for the - ** page cache size. The local setting can be different from - ** the persistent cache size value that is stored in the database - ** file itself. The value returned is the maximum number of - ** pages in the page cache. The second form sets the local - ** page cache size value. It does not change the persistent - ** cache size stored on the disk so the cache size will revert - ** to its default value when the database is closed and reopened. - ** N should be a positive integer. - */ - if( sqlite3StrICmp(zLeft,"cache_size")==0 ){ - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - if( !zRight ){ - returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); - }else{ - int size = atoi(zRight); - if( size<0 ) size = -size; - pDb->pSchema->cache_size = size; - sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); - } - }else - - /* - ** PRAGMA temp_store - ** PRAGMA temp_store = "default"|"memory"|"file" - ** - ** Return or set the local value of the temp_store flag. Changing - ** the local value does not make changes to the disk file and the default - ** value will be restored the next time the database is opened. - ** - ** Note that it is possible for the library compile-time options to - ** override this setting - */ - if( sqlite3StrICmp(zLeft, "temp_store")==0 ){ - if( !zRight ){ - returnSingleInt(pParse, "temp_store", db->temp_store); - }else{ - changeTempStorage(pParse, zRight); - } - }else - - /* - ** PRAGMA temp_store_directory - ** PRAGMA temp_store_directory = ""|"directory_name" - ** - ** Return or set the local value of the temp_store_directory flag. Changing - ** the value sets a specific directory to be used for temporary files. - ** Setting to a null string reverts to the default temporary directory search. - ** If temporary directory is changed, then invalidateTempStorage. - ** - */ - if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){ - if( !zRight ){ - if( sqlite3_temp_directory ){ - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, - "temp_store_directory", P3_STATIC); - sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0); - sqlite3VdbeAddOp(v, OP_Callback, 1, 0); - } - }else{ - if( zRight[0] - && !sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE) - ){ - sqlite3ErrorMsg(pParse, "not a writable directory"); - goto pragma_out; - } - if( TEMP_STORE==0 - || (TEMP_STORE==1 && db->temp_store<=1) - || (TEMP_STORE==2 && db->temp_store==1) - ){ - invalidateTempStorage(pParse); - } - sqlite3_free(sqlite3_temp_directory); - if( zRight[0] ){ - sqlite3_temp_directory = zRight; - zRight = 0; - }else{ - sqlite3_temp_directory = 0; - } - } - }else - - /* - ** PRAGMA [database.]synchronous - ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL - ** - ** Return or set the local value of the synchronous flag. Changing - ** the local value does not make changes to the disk file and the - ** default value will be restored the next time the database is - ** opened. - */ - if( sqlite3StrICmp(zLeft,"synchronous")==0 ){ - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - if( !zRight ){ - returnSingleInt(pParse, "synchronous", pDb->safety_level-1); - }else{ - if( !db->autoCommit ){ - sqlite3ErrorMsg(pParse, - "Safety level may not be changed inside a transaction"); - }else{ - pDb->safety_level = getSafetyLevel(zRight)+1; - } - } - }else -#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ - -#ifndef SQLITE_OMIT_FLAG_PRAGMAS - if( flagPragma(pParse, zLeft, zRight) ){ - /* The flagPragma() subroutine also generates any necessary code - ** there is nothing more to do here */ - }else -#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ - -#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS - /* - ** PRAGMA table_info(
) - ** - ** Return a single row for each column of the named table. The columns of - ** the returned data set are: - ** - ** cid: Column id (numbered from left to right, starting at 0) - ** name: Column name - ** type: Column declaration type. - ** notnull: True if 'NOT NULL' is part of column declaration - ** dflt_value: The default value for the column, if any. - */ - if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){ - Table *pTab; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - pTab = sqlite3FindTable(db, zRight, zDb); - if( pTab ){ - int i; - int nHidden = 0; - Column *pCol; - sqlite3VdbeSetNumCols(v, 6); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", P3_STATIC); - sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC); - sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", P3_STATIC); - sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", P3_STATIC); - sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", P3_STATIC); - sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P3_STATIC); - sqlite3ViewGetColumnNames(pParse, pTab); - for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ - const Token *pDflt; - if( IsHiddenColumn(pCol) ){ - nHidden++; - continue; - } - sqlite3VdbeAddOp(v, OP_Integer, i-nHidden, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zName, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, - pCol->zType ? pCol->zType : "", 0); - sqlite3VdbeAddOp(v, OP_Integer, pCol->notNull, 0); - if( pCol->pDflt && (pDflt = &pCol->pDflt->span)->z ){ - sqlite3VdbeOp3(v, OP_String8, 0, 0, (char*)pDflt->z, pDflt->n); - }else{ - sqlite3VdbeAddOp(v, OP_Null, 0, 0); - } - sqlite3VdbeAddOp(v, OP_Integer, pCol->isPrimKey, 0); - sqlite3VdbeAddOp(v, OP_Callback, 6, 0); - } - } - }else - - if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){ - Index *pIdx; - Table *pTab; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - pIdx = sqlite3FindIndex(db, zRight, zDb); - if( pIdx ){ - int i; - pTab = pIdx->pTable; - sqlite3VdbeSetNumCols(v, 3); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", P3_STATIC); - sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", P3_STATIC); - sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", P3_STATIC); - for(i=0; inColumn; i++){ - int cnum = pIdx->aiColumn[i]; - sqlite3VdbeAddOp(v, OP_Integer, i, 0); - sqlite3VdbeAddOp(v, OP_Integer, cnum, 0); - assert( pTab->nCol>cnum ); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[cnum].zName, 0); - sqlite3VdbeAddOp(v, OP_Callback, 3, 0); - } - } - }else - - if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){ - Index *pIdx; - Table *pTab; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - pTab = sqlite3FindTable(db, zRight, zDb); - if( pTab ){ - v = sqlite3GetVdbe(pParse); - pIdx = pTab->pIndex; - if( pIdx ){ - int i = 0; - sqlite3VdbeSetNumCols(v, 3); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC); - sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC); - sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", P3_STATIC); - while(pIdx){ - sqlite3VdbeAddOp(v, OP_Integer, i, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0); - sqlite3VdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0); - sqlite3VdbeAddOp(v, OP_Callback, 3, 0); - ++i; - pIdx = pIdx->pNext; - } - } - } - }else - - if( sqlite3StrICmp(zLeft, "database_list")==0 ){ - int i; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - sqlite3VdbeSetNumCols(v, 3); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC); - sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC); - sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", P3_STATIC); - for(i=0; inDb; i++){ - if( db->aDb[i].pBt==0 ) continue; - assert( db->aDb[i].zName!=0 ); - sqlite3VdbeAddOp(v, OP_Integer, i, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, - sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); - sqlite3VdbeAddOp(v, OP_Callback, 3, 0); - } - }else - - if( sqlite3StrICmp(zLeft, "collation_list")==0 ){ - int i = 0; - HashElem *p; - sqlite3VdbeSetNumCols(v, 2); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC); - sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC); - for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ - CollSeq *pColl = (CollSeq *)sqliteHashData(p); - sqlite3VdbeAddOp(v, OP_Integer, i++, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pColl->zName, 0); - sqlite3VdbeAddOp(v, OP_Callback, 2, 0); - } - }else -#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */ - -#ifndef SQLITE_OMIT_FOREIGN_KEY - if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){ - FKey *pFK; - Table *pTab; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - pTab = sqlite3FindTable(db, zRight, zDb); - if( pTab ){ - v = sqlite3GetVdbe(pParse); - pFK = pTab->pFKey; - if( pFK ){ - int i = 0; - sqlite3VdbeSetNumCols(v, 5); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", P3_STATIC); - sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", P3_STATIC); - sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", P3_STATIC); - sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", P3_STATIC); - sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", P3_STATIC); - while(pFK){ - int j; - for(j=0; jnCol; j++){ - char *zCol = pFK->aCol[j].zCol; - sqlite3VdbeAddOp(v, OP_Integer, i, 0); - sqlite3VdbeAddOp(v, OP_Integer, j, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->zTo, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, - pTab->aCol[pFK->aCol[j].iFrom].zName, 0); - sqlite3VdbeOp3(v, zCol ? OP_String8 : OP_Null, 0, 0, zCol, 0); - sqlite3VdbeAddOp(v, OP_Callback, 5, 0); - } - ++i; - pFK = pFK->pNextFrom; - } - } - } - }else -#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ - -#ifndef NDEBUG - if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ - if( zRight ){ - if( getBoolean(zRight) ){ - sqlite3ParserTrace(stderr, "parser: "); - }else{ - sqlite3ParserTrace(0, 0); - } - } - }else -#endif - - /* Reinstall the LIKE and GLOB functions. The variant of LIKE - ** used will be case sensitive or not depending on the RHS. - */ - if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){ - if( zRight ){ - sqlite3RegisterLikeFunctions(db, getBoolean(zRight)); - } - }else - -#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX -# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 -#endif - -#ifndef SQLITE_OMIT_INTEGRITY_CHECK - if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){ - int i, j, addr, mxErr; - - /* Code that appears at the end of the integrity check. If no error - ** messages have been generated, output OK. Otherwise output the - ** error message - */ - static const VdbeOpList endCode[] = { - { OP_MemLoad, 0, 0, 0}, - { OP_Integer, 0, 0, 0}, - { OP_Ne, 0, 0, 0}, /* 2 */ - { OP_String8, 0, 0, "ok"}, - { OP_Callback, 1, 0, 0}, - }; - - /* Initialize the VDBE program */ - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", P3_STATIC); - - /* Set the maximum error count */ - mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; - if( zRight ){ - mxErr = atoi(zRight); - if( mxErr<=0 ){ - mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; - } - } - sqlite3VdbeAddOp(v, OP_MemInt, mxErr, 0); - - /* Do an integrity check on each database file */ - for(i=0; inDb; i++){ - HashElem *x; - Hash *pTbls; - int cnt = 0; - - if( OMIT_TEMPDB && i==1 ) continue; - - sqlite3CodeVerifySchema(pParse, i); - addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0); - sqlite3VdbeAddOp(v, OP_Halt, 0, 0); - sqlite3VdbeJumpHere(v, addr); - - /* Do an integrity check of the B-Tree - */ - pTbls = &db->aDb[i].pSchema->tblHash; - for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ - Table *pTab = sqliteHashData(x); - Index *pIdx; - sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0); - cnt++; - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0); - cnt++; - } - } - if( cnt==0 ) continue; - sqlite3VdbeAddOp(v, OP_IntegrityCk, 0, i); - addr = sqlite3VdbeAddOp(v, OP_IsNull, -1, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, - sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), - P3_DYNAMIC); - sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_Concat, 0, 0); - sqlite3VdbeAddOp(v, OP_Callback, 1, 0); - sqlite3VdbeJumpHere(v, addr); - - /* Make sure all the indices are constructed correctly. - */ - for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ - Table *pTab = sqliteHashData(x); - Index *pIdx; - int loopTop; - - if( pTab->pIndex==0 ) continue; - addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0); - sqlite3VdbeAddOp(v, OP_Halt, 0, 0); - sqlite3VdbeJumpHere(v, addr); - sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead); - sqlite3VdbeAddOp(v, OP_MemInt, 0, 1); - loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0); - sqlite3VdbeAddOp(v, OP_MemIncr, 1, 1); - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - int jmp2; - static const VdbeOpList idxErr[] = { - { OP_MemIncr, -1, 0, 0}, - { OP_String8, 0, 0, "rowid "}, - { OP_Rowid, 1, 0, 0}, - { OP_String8, 0, 0, " missing from index "}, - { OP_String8, 0, 0, 0}, /* 4 */ - { OP_Concat, 2, 0, 0}, - { OP_Callback, 1, 0, 0}, - }; - sqlite3GenerateIndexKey(v, pIdx, 1); - jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0); - addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); - sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC); - sqlite3VdbeJumpHere(v, jmp2); - } - sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1); - sqlite3VdbeJumpHere(v, loopTop); - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - static const VdbeOpList cntIdx[] = { - { OP_MemInt, 0, 2, 0}, - { OP_Rewind, 0, 0, 0}, /* 1 */ - { OP_MemIncr, 1, 2, 0}, - { OP_Next, 0, 0, 0}, /* 3 */ - { OP_MemLoad, 1, 0, 0}, - { OP_MemLoad, 2, 0, 0}, - { OP_Eq, 0, 0, 0}, /* 6 */ - { OP_MemIncr, -1, 0, 0}, - { OP_String8, 0, 0, "wrong # of entries in index "}, - { OP_String8, 0, 0, 0}, /* 9 */ - { OP_Concat, 0, 0, 0}, - { OP_Callback, 1, 0, 0}, - }; - if( pIdx->tnum==0 ) continue; - addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0); - sqlite3VdbeAddOp(v, OP_Halt, 0, 0); - sqlite3VdbeJumpHere(v, addr); - addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx); - sqlite3VdbeChangeP1(v, addr+1, j+2); - sqlite3VdbeChangeP2(v, addr+1, addr+4); - sqlite3VdbeChangeP1(v, addr+3, j+2); - sqlite3VdbeChangeP2(v, addr+3, addr+2); - sqlite3VdbeJumpHere(v, addr+6); - sqlite3VdbeChangeP3(v, addr+9, pIdx->zName, P3_STATIC); - } - } - } - addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); - sqlite3VdbeChangeP1(v, addr+1, mxErr); - sqlite3VdbeJumpHere(v, addr+2); - }else -#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -#ifndef SQLITE_OMIT_UTF16 - /* - ** PRAGMA encoding - ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be" - ** - ** In it's first form, this pragma returns the encoding of the main - ** database. If the database is not initialized, it is initialized now. - ** - ** The second form of this pragma is a no-op if the main database file - ** has not already been initialized. In this case it sets the default - ** encoding that will be used for the main database file if a new file - ** is created. If an existing main database file is opened, then the - ** default text encoding for the existing database is used. - ** - ** In all cases new databases created using the ATTACH command are - ** created to use the same default text encoding as the main database. If - ** the main database has not been initialized and/or created when ATTACH - ** is executed, this is done before the ATTACH operation. - ** - ** In the second form this pragma sets the text encoding to be used in - ** new database files created using this database handle. It is only - ** useful if invoked immediately after the main database i - */ - if( sqlite3StrICmp(zLeft, "encoding")==0 ){ - static const struct EncName { - char *zName; - u8 enc; - } encnames[] = { - { "UTF-8", SQLITE_UTF8 }, - { "UTF8", SQLITE_UTF8 }, - { "UTF-16le", SQLITE_UTF16LE }, - { "UTF16le", SQLITE_UTF16LE }, - { "UTF-16be", SQLITE_UTF16BE }, - { "UTF16be", SQLITE_UTF16BE }, - { "UTF-16", 0 }, /* SQLITE_UTF16NATIVE */ - { "UTF16", 0 }, /* SQLITE_UTF16NATIVE */ - { 0, 0 } - }; - const struct EncName *pEnc; - if( !zRight ){ /* "PRAGMA encoding" */ - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", P3_STATIC); - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ - if( pEnc->enc==ENC(pParse->db) ){ - sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC); - break; - } - } - sqlite3VdbeAddOp(v, OP_Callback, 1, 0); - }else{ /* "PRAGMA encoding = XXX" */ - /* Only change the value of sqlite.enc if the database handle is not - ** initialized. If the main database exists, the new sqlite.enc value - ** will be overwritten when the schema is next loaded. If it does not - ** already exists, it will be created to use the new encoding value. - */ - if( - !(DbHasProperty(db, 0, DB_SchemaLoaded)) || - DbHasProperty(db, 0, DB_Empty) - ){ - for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ - if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ - ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE; - break; - } - } - if( !pEnc->zName ){ - sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight); - } - } - } - }else -#endif /* SQLITE_OMIT_UTF16 */ - -#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS - /* - ** PRAGMA [database.]schema_version - ** PRAGMA [database.]schema_version = - ** - ** PRAGMA [database.]user_version - ** PRAGMA [database.]user_version = - ** - ** The pragma's schema_version and user_version are used to set or get - ** the value of the schema-version and user-version, respectively. Both - ** the schema-version and the user-version are 32-bit signed integers - ** stored in the database header. - ** - ** The schema-cookie is usually only manipulated internally by SQLite. It - ** is incremented by SQLite whenever the database schema is modified (by - ** creating or dropping a table or index). The schema version is used by - ** SQLite each time a query is executed to ensure that the internal cache - ** of the schema used when compiling the SQL query matches the schema of - ** the database against which the compiled query is actually executed. - ** Subverting this mechanism by using "PRAGMA schema_version" to modify - ** the schema-version is potentially dangerous and may lead to program - ** crashes or database corruption. Use with caution! - ** - ** The user-version is not used internally by SQLite. It may be used by - ** applications for any purpose. - */ - if( sqlite3StrICmp(zLeft, "schema_version")==0 - || sqlite3StrICmp(zLeft, "user_version")==0 - || sqlite3StrICmp(zLeft, "freelist_count")==0 - ){ - - int iCookie; /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */ - sqlite3VdbeUsesBtree(v, iDb); - switch( zLeft[0] ){ - case 's': case 'S': - iCookie = 0; - break; - case 'f': case 'F': - iCookie = 1; - iDb = (-1*(iDb+1)); - assert(iDb<=0); - break; - default: - iCookie = 5; - break; - } - - if( zRight && iDb>=0 ){ - /* Write the specified cookie value */ - static const VdbeOpList setCookie[] = { - { OP_Transaction, 0, 1, 0}, /* 0 */ - { OP_Integer, 0, 0, 0}, /* 1 */ - { OP_SetCookie, 0, 0, 0}, /* 2 */ - }; - int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie); - sqlite3VdbeChangeP1(v, addr, iDb); - sqlite3VdbeChangeP1(v, addr+1, atoi(zRight)); - sqlite3VdbeChangeP1(v, addr+2, iDb); - sqlite3VdbeChangeP2(v, addr+2, iCookie); - }else{ - /* Read the specified cookie value */ - static const VdbeOpList readCookie[] = { - { OP_ReadCookie, 0, 0, 0}, /* 0 */ - { OP_Callback, 1, 0, 0} - }; - int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie); - sqlite3VdbeChangeP1(v, addr, iDb); - sqlite3VdbeChangeP2(v, addr, iCookie); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, P3_TRANSIENT); - } - }else -#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ - -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - /* - ** Report the current state of file logs for all databases - */ - if( sqlite3StrICmp(zLeft, "lock_status")==0 ){ - static const char *const azLockName[] = { - "unlocked", "shared", "reserved", "pending", "exclusive" - }; - int i; - Vdbe *v = sqlite3GetVdbe(pParse); - sqlite3VdbeSetNumCols(v, 2); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", P3_STATIC); - sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", P3_STATIC); - for(i=0; inDb; i++){ - Btree *pBt; - Pager *pPager; - const char *zState = "unknown"; - int j; - if( db->aDb[i].zName==0 ) continue; - sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, P3_STATIC); - pBt = db->aDb[i].pBt; - if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){ - zState = "closed"; - }else if( sqlite3_file_control(db, db->aDb[i].zName, - SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ - zState = azLockName[j]; - } - sqlite3VdbeOp3(v, OP_String8, 0, 0, zState, P3_STATIC); - sqlite3VdbeAddOp(v, OP_Callback, 2, 0); - } - }else -#endif - -#ifdef SQLITE_SSE - /* - ** Check to see if the sqlite_statements table exists. Create it - ** if it does not. - */ - if( sqlite3StrICmp(zLeft, "create_sqlite_statement_table")==0 ){ - extern int sqlite3CreateStatementsTable(Parse*); - sqlite3CreateStatementsTable(pParse); - }else -#endif - -#if SQLITE_HAS_CODEC - if( sqlite3StrICmp(zLeft, "key")==0 ){ - sqlite3_key(db, zRight, strlen(zRight)); - }else -#endif -#if SQLITE_HAS_CODEC || defined(SQLITE_ENABLE_CEROD) - if( sqlite3StrICmp(zLeft, "activate_extensions")==0 ){ -#if SQLITE_HAS_CODEC - if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){ - extern void sqlite3_activate_see(const char*); - sqlite3_activate_see(&zRight[4]); - } -#endif -#ifdef SQLITE_ENABLE_CEROD - if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){ - extern void sqlite3_activate_cerod(const char*); - sqlite3_activate_cerod(&zRight[6]); - } -#endif - } -#endif - - {} - - if( v ){ - /* Code an OP_Expire at the end of each PRAGMA program to cause - ** the VDBE implementing the pragma to expire. Most (all?) pragmas - ** are only valid for a single execution. - */ - sqlite3VdbeAddOp(v, OP_Expire, 1, 0); - - /* - ** Reset the safety level, in case the fullfsync flag or synchronous - ** setting changed. - */ -#ifndef SQLITE_OMIT_PAGER_PRAGMAS - if( db->autoCommit ){ - sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level, - (db->flags&SQLITE_FullFSync)!=0); - } -#endif - } -pragma_out: - sqlite3_free(zLeft); - sqlite3_free(zRight); -} - -#endif /* SQLITE_OMIT_PRAGMA || SQLITE_OMIT_PARSER */ diff --git a/extensions/sqlite/sqlite-source/prepare.c b/extensions/sqlite/sqlite-source/prepare.c deleted file mode 100644 index 6a548aa4..00000000 --- a/extensions/sqlite/sqlite-source/prepare.c +++ /dev/null @@ -1,742 +0,0 @@ -/* -** 2005 May 25 -** -** 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 file contains the implementation of the sqlite3_prepare() -** interface, and routines that contribute to loading the database schema -** from disk. -** -** $Id$ -*/ -#include "sqliteInt.h" -#include - -/* -** Fill the InitData structure with an error message that indicates -** that the database is corrupt. -*/ -static void corruptSchema(InitData *pData, const char *zExtra){ - if( !pData->db->mallocFailed ){ - sqlite3SetString(pData->pzErrMsg, "malformed database schema", - zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0); - } - pData->rc = SQLITE_CORRUPT; -} - -/* -** This is the callback routine for the code that initializes the -** database. See sqlite3Init() below for additional information. -** This routine is also called from the OP_ParseSchema opcode of the VDBE. -** -** Each callback contains the following information: -** -** argv[0] = name of thing being created -** argv[1] = root page number for table or index. 0 for trigger or view. -** argv[2] = SQL text for the CREATE statement. -** -*/ -int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ - InitData *pData = (InitData*)pInit; - sqlite3 *db = pData->db; - int iDb = pData->iDb; - - assert( sqlite3_mutex_held(db->mutex) ); - pData->rc = SQLITE_OK; - DbClearProperty(db, iDb, DB_Empty); - if( db->mallocFailed ){ - corruptSchema(pData, 0); - return SQLITE_NOMEM; - } - - assert( argc==3 ); - if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ - if( argv[1]==0 ){ - corruptSchema(pData, 0); - return 1; - } - assert( iDb>=0 && iDbnDb ); - if( argv[2] && argv[2][0] ){ - /* Call the parser to process a CREATE TABLE, INDEX or VIEW. - ** But because db->init.busy is set to 1, no VDBE code is generated - ** or executed. All the parser does is build the internal data - ** structures that describe the table, index, or view. - */ - char *zErr; - int rc; - assert( db->init.busy ); - db->init.iDb = iDb; - db->init.newTnum = atoi(argv[1]); - rc = sqlite3_exec(db, argv[2], 0, 0, &zErr); - db->init.iDb = 0; - assert( rc!=SQLITE_OK || zErr==0 ); - if( SQLITE_OK!=rc ){ - pData->rc = rc; - if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; - }else if( rc!=SQLITE_INTERRUPT ){ - corruptSchema(pData, zErr); - } - sqlite3_free(zErr); - return 1; - } - }else{ - /* If the SQL column is blank it means this is an index that - ** was created to be the PRIMARY KEY or to fulfill a UNIQUE - ** constraint for a CREATE TABLE. The index should have already - ** been created when we processed the CREATE TABLE. All we have - ** to do here is record the root page number for that index. - */ - Index *pIndex; - pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName); - if( pIndex==0 || pIndex->tnum!=0 ){ - /* This can occur if there exists an index on a TEMP table which - ** has the same name as another index on a permanent index. Since - ** the permanent table is hidden by the TEMP table, we can also - ** safely ignore the index on the permanent table. - */ - /* Do Nothing */; - }else{ - pIndex->tnum = atoi(argv[1]); - } - } - return 0; -} - -/* -** Attempt to read the database schema and initialize internal -** data structures for a single database file. The index of the -** database file is given by iDb. iDb==0 is used for the main -** database. iDb==1 should never be used. iDb>=2 is used for -** auxiliary databases. Return one of the SQLITE_ error codes to -** indicate success or failure. -*/ -static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ - int rc; - BtCursor *curMain; - int size; - Table *pTab; - Db *pDb; - char const *azArg[4]; - int meta[10]; - InitData initData; - char const *zMasterSchema; - char const *zMasterName = SCHEMA_TABLE(iDb); - - /* - ** The master database table has a structure like this - */ - static const char master_schema[] = - "CREATE TABLE sqlite_master(\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")" - ; -#ifndef SQLITE_OMIT_TEMPDB - static const char temp_master_schema[] = - "CREATE TEMP TABLE sqlite_temp_master(\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")" - ; -#else - #define temp_master_schema 0 -#endif - - assert( iDb>=0 && iDbnDb ); - assert( db->aDb[iDb].pSchema ); - assert( sqlite3_mutex_held(db->mutex) ); - - /* zMasterSchema and zInitScript are set to point at the master schema - ** and initialisation script appropriate for the database being - ** initialised. zMasterName is the name of the master table. - */ - if( !OMIT_TEMPDB && iDb==1 ){ - zMasterSchema = temp_master_schema; - }else{ - zMasterSchema = master_schema; - } - zMasterName = SCHEMA_TABLE(iDb); - - /* Construct the schema tables. */ - sqlite3SafetyOff(db); - azArg[0] = zMasterName; - azArg[1] = "1"; - azArg[2] = zMasterSchema; - azArg[3] = 0; - initData.db = db; - initData.iDb = iDb; - initData.pzErrMsg = pzErrMsg; - rc = sqlite3InitCallback(&initData, 3, (char **)azArg, 0); - if( rc ){ - sqlite3SafetyOn(db); - rc = initData.rc; - goto error_out; - } - pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); - if( pTab ){ - pTab->readOnly = 1; - } - sqlite3SafetyOn(db); - - /* Create a cursor to hold the database open - */ - pDb = &db->aDb[iDb]; - if( pDb->pBt==0 ){ - if( !OMIT_TEMPDB && iDb==1 ){ - DbSetProperty(db, 1, DB_SchemaLoaded); - } - return SQLITE_OK; - } - sqlite3BtreeEnter(pDb->pBt); - rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, 0, &curMain); - if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ - sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); - sqlite3BtreeLeave(pDb->pBt); - goto error_out; - } - - /* Get the database meta information. - ** - ** Meta values are as follows: - ** meta[0] Schema cookie. Changes with each schema change. - ** meta[1] File format of schema layer. - ** meta[2] Size of the page cache. - ** meta[3] Use freelist if 0. Autovacuum if greater than zero. - ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE - ** meta[5] The user cookie. Used by the application. - ** meta[6] Incremental-vacuum flag. - ** meta[7] - ** meta[8] - ** meta[9] - ** - ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to - ** the possible values of meta[4]. - */ - if( rc==SQLITE_OK ){ - int i; - for(i=0; rc==SQLITE_OK && ipBt, i+1, (u32 *)&meta[i]); - } - if( rc ){ - sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); - sqlite3BtreeCloseCursor(curMain); - sqlite3BtreeLeave(pDb->pBt); - goto error_out; - } - }else{ - memset(meta, 0, sizeof(meta)); - } - pDb->pSchema->schema_cookie = meta[0]; - - /* If opening a non-empty database, check the text encoding. For the - ** main database, set sqlite3.enc to the encoding of the main database. - ** For an attached db, it is an error if the encoding is not the same - ** as sqlite3.enc. - */ - if( meta[4] ){ /* text encoding */ - if( iDb==0 ){ - /* If opening the main database, set ENC(db). */ - ENC(db) = (u8)meta[4]; - db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0); - }else{ - /* If opening an attached database, the encoding much match ENC(db) */ - if( meta[4]!=ENC(db) ){ - sqlite3BtreeCloseCursor(curMain); - sqlite3SetString(pzErrMsg, "attached databases must use the same" - " text encoding as main database", (char*)0); - sqlite3BtreeLeave(pDb->pBt); - return SQLITE_ERROR; - } - } - }else{ - DbSetProperty(db, iDb, DB_Empty); - } - pDb->pSchema->enc = ENC(db); - - size = meta[2]; - if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } - pDb->pSchema->cache_size = size; - sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); - - /* - ** file_format==1 Version 3.0.0. - ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN - ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults - ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants - */ - pDb->pSchema->file_format = meta[1]; - if( pDb->pSchema->file_format==0 ){ - pDb->pSchema->file_format = 1; - } - if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){ - sqlite3BtreeCloseCursor(curMain); - sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0); - sqlite3BtreeLeave(pDb->pBt); - return SQLITE_ERROR; - } - - - /* Read the schema information out of the schema tables - */ - assert( db->init.busy ); - if( rc==SQLITE_EMPTY ){ - /* For an empty database, there is nothing to read */ - rc = SQLITE_OK; - }else{ - char *zSql; - zSql = sqlite3MPrintf(db, - "SELECT name, rootpage, sql FROM '%q'.%s", - db->aDb[iDb].zName, zMasterName); - sqlite3SafetyOff(db); - rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); - if( rc==SQLITE_ABORT ) rc = initData.rc; - sqlite3SafetyOn(db); - sqlite3_free(zSql); -#ifndef SQLITE_OMIT_ANALYZE - if( rc==SQLITE_OK ){ - sqlite3AnalysisLoad(db, iDb); - } -#endif - sqlite3BtreeCloseCursor(curMain); - } - if( db->mallocFailed ){ - /* sqlite3SetString(pzErrMsg, "out of memory", (char*)0); */ - rc = SQLITE_NOMEM; - sqlite3ResetInternalSchema(db, 0); - } - if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){ - /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider - ** the schema loaded, even if errors occured. In this situation the - ** current sqlite3_prepare() operation will fail, but the following one - ** will attempt to compile the supplied statement against whatever subset - ** of the schema was loaded before the error occured. The primary - ** purpose of this is to allow access to the sqlite_master table - ** even when it's contents have been corrupted. - */ - DbSetProperty(db, iDb, DB_SchemaLoaded); - rc = SQLITE_OK; - } - sqlite3BtreeLeave(pDb->pBt); - -error_out: - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - db->mallocFailed = 1; - } - return rc; -} - -/* -** Initialize all database files - the main database file, the file -** used to store temporary tables, and any additional database files -** created using ATTACH statements. Return a success code. If an -** error occurs, write an error message into *pzErrMsg. -** -** After a database is initialized, the DB_SchemaLoaded bit is set -** bit is set in the flags field of the Db structure. If the database -** file was of zero-length, then the DB_Empty flag is also set. -*/ -int sqlite3Init(sqlite3 *db, char **pzErrMsg){ - int i, rc; - int commit_internal = !(db->flags&SQLITE_InternChanges); - - assert( sqlite3_mutex_held(db->mutex) ); - if( db->init.busy ) return SQLITE_OK; - rc = SQLITE_OK; - db->init.busy = 1; - for(i=0; rc==SQLITE_OK && inDb; i++){ - if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue; - rc = sqlite3InitOne(db, i, pzErrMsg); - if( rc ){ - sqlite3ResetInternalSchema(db, i); - } - } - - /* Once all the other databases have been initialised, load the schema - ** for the TEMP database. This is loaded last, as the TEMP database - ** schema may contain references to objects in other databases. - */ -#ifndef SQLITE_OMIT_TEMPDB - if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ - rc = sqlite3InitOne(db, 1, pzErrMsg); - if( rc ){ - sqlite3ResetInternalSchema(db, 1); - } - } -#endif - - db->init.busy = 0; - if( rc==SQLITE_OK && commit_internal ){ - sqlite3CommitInternalChanges(db); - } - - return rc; -} - -/* -** This routine is a no-op if the database schema is already initialised. -** Otherwise, the schema is loaded. An error code is returned. -*/ -int sqlite3ReadSchema(Parse *pParse){ - int rc = SQLITE_OK; - sqlite3 *db = pParse->db; - assert( sqlite3_mutex_held(db->mutex) ); - if( !db->init.busy ){ - rc = sqlite3Init(db, &pParse->zErrMsg); - } - if( rc!=SQLITE_OK ){ - pParse->rc = rc; - pParse->nErr++; - } - return rc; -} - - -/* -** Check schema cookies in all databases. If any cookie is out -** of date, return 0. If all schema cookies are current, return 1. -*/ -static int schemaIsValid(sqlite3 *db){ - int iDb; - int rc; - BtCursor *curTemp; - int cookie; - int allOk = 1; - - assert( sqlite3_mutex_held(db->mutex) ); - for(iDb=0; allOk && iDbnDb; iDb++){ - Btree *pBt; - pBt = db->aDb[iDb].pBt; - if( pBt==0 ) continue; - rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie); - if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){ - allOk = 0; - } - sqlite3BtreeCloseCursor(curTemp); - } - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - db->mallocFailed = 1; - } - } - return allOk; -} - -/* -** Convert a schema pointer into the iDb index that indicates -** which database file in db->aDb[] the schema refers to. -** -** If the same database is attached more than once, the first -** attached database is returned. -*/ -int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ - int i = -1000000; - - /* If pSchema is NULL, then return -1000000. This happens when code in - ** expr.c is trying to resolve a reference to a transient table (i.e. one - ** created by a sub-select). In this case the return value of this - ** function should never be used. - ** - ** We return -1000000 instead of the more usual -1 simply because using - ** -1000000 as incorrectly using -1000000 index into db->aDb[] is much - ** more likely to cause a segfault than -1 (of course there are assert() - ** statements too, but it never hurts to play the odds). - */ - assert( sqlite3_mutex_held(db->mutex) ); - if( pSchema ){ - for(i=0; inDb; i++){ - if( db->aDb[i].pSchema==pSchema ){ - break; - } - } - assert( i>=0 &&i>=0 && inDb ); - } - return i; -} - -/* -** Compile the UTF-8 encoded SQL statement zSql into a statement handle. -*/ -int sqlite3Prepare( - sqlite3 *db, /* Database handle. */ - const char *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const char **pzTail /* OUT: End of parsed string */ -){ - Parse sParse; - char *zErrMsg = 0; - int rc = SQLITE_OK; - int i; - - assert( ppStmt ); - *ppStmt = 0; - if( sqlite3SafetyOn(db) ){ - return SQLITE_MISUSE; - } - assert( !db->mallocFailed ); - assert( sqlite3_mutex_held(db->mutex) ); - - /* If any attached database schemas are locked, do not proceed with - ** compilation. Instead return SQLITE_LOCKED immediately. - */ - for(i=0; inDb; i++) { - Btree *pBt = db->aDb[i].pBt; - if( pBt ){ - int rc; - rc = sqlite3BtreeSchemaLocked(pBt); - if( rc ){ - const char *zDb = db->aDb[i].zName; - sqlite3Error(db, SQLITE_LOCKED, "database schema is locked: %s", zDb); - sqlite3SafetyOff(db); - return SQLITE_LOCKED; - } - } - } - - memset(&sParse, 0, sizeof(sParse)); - sParse.db = db; - if( nBytes>=0 && zSql[nBytes]!=0 ){ - char *zSqlCopy; - if( nBytes>SQLITE_MAX_SQL_LENGTH ){ - return SQLITE_TOOBIG; - } - zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); - if( zSqlCopy ){ - sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); - sqlite3_free(zSqlCopy); - } - sParse.zTail = &zSql[nBytes]; - }else{ - sqlite3RunParser(&sParse, zSql, &zErrMsg); - } - - if( db->mallocFailed ){ - sParse.rc = SQLITE_NOMEM; - } - if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; - if( sParse.checkSchema && !schemaIsValid(db) ){ - sParse.rc = SQLITE_SCHEMA; - } - if( sParse.rc==SQLITE_SCHEMA ){ - sqlite3ResetInternalSchema(db, 0); - } - if( db->mallocFailed ){ - sParse.rc = SQLITE_NOMEM; - } - if( pzTail ){ - *pzTail = sParse.zTail; - } - rc = sParse.rc; - -#ifndef SQLITE_OMIT_EXPLAIN - if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ - if( sParse.explain==2 ){ - sqlite3VdbeSetNumCols(sParse.pVdbe, 3); - sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", P3_STATIC); - }else{ - sqlite3VdbeSetNumCols(sParse.pVdbe, 5); - sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P3_STATIC); - } - } -#endif - - if( sqlite3SafetyOff(db) ){ - rc = SQLITE_MISUSE; - } - - if( saveSqlFlag ){ - sqlite3VdbeSetSql(sParse.pVdbe, zSql, sParse.zTail - zSql); - } - if( rc!=SQLITE_OK || db->mallocFailed ){ - sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe); - assert(!(*ppStmt)); - }else{ - *ppStmt = (sqlite3_stmt*)sParse.pVdbe; - } - - if( zErrMsg ){ - sqlite3Error(db, rc, "%s", zErrMsg); - sqlite3_free(zErrMsg); - }else{ - sqlite3Error(db, rc, 0); - } - - rc = sqlite3ApiExit(db, rc); - /* sqlite3ReleaseThreadData(); */ - assert( (rc&db->errMask)==rc ); - return rc; -} -static int sqlite3LockAndPrepare( - sqlite3 *db, /* Database handle. */ - const char *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const char **pzTail /* OUT: End of parsed string */ -){ - int rc; - if( sqlite3SafetyCheck(db) ){ - return SQLITE_MISUSE; - } - sqlite3_mutex_enter(db->mutex); - sqlite3BtreeEnterAll(db); - rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail); - sqlite3BtreeLeaveAll(db); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** Rerun the compilation of a statement after a schema change. -** Return true if the statement was recompiled successfully. -** Return false if there is an error of some kind. -*/ -int sqlite3Reprepare(Vdbe *p){ - int rc; - sqlite3_stmt *pNew; - const char *zSql; - sqlite3 *db; - - assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) ); - zSql = sqlite3VdbeGetSql(p); - if( zSql==0 ){ - return 0; - } - db = sqlite3VdbeDb(p); - assert( sqlite3_mutex_held(db->mutex) ); - rc = sqlite3LockAndPrepare(db, zSql, -1, 0, &pNew, 0); - if( rc ){ - assert( pNew==0 ); - return 0; - }else{ - assert( pNew!=0 ); - } - sqlite3VdbeSwap((Vdbe*)pNew, p); - sqlite3_transfer_bindings(pNew, (sqlite3_stmt*)p); - sqlite3VdbeResetStepResult((Vdbe*)pNew); - sqlite3VdbeFinalize((Vdbe*)pNew); - return 1; -} - - -/* -** Two versions of the official API. Legacy and new use. In the legacy -** version, the original SQL text is not saved in the prepared statement -** and so if a schema change occurs, SQLITE_SCHEMA is returned by -** sqlite3_step(). In the new version, the original SQL text is retained -** and the statement is automatically recompiled if an schema change -** occurs. -*/ -int sqlite3_prepare( - sqlite3 *db, /* Database handle. */ - const char *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const char **pzTail /* OUT: End of parsed string */ -){ - return sqlite3LockAndPrepare(db,zSql,nBytes,0,ppStmt,pzTail); -} -int sqlite3_prepare_v2( - sqlite3 *db, /* Database handle. */ - const char *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const char **pzTail /* OUT: End of parsed string */ -){ - return sqlite3LockAndPrepare(db,zSql,nBytes,1,ppStmt,pzTail); -} - - -#ifndef SQLITE_OMIT_UTF16 -/* -** Compile the UTF-16 encoded SQL statement zSql into a statement handle. -*/ -static int sqlite3Prepare16( - sqlite3 *db, /* Database handle. */ - const void *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const void **pzTail /* OUT: End of parsed string */ -){ - /* This function currently works by first transforming the UTF-16 - ** encoded string to UTF-8, then invoking sqlite3_prepare(). The - ** tricky bit is figuring out the pointer to return in *pzTail. - */ - char *zSql8; - const char *zTail8 = 0; - int rc = SQLITE_OK; - - if( sqlite3SafetyCheck(db) ){ - return SQLITE_MISUSE; - } - sqlite3_mutex_enter(db->mutex); - zSql8 = sqlite3Utf16to8(db, zSql, nBytes); - if( zSql8 ){ - rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, ppStmt, &zTail8); - } - - if( zTail8 && pzTail ){ - /* If sqlite3_prepare returns a tail pointer, we calculate the - ** equivalent pointer into the UTF-16 string by counting the unicode - ** characters between zSql8 and zTail8, and then returning a pointer - ** the same number of characters into the UTF-16 string. - */ - int chars_parsed = sqlite3Utf8CharLen(zSql8, zTail8-zSql8); - *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); - } - sqlite3_free(zSql8); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** Two versions of the official API. Legacy and new use. In the legacy -** version, the original SQL text is not saved in the prepared statement -** and so if a schema change occurs, SQLITE_SCHEMA is returned by -** sqlite3_step(). In the new version, the original SQL text is retained -** and the statement is automatically recompiled if an schema change -** occurs. -*/ -int sqlite3_prepare16( - sqlite3 *db, /* Database handle. */ - const void *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const void **pzTail /* OUT: End of parsed string */ -){ - return sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); -} -int sqlite3_prepare16_v2( - sqlite3 *db, /* Database handle. */ - const void *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const void **pzTail /* OUT: End of parsed string */ -){ - return sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail); -} - -#endif /* SQLITE_OMIT_UTF16 */ diff --git a/extensions/sqlite/sqlite-source/printf.c b/extensions/sqlite/sqlite-source/printf.c deleted file mode 100644 index bea91e21..00000000 --- a/extensions/sqlite/sqlite-source/printf.c +++ /dev/null @@ -1,907 +0,0 @@ -/* -** The "printf" code that follows dates from the 1980's. It is in -** the public domain. The original comments are included here for -** completeness. They are very out-of-date but might be useful as -** an historical reference. Most of the "enhancements" have been backed -** out so that the functionality is now the same as standard printf(). -** -************************************************************************** -** -** The following modules is an enhanced replacement for the "printf" subroutines -** found in the standard C library. The following enhancements are -** supported: -** -** + Additional functions. The standard set of "printf" functions -** includes printf, fprintf, sprintf, vprintf, vfprintf, and -** vsprintf. This module adds the following: -** -** * snprintf -- Works like sprintf, but has an extra argument -** which is the size of the buffer written to. -** -** * mprintf -- Similar to sprintf. Writes output to memory -** obtained from malloc. -** -** * xprintf -- Calls a function to dispose of output. -** -** * nprintf -- No output, but returns the number of characters -** that would have been output by printf. -** -** * A v- version (ex: vsnprintf) of every function is also -** supplied. -** -** + A few extensions to the formatting notation are supported: -** -** * The "=" flag (similar to "-") causes the output to be -** be centered in the appropriately sized field. -** -** * The %b field outputs an integer in binary notation. -** -** * The %c field now accepts a precision. The character output -** is repeated by the number of times the precision specifies. -** -** * The %' field works like %c, but takes as its character the -** next character of the format string, instead of the next -** argument. For example, printf("%.78'-") prints 78 minus -** signs, the same as printf("%.78c",'-'). -** -** + When compiled using GCC on a SPARC, this version of printf is -** faster than the library printf for SUN OS 4.1. -** -** + All functions are fully reentrant. -** -*/ -#include "sqliteInt.h" -#include - -/* -** Conversion types fall into various categories as defined by the -** following enumeration. -*/ -#define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ -#define etFLOAT 2 /* Floating point. %f */ -#define etEXP 3 /* Exponentional notation. %e and %E */ -#define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */ -#define etSIZE 5 /* Return number of characters processed so far. %n */ -#define etSTRING 6 /* Strings. %s */ -#define etDYNSTRING 7 /* Dynamically allocated strings. %z */ -#define etPERCENT 8 /* Percent symbol. %% */ -#define etCHARX 9 /* Characters. %c */ -/* The rest are extensions, not normally found in printf() */ -#define etCHARLIT 10 /* Literal characters. %' */ -#define etSQLESCAPE 11 /* Strings with '\'' doubled. %q */ -#define etSQLESCAPE2 12 /* Strings with '\'' doubled and enclosed in '', - NULL pointers replaced by SQL NULL. %Q */ -#define etTOKEN 13 /* a pointer to a Token structure */ -#define etSRCLIST 14 /* a pointer to a SrcList */ -#define etPOINTER 15 /* The %p conversion */ -#define etSQLESCAPE3 16 /* %w -> Strings with '\"' doubled */ - - -/* -** An "etByte" is an 8-bit unsigned value. -*/ -typedef unsigned char etByte; - -/* -** Each builtin conversion character (ex: the 'd' in "%d") is described -** by an instance of the following structure -*/ -typedef struct et_info { /* Information about each format field */ - char fmttype; /* The format field code letter */ - etByte base; /* The base for radix conversion */ - etByte flags; /* One or more of FLAG_ constants below */ - etByte type; /* Conversion paradigm */ - etByte charset; /* Offset into aDigits[] of the digits string */ - etByte prefix; /* Offset into aPrefix[] of the prefix string */ -} et_info; - -/* -** Allowed values for et_info.flags -*/ -#define FLAG_SIGNED 1 /* True if the value to convert is signed */ -#define FLAG_INTERN 2 /* True if for internal use only */ -#define FLAG_STRING 4 /* Allow infinity precision */ - - -/* -** The following table is searched linearly, so it is good to put the -** most frequently used conversion types first. -*/ -static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; -static const char aPrefix[] = "-x0\000X0"; -static const et_info fmtinfo[] = { - { 'd', 10, 1, etRADIX, 0, 0 }, - { 's', 0, 4, etSTRING, 0, 0 }, - { 'g', 0, 1, etGENERIC, 30, 0 }, - { 'z', 0, 4, etDYNSTRING, 0, 0 }, - { 'q', 0, 4, etSQLESCAPE, 0, 0 }, - { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, - { 'w', 0, 4, etSQLESCAPE3, 0, 0 }, - { 'c', 0, 0, etCHARX, 0, 0 }, - { 'o', 8, 0, etRADIX, 0, 2 }, - { 'u', 10, 0, etRADIX, 0, 0 }, - { 'x', 16, 0, etRADIX, 16, 1 }, - { 'X', 16, 0, etRADIX, 0, 4 }, -#ifndef SQLITE_OMIT_FLOATING_POINT - { 'f', 0, 1, etFLOAT, 0, 0 }, - { 'e', 0, 1, etEXP, 30, 0 }, - { 'E', 0, 1, etEXP, 14, 0 }, - { 'G', 0, 1, etGENERIC, 14, 0 }, -#endif - { 'i', 10, 1, etRADIX, 0, 0 }, - { 'n', 0, 0, etSIZE, 0, 0 }, - { '%', 0, 0, etPERCENT, 0, 0 }, - { 'p', 16, 0, etPOINTER, 0, 1 }, - { 'T', 0, 2, etTOKEN, 0, 0 }, - { 'S', 0, 2, etSRCLIST, 0, 0 }, -}; -#define etNINFO (sizeof(fmtinfo)/sizeof(fmtinfo[0])) - -/* -** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point -** conversions will work. -*/ -#ifndef SQLITE_OMIT_FLOATING_POINT -/* -** "*val" is a double such that 0.1 <= *val < 10.0 -** Return the ascii code for the leading digit of *val, then -** multiply "*val" by 10.0 to renormalize. -** -** Example: -** input: *val = 3.14159 -** output: *val = 1.4159 function return = '3' -** -** The counter *cnt is incremented each time. After counter exceeds -** 16 (the number of significant digits in a 64-bit float) '0' is -** always returned. -*/ -static int et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ - int digit; - LONGDOUBLE_TYPE d; - if( (*cnt)++ >= 16 ) return '0'; - digit = (int)*val; - d = digit; - digit += '0'; - *val = (*val - d)*10.0; - return digit; -} -#endif /* SQLITE_OMIT_FLOATING_POINT */ - -/* -** On machines with a small stack size, you can redefine the -** SQLITE_PRINT_BUF_SIZE to be less than 350. But beware - for -** smaller values some %f conversions may go into an infinite loop. -*/ -#ifndef SQLITE_PRINT_BUF_SIZE -# define SQLITE_PRINT_BUF_SIZE 350 -#endif -#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */ - -/* -** The root program. All variations call this core. -** -** INPUTS: -** func This is a pointer to a function taking three arguments -** 1. A pointer to anything. Same as the "arg" parameter. -** 2. A pointer to the list of characters to be output -** (Note, this list is NOT null terminated.) -** 3. An integer number of characters to be output. -** (Note: This number might be zero.) -** -** arg This is the pointer to anything which will be passed as the -** first argument to "func". Use it for whatever you like. -** -** fmt This is the format string, as in the usual print. -** -** ap This is a pointer to a list of arguments. Same as in -** vfprint. -** -** OUTPUTS: -** The return value is the total number of characters sent to -** the function "func". Returns -1 on a error. -** -** Note that the order in which automatic variables are declared below -** seems to make a big difference in determining how fast this beast -** will run. -*/ -static int vxprintf( - void (*func)(void*,const char*,int), /* Consumer of text */ - void *arg, /* First argument to the consumer */ - int useExtended, /* Allow extended %-conversions */ - const char *fmt, /* Format string */ - va_list ap /* arguments */ -){ - int c; /* Next character in the format string */ - char *bufpt; /* Pointer to the conversion buffer */ - int precision; /* Precision of the current field */ - int length; /* Length of the field */ - int idx; /* A general purpose loop counter */ - int count; /* Total number of characters output */ - int width; /* Width of the current field */ - etByte flag_leftjustify; /* True if "-" flag is present */ - etByte flag_plussign; /* True if "+" flag is present */ - etByte flag_blanksign; /* True if " " flag is present */ - etByte flag_alternateform; /* True if "#" flag is present */ - etByte flag_altform2; /* True if "!" flag is present */ - etByte flag_zeropad; /* True if field width constant starts with zero */ - etByte flag_long; /* True if "l" flag is present */ - etByte flag_longlong; /* True if the "ll" flag is present */ - etByte done; /* Loop termination flag */ - sqlite_uint64 longvalue; /* Value for integer types */ - LONGDOUBLE_TYPE realvalue; /* Value for real types */ - const et_info *infop; /* Pointer to the appropriate info structure */ - char buf[etBUFSIZE]; /* Conversion buffer */ - char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ - etByte errorflag = 0; /* True if an error is encountered */ - etByte xtype; /* Conversion paradigm */ - char *zExtra; /* Extra memory used for etTCLESCAPE conversions */ - static const char spaces[] = - " "; -#define etSPACESIZE (sizeof(spaces)-1) -#ifndef SQLITE_OMIT_FLOATING_POINT - int exp, e2; /* exponent of real numbers */ - double rounder; /* Used for rounding floating point values */ - etByte flag_dp; /* True if decimal point should be shown */ - etByte flag_rtz; /* True if trailing zeros should be removed */ - etByte flag_exp; /* True to force display of the exponent */ - int nsd; /* Number of significant digits returned */ -#endif - - func(arg,"",0); - count = length = 0; - bufpt = 0; - for(; (c=(*fmt))!=0; ++fmt){ - if( c!='%' ){ - int amt; - bufpt = (char *)fmt; - amt = 1; - while( (c=(*++fmt))!='%' && c!=0 ) amt++; - (*func)(arg,bufpt,amt); - count += amt; - if( c==0 ) break; - } - if( (c=(*++fmt))==0 ){ - errorflag = 1; - (*func)(arg,"%",1); - count++; - break; - } - /* Find out what flags are present */ - flag_leftjustify = flag_plussign = flag_blanksign = - flag_alternateform = flag_altform2 = flag_zeropad = 0; - done = 0; - do{ - switch( c ){ - case '-': flag_leftjustify = 1; break; - case '+': flag_plussign = 1; break; - case ' ': flag_blanksign = 1; break; - case '#': flag_alternateform = 1; break; - case '!': flag_altform2 = 1; break; - case '0': flag_zeropad = 1; break; - default: done = 1; break; - } - }while( !done && (c=(*++fmt))!=0 ); - /* Get the field width */ - width = 0; - if( c=='*' ){ - width = va_arg(ap,int); - if( width<0 ){ - flag_leftjustify = 1; - width = -width; - } - c = *++fmt; - }else{ - while( c>='0' && c<='9' ){ - width = width*10 + c - '0'; - c = *++fmt; - } - } - if( width > etBUFSIZE-10 ){ - width = etBUFSIZE-10; - } - /* Get the precision */ - if( c=='.' ){ - precision = 0; - c = *++fmt; - if( c=='*' ){ - precision = va_arg(ap,int); - if( precision<0 ) precision = -precision; - c = *++fmt; - }else{ - while( c>='0' && c<='9' ){ - precision = precision*10 + c - '0'; - c = *++fmt; - } - } - }else{ - precision = -1; - } - /* Get the conversion type modifier */ - if( c=='l' ){ - flag_long = 1; - c = *++fmt; - if( c=='l' ){ - flag_longlong = 1; - c = *++fmt; - }else{ - flag_longlong = 0; - } - }else{ - flag_long = flag_longlong = 0; - } - /* Fetch the info entry for the field */ - infop = 0; - for(idx=0; idxflags & FLAG_INTERN)==0 ){ - xtype = infop->type; - }else{ - return -1; - } - break; - } - } - zExtra = 0; - if( infop==0 ){ - return -1; - } - - - /* Limit the precision to prevent overflowing buf[] during conversion */ - if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){ - precision = etBUFSIZE-40; - } - - /* - ** At this point, variables are initialized as follows: - ** - ** flag_alternateform TRUE if a '#' is present. - ** flag_altform2 TRUE if a '!' is present. - ** flag_plussign TRUE if a '+' is present. - ** flag_leftjustify TRUE if a '-' is present or if the - ** field width was negative. - ** flag_zeropad TRUE if the width began with 0. - ** flag_long TRUE if the letter 'l' (ell) prefixed - ** the conversion character. - ** flag_longlong TRUE if the letter 'll' (ell ell) prefixed - ** the conversion character. - ** flag_blanksign TRUE if a ' ' is present. - ** width The specified field width. This is - ** always non-negative. Zero is the default. - ** precision The specified precision. The default - ** is -1. - ** xtype The class of the conversion. - ** infop Pointer to the appropriate info struct. - */ - switch( xtype ){ - case etPOINTER: - flag_longlong = sizeof(char*)==sizeof(i64); - flag_long = sizeof(char*)==sizeof(long int); - /* Fall through into the next case */ - case etRADIX: - if( infop->flags & FLAG_SIGNED ){ - i64 v; - if( flag_longlong ) v = va_arg(ap,i64); - else if( flag_long ) v = va_arg(ap,long int); - else v = va_arg(ap,int); - if( v<0 ){ - longvalue = -v; - prefix = '-'; - }else{ - longvalue = v; - if( flag_plussign ) prefix = '+'; - else if( flag_blanksign ) prefix = ' '; - else prefix = 0; - } - }else{ - if( flag_longlong ) longvalue = va_arg(ap,u64); - else if( flag_long ) longvalue = va_arg(ap,unsigned long int); - else longvalue = va_arg(ap,unsigned int); - prefix = 0; - } - if( longvalue==0 ) flag_alternateform = 0; - if( flag_zeropad && precisioncharset]; - base = infop->base; - do{ /* Convert to ascii */ - *(--bufpt) = cset[longvalue%base]; - longvalue = longvalue/base; - }while( longvalue>0 ); - } - length = &buf[etBUFSIZE-1]-bufpt; - for(idx=precision-length; idx>0; idx--){ - *(--bufpt) = '0'; /* Zero pad */ - } - if( prefix ) *(--bufpt) = prefix; /* Add sign */ - if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ - const char *pre; - char x; - pre = &aPrefix[infop->prefix]; - if( *bufpt!=pre[0] ){ - for(; (x=(*pre))!=0; pre++) *(--bufpt) = x; - } - } - length = &buf[etBUFSIZE-1]-bufpt; - break; - case etFLOAT: - case etEXP: - case etGENERIC: - realvalue = va_arg(ap,double); -#ifndef SQLITE_OMIT_FLOATING_POINT - if( precision<0 ) precision = 6; /* Set default precision */ - if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10; - if( realvalue<0.0 ){ - realvalue = -realvalue; - prefix = '-'; - }else{ - if( flag_plussign ) prefix = '+'; - else if( flag_blanksign ) prefix = ' '; - else prefix = 0; - } - if( xtype==etGENERIC && precision>0 ) precision--; -#if 0 - /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */ - for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1); -#else - /* It makes more sense to use 0.5 */ - for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){} -#endif - if( xtype==etFLOAT ) realvalue += rounder; - /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ - exp = 0; - if( sqlite3_isnan(realvalue) ){ - bufpt = "NaN"; - length = 3; - break; - } - if( realvalue>0.0 ){ - while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; } - while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; } - while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; } - while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; } - while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; } - if( exp>350 || exp<-350 ){ - if( prefix=='-' ){ - bufpt = "-Inf"; - }else if( prefix=='+' ){ - bufpt = "+Inf"; - }else{ - bufpt = "Inf"; - } - length = strlen(bufpt); - break; - } - } - bufpt = buf; - /* - ** If the field type is etGENERIC, then convert to either etEXP - ** or etFLOAT, as appropriate. - */ - flag_exp = xtype==etEXP; - if( xtype!=etFLOAT ){ - realvalue += rounder; - if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } - } - if( xtype==etGENERIC ){ - flag_rtz = !flag_alternateform; - if( exp<-4 || exp>precision ){ - xtype = etEXP; - }else{ - precision = precision - exp; - xtype = etFLOAT; - } - }else{ - flag_rtz = 0; - } - if( xtype==etEXP ){ - e2 = 0; - }else{ - e2 = exp; - } - nsd = 0; - flag_dp = (precision>0) | flag_alternateform | flag_altform2; - /* The sign in front of the number */ - if( prefix ){ - *(bufpt++) = prefix; - } - /* Digits prior to the decimal point */ - if( e2<0 ){ - *(bufpt++) = '0'; - }else{ - for(; e2>=0; e2--){ - *(bufpt++) = et_getdigit(&realvalue,&nsd); - } - } - /* The decimal point */ - if( flag_dp ){ - *(bufpt++) = '.'; - } - /* "0" digits after the decimal point but before the first - ** significant digit of the number */ - for(e2++; e2<0 && precision>0; precision--, e2++){ - *(bufpt++) = '0'; - } - /* Significant digits after the decimal point */ - while( (precision--)>0 ){ - *(bufpt++) = et_getdigit(&realvalue,&nsd); - } - /* Remove trailing zeros and the "." if no digits follow the "." */ - if( flag_rtz && flag_dp ){ - while( bufpt[-1]=='0' ) *(--bufpt) = 0; - assert( bufpt>buf ); - if( bufpt[-1]=='.' ){ - if( flag_altform2 ){ - *(bufpt++) = '0'; - }else{ - *(--bufpt) = 0; - } - } - } - /* Add the "eNNN" suffix */ - if( flag_exp || (xtype==etEXP && exp) ){ - *(bufpt++) = aDigits[infop->charset]; - if( exp<0 ){ - *(bufpt++) = '-'; exp = -exp; - }else{ - *(bufpt++) = '+'; - } - if( exp>=100 ){ - *(bufpt++) = (exp/100)+'0'; /* 100's digit */ - exp %= 100; - } - *(bufpt++) = exp/10+'0'; /* 10's digit */ - *(bufpt++) = exp%10+'0'; /* 1's digit */ - } - *bufpt = 0; - - /* The converted number is in buf[] and zero terminated. Output it. - ** Note that the number is in the usual order, not reversed as with - ** integer conversions. */ - length = bufpt-buf; - bufpt = buf; - - /* Special case: Add leading zeros if the flag_zeropad flag is - ** set and we are not left justified */ - if( flag_zeropad && !flag_leftjustify && length < width){ - int i; - int nPad = width - length; - for(i=width; i>=nPad; i--){ - bufpt[i] = bufpt[i-nPad]; - } - i = prefix!=0; - while( nPad-- ) bufpt[i++] = '0'; - length = width; - } -#endif - break; - case etSIZE: - *(va_arg(ap,int*)) = count; - length = width = 0; - break; - case etPERCENT: - buf[0] = '%'; - bufpt = buf; - length = 1; - break; - case etCHARLIT: - case etCHARX: - c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt); - if( precision>=0 ){ - for(idx=1; idx=0 && precisionetBUFSIZE ){ - bufpt = zExtra = sqlite3_malloc( n ); - if( bufpt==0 ) return -1; - }else{ - bufpt = buf; - } - j = 0; - if( needQuote ) bufpt[j++] = q; - for(i=0; (ch=escarg[i])!=0; i++){ - bufpt[j++] = ch; - if( ch==q ) bufpt[j++] = ch; - } - if( needQuote ) bufpt[j++] = q; - bufpt[j] = 0; - length = j; - /* The precision is ignored on %q and %Q */ - /* if( precision>=0 && precisionz ){ - (*func)(arg, (char*)pToken->z, pToken->n); - } - length = width = 0; - break; - } - case etSRCLIST: { - SrcList *pSrc = va_arg(ap, SrcList*); - int k = va_arg(ap, int); - struct SrcList_item *pItem = &pSrc->a[k]; - assert( k>=0 && knSrc ); - if( pItem->zDatabase && pItem->zDatabase[0] ){ - (*func)(arg, pItem->zDatabase, strlen(pItem->zDatabase)); - (*func)(arg, ".", 1); - } - (*func)(arg, pItem->zName, strlen(pItem->zName)); - length = width = 0; - break; - } - }/* End switch over the format type */ - /* - ** The text of the conversion is pointed to by "bufpt" and is - ** "length" characters long. The field width is "width". Do - ** the output. - */ - if( !flag_leftjustify ){ - register int nspace; - nspace = width-length; - if( nspace>0 ){ - count += nspace; - while( nspace>=etSPACESIZE ){ - (*func)(arg,spaces,etSPACESIZE); - nspace -= etSPACESIZE; - } - if( nspace>0 ) (*func)(arg,spaces,nspace); - } - } - if( length>0 ){ - (*func)(arg,bufpt,length); - count += length; - } - if( flag_leftjustify ){ - register int nspace; - nspace = width-length; - if( nspace>0 ){ - count += nspace; - while( nspace>=etSPACESIZE ){ - (*func)(arg,spaces,etSPACESIZE); - nspace -= etSPACESIZE; - } - if( nspace>0 ) (*func)(arg,spaces,nspace); - } - } - if( zExtra ){ - sqlite3_free(zExtra); - } - }/* End for loop over the format string */ - return errorflag ? -1 : count; -} /* End of function */ - - -/* This structure is used to store state information about the -** write to memory that is currently in progress. -*/ -struct sgMprintf { - char *zBase; /* A base allocation */ - char *zText; /* The string collected so far */ - int nChar; /* Length of the string so far */ - int nTotal; /* Output size if unconstrained */ - int nAlloc; /* Amount of space allocated in zText */ - void *(*xRealloc)(void*,int); /* Function used to realloc memory */ - int iMallocFailed; /* True if xRealloc() has failed */ -}; - -/* -** This function implements the callback from vxprintf. -** -** This routine add nNewChar characters of text in zNewText to -** the sgMprintf structure pointed to by "arg". -*/ -static void mout(void *arg, const char *zNewText, int nNewChar){ - struct sgMprintf *pM = (struct sgMprintf*)arg; - if( pM->iMallocFailed ) return; - pM->nTotal += nNewChar; - if( pM->zText ){ - if( pM->nChar + nNewChar + 1 > pM->nAlloc ){ - if( pM->xRealloc==0 ){ - nNewChar = pM->nAlloc - pM->nChar - 1; - }else{ - int nAlloc = pM->nChar + nNewChar*2 + 1; - if( pM->zText==pM->zBase ){ - pM->zText = pM->xRealloc(0, nAlloc); - if( pM->zText==0 ){ - pM->nAlloc = 0; - pM->iMallocFailed = 1; - return; - }else if( pM->nChar ){ - memcpy(pM->zText, pM->zBase, pM->nChar); - } - }else{ - char *zNew; - zNew = pM->xRealloc(pM->zText, nAlloc); - if( zNew ){ - pM->zText = zNew; - }else{ - pM->iMallocFailed = 1; - pM->xRealloc(pM->zText, 0); - pM->zText = 0; - pM->nAlloc = 0; - return; - } - } - pM->nAlloc = nAlloc; - } - } - if( nNewChar>0 ){ - memcpy(&pM->zText[pM->nChar], zNewText, nNewChar); - pM->nChar += nNewChar; - } - pM->zText[pM->nChar] = 0; - } -} - -/* -** This routine is a wrapper around xprintf() that invokes mout() as -** the consumer. -*/ -static char *base_vprintf( - void *(*xRealloc)(void*, int), /* realloc() function. May be NULL */ - int useInternal, /* Use internal %-conversions if true */ - char *zInitBuf, /* Initially write here, before mallocing */ - int nInitBuf, /* Size of zInitBuf[] */ - const char *zFormat, /* format string */ - va_list ap /* arguments */ -){ - struct sgMprintf sM; - sM.zBase = sM.zText = zInitBuf; - sM.nChar = sM.nTotal = 0; - sM.nAlloc = nInitBuf; - sM.xRealloc = xRealloc; - sM.iMallocFailed = 0; - vxprintf(mout, &sM, useInternal, zFormat, ap); - assert(sM.iMallocFailed==0 || sM.zText==0); - if( xRealloc && !sM.iMallocFailed ){ - if( sM.zText==sM.zBase ){ - sM.zText = xRealloc(0, sM.nChar+1); - if( sM.zText ){ - memcpy(sM.zText, sM.zBase, sM.nChar+1); - } - }else if( sM.nAlloc>sM.nChar+10 ){ - char *zNew; - sqlite3MallocBenignFailure(1); - zNew = xRealloc(sM.zText, sM.nChar+1); - if( zNew ){ - sM.zText = zNew; - } - } - } - return sM.zText; -} - -/* -** Realloc that is a real function, not a macro. -*/ -static void *printf_realloc(void *old, int size){ - return sqlite3_realloc(old, size); -} - -/* -** Print into memory obtained from sqliteMalloc(). Use the internal -** %-conversion extensions. -*/ -char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ - char *z; - char zBase[SQLITE_PRINT_BUF_SIZE]; - z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap); - if( z==0 && db!=0 ){ - db->mallocFailed = 1; - } - return z; -} - -/* -** Print into memory obtained from sqliteMalloc(). Use the internal -** %-conversion extensions. -*/ -char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){ - va_list ap; - char *z; - char zBase[SQLITE_PRINT_BUF_SIZE]; - va_start(ap, zFormat); - z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap); - va_end(ap); - if( z==0 && db!=0 ){ - db->mallocFailed = 1; - } - return z; -} - -/* -** Print into memory obtained from sqlite3_malloc(). Omit the internal -** %-conversion extensions. -*/ -char *sqlite3_vmprintf(const char *zFormat, va_list ap){ - char zBase[SQLITE_PRINT_BUF_SIZE]; - return base_vprintf(sqlite3_realloc, 0, zBase, sizeof(zBase), zFormat, ap); -} - -/* -** Print into memory obtained from sqlite3_malloc()(). Omit the internal -** %-conversion extensions. -*/ -char *sqlite3_mprintf(const char *zFormat, ...){ - va_list ap; - char *z; - va_start(ap, zFormat); - z = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - return z; -} - -/* -** sqlite3_snprintf() works like snprintf() except that it ignores the -** current locale settings. This is important for SQLite because we -** are not able to use a "," as the decimal point in place of "." as -** specified by some locales. -*/ -char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ - char *z; - va_list ap; - - if( n<=0 ){ - return zBuf; - } - zBuf[0] = 0; - va_start(ap,zFormat); - z = base_vprintf(0, 0, zBuf, n, zFormat, ap); - va_end(ap); - return z; -} - -#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) || defined(SQLITE_MEMDEBUG) -/* -** A version of printf() that understands %lld. Used for debugging. -** The printf() built into some versions of windows does not understand %lld -** and segfaults if you give it a long long int. -*/ -void sqlite3DebugPrintf(const char *zFormat, ...){ - extern int getpid(void); - va_list ap; - char zBuf[500]; - va_start(ap, zFormat); - base_vprintf(0, 0, zBuf, sizeof(zBuf), zFormat, ap); - va_end(ap); - fprintf(stdout,"%s", zBuf); - fflush(stdout); -} -#endif diff --git a/extensions/sqlite/sqlite-source/random.c b/extensions/sqlite/sqlite-source/random.c deleted file mode 100644 index b41b770d..00000000 --- a/extensions/sqlite/sqlite-source/random.c +++ /dev/null @@ -1,103 +0,0 @@ -/* -** 2001 September 15 -** -** 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 file contains code to implement a pseudo-random number -** generator (PRNG) for SQLite. -** -** Random numbers are used by some of the database backends in order -** to generate random integer keys for tables or random filenames. -** -** $Id$ -*/ -#include "sqliteInt.h" - - -/* -** Get a single 8-bit random value from the RC4 PRNG. The Mutex -** must be held while executing this routine. -** -** Why not just use a library random generator like lrand48() for this? -** Because the OP_NewRowid opcode in the VDBE depends on having a very -** good source of random numbers. The lrand48() library function may -** well be good enough. But maybe not. Or maybe lrand48() has some -** subtle problems on some systems that could cause problems. It is hard -** to know. To minimize the risk of problems due to bad lrand48() -** implementations, SQLite uses this random number generator based -** on RC4, which we know works very well. -** -** (Later): Actually, OP_NewRowid does not depend on a good source of -** randomness any more. But we will leave this code in all the same. -*/ -static int randomByte(void){ - unsigned char t; - - /* All threads share a single random number generator. - ** This structure is the current state of the generator. - */ - static struct { - unsigned char isInit; /* True if initialized */ - unsigned char i, j; /* State variables */ - unsigned char s[256]; /* State variables */ - } prng; - - /* Initialize the state of the random number generator once, - ** the first time this routine is called. The seed value does - ** not need to contain a lot of randomness since we are not - ** trying to do secure encryption or anything like that... - ** - ** Nothing in this file or anywhere else in SQLite does any kind of - ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random - ** number generator) not as an encryption device. - */ - if( !prng.isInit ){ - int i; - char k[256]; - prng.j = 0; - prng.i = 0; - sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k); - for(i=0; i<256; i++){ - prng.s[i] = i; - } - for(i=0; i<256; i++){ - prng.j += prng.s[i] + k[i]; - t = prng.s[prng.j]; - prng.s[prng.j] = prng.s[i]; - prng.s[i] = t; - } - prng.isInit = 1; - } - - /* Generate and return single random byte - */ - prng.i++; - t = prng.s[prng.i]; - prng.j += t; - prng.s[prng.i] = prng.s[prng.j]; - prng.s[prng.j] = t; - t += prng.s[prng.i]; - return prng.s[t]; -} - -/* -** Return N random bytes. -*/ -void sqlite3Randomness(int N, void *pBuf){ - unsigned char *zBuf = pBuf; - static sqlite3_mutex *mutex = 0; - if( mutex==0 ){ - mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PRNG); - } - sqlite3_mutex_enter(mutex); - while( N-- ){ - *(zBuf++) = randomByte(); - } - sqlite3_mutex_leave(mutex); -} diff --git a/extensions/sqlite/sqlite-source/select.c b/extensions/sqlite/sqlite-source/select.c deleted file mode 100644 index dfa758dd..00000000 --- a/extensions/sqlite/sqlite-source/select.c +++ /dev/null @@ -1,3539 +0,0 @@ -/* -** 2001 September 15 -** -** 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 file contains C code routines that are called by the parser -** to handle SELECT statements in SQLite. -** -** $Id$ -*/ -#include "sqliteInt.h" - - -/* -** Delete all the content of a Select structure but do not deallocate -** the select structure itself. -*/ -static void clearSelect(Select *p){ - sqlite3ExprListDelete(p->pEList); - sqlite3SrcListDelete(p->pSrc); - sqlite3ExprDelete(p->pWhere); - sqlite3ExprListDelete(p->pGroupBy); - sqlite3ExprDelete(p->pHaving); - sqlite3ExprListDelete(p->pOrderBy); - sqlite3SelectDelete(p->pPrior); - sqlite3ExprDelete(p->pLimit); - sqlite3ExprDelete(p->pOffset); -} - - -/* -** Allocate a new Select structure and return a pointer to that -** structure. -*/ -Select *sqlite3SelectNew( - Parse *pParse, /* Parsing context */ - ExprList *pEList, /* which columns to include in the result */ - SrcList *pSrc, /* the FROM clause -- which tables to scan */ - Expr *pWhere, /* the WHERE clause */ - ExprList *pGroupBy, /* the GROUP BY clause */ - Expr *pHaving, /* the HAVING clause */ - ExprList *pOrderBy, /* the ORDER BY clause */ - int isDistinct, /* true if the DISTINCT keyword is present */ - Expr *pLimit, /* LIMIT value. NULL means not used */ - Expr *pOffset /* OFFSET value. NULL means no offset */ -){ - Select *pNew; - Select standin; - sqlite3 *db = pParse->db; - pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); - assert( !pOffset || pLimit ); /* Can't have OFFSET without LIMIT. */ - if( pNew==0 ){ - pNew = &standin; - memset(pNew, 0, sizeof(*pNew)); - } - if( pEList==0 ){ - pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0,0,0), 0); - } - pNew->pEList = pEList; - pNew->pSrc = pSrc; - pNew->pWhere = pWhere; - pNew->pGroupBy = pGroupBy; - pNew->pHaving = pHaving; - pNew->pOrderBy = pOrderBy; - pNew->isDistinct = isDistinct; - pNew->op = TK_SELECT; - assert( pOffset==0 || pLimit!=0 ); - pNew->pLimit = pLimit; - pNew->pOffset = pOffset; - pNew->iLimit = -1; - pNew->iOffset = -1; - pNew->addrOpenEphm[0] = -1; - pNew->addrOpenEphm[1] = -1; - pNew->addrOpenEphm[2] = -1; - if( pNew==&standin) { - clearSelect(pNew); - pNew = 0; - } - return pNew; -} - -/* -** Delete the given Select structure and all of its substructures. -*/ -void sqlite3SelectDelete(Select *p){ - if( p ){ - clearSelect(p); - sqlite3_free(p); - } -} - -/* -** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the -** type of join. Return an integer constant that expresses that type -** in terms of the following bit values: -** -** JT_INNER -** JT_CROSS -** JT_OUTER -** JT_NATURAL -** JT_LEFT -** JT_RIGHT -** -** A full outer join is the combination of JT_LEFT and JT_RIGHT. -** -** If an illegal or unsupported join type is seen, then still return -** a join type, but put an error in the pParse structure. -*/ -int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ - int jointype = 0; - Token *apAll[3]; - Token *p; - static const struct { - const char zKeyword[8]; - u8 nChar; - u8 code; - } keywords[] = { - { "natural", 7, JT_NATURAL }, - { "left", 4, JT_LEFT|JT_OUTER }, - { "right", 5, JT_RIGHT|JT_OUTER }, - { "full", 4, JT_LEFT|JT_RIGHT|JT_OUTER }, - { "outer", 5, JT_OUTER }, - { "inner", 5, JT_INNER }, - { "cross", 5, JT_INNER|JT_CROSS }, - }; - int i, j; - apAll[0] = pA; - apAll[1] = pB; - apAll[2] = pC; - for(i=0; i<3 && apAll[i]; i++){ - p = apAll[i]; - for(j=0; jn==keywords[j].nChar - && sqlite3StrNICmp((char*)p->z, keywords[j].zKeyword, p->n)==0 ){ - jointype |= keywords[j].code; - break; - } - } - if( j>=sizeof(keywords)/sizeof(keywords[0]) ){ - jointype |= JT_ERROR; - break; - } - } - if( - (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) || - (jointype & JT_ERROR)!=0 - ){ - const char *zSp1 = " "; - const char *zSp2 = " "; - if( pB==0 ){ zSp1++; } - if( pC==0 ){ zSp2++; } - sqlite3ErrorMsg(pParse, "unknown or unsupported join type: " - "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC); - jointype = JT_INNER; - }else if( jointype & JT_RIGHT ){ - sqlite3ErrorMsg(pParse, - "RIGHT and FULL OUTER JOINs are not currently supported"); - jointype = JT_INNER; - } - return jointype; -} - -/* -** Return the index of a column in a table. Return -1 if the column -** is not contained in the table. -*/ -static int columnIndex(Table *pTab, const char *zCol){ - int i; - for(i=0; inCol; i++){ - if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i; - } - return -1; -} - -/* -** Set the value of a token to a '\000'-terminated string. -*/ -static void setToken(Token *p, const char *z){ - p->z = (u8*)z; - p->n = z ? strlen(z) : 0; - p->dyn = 0; -} - -/* -** Set the token to the double-quoted and escaped version of the string pointed -** to by z. For example; -** -** {a"bc} -> {"a""bc"} -*/ -static void setQuotedToken(Parse *pParse, Token *p, const char *z){ - p->z = (u8 *)sqlite3MPrintf(0, "\"%w\"", z); - p->dyn = 1; - if( p->z ){ - p->n = strlen((char *)p->z); - }else{ - pParse->db->mallocFailed = 1; - } -} - -/* -** Create an expression node for an identifier with the name of zName -*/ -Expr *sqlite3CreateIdExpr(Parse *pParse, const char *zName){ - Token dummy; - setToken(&dummy, zName); - return sqlite3PExpr(pParse, TK_ID, 0, 0, &dummy); -} - - -/* -** Add a term to the WHERE expression in *ppExpr that requires the -** zCol column to be equal in the two tables pTab1 and pTab2. -*/ -static void addWhereTerm( - Parse *pParse, /* Parsing context */ - const char *zCol, /* Name of the column */ - const Table *pTab1, /* First table */ - const char *zAlias1, /* Alias for first table. May be NULL */ - const Table *pTab2, /* Second table */ - const char *zAlias2, /* Alias for second table. May be NULL */ - int iRightJoinTable, /* VDBE cursor for the right table */ - Expr **ppExpr /* Add the equality term to this expression */ -){ - Expr *pE1a, *pE1b, *pE1c; - Expr *pE2a, *pE2b, *pE2c; - Expr *pE; - - pE1a = sqlite3CreateIdExpr(pParse, zCol); - pE2a = sqlite3CreateIdExpr(pParse, zCol); - if( zAlias1==0 ){ - zAlias1 = pTab1->zName; - } - pE1b = sqlite3CreateIdExpr(pParse, zAlias1); - if( zAlias2==0 ){ - zAlias2 = pTab2->zName; - } - pE2b = sqlite3CreateIdExpr(pParse, zAlias2); - pE1c = sqlite3PExpr(pParse, TK_DOT, pE1b, pE1a, 0); - pE2c = sqlite3PExpr(pParse, TK_DOT, pE2b, pE2a, 0); - pE = sqlite3PExpr(pParse, TK_EQ, pE1c, pE2c, 0); - if( pE ){ - ExprSetProperty(pE, EP_FromJoin); - pE->iRightJoinTable = iRightJoinTable; - } - pE = sqlite3ExprAnd(pParse->db,*ppExpr, pE); - if( pE ){ - *ppExpr = pE; - } -} - -/* -** Set the EP_FromJoin property on all terms of the given expression. -** And set the Expr.iRightJoinTable to iTable for every term in the -** expression. -** -** The EP_FromJoin property is used on terms of an expression to tell -** the LEFT OUTER JOIN processing logic that this term is part of the -** join restriction specified in the ON or USING clause and not a part -** of the more general WHERE clause. These terms are moved over to the -** WHERE clause during join processing but we need to remember that they -** originated in the ON or USING clause. -** -** The Expr.iRightJoinTable tells the WHERE clause processing that the -** expression depends on table iRightJoinTable even if that table is not -** explicitly mentioned in the expression. That information is needed -** for cases like this: -** -** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5 -** -** The where clause needs to defer the handling of the t1.x=5 -** term until after the t2 loop of the join. In that way, a -** NULL t2 row will be inserted whenever t1.x!=5. If we do not -** defer the handling of t1.x=5, it will be processed immediately -** after the t1 loop and rows with t1.x!=5 will never appear in -** the output, which is incorrect. -*/ -static void setJoinExpr(Expr *p, int iTable){ - while( p ){ - ExprSetProperty(p, EP_FromJoin); - p->iRightJoinTable = iTable; - setJoinExpr(p->pLeft, iTable); - p = p->pRight; - } -} - -/* -** This routine processes the join information for a SELECT statement. -** ON and USING clauses are converted into extra terms of the WHERE clause. -** NATURAL joins also create extra WHERE clause terms. -** -** The terms of a FROM clause are contained in the Select.pSrc structure. -** The left most table is the first entry in Select.pSrc. The right-most -** table is the last entry. The join operator is held in the entry to -** the left. Thus entry 0 contains the join operator for the join between -** entries 0 and 1. Any ON or USING clauses associated with the join are -** also attached to the left entry. -** -** This routine returns the number of errors encountered. -*/ -static int sqliteProcessJoin(Parse *pParse, Select *p){ - SrcList *pSrc; /* All tables in the FROM clause */ - int i, j; /* Loop counters */ - struct SrcList_item *pLeft; /* Left table being joined */ - struct SrcList_item *pRight; /* Right table being joined */ - - pSrc = p->pSrc; - pLeft = &pSrc->a[0]; - pRight = &pLeft[1]; - for(i=0; inSrc-1; i++, pRight++, pLeft++){ - Table *pLeftTab = pLeft->pTab; - Table *pRightTab = pRight->pTab; - - if( pLeftTab==0 || pRightTab==0 ) continue; - - /* When the NATURAL keyword is present, add WHERE clause terms for - ** every column that the two tables have in common. - */ - if( pRight->jointype & JT_NATURAL ){ - if( pRight->pOn || pRight->pUsing ){ - sqlite3ErrorMsg(pParse, "a NATURAL join may not have " - "an ON or USING clause", 0); - return 1; - } - for(j=0; jnCol; j++){ - char *zName = pLeftTab->aCol[j].zName; - if( columnIndex(pRightTab, zName)>=0 ){ - addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias, - pRightTab, pRight->zAlias, - pRight->iCursor, &p->pWhere); - - } - } - } - - /* Disallow both ON and USING clauses in the same join - */ - if( pRight->pOn && pRight->pUsing ){ - sqlite3ErrorMsg(pParse, "cannot have both ON and USING " - "clauses in the same join"); - return 1; - } - - /* Add the ON clause to the end of the WHERE clause, connected by - ** an AND operator. - */ - if( pRight->pOn ){ - setJoinExpr(pRight->pOn, pRight->iCursor); - p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn); - pRight->pOn = 0; - } - - /* Create extra terms on the WHERE clause for each column named - ** in the USING clause. Example: If the two tables to be joined are - ** A and B and the USING clause names X, Y, and Z, then add this - ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z - ** Report an error if any column mentioned in the USING clause is - ** not contained in both tables to be joined. - */ - if( pRight->pUsing ){ - IdList *pList = pRight->pUsing; - for(j=0; jnId; j++){ - char *zName = pList->a[j].zName; - if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){ - sqlite3ErrorMsg(pParse, "cannot join using column %s - column " - "not present in both tables", zName); - return 1; - } - addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias, - pRightTab, pRight->zAlias, - pRight->iCursor, &p->pWhere); - } - } - } - return 0; -} - -/* -** Insert code into "v" that will push the record on the top of the -** stack into the sorter. -*/ -static void pushOntoSorter( - Parse *pParse, /* Parser context */ - ExprList *pOrderBy, /* The ORDER BY clause */ - Select *pSelect /* The whole SELECT statement */ -){ - Vdbe *v = pParse->pVdbe; - sqlite3ExprCodeExprList(pParse, pOrderBy); - sqlite3VdbeAddOp(v, OP_Sequence, pOrderBy->iECursor, 0); - sqlite3VdbeAddOp(v, OP_Pull, pOrderBy->nExpr + 1, 0); - sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr + 2, 0); - sqlite3VdbeAddOp(v, OP_IdxInsert, pOrderBy->iECursor, 0); - if( pSelect->iLimit>=0 ){ - int addr1, addr2; - addr1 = sqlite3VdbeAddOp(v, OP_IfMemZero, pSelect->iLimit+1, 0); - sqlite3VdbeAddOp(v, OP_MemIncr, -1, pSelect->iLimit+1); - addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); - sqlite3VdbeJumpHere(v, addr1); - sqlite3VdbeAddOp(v, OP_Last, pOrderBy->iECursor, 0); - sqlite3VdbeAddOp(v, OP_Delete, pOrderBy->iECursor, 0); - sqlite3VdbeJumpHere(v, addr2); - pSelect->iLimit = -1; - } -} - -/* -** Add code to implement the OFFSET -*/ -static void codeOffset( - Vdbe *v, /* Generate code into this VM */ - Select *p, /* The SELECT statement being coded */ - int iContinue, /* Jump here to skip the current record */ - int nPop /* Number of times to pop stack when jumping */ -){ - if( p->iOffset>=0 && iContinue!=0 ){ - int addr; - sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iOffset); - addr = sqlite3VdbeAddOp(v, OP_IfMemNeg, p->iOffset, 0); - if( nPop>0 ){ - sqlite3VdbeAddOp(v, OP_Pop, nPop, 0); - } - sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue); - VdbeComment((v, "# skip OFFSET records")); - sqlite3VdbeJumpHere(v, addr); - } -} - -/* -** Add code that will check to make sure the top N elements of the -** stack are distinct. iTab is a sorting index that holds previously -** seen combinations of the N values. A new entry is made in iTab -** if the current N values are new. -** -** A jump to addrRepeat is made and the N+1 values are popped from the -** stack if the top N elements are not distinct. -*/ -static void codeDistinct( - Vdbe *v, /* Generate code into this VM */ - int iTab, /* A sorting index used to test for distinctness */ - int addrRepeat, /* Jump to here if not distinct */ - int N /* The top N elements of the stack must be distinct */ -){ - sqlite3VdbeAddOp(v, OP_MakeRecord, -N, 0); - sqlite3VdbeAddOp(v, OP_Distinct, iTab, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Pop, N+1, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, addrRepeat); - VdbeComment((v, "# skip indistinct records")); - sqlite3VdbeAddOp(v, OP_IdxInsert, iTab, 0); -} - -/* -** Generate an error message when a SELECT is used within a subexpression -** (example: "a IN (SELECT * FROM table)") but it has more than 1 result -** column. We do this in a subroutine because the error occurs in multiple -** places. -*/ -static int checkForMultiColumnSelectError(Parse *pParse, int eDest, int nExpr){ - if( nExpr>1 && (eDest==SRT_Mem || eDest==SRT_Set) ){ - sqlite3ErrorMsg(pParse, "only a single result allowed for " - "a SELECT that is part of an expression"); - return 1; - }else{ - return 0; - } -} - -/* -** This routine generates the code for the inside of the inner loop -** of a SELECT. -** -** If srcTab and nColumn are both zero, then the pEList expressions -** are evaluated in order to get the data for this row. If nColumn>0 -** then data is pulled from srcTab and pEList is used only to get the -** datatypes for each column. -*/ -static int selectInnerLoop( - Parse *pParse, /* The parser context */ - Select *p, /* The complete select statement being coded */ - ExprList *pEList, /* List of values being extracted */ - int srcTab, /* Pull data from this table */ - int nColumn, /* Number of columns in the source table */ - ExprList *pOrderBy, /* If not NULL, sort results using this key */ - int distinct, /* If >=0, make sure results are distinct */ - int eDest, /* How to dispose of the results */ - int iParm, /* An argument to the disposal method */ - int iContinue, /* Jump here to continue with next row */ - int iBreak, /* Jump here to break out of the inner loop */ - char *aff /* affinity string if eDest is SRT_Union */ -){ - Vdbe *v = pParse->pVdbe; - int i; - int hasDistinct; /* True if the DISTINCT keyword is present */ - - if( v==0 ) return 0; - assert( pEList!=0 ); - - /* If there was a LIMIT clause on the SELECT statement, then do the check - ** to see if this row should be output. - */ - hasDistinct = distinct>=0 && pEList->nExpr>0; - if( pOrderBy==0 && !hasDistinct ){ - codeOffset(v, p, iContinue, 0); - } - - /* Pull the requested columns. - */ - if( nColumn>0 ){ - for(i=0; inExpr; - sqlite3ExprCodeExprList(pParse, pEList); - } - - /* If the DISTINCT keyword was present on the SELECT statement - ** and this row has been seen before, then do not make this row - ** part of the result. - */ - if( hasDistinct ){ - assert( pEList!=0 ); - assert( pEList->nExpr==nColumn ); - codeDistinct(v, distinct, iContinue, nColumn); - if( pOrderBy==0 ){ - codeOffset(v, p, iContinue, nColumn); - } - } - - if( checkForMultiColumnSelectError(pParse, eDest, pEList->nExpr) ){ - return 0; - } - - switch( eDest ){ - /* In this mode, write each query result to the key of the temporary - ** table iParm. - */ -#ifndef SQLITE_OMIT_COMPOUND_SELECT - case SRT_Union: { - sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); - if( aff ){ - sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC); - } - sqlite3VdbeAddOp(v, OP_IdxInsert, iParm, 0); - break; - } - - /* Construct a record from the query result, but instead of - ** saving that record, use it as a key to delete elements from - ** the temporary table iParm. - */ - case SRT_Except: { - int addr; - addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); - sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC); - sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3); - sqlite3VdbeAddOp(v, OP_Delete, iParm, 0); - break; - } -#endif - - /* Store the result as data using a unique key. - */ - case SRT_Table: - case SRT_EphemTab: { - sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); - if( pOrderBy ){ - pushOntoSorter(pParse, pOrderBy, p); - }else{ - sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0); - sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_Insert, iParm, OPFLAG_APPEND); - } - break; - } - -#ifndef SQLITE_OMIT_SUBQUERY - /* If we are creating a set for an "expr IN (SELECT ...)" construct, - ** then there should be a single item on the stack. Write this - ** item into the set table with bogus data. - */ - case SRT_Set: { - int addr1 = sqlite3VdbeCurrentAddr(v); - int addr2; - - assert( nColumn==1 ); - sqlite3VdbeAddOp(v, OP_NotNull, -1, addr1+3); - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); - p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr,(iParm>>16)&0xff); - if( pOrderBy ){ - /* At first glance you would think we could optimize out the - ** ORDER BY in this case since the order of entries in the set - ** does not matter. But there might be a LIMIT clause, in which - ** case the order does matter */ - pushOntoSorter(pParse, pOrderBy, p); - }else{ - sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &p->affinity, 1); - sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0); - } - sqlite3VdbeJumpHere(v, addr2); - break; - } - - /* If any row exist in the result set, record that fact and abort. - */ - case SRT_Exists: { - sqlite3VdbeAddOp(v, OP_MemInt, 1, iParm); - sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); - /* The LIMIT clause will terminate the loop for us */ - break; - } - - /* If this is a scalar select that is part of an expression, then - ** store the results in the appropriate memory cell and break out - ** of the scan loop. - */ - case SRT_Mem: { - assert( nColumn==1 ); - if( pOrderBy ){ - pushOntoSorter(pParse, pOrderBy, p); - }else{ - sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1); - /* The LIMIT clause will jump out of the loop for us */ - } - break; - } -#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ - - /* Send the data to the callback function or to a subroutine. In the - ** case of a subroutine, the subroutine itself is responsible for - ** popping the data from the stack. - */ - case SRT_Subroutine: - case SRT_Callback: { - if( pOrderBy ){ - sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); - pushOntoSorter(pParse, pOrderBy, p); - }else if( eDest==SRT_Subroutine ){ - sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm); - }else{ - sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0); - } - break; - } - -#if !defined(SQLITE_OMIT_TRIGGER) - /* Discard the results. This is used for SELECT statements inside - ** the body of a TRIGGER. The purpose of such selects is to call - ** user-defined functions that have side effects. We do not care - ** about the actual results of the select. - */ - default: { - assert( eDest==SRT_Discard ); - sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); - break; - } -#endif - } - - /* Jump to the end of the loop if the LIMIT is reached. - */ - if( p->iLimit>=0 && pOrderBy==0 ){ - sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iLimit); - sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, iBreak); - } - return 0; -} - -/* -** Given an expression list, generate a KeyInfo structure that records -** the collating sequence for each expression in that expression list. -** -** If the ExprList is an ORDER BY or GROUP BY clause then the resulting -** KeyInfo structure is appropriate for initializing a virtual index to -** implement that clause. If the ExprList is the result set of a SELECT -** then the KeyInfo structure is appropriate for initializing a virtual -** index to implement a DISTINCT test. -** -** Space to hold the KeyInfo structure is obtain from malloc. The calling -** function is responsible for seeing that this structure is eventually -** freed. Add the KeyInfo structure to the P3 field of an opcode using -** P3_KEYINFO_HANDOFF is the usual way of dealing with this. -*/ -static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){ - sqlite3 *db = pParse->db; - int nExpr; - KeyInfo *pInfo; - struct ExprList_item *pItem; - int i; - - nExpr = pList->nExpr; - pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) ); - if( pInfo ){ - pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr]; - pInfo->nField = nExpr; - pInfo->enc = ENC(db); - for(i=0, pItem=pList->a; ipExpr); - if( !pColl ){ - pColl = db->pDfltColl; - } - pInfo->aColl[i] = pColl; - pInfo->aSortOrder[i] = pItem->sortOrder; - } - } - return pInfo; -} - - -/* -** If the inner loop was generated using a non-null pOrderBy argument, -** then the results were placed in a sorter. After the loop is terminated -** we need to run the sorter and output the results. The following -** routine generates the code needed to do that. -*/ -static void generateSortTail( - Parse *pParse, /* Parsing context */ - Select *p, /* The SELECT statement */ - Vdbe *v, /* Generate code into this VDBE */ - int nColumn, /* Number of columns of data */ - int eDest, /* Write the sorted results here */ - int iParm /* Optional parameter associated with eDest */ -){ - int brk = sqlite3VdbeMakeLabel(v); - int cont = sqlite3VdbeMakeLabel(v); - int addr; - int iTab; - int pseudoTab = 0; - ExprList *pOrderBy = p->pOrderBy; - - iTab = pOrderBy->iECursor; - if( eDest==SRT_Callback || eDest==SRT_Subroutine ){ - pseudoTab = pParse->nTab++; - sqlite3VdbeAddOp(v, OP_OpenPseudo, pseudoTab, 0); - sqlite3VdbeAddOp(v, OP_SetNumColumns, pseudoTab, nColumn); - } - addr = 1 + sqlite3VdbeAddOp(v, OP_Sort, iTab, brk); - codeOffset(v, p, cont, 0); - if( eDest==SRT_Callback || eDest==SRT_Subroutine ){ - sqlite3VdbeAddOp(v, OP_Integer, 1, 0); - } - sqlite3VdbeAddOp(v, OP_Column, iTab, pOrderBy->nExpr + 1); - switch( eDest ){ - case SRT_Table: - case SRT_EphemTab: { - sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0); - sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_Insert, iParm, OPFLAG_APPEND); - break; - } -#ifndef SQLITE_OMIT_SUBQUERY - case SRT_Set: { - assert( nColumn==1 ); - sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &p->affinity, 1); - sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0); - break; - } - case SRT_Mem: { - assert( nColumn==1 ); - sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1); - /* The LIMIT clause will terminate the loop for us */ - break; - } -#endif - case SRT_Callback: - case SRT_Subroutine: { - int i; - sqlite3VdbeAddOp(v, OP_Insert, pseudoTab, 0); - for(i=0; iiLimit>=0 ){ - sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iLimit); - sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, brk); - } - - /* The bottom of the loop - */ - sqlite3VdbeResolveLabel(v, cont); - sqlite3VdbeAddOp(v, OP_Next, iTab, addr); - sqlite3VdbeResolveLabel(v, brk); - if( eDest==SRT_Callback || eDest==SRT_Subroutine ){ - sqlite3VdbeAddOp(v, OP_Close, pseudoTab, 0); - } - -} - -/* -** Return a pointer to a string containing the 'declaration type' of the -** expression pExpr. The string may be treated as static by the caller. -** -** The declaration type is the exact datatype definition extracted from the -** original CREATE TABLE statement if the expression is a column. The -** declaration type for a ROWID field is INTEGER. Exactly when an expression -** is considered a column can be complex in the presence of subqueries. The -** result-set expression in all of the following SELECT statements is -** considered a column by this function. -** -** SELECT col FROM tbl; -** SELECT (SELECT col FROM tbl; -** SELECT (SELECT col FROM tbl); -** SELECT abc FROM (SELECT col AS abc FROM tbl); -** -** The declaration type for any expression other than a column is NULL. -*/ -static const char *columnType( - NameContext *pNC, - Expr *pExpr, - const char **pzOriginDb, - const char **pzOriginTab, - const char **pzOriginCol -){ - char const *zType = 0; - char const *zOriginDb = 0; - char const *zOriginTab = 0; - char const *zOriginCol = 0; - int j; - if( pExpr==0 || pNC->pSrcList==0 ) return 0; - - switch( pExpr->op ){ - case TK_AGG_COLUMN: - case TK_COLUMN: { - /* The expression is a column. Locate the table the column is being - ** extracted from in NameContext.pSrcList. This table may be real - ** database table or a subquery. - */ - Table *pTab = 0; /* Table structure column is extracted from */ - Select *pS = 0; /* Select the column is extracted from */ - int iCol = pExpr->iColumn; /* Index of column in pTab */ - while( pNC && !pTab ){ - SrcList *pTabList = pNC->pSrcList; - for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); - if( jnSrc ){ - pTab = pTabList->a[j].pTab; - pS = pTabList->a[j].pSelect; - }else{ - pNC = pNC->pNext; - } - } - - if( pTab==0 ){ - /* FIX ME: - ** This can occurs if you have something like "SELECT new.x;" inside - ** a trigger. In other words, if you reference the special "new" - ** table in the result set of a select. We do not have a good way - ** to find the actual table type, so call it "TEXT". This is really - ** something of a bug, but I do not know how to fix it. - ** - ** This code does not produce the correct answer - it just prevents - ** a segfault. See ticket #1229. - */ - zType = "TEXT"; - break; - } - - assert( pTab ); - if( pS ){ - /* The "table" is actually a sub-select or a view in the FROM clause - ** of the SELECT statement. Return the declaration type and origin - ** data for the result-set column of the sub-select. - */ - if( iCol>=0 && iColpEList->nExpr ){ - /* If iCol is less than zero, then the expression requests the - ** rowid of the sub-select or view. This expression is legal (see - ** test case misc2.2.2) - it always evaluates to NULL. - */ - NameContext sNC; - Expr *p = pS->pEList->a[iCol].pExpr; - sNC.pSrcList = pS->pSrc; - sNC.pNext = 0; - sNC.pParse = pNC->pParse; - zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); - } - }else if( pTab->pSchema ){ - /* A real table */ - assert( !pS ); - if( iCol<0 ) iCol = pTab->iPKey; - assert( iCol==-1 || (iCol>=0 && iColnCol) ); - if( iCol<0 ){ - zType = "INTEGER"; - zOriginCol = "rowid"; - }else{ - zType = pTab->aCol[iCol].zType; - zOriginCol = pTab->aCol[iCol].zName; - } - zOriginTab = pTab->zName; - if( pNC->pParse ){ - int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); - zOriginDb = pNC->pParse->db->aDb[iDb].zName; - } - } - break; - } -#ifndef SQLITE_OMIT_SUBQUERY - case TK_SELECT: { - /* The expression is a sub-select. Return the declaration type and - ** origin info for the single column in the result set of the SELECT - ** statement. - */ - NameContext sNC; - Select *pS = pExpr->pSelect; - Expr *p = pS->pEList->a[0].pExpr; - sNC.pSrcList = pS->pSrc; - sNC.pNext = pNC; - sNC.pParse = pNC->pParse; - zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); - break; - } -#endif - } - - if( pzOriginDb ){ - assert( pzOriginTab && pzOriginCol ); - *pzOriginDb = zOriginDb; - *pzOriginTab = zOriginTab; - *pzOriginCol = zOriginCol; - } - return zType; -} - -/* -** Generate code that will tell the VDBE the declaration types of columns -** in the result set. -*/ -static void generateColumnTypes( - Parse *pParse, /* Parser context */ - SrcList *pTabList, /* List of tables */ - ExprList *pEList /* Expressions defining the result set */ -){ - Vdbe *v = pParse->pVdbe; - int i; - NameContext sNC; - sNC.pSrcList = pTabList; - sNC.pParse = pParse; - for(i=0; inExpr; i++){ - Expr *p = pEList->a[i].pExpr; - const char *zOrigDb = 0; - const char *zOrigTab = 0; - const char *zOrigCol = 0; - const char *zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); - - /* The vdbe must make it's own copy of the column-type and other - ** column specific strings, in case the schema is reset before this - ** virtual machine is deleted. - */ - sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, P3_TRANSIENT); - sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, P3_TRANSIENT); - sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, P3_TRANSIENT); - sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, P3_TRANSIENT); - } -} - -/* -** Generate code that will tell the VDBE the names of columns -** in the result set. This information is used to provide the -** azCol[] values in the callback. -*/ -static void generateColumnNames( - Parse *pParse, /* Parser context */ - SrcList *pTabList, /* List of tables */ - ExprList *pEList /* Expressions defining the result set */ -){ - Vdbe *v = pParse->pVdbe; - int i, j; - sqlite3 *db = pParse->db; - int fullNames, shortNames; - -#ifndef SQLITE_OMIT_EXPLAIN - /* If this is an EXPLAIN, skip this step */ - if( pParse->explain ){ - return; - } -#endif - - assert( v!=0 ); - if( pParse->colNamesSet || v==0 || db->mallocFailed ) return; - pParse->colNamesSet = 1; - fullNames = (db->flags & SQLITE_FullColNames)!=0; - shortNames = (db->flags & SQLITE_ShortColNames)!=0; - sqlite3VdbeSetNumCols(v, pEList->nExpr); - for(i=0; inExpr; i++){ - Expr *p; - p = pEList->a[i].pExpr; - if( p==0 ) continue; - if( pEList->a[i].zName ){ - char *zName = pEList->a[i].zName; - sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, strlen(zName)); - continue; - } - if( p->op==TK_COLUMN && pTabList ){ - Table *pTab; - char *zCol; - int iCol = p->iColumn; - for(j=0; jnSrc && pTabList->a[j].iCursor!=p->iTable; j++){} - assert( jnSrc ); - pTab = pTabList->a[j].pTab; - if( iCol<0 ) iCol = pTab->iPKey; - assert( iCol==-1 || (iCol>=0 && iColnCol) ); - if( iCol<0 ){ - zCol = "rowid"; - }else{ - zCol = pTab->aCol[iCol].zName; - } - if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){ - sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n); - }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){ - char *zName = 0; - char *zTab; - - zTab = pTabList->a[j].zAlias; - if( fullNames || zTab==0 ) zTab = pTab->zName; - sqlite3SetString(&zName, zTab, ".", zCol, (char*)0); - sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, P3_DYNAMIC); - }else{ - sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, strlen(zCol)); - } - }else if( p->span.z && p->span.z[0] ){ - sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n); - /* sqlite3VdbeCompressSpace(v, addr); */ - }else{ - char zName[30]; - assert( p->op!=TK_COLUMN || pTabList==0 ); - sqlite3_snprintf(sizeof(zName), zName, "column%d", i+1); - sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, 0); - } - } - generateColumnTypes(pParse, pTabList, pEList); -} - -#ifndef SQLITE_OMIT_COMPOUND_SELECT -/* -** Name of the connection operator, used for error messages. -*/ -static const char *selectOpName(int id){ - char *z; - switch( id ){ - case TK_ALL: z = "UNION ALL"; break; - case TK_INTERSECT: z = "INTERSECT"; break; - case TK_EXCEPT: z = "EXCEPT"; break; - default: z = "UNION"; break; - } - return z; -} -#endif /* SQLITE_OMIT_COMPOUND_SELECT */ - -/* -** Forward declaration -*/ -static int prepSelectStmt(Parse*, Select*); - -/* -** Given a SELECT statement, generate a Table structure that describes -** the result set of that SELECT. -*/ -Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ - Table *pTab; - int i, j; - ExprList *pEList; - Column *aCol, *pCol; - sqlite3 *db = pParse->db; - - while( pSelect->pPrior ) pSelect = pSelect->pPrior; - if( prepSelectStmt(pParse, pSelect) ){ - return 0; - } - if( sqlite3SelectResolve(pParse, pSelect, 0) ){ - return 0; - } - pTab = sqlite3DbMallocZero(db, sizeof(Table) ); - if( pTab==0 ){ - return 0; - } - pTab->nRef = 1; - pTab->zName = zTabName ? sqlite3DbStrDup(db, zTabName) : 0; - pEList = pSelect->pEList; - pTab->nCol = pEList->nExpr; - assert( pTab->nCol>0 ); - pTab->aCol = aCol = sqlite3DbMallocZero(db, sizeof(pTab->aCol[0])*pTab->nCol); - for(i=0, pCol=aCol; inCol; i++, pCol++){ - Expr *p, *pR; - char *zType; - char *zName; - int nName; - CollSeq *pColl; - int cnt; - NameContext sNC; - - /* Get an appropriate name for the column - */ - p = pEList->a[i].pExpr; - assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 ); - if( (zName = pEList->a[i].zName)!=0 ){ - /* If the column contains an "AS " phrase, use as the name */ - zName = sqlite3DbStrDup(db, zName); - }else if( p->op==TK_DOT - && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){ - /* For columns of the from A.B use B as the name */ - zName = sqlite3MPrintf(db, "%T", &pR->token); - }else if( p->span.z && p->span.z[0] ){ - /* Use the original text of the column expression as its name */ - zName = sqlite3MPrintf(db, "%T", &p->span); - }else{ - /* If all else fails, make up a name */ - zName = sqlite3MPrintf(db, "column%d", i+1); - } - if( !zName || db->mallocFailed ){ - db->mallocFailed = 1; - sqlite3_free(zName); - sqlite3DeleteTable(pTab); - return 0; - } - sqlite3Dequote(zName); - - /* Make sure the column name is unique. If the name is not unique, - ** append a integer to the name so that it becomes unique. - */ - nName = strlen(zName); - for(j=cnt=0; jzName = zName; - - /* Get the typename, type affinity, and collating sequence for the - ** column. - */ - memset(&sNC, 0, sizeof(sNC)); - sNC.pSrcList = pSelect->pSrc; - zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0)); - pCol->zType = zType; - pCol->affinity = sqlite3ExprAffinity(p); - pColl = sqlite3ExprCollSeq(pParse, p); - if( pColl ){ - pCol->zColl = sqlite3DbStrDup(db, pColl->zName); - } - } - pTab->iPKey = -1; - return pTab; -} - -/* -** Prepare a SELECT statement for processing by doing the following -** things: -** -** (1) Make sure VDBE cursor numbers have been assigned to every -** element of the FROM clause. -** -** (2) Fill in the pTabList->a[].pTab fields in the SrcList that -** defines FROM clause. When views appear in the FROM clause, -** fill pTabList->a[].pSelect with a copy of the SELECT statement -** that implements the view. A copy is made of the view's SELECT -** statement so that we can freely modify or delete that statement -** without worrying about messing up the presistent representation -** of the view. -** -** (3) Add terms to the WHERE clause to accomodate the NATURAL keyword -** on joins and the ON and USING clause of joins. -** -** (4) Scan the list of columns in the result set (pEList) looking -** for instances of the "*" operator or the TABLE.* operator. -** If found, expand each "*" to be every column in every table -** and TABLE.* to be every column in TABLE. -** -** Return 0 on success. If there are problems, leave an error message -** in pParse and return non-zero. -*/ -static int prepSelectStmt(Parse *pParse, Select *p){ - int i, j, k, rc; - SrcList *pTabList; - ExprList *pEList; - struct SrcList_item *pFrom; - sqlite3 *db = pParse->db; - - if( p==0 || p->pSrc==0 || db->mallocFailed ){ - return 1; - } - pTabList = p->pSrc; - pEList = p->pEList; - - /* Make sure cursor numbers have been assigned to all entries in - ** the FROM clause of the SELECT statement. - */ - sqlite3SrcListAssignCursors(pParse, p->pSrc); - - /* Look up every table named in the FROM clause of the select. If - ** an entry of the FROM clause is a subquery instead of a table or view, - ** then create a transient table structure to describe the subquery. - */ - for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ - Table *pTab; - if( pFrom->pTab!=0 ){ - /* This statement has already been prepared. There is no need - ** to go further. */ - assert( i==0 ); - return 0; - } - if( pFrom->zName==0 ){ -#ifndef SQLITE_OMIT_SUBQUERY - /* A sub-query in the FROM clause of a SELECT */ - assert( pFrom->pSelect!=0 ); - if( pFrom->zAlias==0 ){ - pFrom->zAlias = - sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pFrom->pSelect); - } - assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = - sqlite3ResultSetOfSelect(pParse, pFrom->zAlias, pFrom->pSelect); - if( pTab==0 ){ - return 1; - } - /* The isEphem flag indicates that the Table structure has been - ** dynamically allocated and may be freed at any time. In other words, - ** pTab is not pointing to a persistent table structure that defines - ** part of the schema. */ - pTab->isEphem = 1; -#endif - }else{ - /* An ordinary table or view name in the FROM clause */ - assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = - sqlite3LocateTable(pParse,pFrom->zName,pFrom->zDatabase); - if( pTab==0 ){ - return 1; - } - pTab->nRef++; -#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) - if( pTab->pSelect || IsVirtual(pTab) ){ - /* We reach here if the named table is a really a view */ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - return 1; - } - /* If pFrom->pSelect!=0 it means we are dealing with a - ** view within a view. The SELECT structure has already been - ** copied by the outer view so we can skip the copy step here - ** in the inner view. - */ - if( pFrom->pSelect==0 ){ - pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect); - } - } -#endif - } - } - - /* Process NATURAL keywords, and ON and USING clauses of joins. - */ - if( sqliteProcessJoin(pParse, p) ) return 1; - - /* For every "*" that occurs in the column list, insert the names of - ** all columns in all tables. And for every TABLE.* insert the names - ** of all columns in TABLE. The parser inserted a special expression - ** with the TK_ALL operator for each "*" that it found in the column list. - ** The following code just has to locate the TK_ALL expressions and expand - ** each one to the list of all columns in all tables. - ** - ** The first loop just checks to see if there are any "*" operators - ** that need expanding. - */ - for(k=0; knExpr; k++){ - Expr *pE = pEList->a[k].pExpr; - if( pE->op==TK_ALL ) break; - if( pE->op==TK_DOT && pE->pRight && pE->pRight->op==TK_ALL - && pE->pLeft && pE->pLeft->op==TK_ID ) break; - } - rc = 0; - if( knExpr ){ - /* - ** If we get here it means the result set contains one or more "*" - ** operators that need to be expanded. Loop through each expression - ** in the result set and expand them one by one. - */ - struct ExprList_item *a = pEList->a; - ExprList *pNew = 0; - int flags = pParse->db->flags; - int longNames = (flags & SQLITE_FullColNames)!=0 && - (flags & SQLITE_ShortColNames)==0; - - for(k=0; knExpr; k++){ - Expr *pE = a[k].pExpr; - if( pE->op!=TK_ALL && - (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){ - /* This particular expression does not need to be expanded. - */ - pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr, 0); - if( pNew ){ - pNew->a[pNew->nExpr-1].zName = a[k].zName; - }else{ - rc = 1; - } - a[k].pExpr = 0; - a[k].zName = 0; - }else{ - /* This expression is a "*" or a "TABLE.*" and needs to be - ** expanded. */ - int tableSeen = 0; /* Set to 1 when TABLE matches */ - char *zTName; /* text of name of TABLE */ - if( pE->op==TK_DOT && pE->pLeft ){ - zTName = sqlite3NameFromToken(db, &pE->pLeft->token); - }else{ - zTName = 0; - } - for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ - Table *pTab = pFrom->pTab; - char *zTabName = pFrom->zAlias; - if( zTabName==0 || zTabName[0]==0 ){ - zTabName = pTab->zName; - } - if( zTName && (zTabName==0 || zTabName[0]==0 || - sqlite3StrICmp(zTName, zTabName)!=0) ){ - continue; - } - tableSeen = 1; - for(j=0; jnCol; j++){ - Expr *pExpr, *pRight; - char *zName = pTab->aCol[j].zName; - - /* If a column is marked as 'hidden' (currently only possible - ** for virtual tables), do not include it in the expanded - ** result-set list. - */ - if( IsHiddenColumn(&pTab->aCol[j]) ){ - assert(IsVirtual(pTab)); - continue; - } - - if( i>0 ){ - struct SrcList_item *pLeft = &pTabList->a[i-1]; - if( (pLeft[1].jointype & JT_NATURAL)!=0 && - columnIndex(pLeft->pTab, zName)>=0 ){ - /* In a NATURAL join, omit the join columns from the - ** table on the right */ - continue; - } - if( sqlite3IdListIndex(pLeft[1].pUsing, zName)>=0 ){ - /* In a join with a USING clause, omit columns in the - ** using clause from the table on the right. */ - continue; - } - } - pRight = sqlite3PExpr(pParse, TK_ID, 0, 0, 0); - if( pRight==0 ) break; - setQuotedToken(pParse, &pRight->token, zName); - if( zTabName && (longNames || pTabList->nSrc>1) ){ - Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, 0); - pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); - if( pExpr==0 ) break; - setQuotedToken(pParse, &pLeft->token, zTabName); - setToken(&pExpr->span, - sqlite3MPrintf(db, "%s.%s", zTabName, zName)); - pExpr->span.dyn = 1; - pExpr->token.z = 0; - pExpr->token.n = 0; - pExpr->token.dyn = 0; - }else{ - pExpr = pRight; - pExpr->span = pExpr->token; - pExpr->span.dyn = 0; - } - if( longNames ){ - pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pExpr->span); - }else{ - pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pRight->token); - } - } - } - if( !tableSeen ){ - if( zTName ){ - sqlite3ErrorMsg(pParse, "no such table: %s", zTName); - }else{ - sqlite3ErrorMsg(pParse, "no tables specified"); - } - rc = 1; - } - sqlite3_free(zTName); - } - } - sqlite3ExprListDelete(pEList); - p->pEList = pNew; - } - if( p->pEList && p->pEList->nExpr>SQLITE_MAX_COLUMN ){ - sqlite3ErrorMsg(pParse, "too many columns in result set"); - rc = SQLITE_ERROR; - } - if( db->mallocFailed ){ - rc = SQLITE_NOMEM; - } - return rc; -} - -#ifndef SQLITE_OMIT_COMPOUND_SELECT -/* -** This routine associates entries in an ORDER BY expression list with -** columns in a result. For each ORDER BY expression, the opcode of -** the top-level node is changed to TK_COLUMN and the iColumn value of -** the top-level node is filled in with column number and the iTable -** value of the top-level node is filled with iTable parameter. -** -** If there are prior SELECT clauses, they are processed first. A match -** in an earlier SELECT takes precedence over a later SELECT. -** -** Any entry that does not match is flagged as an error. The number -** of errors is returned. -*/ -static int matchOrderbyToColumn( - Parse *pParse, /* A place to leave error messages */ - Select *pSelect, /* Match to result columns of this SELECT */ - ExprList *pOrderBy, /* The ORDER BY values to match against columns */ - int iTable, /* Insert this value in iTable */ - int mustComplete /* If TRUE all ORDER BYs must match */ -){ - int nErr = 0; - int i, j; - ExprList *pEList; - sqlite3 *db = pParse->db; - - if( pSelect==0 || pOrderBy==0 ) return 1; - if( mustComplete ){ - for(i=0; inExpr; i++){ pOrderBy->a[i].done = 0; } - } - if( prepSelectStmt(pParse, pSelect) ){ - return 1; - } - if( pSelect->pPrior ){ - if( matchOrderbyToColumn(pParse, pSelect->pPrior, pOrderBy, iTable, 0) ){ - return 1; - } - } - pEList = pSelect->pEList; - for(i=0; inExpr; i++){ - struct ExprList_item *pItem; - Expr *pE = pOrderBy->a[i].pExpr; - int iCol = -1; - char *zLabel; - - if( pOrderBy->a[i].done ) continue; - if( sqlite3ExprIsInteger(pE, &iCol) ){ - if( iCol<=0 || iCol>pEList->nExpr ){ - sqlite3ErrorMsg(pParse, - "ORDER BY position %d should be between 1 and %d", - iCol, pEList->nExpr); - nErr++; - break; - } - if( !mustComplete ) continue; - iCol--; - } - if( iCol<0 && (zLabel = sqlite3NameFromToken(db, &pE->token))!=0 ){ - for(j=0, pItem=pEList->a; jnExpr; j++, pItem++){ - char *zName; - int isMatch; - if( pItem->zName ){ - zName = sqlite3DbStrDup(db, pItem->zName); - }else{ - zName = sqlite3NameFromToken(db, &pItem->pExpr->token); - } - isMatch = zName && sqlite3StrICmp(zName, zLabel)==0; - sqlite3_free(zName); - if( isMatch ){ - iCol = j; - break; - } - } - sqlite3_free(zLabel); - } - if( iCol>=0 ){ - pE->op = TK_COLUMN; - pE->iColumn = iCol; - pE->iTable = iTable; - pE->iAgg = -1; - pOrderBy->a[i].done = 1; - }else if( mustComplete ){ - sqlite3ErrorMsg(pParse, - "ORDER BY term number %d does not match any result column", i+1); - nErr++; - break; - } - } - return nErr; -} -#endif /* #ifndef SQLITE_OMIT_COMPOUND_SELECT */ - -/* -** Get a VDBE for the given parser context. Create a new one if necessary. -** If an error occurs, return NULL and leave a message in pParse. -*/ -Vdbe *sqlite3GetVdbe(Parse *pParse){ - Vdbe *v = pParse->pVdbe; - if( v==0 ){ - v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db); - } - return v; -} - - -/* -** Compute the iLimit and iOffset fields of the SELECT based on the -** pLimit and pOffset expressions. pLimit and pOffset hold the expressions -** that appear in the original SQL statement after the LIMIT and OFFSET -** keywords. Or NULL if those keywords are omitted. iLimit and iOffset -** are the integer memory register numbers for counters used to compute -** the limit and offset. If there is no limit and/or offset, then -** iLimit and iOffset are negative. -** -** This routine changes the values of iLimit and iOffset only if -** a limit or offset is defined by pLimit and pOffset. iLimit and -** iOffset should have been preset to appropriate default values -** (usually but not always -1) prior to calling this routine. -** Only if pLimit!=0 or pOffset!=0 do the limit registers get -** redefined. The UNION ALL operator uses this property to force -** the reuse of the same limit and offset registers across multiple -** SELECT statements. -*/ -static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ - Vdbe *v = 0; - int iLimit = 0; - int iOffset; - int addr1, addr2; - - /* - ** "LIMIT -1" always shows all rows. There is some - ** contraversy about what the correct behavior should be. - ** The current implementation interprets "LIMIT 0" to mean - ** no rows. - */ - if( p->pLimit ){ - p->iLimit = iLimit = pParse->nMem; - pParse->nMem += 2; - v = sqlite3GetVdbe(pParse); - if( v==0 ) return; - sqlite3ExprCode(pParse, p->pLimit); - sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); - sqlite3VdbeAddOp(v, OP_MemStore, iLimit, 1); - VdbeComment((v, "# LIMIT counter")); - sqlite3VdbeAddOp(v, OP_IfMemZero, iLimit, iBreak); - sqlite3VdbeAddOp(v, OP_MemLoad, iLimit, 0); - } - if( p->pOffset ){ - p->iOffset = iOffset = pParse->nMem++; - v = sqlite3GetVdbe(pParse); - if( v==0 ) return; - sqlite3ExprCode(pParse, p->pOffset); - sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); - sqlite3VdbeAddOp(v, OP_MemStore, iOffset, p->pLimit==0); - VdbeComment((v, "# OFFSET counter")); - addr1 = sqlite3VdbeAddOp(v, OP_IfMemPos, iOffset, 0); - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3VdbeAddOp(v, OP_Integer, 0, 0); - sqlite3VdbeJumpHere(v, addr1); - if( p->pLimit ){ - sqlite3VdbeAddOp(v, OP_Add, 0, 0); - } - } - if( p->pLimit ){ - addr1 = sqlite3VdbeAddOp(v, OP_IfMemPos, iLimit, 0); - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3VdbeAddOp(v, OP_MemInt, -1, iLimit+1); - addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); - sqlite3VdbeJumpHere(v, addr1); - sqlite3VdbeAddOp(v, OP_MemStore, iLimit+1, 1); - VdbeComment((v, "# LIMIT+OFFSET")); - sqlite3VdbeJumpHere(v, addr2); - } -} - -/* -** Allocate a virtual index to use for sorting. -*/ -static void createSortingIndex(Parse *pParse, Select *p, ExprList *pOrderBy){ - if( pOrderBy ){ - int addr; - assert( pOrderBy->iECursor==0 ); - pOrderBy->iECursor = pParse->nTab++; - addr = sqlite3VdbeAddOp(pParse->pVdbe, OP_OpenEphemeral, - pOrderBy->iECursor, pOrderBy->nExpr+1); - assert( p->addrOpenEphm[2] == -1 ); - p->addrOpenEphm[2] = addr; - } -} - -#ifndef SQLITE_OMIT_COMPOUND_SELECT -/* -** Return the appropriate collating sequence for the iCol-th column of -** the result set for the compound-select statement "p". Return NULL if -** the column has no default collating sequence. -** -** The collating sequence for the compound select is taken from the -** left-most term of the select that has a collating sequence. -*/ -static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ - CollSeq *pRet; - if( p->pPrior ){ - pRet = multiSelectCollSeq(pParse, p->pPrior, iCol); - }else{ - pRet = 0; - } - if( pRet==0 ){ - pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr); - } - return pRet; -} -#endif /* SQLITE_OMIT_COMPOUND_SELECT */ - -#ifndef SQLITE_OMIT_COMPOUND_SELECT -/* -** This routine is called to process a query that is really the union -** or intersection of two or more separate queries. -** -** "p" points to the right-most of the two queries. the query on the -** left is p->pPrior. The left query could also be a compound query -** in which case this routine will be called recursively. -** -** The results of the total query are to be written into a destination -** of type eDest with parameter iParm. -** -** Example 1: Consider a three-way compound SQL statement. -** -** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3 -** -** This statement is parsed up as follows: -** -** SELECT c FROM t3 -** | -** `-----> SELECT b FROM t2 -** | -** `------> SELECT a FROM t1 -** -** The arrows in the diagram above represent the Select.pPrior pointer. -** So if this routine is called with p equal to the t3 query, then -** pPrior will be the t2 query. p->op will be TK_UNION in this case. -** -** Notice that because of the way SQLite parses compound SELECTs, the -** individual selects always group from left to right. -*/ -static int multiSelect( - Parse *pParse, /* Parsing context */ - Select *p, /* The right-most of SELECTs to be coded */ - int eDest, /* \___ Store query results as specified */ - int iParm, /* / by these two parameters. */ - char *aff /* If eDest is SRT_Union, the affinity string */ -){ - int rc = SQLITE_OK; /* Success code from a subroutine */ - Select *pPrior; /* Another SELECT immediately to our left */ - Vdbe *v; /* Generate code to this VDBE */ - int nCol; /* Number of columns in the result set */ - ExprList *pOrderBy; /* The ORDER BY clause on p */ - int aSetP2[2]; /* Set P2 value of these op to number of columns */ - int nSetP2 = 0; /* Number of slots in aSetP2[] used */ - - /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only - ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. - */ - if( p==0 || p->pPrior==0 ){ - rc = 1; - goto multi_select_end; - } - pPrior = p->pPrior; - assert( pPrior->pRightmost!=pPrior ); - assert( pPrior->pRightmost==p->pRightmost ); - if( pPrior->pOrderBy ){ - sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before", - selectOpName(p->op)); - rc = 1; - goto multi_select_end; - } - if( pPrior->pLimit ){ - sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before", - selectOpName(p->op)); - rc = 1; - goto multi_select_end; - } - - /* Make sure we have a valid query engine. If not, create a new one. - */ - v = sqlite3GetVdbe(pParse); - if( v==0 ){ - rc = 1; - goto multi_select_end; - } - - /* Create the destination temporary table if necessary - */ - if( eDest==SRT_EphemTab ){ - assert( p->pEList ); - assert( nSetP2pOrderBy; - switch( p->op ){ - case TK_ALL: { - if( pOrderBy==0 ){ - int addr = 0; - assert( !pPrior->pLimit ); - pPrior->pLimit = p->pLimit; - pPrior->pOffset = p->pOffset; - rc = sqlite3Select(pParse, pPrior, eDest, iParm, 0, 0, 0, aff); - p->pLimit = 0; - p->pOffset = 0; - if( rc ){ - goto multi_select_end; - } - p->pPrior = 0; - p->iLimit = pPrior->iLimit; - p->iOffset = pPrior->iOffset; - if( p->iLimit>=0 ){ - addr = sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, 0); - VdbeComment((v, "# Jump ahead if LIMIT reached")); - } - rc = sqlite3Select(pParse, p, eDest, iParm, 0, 0, 0, aff); - p->pPrior = pPrior; - if( rc ){ - goto multi_select_end; - } - if( addr ){ - sqlite3VdbeJumpHere(v, addr); - } - break; - } - /* For UNION ALL ... ORDER BY fall through to the next case */ - } - case TK_EXCEPT: - case TK_UNION: { - int unionTab; /* Cursor number of the temporary table holding result */ - int op = 0; /* One of the SRT_ operations to apply to self */ - int priorOp; /* The SRT_ operation to apply to prior selects */ - Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */ - int addr; - - priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union; - if( eDest==priorOp && pOrderBy==0 && !p->pLimit && !p->pOffset ){ - /* We can reuse a temporary table generated by a SELECT to our - ** right. - */ - unionTab = iParm; - }else{ - /* We will need to create our own temporary table to hold the - ** intermediate results. - */ - unionTab = pParse->nTab++; - if( pOrderBy && matchOrderbyToColumn(pParse, p, pOrderBy, unionTab,1) ){ - rc = 1; - goto multi_select_end; - } - addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, unionTab, 0); - if( priorOp==SRT_Table ){ - assert( nSetP2addrOpenEphm[0] == -1 ); - p->addrOpenEphm[0] = addr; - p->pRightmost->usesEphm = 1; - } - createSortingIndex(pParse, p, pOrderBy); - assert( p->pEList ); - } - - /* Code the SELECT statements to our left - */ - assert( !pPrior->pOrderBy ); - rc = sqlite3Select(pParse, pPrior, priorOp, unionTab, 0, 0, 0, aff); - if( rc ){ - goto multi_select_end; - } - - /* Code the current SELECT statement - */ - switch( p->op ){ - case TK_EXCEPT: op = SRT_Except; break; - case TK_UNION: op = SRT_Union; break; - case TK_ALL: op = SRT_Table; break; - } - p->pPrior = 0; - p->pOrderBy = 0; - p->disallowOrderBy = pOrderBy!=0; - pLimit = p->pLimit; - p->pLimit = 0; - pOffset = p->pOffset; - p->pOffset = 0; - rc = sqlite3Select(pParse, p, op, unionTab, 0, 0, 0, aff); - /* Query flattening in sqlite3Select() might refill p->pOrderBy. - ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */ - sqlite3ExprListDelete(p->pOrderBy); - p->pPrior = pPrior; - p->pOrderBy = pOrderBy; - sqlite3ExprDelete(p->pLimit); - p->pLimit = pLimit; - p->pOffset = pOffset; - p->iLimit = -1; - p->iOffset = -1; - if( rc ){ - goto multi_select_end; - } - - - /* Convert the data in the temporary table into whatever form - ** it is that we currently need. - */ - if( eDest!=priorOp || unionTab!=iParm ){ - int iCont, iBreak, iStart; - assert( p->pEList ); - if( eDest==SRT_Callback ){ - Select *pFirst = p; - while( pFirst->pPrior ) pFirst = pFirst->pPrior; - generateColumnNames(pParse, 0, pFirst->pEList); - } - iBreak = sqlite3VdbeMakeLabel(v); - iCont = sqlite3VdbeMakeLabel(v); - computeLimitRegisters(pParse, p, iBreak); - sqlite3VdbeAddOp(v, OP_Rewind, unionTab, iBreak); - iStart = sqlite3VdbeCurrentAddr(v); - rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr, - pOrderBy, -1, eDest, iParm, - iCont, iBreak, 0); - if( rc ){ - rc = 1; - goto multi_select_end; - } - sqlite3VdbeResolveLabel(v, iCont); - sqlite3VdbeAddOp(v, OP_Next, unionTab, iStart); - sqlite3VdbeResolveLabel(v, iBreak); - sqlite3VdbeAddOp(v, OP_Close, unionTab, 0); - } - break; - } - case TK_INTERSECT: { - int tab1, tab2; - int iCont, iBreak, iStart; - Expr *pLimit, *pOffset; - int addr; - - /* INTERSECT is different from the others since it requires - ** two temporary tables. Hence it has its own case. Begin - ** by allocating the tables we will need. - */ - tab1 = pParse->nTab++; - tab2 = pParse->nTab++; - if( pOrderBy && matchOrderbyToColumn(pParse,p,pOrderBy,tab1,1) ){ - rc = 1; - goto multi_select_end; - } - createSortingIndex(pParse, p, pOrderBy); - - addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, tab1, 0); - assert( p->addrOpenEphm[0] == -1 ); - p->addrOpenEphm[0] = addr; - p->pRightmost->usesEphm = 1; - assert( p->pEList ); - - /* Code the SELECTs to our left into temporary table "tab1". - */ - rc = sqlite3Select(pParse, pPrior, SRT_Union, tab1, 0, 0, 0, aff); - if( rc ){ - goto multi_select_end; - } - - /* Code the current SELECT into temporary table "tab2" - */ - addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, tab2, 0); - assert( p->addrOpenEphm[1] == -1 ); - p->addrOpenEphm[1] = addr; - p->pPrior = 0; - pLimit = p->pLimit; - p->pLimit = 0; - pOffset = p->pOffset; - p->pOffset = 0; - rc = sqlite3Select(pParse, p, SRT_Union, tab2, 0, 0, 0, aff); - p->pPrior = pPrior; - sqlite3ExprDelete(p->pLimit); - p->pLimit = pLimit; - p->pOffset = pOffset; - if( rc ){ - goto multi_select_end; - } - - /* Generate code to take the intersection of the two temporary - ** tables. - */ - assert( p->pEList ); - if( eDest==SRT_Callback ){ - Select *pFirst = p; - while( pFirst->pPrior ) pFirst = pFirst->pPrior; - generateColumnNames(pParse, 0, pFirst->pEList); - } - iBreak = sqlite3VdbeMakeLabel(v); - iCont = sqlite3VdbeMakeLabel(v); - computeLimitRegisters(pParse, p, iBreak); - sqlite3VdbeAddOp(v, OP_Rewind, tab1, iBreak); - iStart = sqlite3VdbeAddOp(v, OP_RowKey, tab1, 0); - sqlite3VdbeAddOp(v, OP_NotFound, tab2, iCont); - rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr, - pOrderBy, -1, eDest, iParm, - iCont, iBreak, 0); - if( rc ){ - rc = 1; - goto multi_select_end; - } - sqlite3VdbeResolveLabel(v, iCont); - sqlite3VdbeAddOp(v, OP_Next, tab1, iStart); - sqlite3VdbeResolveLabel(v, iBreak); - sqlite3VdbeAddOp(v, OP_Close, tab2, 0); - sqlite3VdbeAddOp(v, OP_Close, tab1, 0); - break; - } - } - - /* Make sure all SELECTs in the statement have the same number of elements - ** in their result sets. - */ - assert( p->pEList && pPrior->pEList ); - if( p->pEList->nExpr!=pPrior->pEList->nExpr ){ - sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" - " do not have the same number of result columns", selectOpName(p->op)); - rc = 1; - goto multi_select_end; - } - - /* Set the number of columns in temporary tables - */ - nCol = p->pEList->nExpr; - while( nSetP2 ){ - sqlite3VdbeChangeP2(v, aSetP2[--nSetP2], nCol); - } - - /* Compute collating sequences used by either the ORDER BY clause or - ** by any temporary tables needed to implement the compound select. - ** Attach the KeyInfo structure to all temporary tables. Invoke the - ** ORDER BY processing if there is an ORDER BY clause. - ** - ** This section is run by the right-most SELECT statement only. - ** SELECT statements to the left always skip this part. The right-most - ** SELECT might also skip this part if it has no ORDER BY clause and - ** no temp tables are required. - */ - if( pOrderBy || p->usesEphm ){ - int i; /* Loop counter */ - KeyInfo *pKeyInfo; /* Collating sequence for the result set */ - Select *pLoop; /* For looping through SELECT statements */ - int nKeyCol; /* Number of entries in pKeyInfo->aCol[] */ - CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ - CollSeq **aCopy; /* A copy of pKeyInfo->aColl[] */ - - assert( p->pRightmost==p ); - nKeyCol = nCol + (pOrderBy ? pOrderBy->nExpr : 0); - pKeyInfo = sqlite3DbMallocZero(pParse->db, - sizeof(*pKeyInfo)+nKeyCol*(sizeof(CollSeq*) + 1)); - if( !pKeyInfo ){ - rc = SQLITE_NOMEM; - goto multi_select_end; - } - - pKeyInfo->enc = ENC(pParse->db); - pKeyInfo->nField = nCol; - - for(i=0, apColl=pKeyInfo->aColl; idb->pDfltColl; - } - } - - for(pLoop=p; pLoop; pLoop=pLoop->pPrior){ - for(i=0; i<2; i++){ - int addr = pLoop->addrOpenEphm[i]; - if( addr<0 ){ - /* If [0] is unused then [1] is also unused. So we can - ** always safely abort as soon as the first unused slot is found */ - assert( pLoop->addrOpenEphm[1]<0 ); - break; - } - sqlite3VdbeChangeP2(v, addr, nCol); - sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO); - pLoop->addrOpenEphm[i] = -1; - } - } - - if( pOrderBy ){ - struct ExprList_item *pOTerm = pOrderBy->a; - int nOrderByExpr = pOrderBy->nExpr; - int addr; - u8 *pSortOrder; - - /* Reuse the same pKeyInfo for the ORDER BY as was used above for - ** the compound select statements. Except we have to change out the - ** pKeyInfo->aColl[] values. Some of the aColl[] values will be - ** reused when constructing the pKeyInfo for the ORDER BY, so make - ** a copy. Sufficient space to hold both the nCol entries for - ** the compound select and the nOrderbyExpr entries for the ORDER BY - ** was allocated above. But we need to move the compound select - ** entries out of the way before constructing the ORDER BY entries. - ** Move the compound select entries into aCopy[] where they can be - ** accessed and reused when constructing the ORDER BY entries. - ** Because nCol might be greater than or less than nOrderByExpr - ** we have to use memmove() when doing the copy. - */ - aCopy = &pKeyInfo->aColl[nOrderByExpr]; - pSortOrder = pKeyInfo->aSortOrder = (u8*)&aCopy[nCol]; - memmove(aCopy, pKeyInfo->aColl, nCol*sizeof(CollSeq*)); - - apColl = pKeyInfo->aColl; - for(i=0; ipExpr; - if( (pExpr->flags & EP_ExpCollate) ){ - assert( pExpr->pColl!=0 ); - *apColl = pExpr->pColl; - }else{ - *apColl = aCopy[pExpr->iColumn]; - } - *pSortOrder = pOTerm->sortOrder; - } - assert( p->pRightmost==p ); - assert( p->addrOpenEphm[2]>=0 ); - addr = p->addrOpenEphm[2]; - sqlite3VdbeChangeP2(v, addr, p->pOrderBy->nExpr+2); - pKeyInfo->nField = nOrderByExpr; - sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); - pKeyInfo = 0; - generateSortTail(pParse, p, v, p->pEList->nExpr, eDest, iParm); - } - - sqlite3_free(pKeyInfo); - } - -multi_select_end: - return rc; -} -#endif /* SQLITE_OMIT_COMPOUND_SELECT */ - -#ifndef SQLITE_OMIT_VIEW -/* Forward Declarations */ -static void substExprList(sqlite3*, ExprList*, int, ExprList*); -static void substSelect(sqlite3*, Select *, int, ExprList *); - -/* -** Scan through the expression pExpr. Replace every reference to -** a column in table number iTable with a copy of the iColumn-th -** entry in pEList. (But leave references to the ROWID column -** unchanged.) -** -** This routine is part of the flattening procedure. A subquery -** whose result set is defined by pEList appears as entry in the -** FROM clause of a SELECT such that the VDBE cursor assigned to that -** FORM clause entry is iTable. This routine make the necessary -** changes to pExpr so that it refers directly to the source table -** of the subquery rather the result set of the subquery. -*/ -static void substExpr( - sqlite3 *db, /* Report malloc errors to this connection */ - Expr *pExpr, /* Expr in which substitution occurs */ - int iTable, /* Table to be substituted */ - ExprList *pEList /* Substitute expressions */ -){ - if( pExpr==0 ) return; - if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){ - if( pExpr->iColumn<0 ){ - pExpr->op = TK_NULL; - }else{ - Expr *pNew; - assert( pEList!=0 && pExpr->iColumnnExpr ); - assert( pExpr->pLeft==0 && pExpr->pRight==0 && pExpr->pList==0 ); - pNew = pEList->a[pExpr->iColumn].pExpr; - assert( pNew!=0 ); - pExpr->op = pNew->op; - assert( pExpr->pLeft==0 ); - pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft); - assert( pExpr->pRight==0 ); - pExpr->pRight = sqlite3ExprDup(db, pNew->pRight); - assert( pExpr->pList==0 ); - pExpr->pList = sqlite3ExprListDup(db, pNew->pList); - pExpr->iTable = pNew->iTable; - pExpr->pTab = pNew->pTab; - pExpr->iColumn = pNew->iColumn; - pExpr->iAgg = pNew->iAgg; - sqlite3TokenCopy(db, &pExpr->token, &pNew->token); - sqlite3TokenCopy(db, &pExpr->span, &pNew->span); - pExpr->pSelect = sqlite3SelectDup(db, pNew->pSelect); - pExpr->flags = pNew->flags; - } - }else{ - substExpr(db, pExpr->pLeft, iTable, pEList); - substExpr(db, pExpr->pRight, iTable, pEList); - substSelect(db, pExpr->pSelect, iTable, pEList); - substExprList(db, pExpr->pList, iTable, pEList); - } -} -static void substExprList( - sqlite3 *db, /* Report malloc errors here */ - ExprList *pList, /* List to scan and in which to make substitutes */ - int iTable, /* Table to be substituted */ - ExprList *pEList /* Substitute values */ -){ - int i; - if( pList==0 ) return; - for(i=0; inExpr; i++){ - substExpr(db, pList->a[i].pExpr, iTable, pEList); - } -} -static void substSelect( - sqlite3 *db, /* Report malloc errors here */ - Select *p, /* SELECT statement in which to make substitutions */ - int iTable, /* Table to be replaced */ - ExprList *pEList /* Substitute values */ -){ - if( !p ) return; - substExprList(db, p->pEList, iTable, pEList); - substExprList(db, p->pGroupBy, iTable, pEList); - substExprList(db, p->pOrderBy, iTable, pEList); - substExpr(db, p->pHaving, iTable, pEList); - substExpr(db, p->pWhere, iTable, pEList); - substSelect(db, p->pPrior, iTable, pEList); -} -#endif /* !defined(SQLITE_OMIT_VIEW) */ - -#ifndef SQLITE_OMIT_VIEW -/* -** This routine attempts to flatten subqueries in order to speed -** execution. It returns 1 if it makes changes and 0 if no flattening -** occurs. -** -** To understand the concept of flattening, consider the following -** query: -** -** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5 -** -** The default way of implementing this query is to execute the -** subquery first and store the results in a temporary table, then -** run the outer query on that temporary table. This requires two -** passes over the data. Furthermore, because the temporary table -** has no indices, the WHERE clause on the outer query cannot be -** optimized. -** -** This routine attempts to rewrite queries such as the above into -** a single flat select, like this: -** -** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5 -** -** The code generated for this simpification gives the same result -** but only has to scan the data once. And because indices might -** exist on the table t1, a complete scan of the data might be -** avoided. -** -** Flattening is only attempted if all of the following are true: -** -** (1) The subquery and the outer query do not both use aggregates. -** -** (2) The subquery is not an aggregate or the outer query is not a join. -** -** (3) The subquery is not the right operand of a left outer join, or -** the subquery is not itself a join. (Ticket #306) -** -** (4) The subquery is not DISTINCT or the outer query is not a join. -** -** (5) The subquery is not DISTINCT or the outer query does not use -** aggregates. -** -** (6) The subquery does not use aggregates or the outer query is not -** DISTINCT. -** -** (7) The subquery has a FROM clause. -** -** (8) The subquery does not use LIMIT or the outer query is not a join. -** -** (9) The subquery does not use LIMIT or the outer query does not use -** aggregates. -** -** (10) The subquery does not use aggregates or the outer query does not -** use LIMIT. -** -** (11) The subquery and the outer query do not both have ORDER BY clauses. -** -** (12) The subquery is not the right term of a LEFT OUTER JOIN or the -** subquery has no WHERE clause. (added by ticket #350) -** -** (13) The subquery and outer query do not both use LIMIT -** -** (14) The subquery does not use OFFSET -** -** (15) The outer query is not part of a compound select or the -** subquery does not have both an ORDER BY and a LIMIT clause. -** (See ticket #2339) -** -** In this routine, the "p" parameter is a pointer to the outer query. -** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query -** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates. -** -** If flattening is not attempted, this routine is a no-op and returns 0. -** If flattening is attempted this routine returns 1. -** -** All of the expression analysis must occur on both the outer query and -** the subquery before this routine runs. -*/ -static int flattenSubquery( - sqlite3 *db, /* Database connection */ - Select *p, /* The parent or outer SELECT statement */ - int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ - int isAgg, /* True if outer SELECT uses aggregate functions */ - int subqueryIsAgg /* True if the subquery uses aggregate functions */ -){ - Select *pSub; /* The inner query or "subquery" */ - SrcList *pSrc; /* The FROM clause of the outer query */ - SrcList *pSubSrc; /* The FROM clause of the subquery */ - ExprList *pList; /* The result set of the outer query */ - int iParent; /* VDBE cursor number of the pSub result set temp table */ - int i; /* Loop counter */ - Expr *pWhere; /* The WHERE clause */ - struct SrcList_item *pSubitem; /* The subquery */ - - /* Check to see if flattening is permitted. Return 0 if not. - */ - if( p==0 ) return 0; - pSrc = p->pSrc; - assert( pSrc && iFrom>=0 && iFromnSrc ); - pSubitem = &pSrc->a[iFrom]; - pSub = pSubitem->pSelect; - assert( pSub!=0 ); - if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */ - if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */ - pSubSrc = pSub->pSrc; - assert( pSubSrc ); - /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants, - ** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET - ** because they could be computed at compile-time. But when LIMIT and OFFSET - ** became arbitrary expressions, we were forced to add restrictions (13) - ** and (14). */ - if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */ - if( pSub->pOffset ) return 0; /* Restriction (14) */ - if( p->pRightmost && pSub->pLimit && pSub->pOrderBy ){ - return 0; /* Restriction (15) */ - } - if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */ - if( (pSub->isDistinct || pSub->pLimit) - && (pSrc->nSrc>1 || isAgg) ){ /* Restrictions (4)(5)(8)(9) */ - return 0; - } - if( p->isDistinct && subqueryIsAgg ) return 0; /* Restriction (6) */ - if( (p->disallowOrderBy || p->pOrderBy) && pSub->pOrderBy ){ - return 0; /* Restriction (11) */ - } - - /* Restriction 3: If the subquery is a join, make sure the subquery is - ** not used as the right operand of an outer join. Examples of why this - ** is not allowed: - ** - ** t1 LEFT OUTER JOIN (t2 JOIN t3) - ** - ** If we flatten the above, we would get - ** - ** (t1 LEFT OUTER JOIN t2) JOIN t3 - ** - ** which is not at all the same thing. - */ - if( pSubSrc->nSrc>1 && (pSubitem->jointype & JT_OUTER)!=0 ){ - return 0; - } - - /* Restriction 12: If the subquery is the right operand of a left outer - ** join, make sure the subquery has no WHERE clause. - ** An examples of why this is not allowed: - ** - ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0) - ** - ** If we flatten the above, we would get - ** - ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0 - ** - ** But the t2.x>0 test will always fail on a NULL row of t2, which - ** effectively converts the OUTER JOIN into an INNER JOIN. - */ - if( (pSubitem->jointype & JT_OUTER)!=0 && pSub->pWhere!=0 ){ - return 0; - } - - /* If we reach this point, it means flattening is permitted for the - ** iFrom-th entry of the FROM clause in the outer query. - */ - - /* Move all of the FROM elements of the subquery into the - ** the FROM clause of the outer query. Before doing this, remember - ** the cursor number for the original outer query FROM element in - ** iParent. The iParent cursor will never be used. Subsequent code - ** will scan expressions looking for iParent references and replace - ** those references with expressions that resolve to the subquery FROM - ** elements we are now copying in. - */ - iParent = pSubitem->iCursor; - { - int nSubSrc = pSubSrc->nSrc; - int jointype = pSubitem->jointype; - - sqlite3DeleteTable(pSubitem->pTab); - sqlite3_free(pSubitem->zDatabase); - sqlite3_free(pSubitem->zName); - sqlite3_free(pSubitem->zAlias); - if( nSubSrc>1 ){ - int extra = nSubSrc - 1; - for(i=1; ipSrc = pSrc; - for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){ - pSrc->a[i] = pSrc->a[i-extra]; - } - } - for(i=0; ia[i+iFrom] = pSubSrc->a[i]; - memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); - } - pSrc->a[iFrom].jointype = jointype; - } - - /* Now begin substituting subquery result set expressions for - ** references to the iParent in the outer query. - ** - ** Example: - ** - ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b; - ** \ \_____________ subquery __________/ / - ** \_____________________ outer query ______________________________/ - ** - ** We look at every expression in the outer query and every place we see - ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". - */ - pList = p->pEList; - for(i=0; inExpr; i++){ - Expr *pExpr; - if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){ - pList->a[i].zName = - sqlite3DbStrNDup(db, (char*)pExpr->span.z, pExpr->span.n); - } - } - substExprList(db, p->pEList, iParent, pSub->pEList); - if( isAgg ){ - substExprList(db, p->pGroupBy, iParent, pSub->pEList); - substExpr(db, p->pHaving, iParent, pSub->pEList); - } - if( pSub->pOrderBy ){ - assert( p->pOrderBy==0 ); - p->pOrderBy = pSub->pOrderBy; - pSub->pOrderBy = 0; - }else if( p->pOrderBy ){ - substExprList(db, p->pOrderBy, iParent, pSub->pEList); - } - if( pSub->pWhere ){ - pWhere = sqlite3ExprDup(db, pSub->pWhere); - }else{ - pWhere = 0; - } - if( subqueryIsAgg ){ - assert( p->pHaving==0 ); - p->pHaving = p->pWhere; - p->pWhere = pWhere; - substExpr(db, p->pHaving, iParent, pSub->pEList); - p->pHaving = sqlite3ExprAnd(db, p->pHaving, - sqlite3ExprDup(db, pSub->pHaving)); - assert( p->pGroupBy==0 ); - p->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy); - }else{ - substExpr(db, p->pWhere, iParent, pSub->pEList); - p->pWhere = sqlite3ExprAnd(db, p->pWhere, pWhere); - } - - /* The flattened query is distinct if either the inner or the - ** outer query is distinct. - */ - p->isDistinct = p->isDistinct || pSub->isDistinct; - - /* - ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y; - ** - ** One is tempted to try to add a and b to combine the limits. But this - ** does not work if either limit is negative. - */ - if( pSub->pLimit ){ - p->pLimit = pSub->pLimit; - pSub->pLimit = 0; - } - - /* Finially, delete what is left of the subquery and return - ** success. - */ - sqlite3SelectDelete(pSub); - return 1; -} -#endif /* SQLITE_OMIT_VIEW */ - -/* -** Analyze the SELECT statement passed in as an argument to see if it -** is a simple min() or max() query. If it is and this query can be -** satisfied using a single seek to the beginning or end of an index, -** then generate the code for this SELECT and return 1. If this is not a -** simple min() or max() query, then return 0; -** -** A simply min() or max() query looks like this: -** -** SELECT min(a) FROM table; -** SELECT max(a) FROM table; -** -** The query may have only a single table in its FROM argument. There -** can be no GROUP BY or HAVING or WHERE clauses. The result set must -** be the min() or max() of a single column of the table. The column -** in the min() or max() function must be indexed. -** -** The parameters to this routine are the same as for sqlite3Select(). -** See the header comment on that routine for additional information. -*/ -static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ - Expr *pExpr; - int iCol; - Table *pTab; - Index *pIdx; - int base; - Vdbe *v; - int seekOp; - ExprList *pEList, *pList, eList; - struct ExprList_item eListItem; - SrcList *pSrc; - int brk; - int iDb; - - /* Check to see if this query is a simple min() or max() query. Return - ** zero if it is not. - */ - if( p->pGroupBy || p->pHaving || p->pWhere ) return 0; - pSrc = p->pSrc; - if( pSrc->nSrc!=1 ) return 0; - pEList = p->pEList; - if( pEList->nExpr!=1 ) return 0; - pExpr = pEList->a[0].pExpr; - if( pExpr->op!=TK_AGG_FUNCTION ) return 0; - pList = pExpr->pList; - if( pList==0 || pList->nExpr!=1 ) return 0; - if( pExpr->token.n!=3 ) return 0; - if( sqlite3StrNICmp((char*)pExpr->token.z,"min",3)==0 ){ - seekOp = OP_Rewind; - }else if( sqlite3StrNICmp((char*)pExpr->token.z,"max",3)==0 ){ - seekOp = OP_Last; - }else{ - return 0; - } - pExpr = pList->a[0].pExpr; - if( pExpr->op!=TK_COLUMN ) return 0; - iCol = pExpr->iColumn; - pTab = pSrc->a[0].pTab; - - /* This optimization cannot be used with virtual tables. */ - if( IsVirtual(pTab) ) return 0; - - /* If we get to here, it means the query is of the correct form. - ** Check to make sure we have an index and make pIdx point to the - ** appropriate index. If the min() or max() is on an INTEGER PRIMARY - ** key column, no index is necessary so set pIdx to NULL. If no - ** usable index is found, return 0. - */ - if( iCol<0 ){ - pIdx = 0; - }else{ - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr); - if( pColl==0 ) return 0; - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - assert( pIdx->nColumn>=1 ); - if( pIdx->aiColumn[0]==iCol && - 0==sqlite3StrICmp(pIdx->azColl[0], pColl->zName) ){ - break; - } - } - if( pIdx==0 ) return 0; - } - - /* Identify column types if we will be using the callback. This - ** step is skipped if the output is going to a table or a memory cell. - ** The column names have already been generated in the calling function. - */ - v = sqlite3GetVdbe(pParse); - if( v==0 ) return 0; - - /* If the output is destined for a temporary table, open that table. - */ - if( eDest==SRT_EphemTab ){ - sqlite3VdbeAddOp(v, OP_OpenEphemeral, iParm, 1); - } - - /* Generating code to find the min or the max. Basically all we have - ** to do is find the first or the last entry in the chosen index. If - ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first - ** or last entry in the main table. - */ - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - assert( iDb>=0 || pTab->isEphem ); - sqlite3CodeVerifySchema(pParse, iDb); - sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - base = pSrc->a[0].iCursor; - brk = sqlite3VdbeMakeLabel(v); - computeLimitRegisters(pParse, p, brk); - if( pSrc->a[0].pSelect==0 ){ - sqlite3OpenTable(pParse, base, iDb, pTab, OP_OpenRead); - } - if( pIdx==0 ){ - sqlite3VdbeAddOp(v, seekOp, base, 0); - }else{ - /* Even though the cursor used to open the index here is closed - ** as soon as a single value has been read from it, allocate it - ** using (pParse->nTab++) to prevent the cursor id from being - ** reused. This is important for statements of the form - ** "INSERT INTO x SELECT max() FROM x". - */ - int iIdx; - KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); - iIdx = pParse->nTab++; - assert( pIdx->pSchema==pTab->pSchema ); - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); - sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum, - (char*)pKey, P3_KEYINFO_HANDOFF); - if( seekOp==OP_Rewind ){ - sqlite3VdbeAddOp(v, OP_Null, 0, 0); - sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0); - seekOp = OP_MoveGt; - } - if( pIdx->aSortOrder[0]==SQLITE_SO_DESC ){ - /* Ticket #2514: invert the seek operator if we are using - ** a descending index. */ - if( seekOp==OP_Last ){ - seekOp = OP_Rewind; - }else{ - assert( seekOp==OP_MoveGt ); - seekOp = OP_MoveLt; - } - } - sqlite3VdbeAddOp(v, seekOp, iIdx, 0); - sqlite3VdbeAddOp(v, OP_IdxRowid, iIdx, 0); - sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); - sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); - } - eList.nExpr = 1; - memset(&eListItem, 0, sizeof(eListItem)); - eList.a = &eListItem; - eList.a[0].pExpr = pExpr; - selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, brk, brk, 0); - sqlite3VdbeResolveLabel(v, brk); - sqlite3VdbeAddOp(v, OP_Close, base, 0); - - return 1; -} - -/* -** Analyze and ORDER BY or GROUP BY clause in a SELECT statement. Return -** the number of errors seen. -** -** An ORDER BY or GROUP BY is a list of expressions. If any expression -** is an integer constant, then that expression is replaced by the -** corresponding entry in the result set. -*/ -static int processOrderGroupBy( - NameContext *pNC, /* Name context of the SELECT statement. */ - ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */ - const char *zType /* Either "ORDER" or "GROUP", as appropriate */ -){ - int i; - ExprList *pEList = pNC->pEList; /* The result set of the SELECT */ - Parse *pParse = pNC->pParse; /* The result set of the SELECT */ - assert( pEList ); - - if( pOrderBy==0 ) return 0; - if( pOrderBy->nExpr>SQLITE_MAX_COLUMN ){ - sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); - return 1; - } - for(i=0; inExpr; i++){ - int iCol; - Expr *pE = pOrderBy->a[i].pExpr; - if( sqlite3ExprIsInteger(pE, &iCol) ){ - if( iCol>0 && iCol<=pEList->nExpr ){ - CollSeq *pColl = pE->pColl; - int flags = pE->flags & EP_ExpCollate; - sqlite3ExprDelete(pE); - pE = sqlite3ExprDup(pParse->db, pEList->a[iCol-1].pExpr); - pOrderBy->a[i].pExpr = pE; - if( pColl && flags ){ - pE->pColl = pColl; - pE->flags |= flags; - } - }else{ - sqlite3ErrorMsg(pParse, - "%s BY column number %d out of range - should be " - "between 1 and %d", zType, iCol, pEList->nExpr); - return 1; - } - } - if( sqlite3ExprResolveNames(pNC, pE) ){ - return 1; - } - } - return 0; -} - -/* -** This routine resolves any names used in the result set of the -** supplied SELECT statement. If the SELECT statement being resolved -** is a sub-select, then pOuterNC is a pointer to the NameContext -** of the parent SELECT. -*/ -int sqlite3SelectResolve( - Parse *pParse, /* The parser context */ - Select *p, /* The SELECT statement being coded. */ - NameContext *pOuterNC /* The outer name context. May be NULL. */ -){ - ExprList *pEList; /* Result set. */ - int i; /* For-loop variable used in multiple places */ - NameContext sNC; /* Local name-context */ - ExprList *pGroupBy; /* The group by clause */ - - /* If this routine has run before, return immediately. */ - if( p->isResolved ){ - assert( !pOuterNC ); - return SQLITE_OK; - } - p->isResolved = 1; - - /* If there have already been errors, do nothing. */ - if( pParse->nErr>0 ){ - return SQLITE_ERROR; - } - - /* Prepare the select statement. This call will allocate all cursors - ** required to handle the tables and subqueries in the FROM clause. - */ - if( prepSelectStmt(pParse, p) ){ - return SQLITE_ERROR; - } - - /* Resolve the expressions in the LIMIT and OFFSET clauses. These - ** are not allowed to refer to any names, so pass an empty NameContext. - */ - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - if( sqlite3ExprResolveNames(&sNC, p->pLimit) || - sqlite3ExprResolveNames(&sNC, p->pOffset) ){ - return SQLITE_ERROR; - } - - /* Set up the local name-context to pass to ExprResolveNames() to - ** resolve the expression-list. - */ - sNC.allowAgg = 1; - sNC.pSrcList = p->pSrc; - sNC.pNext = pOuterNC; - - /* Resolve names in the result set. */ - pEList = p->pEList; - if( !pEList ) return SQLITE_ERROR; - for(i=0; inExpr; i++){ - Expr *pX = pEList->a[i].pExpr; - if( sqlite3ExprResolveNames(&sNC, pX) ){ - return SQLITE_ERROR; - } - } - - /* If there are no aggregate functions in the result-set, and no GROUP BY - ** expression, do not allow aggregates in any of the other expressions. - */ - assert( !p->isAgg ); - pGroupBy = p->pGroupBy; - if( pGroupBy || sNC.hasAgg ){ - p->isAgg = 1; - }else{ - sNC.allowAgg = 0; - } - - /* If a HAVING clause is present, then there must be a GROUP BY clause. - */ - if( p->pHaving && !pGroupBy ){ - sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); - return SQLITE_ERROR; - } - - /* Add the expression list to the name-context before parsing the - ** other expressions in the SELECT statement. This is so that - ** expressions in the WHERE clause (etc.) can refer to expressions by - ** aliases in the result set. - ** - ** Minor point: If this is the case, then the expression will be - ** re-evaluated for each reference to it. - */ - sNC.pEList = p->pEList; - if( sqlite3ExprResolveNames(&sNC, p->pWhere) || - sqlite3ExprResolveNames(&sNC, p->pHaving) ){ - return SQLITE_ERROR; - } - if( p->pPrior==0 ){ - if( processOrderGroupBy(&sNC, p->pOrderBy, "ORDER") || - processOrderGroupBy(&sNC, pGroupBy, "GROUP") ){ - return SQLITE_ERROR; - } - } - - if( pParse->db->mallocFailed ){ - return SQLITE_NOMEM; - } - - /* Make sure the GROUP BY clause does not contain aggregate functions. - */ - if( pGroupBy ){ - struct ExprList_item *pItem; - - for(i=0, pItem=pGroupBy->a; inExpr; i++, pItem++){ - if( ExprHasProperty(pItem->pExpr, EP_Agg) ){ - sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in " - "the GROUP BY clause"); - return SQLITE_ERROR; - } - } - } - - /* If this is one SELECT of a compound, be sure to resolve names - ** in the other SELECTs. - */ - if( p->pPrior ){ - return sqlite3SelectResolve(pParse, p->pPrior, pOuterNC); - }else{ - return SQLITE_OK; - } -} - -/* -** Reset the aggregate accumulator. -** -** The aggregate accumulator is a set of memory cells that hold -** intermediate results while calculating an aggregate. This -** routine simply stores NULLs in all of those memory cells. -*/ -static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ - Vdbe *v = pParse->pVdbe; - int i; - struct AggInfo_func *pFunc; - if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){ - return; - } - for(i=0; inColumn; i++){ - sqlite3VdbeAddOp(v, OP_MemNull, pAggInfo->aCol[i].iMem, 0); - } - for(pFunc=pAggInfo->aFunc, i=0; inFunc; i++, pFunc++){ - sqlite3VdbeAddOp(v, OP_MemNull, pFunc->iMem, 0); - if( pFunc->iDistinct>=0 ){ - Expr *pE = pFunc->pExpr; - if( pE->pList==0 || pE->pList->nExpr!=1 ){ - sqlite3ErrorMsg(pParse, "DISTINCT in aggregate must be followed " - "by an expression"); - pFunc->iDistinct = -1; - }else{ - KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->pList); - sqlite3VdbeOp3(v, OP_OpenEphemeral, pFunc->iDistinct, 0, - (char*)pKeyInfo, P3_KEYINFO_HANDOFF); - } - } - } -} - -/* -** Invoke the OP_AggFinalize opcode for every aggregate function -** in the AggInfo structure. -*/ -static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ - Vdbe *v = pParse->pVdbe; - int i; - struct AggInfo_func *pF; - for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ - ExprList *pList = pF->pExpr->pList; - sqlite3VdbeOp3(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, - (void*)pF->pFunc, P3_FUNCDEF); - } -} - -/* -** Update the accumulator memory cells for an aggregate based on -** the current cursor position. -*/ -static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ - Vdbe *v = pParse->pVdbe; - int i; - struct AggInfo_func *pF; - struct AggInfo_col *pC; - - pAggInfo->directMode = 1; - for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ - int nArg; - int addrNext = 0; - ExprList *pList = pF->pExpr->pList; - if( pList ){ - nArg = pList->nExpr; - sqlite3ExprCodeExprList(pParse, pList); - }else{ - nArg = 0; - } - if( pF->iDistinct>=0 ){ - addrNext = sqlite3VdbeMakeLabel(v); - assert( nArg==1 ); - codeDistinct(v, pF->iDistinct, addrNext, 1); - } - if( pF->pFunc->needCollSeq ){ - CollSeq *pColl = 0; - struct ExprList_item *pItem; - int j; - assert( pList!=0 ); /* pList!=0 if pF->pFunc->needCollSeq is true */ - for(j=0, pItem=pList->a; !pColl && jpExpr); - } - if( !pColl ){ - pColl = pParse->db->pDfltColl; - } - sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ); - } - sqlite3VdbeOp3(v, OP_AggStep, pF->iMem, nArg, (void*)pF->pFunc, P3_FUNCDEF); - if( addrNext ){ - sqlite3VdbeResolveLabel(v, addrNext); - } - } - for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ - sqlite3ExprCode(pParse, pC->pExpr); - sqlite3VdbeAddOp(v, OP_MemStore, pC->iMem, 1); - } - pAggInfo->directMode = 0; -} - - -/* -** Generate code for the given SELECT statement. -** -** The results are distributed in various ways depending on the -** value of eDest and iParm. -** -** eDest Value Result -** ------------ ------------------------------------------- -** SRT_Callback Invoke the callback for each row of the result. -** -** SRT_Mem Store first result in memory cell iParm -** -** SRT_Set Store results as keys of table iParm. -** -** SRT_Union Store results as a key in a temporary table iParm -** -** SRT_Except Remove results from the temporary table iParm. -** -** SRT_Table Store results in temporary table iParm -** -** The table above is incomplete. Additional eDist value have be added -** since this comment was written. See the selectInnerLoop() function for -** a complete listing of the allowed values of eDest and their meanings. -** -** This routine returns the number of errors. If any errors are -** encountered, then an appropriate error message is left in -** pParse->zErrMsg. -** -** This routine does NOT free the Select structure passed in. The -** calling function needs to do that. -** -** The pParent, parentTab, and *pParentAgg fields are filled in if this -** SELECT is a subquery. This routine may try to combine this SELECT -** with its parent to form a single flat query. In so doing, it might -** change the parent query from a non-aggregate to an aggregate query. -** For that reason, the pParentAgg flag is passed as a pointer, so it -** can be changed. -** -** Example 1: The meaning of the pParent parameter. -** -** SELECT * FROM t1 JOIN (SELECT x, count(*) FROM t2) JOIN t3; -** \ \_______ subquery _______/ / -** \ / -** \____________________ outer query ___________________/ -** -** This routine is called for the outer query first. For that call, -** pParent will be NULL. During the processing of the outer query, this -** routine is called recursively to handle the subquery. For the recursive -** call, pParent will point to the outer query. Because the subquery is -** the second element in a three-way join, the parentTab parameter will -** be 1 (the 2nd value of a 0-indexed array.) -*/ -int sqlite3Select( - Parse *pParse, /* The parser context */ - Select *p, /* The SELECT statement being coded. */ - int eDest, /* How to dispose of the results */ - int iParm, /* A parameter used by the eDest disposal method */ - Select *pParent, /* Another SELECT for which this is a sub-query */ - int parentTab, /* Index in pParent->pSrc of this query */ - int *pParentAgg, /* True if pParent uses aggregate functions */ - char *aff /* If eDest is SRT_Union, the affinity string */ -){ - int i, j; /* Loop counters */ - WhereInfo *pWInfo; /* Return from sqlite3WhereBegin() */ - Vdbe *v; /* The virtual machine under construction */ - int isAgg; /* True for select lists like "count(*)" */ - ExprList *pEList; /* List of columns to extract. */ - SrcList *pTabList; /* List of tables to select from */ - Expr *pWhere; /* The WHERE clause. May be NULL */ - ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */ - ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ - Expr *pHaving; /* The HAVING clause. May be NULL */ - int isDistinct; /* True if the DISTINCT keyword is present */ - int distinct; /* Table to use for the distinct set */ - int rc = 1; /* Value to return from this function */ - int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ - AggInfo sAggInfo; /* Information used by aggregate queries */ - int iEnd; /* Address of the end of the query */ - sqlite3 *db; /* The database connection */ - - db = pParse->db; - if( p==0 || db->mallocFailed || pParse->nErr ){ - return 1; - } - if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; - memset(&sAggInfo, 0, sizeof(sAggInfo)); - -#ifndef SQLITE_OMIT_COMPOUND_SELECT - /* If there is are a sequence of queries, do the earlier ones first. - */ - if( p->pPrior ){ - if( p->pRightmost==0 ){ - Select *pLoop; - int cnt = 0; - for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){ - pLoop->pRightmost = p; - } - if( SQLITE_MAX_COMPOUND_SELECT>0 && cnt>SQLITE_MAX_COMPOUND_SELECT ){ - sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); - return 1; - } - } - return multiSelect(pParse, p, eDest, iParm, aff); - } -#endif - - pOrderBy = p->pOrderBy; - if( IgnorableOrderby(eDest) ){ - p->pOrderBy = 0; - } - if( sqlite3SelectResolve(pParse, p, 0) ){ - goto select_end; - } - p->pOrderBy = pOrderBy; - - /* Make local copies of the parameters for this query. - */ - pTabList = p->pSrc; - pWhere = p->pWhere; - pGroupBy = p->pGroupBy; - pHaving = p->pHaving; - isAgg = p->isAgg; - isDistinct = p->isDistinct; - pEList = p->pEList; - if( pEList==0 ) goto select_end; - - /* - ** Do not even attempt to generate any code if we have already seen - ** errors before this routine starts. - */ - if( pParse->nErr>0 ) goto select_end; - - /* If writing to memory or generating a set - ** only a single column may be output. - */ -#ifndef SQLITE_OMIT_SUBQUERY - if( checkForMultiColumnSelectError(pParse, eDest, pEList->nExpr) ){ - goto select_end; - } -#endif - - /* ORDER BY is ignored for some destinations. - */ - if( IgnorableOrderby(eDest) ){ - pOrderBy = 0; - } - - /* Begin generating code. - */ - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto select_end; - - /* Generate code for all sub-queries in the FROM clause - */ -#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) - for(i=0; inSrc; i++){ - const char *zSavedAuthContext = 0; - int needRestoreContext; - struct SrcList_item *pItem = &pTabList->a[i]; - - if( pItem->pSelect==0 || pItem->isPopulated ) continue; - if( pItem->zName!=0 ){ - zSavedAuthContext = pParse->zAuthContext; - pParse->zAuthContext = pItem->zName; - needRestoreContext = 1; - }else{ - needRestoreContext = 0; - } -#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0 - /* Increment Parse.nHeight by the height of the largest expression - ** tree refered to by this, the parent select. The child select - ** may contain expression trees of at most - ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit - ** more conservative than necessary, but much easier than enforcing - ** an exact limit. - */ - pParse->nHeight += sqlite3SelectExprHeight(p); -#endif - sqlite3Select(pParse, pItem->pSelect, SRT_EphemTab, - pItem->iCursor, p, i, &isAgg, 0); -#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0 - pParse->nHeight -= sqlite3SelectExprHeight(p); -#endif - if( needRestoreContext ){ - pParse->zAuthContext = zSavedAuthContext; - } - pTabList = p->pSrc; - pWhere = p->pWhere; - if( !IgnorableOrderby(eDest) ){ - pOrderBy = p->pOrderBy; - } - pGroupBy = p->pGroupBy; - pHaving = p->pHaving; - isDistinct = p->isDistinct; - } -#endif - - /* Check for the special case of a min() or max() function by itself - ** in the result set. - */ - if( simpleMinMaxQuery(pParse, p, eDest, iParm) ){ - rc = 0; - goto select_end; - } - - /* Check to see if this is a subquery that can be "flattened" into its parent. - ** If flattening is a possiblity, do so and return immediately. - */ -#ifndef SQLITE_OMIT_VIEW - if( pParent && pParentAgg && - flattenSubquery(db, pParent, parentTab, *pParentAgg, isAgg) ){ - if( isAgg ) *pParentAgg = 1; - goto select_end; - } -#endif - - /* If there is an ORDER BY clause, then this sorting - ** index might end up being unused if the data can be - ** extracted in pre-sorted order. If that is the case, then the - ** OP_OpenEphemeral instruction will be changed to an OP_Noop once - ** we figure out that the sorting index is not needed. The addrSortIndex - ** variable is used to facilitate that change. - */ - if( pOrderBy ){ - KeyInfo *pKeyInfo; - if( pParse->nErr ){ - goto select_end; - } - pKeyInfo = keyInfoFromExprList(pParse, pOrderBy); - pOrderBy->iECursor = pParse->nTab++; - p->addrOpenEphm[2] = addrSortIndex = - sqlite3VdbeOp3(v, OP_OpenEphemeral, pOrderBy->iECursor, pOrderBy->nExpr+2, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); - }else{ - addrSortIndex = -1; - } - - /* If the output is destined for a temporary table, open that table. - */ - if( eDest==SRT_EphemTab ){ - sqlite3VdbeAddOp(v, OP_OpenEphemeral, iParm, pEList->nExpr); - } - - /* Set the limiter. - */ - iEnd = sqlite3VdbeMakeLabel(v); - computeLimitRegisters(pParse, p, iEnd); - - /* Open a virtual index to use for the distinct set. - */ - if( isDistinct ){ - KeyInfo *pKeyInfo; - distinct = pParse->nTab++; - pKeyInfo = keyInfoFromExprList(pParse, p->pEList); - sqlite3VdbeOp3(v, OP_OpenEphemeral, distinct, 0, - (char*)pKeyInfo, P3_KEYINFO_HANDOFF); - }else{ - distinct = -1; - } - - /* Aggregate and non-aggregate queries are handled differently */ - if( !isAgg && pGroupBy==0 ){ - /* This case is for non-aggregate queries - ** Begin the database scan - */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy); - if( pWInfo==0 ) goto select_end; - - /* If sorting index that was created by a prior OP_OpenEphemeral - ** instruction ended up not being needed, then change the OP_OpenEphemeral - ** into an OP_Noop. - */ - if( addrSortIndex>=0 && pOrderBy==0 ){ - sqlite3VdbeChangeToNoop(v, addrSortIndex, 1); - p->addrOpenEphm[2] = -1; - } - - /* Use the standard inner loop - */ - if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest, - iParm, pWInfo->iContinue, pWInfo->iBreak, aff) ){ - goto select_end; - } - - /* End the database scan loop. - */ - sqlite3WhereEnd(pWInfo); - }else{ - /* This is the processing for aggregate queries */ - NameContext sNC; /* Name context for processing aggregate information */ - int iAMem; /* First Mem address for storing current GROUP BY */ - int iBMem; /* First Mem address for previous GROUP BY */ - int iUseFlag; /* Mem address holding flag indicating that at least - ** one row of the input to the aggregator has been - ** processed */ - int iAbortFlag; /* Mem address which causes query abort if positive */ - int groupBySort; /* Rows come from source in GROUP BY order */ - - - /* The following variables hold addresses or labels for parts of the - ** virtual machine program we are putting together */ - int addrOutputRow; /* Start of subroutine that outputs a result row */ - int addrSetAbort; /* Set the abort flag and return */ - int addrInitializeLoop; /* Start of code that initializes the input loop */ - int addrTopOfLoop; /* Top of the input loop */ - int addrGroupByChange; /* Code that runs when any GROUP BY term changes */ - int addrProcessRow; /* Code to process a single input row */ - int addrEnd; /* End of all processing */ - int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ - int addrReset; /* Subroutine for resetting the accumulator */ - - addrEnd = sqlite3VdbeMakeLabel(v); - - /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in - ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the - ** SELECT statement. - */ - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - sNC.pSrcList = pTabList; - sNC.pAggInfo = &sAggInfo; - sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0; - sAggInfo.pGroupBy = pGroupBy; - if( sqlite3ExprAnalyzeAggList(&sNC, pEList) ){ - goto select_end; - } - if( sqlite3ExprAnalyzeAggList(&sNC, pOrderBy) ){ - goto select_end; - } - if( pHaving && sqlite3ExprAnalyzeAggregates(&sNC, pHaving) ){ - goto select_end; - } - sAggInfo.nAccumulator = sAggInfo.nColumn; - for(i=0; ipList) ){ - goto select_end; - } - } - if( db->mallocFailed ) goto select_end; - - /* Processing for aggregates with GROUP BY is very different and - ** much more complex tha aggregates without a GROUP BY. - */ - if( pGroupBy ){ - KeyInfo *pKeyInfo; /* Keying information for the group by clause */ - - /* Create labels that we will be needing - */ - - addrInitializeLoop = sqlite3VdbeMakeLabel(v); - addrGroupByChange = sqlite3VdbeMakeLabel(v); - addrProcessRow = sqlite3VdbeMakeLabel(v); - - /* If there is a GROUP BY clause we might need a sorting index to - ** implement it. Allocate that sorting index now. If it turns out - ** that we do not need it after all, the OpenEphemeral instruction - ** will be converted into a Noop. - */ - sAggInfo.sortingIdx = pParse->nTab++; - pKeyInfo = keyInfoFromExprList(pParse, pGroupBy); - addrSortingIdx = - sqlite3VdbeOp3(v, OP_OpenEphemeral, sAggInfo.sortingIdx, - sAggInfo.nSortingColumn, - (char*)pKeyInfo, P3_KEYINFO_HANDOFF); - - /* Initialize memory locations used by GROUP BY aggregate processing - */ - iUseFlag = pParse->nMem++; - iAbortFlag = pParse->nMem++; - iAMem = pParse->nMem; - pParse->nMem += pGroupBy->nExpr; - iBMem = pParse->nMem; - pParse->nMem += pGroupBy->nExpr; - sqlite3VdbeAddOp(v, OP_MemInt, 0, iAbortFlag); - VdbeComment((v, "# clear abort flag")); - sqlite3VdbeAddOp(v, OP_MemInt, 0, iUseFlag); - VdbeComment((v, "# indicate accumulator empty")); - sqlite3VdbeAddOp(v, OP_Goto, 0, addrInitializeLoop); - - /* Generate a subroutine that outputs a single row of the result - ** set. This subroutine first looks at the iUseFlag. If iUseFlag - ** is less than or equal to zero, the subroutine is a no-op. If - ** the processing calls for the query to abort, this subroutine - ** increments the iAbortFlag memory location before returning in - ** order to signal the caller to abort. - */ - addrSetAbort = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp(v, OP_MemInt, 1, iAbortFlag); - VdbeComment((v, "# set abort flag")); - sqlite3VdbeAddOp(v, OP_Return, 0, 0); - addrOutputRow = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp(v, OP_IfMemPos, iUseFlag, addrOutputRow+2); - VdbeComment((v, "# Groupby result generator entry point")); - sqlite3VdbeAddOp(v, OP_Return, 0, 0); - finalizeAggFunctions(pParse, &sAggInfo); - if( pHaving ){ - sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, 1); - } - rc = selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy, - distinct, eDest, iParm, - addrOutputRow+1, addrSetAbort, aff); - if( rc ){ - goto select_end; - } - sqlite3VdbeAddOp(v, OP_Return, 0, 0); - VdbeComment((v, "# end groupby result generator")); - - /* Generate a subroutine that will reset the group-by accumulator - */ - addrReset = sqlite3VdbeCurrentAddr(v); - resetAccumulator(pParse, &sAggInfo); - sqlite3VdbeAddOp(v, OP_Return, 0, 0); - - /* Begin a loop that will extract all source rows in GROUP BY order. - ** This might involve two separate loops with an OP_Sort in between, or - ** it might be a single loop that uses an index to extract information - ** in the right order to begin with. - */ - sqlite3VdbeResolveLabel(v, addrInitializeLoop); - sqlite3VdbeAddOp(v, OP_Gosub, 0, addrReset); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy); - if( pWInfo==0 ) goto select_end; - if( pGroupBy==0 ){ - /* The optimizer is able to deliver rows in group by order so - ** we do not have to sort. The OP_OpenEphemeral table will be - ** cancelled later because we still need to use the pKeyInfo - */ - pGroupBy = p->pGroupBy; - groupBySort = 0; - }else{ - /* Rows are coming out in undetermined order. We have to push - ** each row into a sorting index, terminate the first loop, - ** then loop over the sorting index in order to get the output - ** in sorted order - */ - groupBySort = 1; - sqlite3ExprCodeExprList(pParse, pGroupBy); - sqlite3VdbeAddOp(v, OP_Sequence, sAggInfo.sortingIdx, 0); - j = pGroupBy->nExpr+1; - for(i=0; iiSorterColumnpTab, pCol->iColumn, pCol->iTable); - j++; - } - sqlite3VdbeAddOp(v, OP_MakeRecord, j, 0); - sqlite3VdbeAddOp(v, OP_IdxInsert, sAggInfo.sortingIdx, 0); - sqlite3WhereEnd(pWInfo); - sqlite3VdbeAddOp(v, OP_Sort, sAggInfo.sortingIdx, addrEnd); - VdbeComment((v, "# GROUP BY sort")); - sAggInfo.useSortingIdx = 1; - } - - /* Evaluate the current GROUP BY terms and store in b0, b1, b2... - ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth) - ** Then compare the current GROUP BY terms against the GROUP BY terms - ** from the previous row currently stored in a0, a1, a2... - */ - addrTopOfLoop = sqlite3VdbeCurrentAddr(v); - for(j=0; jnExpr; j++){ - if( groupBySort ){ - sqlite3VdbeAddOp(v, OP_Column, sAggInfo.sortingIdx, j); - }else{ - sAggInfo.directMode = 1; - sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr); - } - sqlite3VdbeAddOp(v, OP_MemStore, iBMem+j, jnExpr-1); - } - for(j=pGroupBy->nExpr-1; j>=0; j--){ - if( jnExpr-1 ){ - sqlite3VdbeAddOp(v, OP_MemLoad, iBMem+j, 0); - } - sqlite3VdbeAddOp(v, OP_MemLoad, iAMem+j, 0); - if( j==0 ){ - sqlite3VdbeAddOp(v, OP_Eq, 0x200, addrProcessRow); - }else{ - sqlite3VdbeAddOp(v, OP_Ne, 0x200, addrGroupByChange); - } - sqlite3VdbeChangeP3(v, -1, (void*)pKeyInfo->aColl[j], P3_COLLSEQ); - } - - /* Generate code that runs whenever the GROUP BY changes. - ** Change in the GROUP BY are detected by the previous code - ** block. If there were no changes, this block is skipped. - ** - ** This code copies current group by terms in b0,b1,b2,... - ** over to a0,a1,a2. It then calls the output subroutine - ** and resets the aggregate accumulator registers in preparation - ** for the next GROUP BY batch. - */ - sqlite3VdbeResolveLabel(v, addrGroupByChange); - for(j=0; jnExpr; j++){ - sqlite3VdbeAddOp(v, OP_MemMove, iAMem+j, iBMem+j); - } - sqlite3VdbeAddOp(v, OP_Gosub, 0, addrOutputRow); - VdbeComment((v, "# output one row")); - sqlite3VdbeAddOp(v, OP_IfMemPos, iAbortFlag, addrEnd); - VdbeComment((v, "# check abort flag")); - sqlite3VdbeAddOp(v, OP_Gosub, 0, addrReset); - VdbeComment((v, "# reset accumulator")); - - /* Update the aggregate accumulators based on the content of - ** the current row - */ - sqlite3VdbeResolveLabel(v, addrProcessRow); - updateAccumulator(pParse, &sAggInfo); - sqlite3VdbeAddOp(v, OP_MemInt, 1, iUseFlag); - VdbeComment((v, "# indicate data in accumulator")); - - /* End of the loop - */ - if( groupBySort ){ - sqlite3VdbeAddOp(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop); - }else{ - sqlite3WhereEnd(pWInfo); - sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1); - } - - /* Output the final row of result - */ - sqlite3VdbeAddOp(v, OP_Gosub, 0, addrOutputRow); - VdbeComment((v, "# output final row")); - - } /* endif pGroupBy */ - else { - /* This case runs if the aggregate has no GROUP BY clause. The - ** processing is much simpler since there is only a single row - ** of output. - */ - resetAccumulator(pParse, &sAggInfo); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0); - if( pWInfo==0 ) goto select_end; - updateAccumulator(pParse, &sAggInfo); - sqlite3WhereEnd(pWInfo); - finalizeAggFunctions(pParse, &sAggInfo); - pOrderBy = 0; - if( pHaving ){ - sqlite3ExprIfFalse(pParse, pHaving, addrEnd, 1); - } - selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1, - eDest, iParm, addrEnd, addrEnd, aff); - } - sqlite3VdbeResolveLabel(v, addrEnd); - - } /* endif aggregate query */ - - /* If there is an ORDER BY clause, then we need to sort the results - ** and send them to the callback one by one. - */ - if( pOrderBy ){ - generateSortTail(pParse, p, v, pEList->nExpr, eDest, iParm); - } - -#ifndef SQLITE_OMIT_SUBQUERY - /* If this was a subquery, we have now converted the subquery into a - ** temporary table. So set the SrcList_item.isPopulated flag to prevent - ** this subquery from being evaluated again and to force the use of - ** the temporary table. - */ - if( pParent ){ - assert( pParent->pSrc->nSrc>parentTab ); - assert( pParent->pSrc->a[parentTab].pSelect==p ); - pParent->pSrc->a[parentTab].isPopulated = 1; - } -#endif - - /* Jump here to skip this query - */ - sqlite3VdbeResolveLabel(v, iEnd); - - /* The SELECT was successfully coded. Set the return code to 0 - ** to indicate no errors. - */ - rc = 0; - - /* Control jumps to here if an error is encountered above, or upon - ** successful coding of the SELECT. - */ -select_end: - - /* Identify column names if we will be using them in a callback. This - ** step is skipped if the output is going to some other destination. - */ - if( rc==SQLITE_OK && eDest==SRT_Callback ){ - generateColumnNames(pParse, pTabList, pEList); - } - - sqlite3_free(sAggInfo.aCol); - sqlite3_free(sAggInfo.aFunc); - return rc; -} - -#if defined(SQLITE_DEBUG) -/* -******************************************************************************* -** The following code is used for testing and debugging only. The code -** that follows does not appear in normal builds. -** -** These routines are used to print out the content of all or part of a -** parse structures such as Select or Expr. Such printouts are useful -** for helping to understand what is happening inside the code generator -** during the execution of complex SELECT statements. -** -** These routine are not called anywhere from within the normal -** code base. Then are intended to be called from within the debugger -** or from temporary "printf" statements inserted for debugging. -*/ -void sqlite3PrintExpr(Expr *p){ - if( p->token.z && p->token.n>0 ){ - sqlite3DebugPrintf("(%.*s", p->token.n, p->token.z); - }else{ - sqlite3DebugPrintf("(%d", p->op); - } - if( p->pLeft ){ - sqlite3DebugPrintf(" "); - sqlite3PrintExpr(p->pLeft); - } - if( p->pRight ){ - sqlite3DebugPrintf(" "); - sqlite3PrintExpr(p->pRight); - } - sqlite3DebugPrintf(")"); -} -void sqlite3PrintExprList(ExprList *pList){ - int i; - for(i=0; inExpr; i++){ - sqlite3PrintExpr(pList->a[i].pExpr); - if( inExpr-1 ){ - sqlite3DebugPrintf(", "); - } - } -} -void sqlite3PrintSelect(Select *p, int indent){ - sqlite3DebugPrintf("%*sSELECT(%p) ", indent, "", p); - sqlite3PrintExprList(p->pEList); - sqlite3DebugPrintf("\n"); - if( p->pSrc ){ - char *zPrefix; - int i; - zPrefix = "FROM"; - for(i=0; ipSrc->nSrc; i++){ - struct SrcList_item *pItem = &p->pSrc->a[i]; - sqlite3DebugPrintf("%*s ", indent+6, zPrefix); - zPrefix = ""; - if( pItem->pSelect ){ - sqlite3DebugPrintf("(\n"); - sqlite3PrintSelect(pItem->pSelect, indent+10); - sqlite3DebugPrintf("%*s)", indent+8, ""); - }else if( pItem->zName ){ - sqlite3DebugPrintf("%s", pItem->zName); - } - if( pItem->pTab ){ - sqlite3DebugPrintf("(table: %s)", pItem->pTab->zName); - } - if( pItem->zAlias ){ - sqlite3DebugPrintf(" AS %s", pItem->zAlias); - } - if( ipSrc->nSrc-1 ){ - sqlite3DebugPrintf(","); - } - sqlite3DebugPrintf("\n"); - } - } - if( p->pWhere ){ - sqlite3DebugPrintf("%*s WHERE ", indent, ""); - sqlite3PrintExpr(p->pWhere); - sqlite3DebugPrintf("\n"); - } - if( p->pGroupBy ){ - sqlite3DebugPrintf("%*s GROUP BY ", indent, ""); - sqlite3PrintExprList(p->pGroupBy); - sqlite3DebugPrintf("\n"); - } - if( p->pHaving ){ - sqlite3DebugPrintf("%*s HAVING ", indent, ""); - sqlite3PrintExpr(p->pHaving); - sqlite3DebugPrintf("\n"); - } - if( p->pOrderBy ){ - sqlite3DebugPrintf("%*s ORDER BY ", indent, ""); - sqlite3PrintExprList(p->pOrderBy); - sqlite3DebugPrintf("\n"); - } -} -/* End of the structure debug printing code -*****************************************************************************/ -#endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ diff --git a/extensions/sqlite/sqlite-source/sqlite3.h b/extensions/sqlite/sqlite-source/sqlite3.h deleted file mode 100644 index 861263b7..00000000 --- a/extensions/sqlite/sqlite-source/sqlite3.h +++ /dev/null @@ -1,3552 +0,0 @@ -/* -** 2001 September 15 -** -** 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 interface that the SQLite library -** presents to client programs. If a C-function, structure, datatype, -** or constant definition does not appear in this file, then it is -** not a published API of SQLite, is subject to change without -** notice, and should not be referenced by programs that use SQLite. -** -** Some of the definitions that are in this file are marked as -** "experimental". Experimental interfaces are normally new -** features recently added to SQLite. We do not anticipate changes -** to experimental interfaces but reserve to make minor changes if -** experience from use "in the wild" suggest such changes are prudent. -** -** The official C-language API documentation for SQLite is derived -** from comments in this file. This file is the authoritative source -** on how SQLite interfaces are suppose to operate. -** -** The name of this file under configuration management is "sqlite.h.in". -** The makefile makes some minor changes to this file (such as inserting -** the version number) and changes its name to "sqlite3.h" as -** part of the build process. -** -** @(#) $Id$ -*/ -#ifndef _SQLITE3_H_ -#define _SQLITE3_H_ -#include /* Needed for the definition of va_list */ - -/* -** Make sure we can call this stuff from C++. -*/ -#ifdef __cplusplus -extern "C" { -#endif - - -/* -** Add the ability to override 'extern' -*/ -#ifndef SQLITE_EXTERN -# define SQLITE_EXTERN extern -#endif - -/* -** Make sure these symbols where not defined by some previous header -** file. -*/ -#ifdef SQLITE_VERSION -# undef SQLITE_VERSION -#endif -#ifdef SQLITE_VERSION_NUMBER -# undef SQLITE_VERSION_NUMBER -#endif - -/* -** CAPI3REF: Compile-Time Library Version Numbers -** -** The version of the SQLite library is contained in the sqlite3.h -** header file in a #define named SQLITE_VERSION. The SQLITE_VERSION -** macro resolves to a string constant. -** -** The format of the version string is "X.Y.Z", where -** X is the major version number, Y is the minor version number and Z -** is the release number. The X.Y.Z might be followed by "alpha" or "beta". -** For example "3.1.1beta". -** -** The X value is always 3 in SQLite. The X value only changes when -** backwards compatibility is broken and we intend to never break -** backwards compatibility. The Y value only changes when -** there are major feature enhancements that are forwards compatible -** but not backwards compatible. The Z value is incremented with -** each release but resets back to 0 when Y is incremented. -** -** The SQLITE_VERSION_NUMBER is an integer with the value -** (X*1000000 + Y*1000 + Z). For example, for version "3.1.1beta", -** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using -** version 3.1.1 or greater at compile time, programs may use the test -** (SQLITE_VERSION_NUMBER>=3001001). -** -** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. -*/ -#define SQLITE_VERSION "3.5.1" -#define SQLITE_VERSION_NUMBER 3005001 - -/* -** CAPI3REF: Run-Time Library Version Numbers -** -** These routines return values equivalent to the header constants -** [SQLITE_VERSION] and [SQLITE_VERSION_NUMBER]. The values returned -** by this routines should only be different from the header values -** if you compile your program using an sqlite3.h header from a -** different version of SQLite that the version of the library you -** link against. -** -** The sqlite3_version[] string constant contains the text of the -** [SQLITE_VERSION] string. The sqlite3_libversion() function returns -** a poiner to the sqlite3_version[] string constant. The function -** is provided for DLL users who can only access functions and not -** constants within the DLL. -*/ -SQLITE_EXTERN const char sqlite3_version[]; -const char *sqlite3_libversion(void); -int sqlite3_libversion_number(void); - -/* -** CAPI3REF: Test To See If The Library Is Threadsafe -** -** This routine returns TRUE (nonzero) if SQLite was compiled with -** all of its mutexes enabled and is thus threadsafe. It returns -** zero if the particular build is for single-threaded operation -** only. -** -** Really all this routine does is return true if SQLite was compiled -** with the -DSQLITE_THREADSAFE=1 option and false if -** compiled with -DSQLITE_THREADSAFE=0. If SQLite uses an -** application-defined mutex subsystem, malloc subsystem, collating -** sequence, VFS, SQL function, progress callback, commit hook, -** extension, or other accessories and these add-ons are not -** threadsafe, then clearly the combination will not be threadsafe -** either. Hence, this routine never reports that the library -** is guaranteed to be threadsafe, only when it is guaranteed not -** to be. -** -** This is an experimental API and may go away or change in future -** releases. -*/ -int sqlite3_threadsafe(void); - -/* -** CAPI3REF: Database Connection Handle -** -** Each open SQLite database is represented by pointer to an instance of the -** opaque structure named "sqlite3". It is useful to think of an sqlite3 -** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and -** [sqlite3_open_v2()] interfaces are its constructors -** and [sqlite3_close()] is its destructor. There are many other interfaces -** (such as [sqlite3_prepare_v2()], [sqlite3_create_function()], and -** [sqlite3_busy_timeout()] to name but three) that are methods on this -** object. -*/ -typedef struct sqlite3 sqlite3; - - -/* -** CAPI3REF: 64-Bit Integer Types -** -** Some compilers do not support the "long long" datatype. So we have -** to do compiler-specific typedefs for 64-bit signed and unsigned integers. -** -** Many SQLite interface functions require a 64-bit integer arguments. -** Those interfaces are declared using this typedef. -*/ -#ifdef SQLITE_INT64_TYPE - typedef SQLITE_INT64_TYPE sqlite_int64; - typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; -#elif defined(_MSC_VER) || defined(__BORLANDC__) - typedef __int64 sqlite_int64; - typedef unsigned __int64 sqlite_uint64; -#else - typedef long long int sqlite_int64; - typedef unsigned long long int sqlite_uint64; -#endif -typedef sqlite_int64 sqlite3_int64; -typedef sqlite_uint64 sqlite3_uint64; - -/* -** If compiling for a processor that lacks floating point support, -** substitute integer for floating-point -*/ -#ifdef SQLITE_OMIT_FLOATING_POINT -# define double sqlite3_int64 -#endif - -/* -** CAPI3REF: Closing A Database Connection -** -** Call this function with a pointer to a structure that was previously -** returned from [sqlite3_open()], [sqlite3_open16()], or -** [sqlite3_open_v2()] and the corresponding database will by -** closed. -** -** All SQL statements prepared using [sqlite3_prepare_v2()] or -** [sqlite3_prepare16_v2()] must be destroyed using [sqlite3_finalize()] -** before this routine is called. Otherwise, SQLITE_BUSY is returned and the -** database connection remains open. -** -** Passing this routine a database connection that has already been -** closed results in undefined behavior. If other interfaces that -** reference the same database connection are pending (either in the -** same thread or in different threads) when this routine is called, -** then the behavior is undefined and is almost certainly undesirable. -*/ -int sqlite3_close(sqlite3 *); - -/* -** The type for a callback function. -** This is legacy and deprecated. It is included for historical -** compatibility and is not documented. -*/ -typedef int (*sqlite3_callback)(void*,int,char**, char**); - -/* -** CAPI3REF: One-Step Query Execution Interface -** -** This interface is used to do a one-time evaluatation of zero -** or more SQL statements. UTF-8 text of the SQL statements to -** be evaluted is passed in as the second parameter. The statements -** are prepared one by one using [sqlite3_prepare()], evaluated -** using [sqlite3_step()], then destroyed using [sqlite3_finalize()]. -** -** If one or more of the SQL statements are queries, then -** the callback function specified by the 3rd parameter is -** invoked once for each row of the query result. This callback -** should normally return 0. If the callback returns a non-zero -** value then the query is aborted, all subsequent SQL statements -** are skipped and the sqlite3_exec() function returns the [SQLITE_ABORT]. -** -** The 4th parameter to this interface is an arbitrary pointer that is -** passed through to the callback function as its first parameter. -** -** The 2nd parameter to the callback function is the number of -** columns in the query result. The 3rd parameter to the callback -** is an array of strings holding the values for each column -** as extracted using [sqlite3_column_text()]. -** The 4th parameter to the callback is an array of strings -** obtained using [sqlite3_column_name()] and holding -** the names of each column. -** -** The callback function may be NULL, even for queries. A NULL -** callback is not an error. It just means that no callback -** will be invoked. -** -** If an error occurs while parsing or evaluating the SQL (but -** not while executing the callback) then an appropriate error -** message is written into memory obtained from [sqlite3_malloc()] and -** *errmsg is made to point to that message. The calling function -** is responsible for freeing the memory using [sqlite3_free()]. -** If errmsg==NULL, then no error message is ever written. -** -** The return value is is SQLITE_OK if there are no errors and -** some other [SQLITE_OK | return code] if there is an error. -** The particular return value depends on the type of error. -** -*/ -int sqlite3_exec( - sqlite3*, /* An open database */ - const char *sql, /* SQL to be evaluted */ - int (*callback)(void*,int,char**,char**), /* Callback function */ - void *, /* 1st argument to callback */ - char **errmsg /* Error msg written here */ -); - -/* -** CAPI3REF: Result Codes -** KEYWORDS: SQLITE_OK -** -** Many SQLite functions return an integer result code from the set shown -** above in order to indicates success or failure. -** -** The result codes above are the only ones returned by SQLite in its -** default configuration. However, the [sqlite3_extended_result_codes()] -** API can be used to set a database connectoin to return more detailed -** result codes. -** -** See also: [SQLITE_IOERR_READ | extended result codes] -** -*/ -#define SQLITE_OK 0 /* Successful result */ -/* beginning-of-error-codes */ -#define SQLITE_ERROR 1 /* SQL error or missing database */ -#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */ -#define SQLITE_PERM 3 /* Access permission denied */ -#define SQLITE_ABORT 4 /* Callback routine requested an abort */ -#define SQLITE_BUSY 5 /* The database file is locked */ -#define SQLITE_LOCKED 6 /* A table in the database is locked */ -#define SQLITE_NOMEM 7 /* A malloc() failed */ -#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ -#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ -#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ -#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ -#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */ -#define SQLITE_FULL 13 /* Insertion failed because database is full */ -#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ -#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */ -#define SQLITE_EMPTY 16 /* Database is empty */ -#define SQLITE_SCHEMA 17 /* The database schema changed */ -#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ -#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ -#define SQLITE_MISMATCH 20 /* Data type mismatch */ -#define SQLITE_MISUSE 21 /* Library used incorrectly */ -#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ -#define SQLITE_AUTH 23 /* Authorization denied */ -#define SQLITE_FORMAT 24 /* Auxiliary database format error */ -#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ -#define SQLITE_NOTADB 26 /* File opened that is not a database file */ -#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ -#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ -/* end-of-error-codes */ - -/* -** CAPI3REF: Extended Result Codes -** -** In its default configuration, SQLite API routines return one of 26 integer -** result codes described at result-codes. However, experience has shown that -** many of these result codes are too course-grained. They do not provide as -** much information about problems as users 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) for -** each database -** connection using the [sqlite3_extended_result_codes()] API. -** -** Some of the available extended result codes are listed above. -** We expect the number of extended result codes will be expand -** over time. Software that uses extended result codes should expect -** to see new result codes in future releases of SQLite. -** -** The symbolic name for an extended result code always contains a related -** primary result code as a prefix. Primary result codes contain a single -** "_" character. Extended result codes contain two or more "_" characters. -** The numeric value of an extended result code can be converted to its -** corresponding primary result code by masking off the lower 8 bytes. -** -** The SQLITE_OK result code will never be extended. It will always -** be exactly zero. -*/ -#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) -#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) -#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) -#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) -#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) -#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) -#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) -#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) -#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) -#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) -#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) -#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) - -/* -** CAPI3REF: Flags For File Open Operations -** -** Combination of the following bit values are used as the -** third argument to the [sqlite3_open_v2()] interface and -** as fourth argument to the xOpen method of the -** [sqlite3_vfs] object. -** -*/ -#define SQLITE_OPEN_READONLY 0x00000001 -#define SQLITE_OPEN_READWRITE 0x00000002 -#define SQLITE_OPEN_CREATE 0x00000004 -#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 -#define SQLITE_OPEN_EXCLUSIVE 0x00000010 -#define SQLITE_OPEN_MAIN_DB 0x00000100 -#define SQLITE_OPEN_TEMP_DB 0x00000200 -#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 -#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 -#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 -#define SQLITE_OPEN_SUBJOURNAL 0x00002000 -#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 - -/* -** CAPI3REF: Device Characteristics -** -** The xDeviceCapabilities method of the [sqlite3_io_methods] -** object returns an integer which is a vector of the following -** bit values expressing I/O characteristics of the mass storage -** device that holds the file that the [sqlite3_io_methods] -** refers to. -** -** The SQLITE_IOCAP_ATOMIC property means that all writes of -** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values -** mean that writes of blocks that are nnn bytes in size and -** are aligned to an address which is an integer multiple of -** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means -** that when data is appended to a file, the data is appended -** first then the size of the file is extended, never the other -** way around. The SQLITE_IOCAP_SEQUENTIAL property means that -** information is written to disk in the same order as calls -** to xWrite(). -*/ -#define SQLITE_IOCAP_ATOMIC 0x00000001 -#define SQLITE_IOCAP_ATOMIC512 0x00000002 -#define SQLITE_IOCAP_ATOMIC1K 0x00000004 -#define SQLITE_IOCAP_ATOMIC2K 0x00000008 -#define SQLITE_IOCAP_ATOMIC4K 0x00000010 -#define SQLITE_IOCAP_ATOMIC8K 0x00000020 -#define SQLITE_IOCAP_ATOMIC16K 0x00000040 -#define SQLITE_IOCAP_ATOMIC32K 0x00000080 -#define SQLITE_IOCAP_ATOMIC64K 0x00000100 -#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 -#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 - -/* -** CAPI3REF: File Locking Levels -** -** SQLite uses one of the following integer values as the second -** argument to calls it makes to the xLock() and xUnlock() methods -** of an [sqlite3_io_methods] object. -*/ -#define SQLITE_LOCK_NONE 0 -#define SQLITE_LOCK_SHARED 1 -#define SQLITE_LOCK_RESERVED 2 -#define SQLITE_LOCK_PENDING 3 -#define SQLITE_LOCK_EXCLUSIVE 4 - -/* -** CAPI3REF: Synchronization Type Flags -** -** When SQLite invokes the xSync() method of an [sqlite3_io_methods] -** object it uses a combination of the following integer values as -** the second argument. -** -** When the SQLITE_SYNC_DATAONLY flag is used, it means that the -** sync operation only needs to flush data to mass storage. Inode -** information need not be flushed. The SQLITE_SYNC_NORMAL means -** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means -** to use Mac OS-X style fullsync instead of fsync(). -*/ -#define SQLITE_SYNC_NORMAL 0x00002 -#define SQLITE_SYNC_FULL 0x00003 -#define SQLITE_SYNC_DATAONLY 0x00010 - - -/* -** CAPI3REF: OS Interface Open File Handle -** -** An [sqlite3_file] object represents an open file in the OS -** interface layer. Individual OS interface implementations will -** want to subclass this object by appending additional fields -** for their own use. The pMethods entry is a pointer to an -** [sqlite3_io_methods] object that defines methods for performing -** I/O operations on the open file. -*/ -typedef struct sqlite3_file sqlite3_file; -struct sqlite3_file { - const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ -}; - -/* -** CAPI3REF: OS Interface File Virtual Methods Object -** -** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to -** an instance of the this object. This object defines the -** methods used to perform various operations against the open file. -** -** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or -** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). -* The second choice is an -** OS-X style fullsync. The SQLITE_SYNC_DATA flag may be ORed in to -** indicate that only the data of the file and not its inode needs to be -** synced. -** -** The integer values to xLock() and xUnlock() are one of -**
    -**
  • [SQLITE_LOCK_NONE], -**
  • [SQLITE_LOCK_SHARED], -**
  • [SQLITE_LOCK_RESERVED], -**
  • [SQLITE_LOCK_PENDING], or -**
  • [SQLITE_LOCK_EXCLUSIVE]. -**
-** xLock() increases the lock. xUnlock() decreases the lock. -** The xCheckReservedLock() method looks -** to see if any database connection, either in this -** process or in some other process, is holding an RESERVED, -** PENDING, or EXCLUSIVE lock on the file. It returns true -** if such a lock exists and false if not. -** -** The xFileControl() method is a generic interface that allows custom -** VFS implementations to directly control an open file using the -** [sqlite3_file_control()] interface. The second "op" argument -** is an integer opcode. The third -** argument is a generic pointer which is intended to be a pointer -** to a structure that may contain arguments or space in which to -** write return values. Potential uses for xFileControl() might be -** functions to enable blocking locks with timeouts, to change the -** 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 opcodes less than 100 for its own use. -** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. -** Applications that define a custom xFileControl method should use opcodes -** greater than 100 to avoid conflicts. -** -** The xSectorSize() method returns the sector size of the -** device that underlies the file. The sector size is the -** minimum write that can be performed without disturbing -** other bytes in the file. The xDeviceCharacteristics() -** method returns a bit vector describing behaviors of the -** underlying device: -** -**
    -**
  • [SQLITE_IOCAP_ATOMIC] -**
  • [SQLITE_IOCAP_ATOMIC512] -**
  • [SQLITE_IOCAP_ATOMIC1K] -**
  • [SQLITE_IOCAP_ATOMIC2K] -**
  • [SQLITE_IOCAP_ATOMIC4K] -**
  • [SQLITE_IOCAP_ATOMIC8K] -**
  • [SQLITE_IOCAP_ATOMIC16K] -**
  • [SQLITE_IOCAP_ATOMIC32K] -**
  • [SQLITE_IOCAP_ATOMIC64K] -**
  • [SQLITE_IOCAP_SAFE_APPEND] -**
  • [SQLITE_IOCAP_SEQUENTIAL] -**
-** -** The SQLITE_IOCAP_ATOMIC property means that all writes of -** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values -** mean that writes of blocks that are nnn bytes in size and -** are aligned to an address which is an integer multiple of -** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means -** that when data is appended to a file, the data is appended -** first then the size of the file is extended, never the other -** way around. The SQLITE_IOCAP_SEQUENTIAL property means that -** information is written to disk in the same order as calls -** to xWrite(). -*/ -typedef struct sqlite3_io_methods sqlite3_io_methods; -struct sqlite3_io_methods { - int iVersion; - int (*xClose)(sqlite3_file*); - int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); - int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); - int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); - int (*xSync)(sqlite3_file*, int flags); - int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); - int (*xLock)(sqlite3_file*, int); - int (*xUnlock)(sqlite3_file*, int); - int (*xCheckReservedLock)(sqlite3_file*); - int (*xFileControl)(sqlite3_file*, int op, void *pArg); - int (*xSectorSize)(sqlite3_file*); - int (*xDeviceCharacteristics)(sqlite3_file*); - /* Additional methods may be added in future releases */ -}; - -/* -** CAPI3REF: Standard File Control Opcodes -** -** These integer constants are opcodes for the xFileControl method -** of the [sqlite3_io_methods] object and to the [sqlite3_file_control()] -** interface. -** -** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This -** opcode cases the xFileControl method to write the current state of -** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], -** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) -** into an integer that the pArg argument points to. This capability -** is used during testing and only needs to be supported when SQLITE_TEST -** is defined. -*/ -#define SQLITE_FCNTL_LOCKSTATE 1 - -/* -** CAPI3REF: Mutex Handle -** -** The mutex module within SQLite defines [sqlite3_mutex] to be an -** abstract type for a mutex object. The SQLite core never looks -** at the internal representation of an [sqlite3_mutex]. It only -** deals with pointers to the [sqlite3_mutex] object. -** -** Mutexes are created using [sqlite3_mutex_alloc()]. -*/ -typedef struct sqlite3_mutex sqlite3_mutex; - -/* -** CAPI3REF: OS Interface Object -** -** An instance of this object defines the interface between the -** SQLite core and the underlying operating system. The "vfs" -** in the name of the object stands for "virtual file system". -** -** The iVersion field is initially 1 but may be larger for future -** versions of SQLite. Additional fields may be appended to this -** object when the iVersion value is increased. -** -** The szOsFile field is the size of the subclassed [sqlite3_file] -** structure used by this VFS. mxPathname is the maximum length of -** a pathname in this VFS. -** -** Registered vfs modules are kept on a linked list formed by -** the pNext pointer. The [sqlite3_vfs_register()] -** and [sqlite3_vfs_unregister()] interfaces manage this list -** in a thread-safe way. The [sqlite3_vfs_find()] interface -** searches the list. -** -** The pNext field is the only fields in the sqlite3_vfs -** structure that SQLite will ever modify. SQLite will only access -** or modify this field while holding a particular static mutex. -** The application should never modify anything within the sqlite3_vfs -** object once the object has been registered. -** -** The zName field holds the name of the VFS module. The name must -** be unique across all VFS modules. -** -** SQLite will guarantee that the zFilename string passed to -** xOpen() is a full pathname as generated by xFullPathname() and -** that the string will be valid and unchanged until xClose() is -** called. So the [sqlite3_file] can store a pointer to the -** filename if it needs to remember the filename for some reason. -** -** The flags argument to xOpen() is a copy of the flags argument -** to [sqlite3_open_v2()]. If [sqlite3_open()] or [sqlite3_open16()] -** is used, then flags is [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. -** If xOpen() opens a file read-only then it sets *pOutFlags to -** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be -** set. -** -** SQLite will also add one of the following flags to the xOpen() -** call, depending on the object being opened: -** -**
    -**
  • [SQLITE_OPEN_MAIN_DB] -**
  • [SQLITE_OPEN_MAIN_JOURNAL] -**
  • [SQLITE_OPEN_TEMP_DB] -**
  • [SQLITE_OPEN_TEMP_JOURNAL] -**
  • [SQLITE_OPEN_TRANSIENT_DB] -**
  • [SQLITE_OPEN_SUBJOURNAL] -**
  • [SQLITE_OPEN_MASTER_JOURNAL] -**
-** -** The file I/O implementation can use the object type flags to -** changes the way it deals with files. For example, an application -** that does not care about crash recovery or rollback, might make -** the open of a journal file a no-op. Writes to this journal are -** also a no-op. Any attempt to read the journal return SQLITE_IOERR. -** Or the implementation might recognize the a database file will -** be doing page-aligned sector reads and writes in a random order -** and set up its I/O subsystem accordingly. -** -** SQLite might also add one of the following flags to the xOpen -** method: -** -**
    -**
  • [SQLITE_OPEN_DELETEONCLOSE] -**
  • [SQLITE_OPEN_EXCLUSIVE] -**
-** -** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be -** deleted when it is closed. This will always be set for TEMP -** databases and journals and for subjournals. The -** [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened -** for exclusive access. This flag is set for all files except -** for the main database file. -** -** Space to hold the [sqlite3_file] structure passed as the third -** argument to xOpen is allocated by caller (the SQLite core). -** szOsFile bytes are allocated for this object. The xOpen method -** fills in the allocated space. -** -** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] -** to test for the existance of a file, -** or [SQLITE_ACCESS_READWRITE] to test to see -** if a file is readable and writable, or [SQLITE_ACCESS_READ] -** to test to see if a file is at least readable. The file can be a -** directory. -** -** SQLite will always allocate at least mxPathname+1 byte for -** the output buffers for xGetTempname and xFullPathname. The exact -** size of the output buffer is also passed as a parameter to both -** methods. If the output buffer is not large enough, SQLITE_CANTOPEN -** should be returned. As this is handled as a fatal error by SQLite, -** vfs implementations should endevour to prevent this by setting -** mxPathname to a sufficiently large value. -** -** The xRandomness(), xSleep(), and xCurrentTime() interfaces -** are not strictly a part of the filesystem, but they are -** included in the VFS structure for completeness. -** The xRandomness() function attempts to return nBytes bytes -** of good-quality randomness into zOut. The return value is -** the actual number of bytes of randomness obtained. The -** xSleep() method cause the calling thread to sleep for at -** least the number of microseconds given. The xCurrentTime() -** method returns a Julian Day Number for the current date and -** time. -*/ -typedef struct sqlite3_vfs sqlite3_vfs; -struct sqlite3_vfs { - int iVersion; /* Structure version number */ - int szOsFile; /* Size of subclassed sqlite3_file */ - int mxPathname; /* Maximum file pathname length */ - sqlite3_vfs *pNext; /* Next registered VFS */ - const char *zName; /* Name of this virtual file system */ - void *pAppData; /* Pointer to application-specific data */ - int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, - int flags, int *pOutFlags); - int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); - int (*xAccess)(sqlite3_vfs*, const char *zName, int flags); - int (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut); - int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); - void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); - void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); - void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); - void (*xDlClose)(sqlite3_vfs*, void*); - int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); - int (*xSleep)(sqlite3_vfs*, int microseconds); - int (*xCurrentTime)(sqlite3_vfs*, double*); - /* New fields may be appended in figure versions. The iVersion - ** value will increment whenever this happens. */ -}; - -/* -** CAPI3REF: Flags for the xAccess VFS method -** -** These integer constants can be used as the third parameter to -** the xAccess method of an [sqlite3_vfs] object. They determine -** the kind of what kind of permissions the xAccess method is -** looking for. With SQLITE_ACCESS_EXISTS, the xAccess method -** simply checks to see if the file exists. With SQLITE_ACCESS_READWRITE, -** the xAccess method checks to see if the file is both readable -** and writable. With SQLITE_ACCESS_READ the xAccess method -** checks to see if the file is readable. -*/ -#define SQLITE_ACCESS_EXISTS 0 -#define SQLITE_ACCESS_READWRITE 1 -#define SQLITE_ACCESS_READ 2 - -/* -** CAPI3REF: Enable Or Disable Extended Result Codes -** -** This routine enables or disables the -** [SQLITE_IOERR_READ | extended result codes] feature. -** By default, SQLite API routines return one of only 26 integer -** [SQLITE_OK | result codes]. When extended result codes -** are enabled by this routine, the repetoire of result codes can be -** much larger and can (hopefully) provide more detailed information -** about the cause of an error. -** -** The second argument is a boolean value that turns extended result -** codes on and off. Extended result codes are off by default for -** backwards compatibility with older versions of SQLite. -*/ -int sqlite3_extended_result_codes(sqlite3*, int onoff); - -/* -** CAPI3REF: Last Insert Rowid -** -** Each entry in an SQLite table has a unique 64-bit signed integer key -** called the "rowid". The rowid is always available as an undeclared -** column named ROWID, OID, or _ROWID_. If the table has a column of -** type INTEGER PRIMARY KEY then that column is another an alias for the -** rowid. -** -** This routine returns the rowid of the most recent INSERT into -** the database from the database connection given in the first -** argument. If no inserts have ever occurred on this database -** connection, zero is returned. -** -** If an INSERT occurs within a trigger, then the rowid of the -** inserted row is returned by this routine as long as the trigger -** is running. But once the trigger terminates, the value returned -** by this routine reverts to the last value inserted before the -** trigger fired. -** -** If another thread does a new insert on the same database connection -** while this routine is running and thus changes the last insert rowid, -** then the return value of this routine is undefined. -*/ -sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); - -/* -** CAPI3REF: Count The Number Of Rows Modified -** -** This function returns the number of database rows that were changed -** (or inserted or deleted) by the most recent SQL statement. Only -** changes that are directly specified by the INSERT, UPDATE, or -** DELETE statement are counted. Auxiliary changes caused by -** triggers are not counted. Use the [sqlite3_total_changes()] function -** to find the total number of changes including changes caused by triggers. -** -** Within the body of a trigger, the sqlite3_changes() interface can be -** called to find the number of -** changes in the most recently completed INSERT, UPDATE, or DELETE -** statement within the body of the trigger. -** -** All changes are counted, even if they were later undone by a -** ROLLBACK or ABORT. Except, changes associated with creating and -** dropping tables are not counted. -** -** If a callback invokes [sqlite3_exec()] or [sqlite3_step()] recursively, -** then the changes in the inner, recursive call are counted together -** with the changes in the outer call. -** -** SQLite implements the command "DELETE FROM table" without a WHERE clause -** by dropping and recreating the table. (This is much faster than going -** through and deleting individual elements from the table.) Because of -** this optimization, the change count for "DELETE FROM table" will be -** zero regardless of the number of elements that were originally in the -** table. To get an accurate count of the number of rows deleted, use -** "DELETE FROM table WHERE 1" instead. -** -** If another thread makes changes on the same database connection -** while this routine is running then the return value of this routine -** is undefined. -*/ -int sqlite3_changes(sqlite3*); - -/* -** CAPI3REF: Total Number Of Rows Modified -*** -** This function returns the number of database rows that have been -** modified by INSERT, UPDATE or DELETE statements since the database handle -** was opened. This includes UPDATE, INSERT and DELETE statements executed -** as part of trigger programs. All changes are counted as soon as the -** statement that makes them is completed (when the statement handle is -** passed to [sqlite3_reset()] or [sqlite3_finalize()]). -** -** See also the [sqlite3_change()] interface. -** -** SQLite implements the command "DELETE FROM table" without a WHERE clause -** by dropping and recreating the table. (This is much faster than going -** through and deleting individual elements form the table.) Because of -** this optimization, the change count for "DELETE FROM table" will be -** zero regardless of the number of elements that were originally in the -** table. To get an accurate count of the number of rows deleted, use -** "DELETE FROM table WHERE 1" instead. -** -** If another thread makes changes on the same database connection -** while this routine is running then the return value of this routine -** is undefined. -*/ -int sqlite3_total_changes(sqlite3*); - -/* -** CAPI3REF: Interrupt A Long-Running Query -** -** This function causes any pending database operation to abort and -** return at its earliest opportunity. This routine is typically -** called in response to a user action such as pressing "Cancel" -** or Ctrl-C where the user wants a long query operation to halt -** immediately. -** -** It is safe to call this routine from a thread different from the -** thread that is currently running the database operation. But it -** is not safe to call this routine with a database connection that -** is closed or might close before sqlite3_interrupt() returns. -** -** The SQL operation that is interrupted will return [SQLITE_INTERRUPT]. -** If an interrupted operation was an update that is inside an -** explicit transaction, then the entire transaction will be rolled -** back automatically. -*/ -void sqlite3_interrupt(sqlite3*); - -/* -** CAPI3REF: Determine If An SQL Statement Is Complete -** -** These functions return true if the given input string comprises -** one or more complete SQL statements. For the sqlite3_complete() call, -** the parameter must be a nul-terminated UTF-8 string. For -** sqlite3_complete16(), a nul-terminated machine byte order UTF-16 string -** is required. -** -** These routines are useful for command-line input to determine if the -** currently entered text forms one or more complete SQL statements or -** if additional input is needed before sending the statements into -** SQLite for parsing. The algorithm is simple. If the -** last token other than spaces and comments is a semicolon, then return -** true. Actually, the algorithm is a little more complicated than that -** in order to deal with triggers, but the basic idea is the same: the -** statement is not complete unless it ends in a semicolon. -*/ -int sqlite3_complete(const char *sql); -int sqlite3_complete16(const void *sql); - -/* -** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors -** -** This routine identifies a callback function that might be invoked -** whenever an attempt is made to open a database table -** that another thread or process has locked. -** If the busy callback is NULL, then [SQLITE_BUSY] -** (or sometimes [SQLITE_IOERR_BLOCKED]) -** is returned immediately upon encountering the lock. -** If the busy callback is not NULL, then the -** callback will be invoked with two arguments. The -** first argument to the handler is a copy of the void* pointer which -** is the third argument to this routine. The second argument to -** the handler is the number of times that the busy handler has -** been invoked for this 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. -** If the callback returns non-zero, then another attempt is made to open the -** database for reading 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 return [SQLITE_BUSY] instead. -** 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 -** to promote to an exclusive lock. The first process cannot proceed -** because it is blocked by the second and the second process cannot -** proceed because it is blocked by the first. If both processes -** invoke the busy handlers, neither will make any progress. Therefore, -** SQLite returns [SQLITE_BUSY] for the first process, hoping that this -** will induce the first process to release its read lock and allow -** the second process to proceed. -** -** 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 -** -** CorruptionFollowingBusyError wiki page for a discussion of why -** this is important. -** -** Sqlite is re-entrant, so the busy handler may start a new query. -** (It is not clear why anyone would every want to do this, but it -** is allowed, in theory.) But the busy handler may not close the -** database. Closing the database from a busy handler will delete -** data structures out from under the executing query and will -** probably result in a segmentation fault or other runtime error. -** -** There can only be a single busy handler defined for each database -** connection. Setting a new busy handler clears any previous one. -** Note that calling [sqlite3_busy_timeout()] will also set or clear -** the busy handler. -** -** When operating in [sqlite3_enable_shared_cache | shared cache mode], -** only a single busy handler can be defined for each database file. -** So if two database connections share a single cache, then changing -** the busy handler on one connection will also change the busy -** handler in the other connection. The busy handler is invoked -** in the thread that was running when the SQLITE_BUSY was hit. -*/ -int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); - -/* -** CAPI3REF: Set A Busy Timeout -** -** This routine sets a busy handler that sleeps for a while when a -** table is locked. The handler will sleep multiple times until -** at least "ms" milliseconds of sleeping have been done. After -** "ms" milliseconds of sleeping, the handler returns 0 which -** causes [sqlite3_step()] to return [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. -** -** Calling this routine with an argument less than or equal to zero -** turns off all busy handlers. -** -** There can only be a single busy handler for a particular database -** connection. If another busy handler was defined -** (using [sqlite3_busy_handler()]) prior to calling -** this routine, that other busy handler is cleared. -*/ -int sqlite3_busy_timeout(sqlite3*, int ms); - -/* -** CAPI3REF: Convenience Routines For Running Queries -** -** This next routine is a convenience wrapper around [sqlite3_exec()]. -** Instead of invoking a user-supplied callback for each row of the -** result, this routine remembers each row of the result in memory -** obtained from [sqlite3_malloc()], then returns all of the result after the -** query has finished. -** -** As an example, suppose the query result where this table: -** -**
-**        Name        | Age
-**        -----------------------
-**        Alice       | 43
-**        Bob         | 28
-**        Cindy       | 21
-** 
-** -** If the 3rd argument were &azResult then after the function returns -** azResult will contain the following data: -** -**
-**        azResult[0] = "Name";
-**        azResult[1] = "Age";
-**        azResult[2] = "Alice";
-**        azResult[3] = "43";
-**        azResult[4] = "Bob";
-**        azResult[5] = "28";
-**        azResult[6] = "Cindy";
-**        azResult[7] = "21";
-** 
-** -** Notice that there is an extra row of data containing the column -** headers. But the *nrow return value is still 3. *ncolumn is -** set to 2. In general, the number of values inserted into azResult -** will be ((*nrow) + 1)*(*ncolumn). -** -** After the calling function has finished using the result, it should -** pass the result data pointer to sqlite3_free_table() in order to -** release the memory that was malloc-ed. Because of the way the -** [sqlite3_malloc()] happens, the calling function must not try to call -** [sqlite3_free()] directly. Only [sqlite3_free_table()] is able to release -** the memory properly and safely. -** -** The return value of this routine is the same as from [sqlite3_exec()]. -*/ -int sqlite3_get_table( - sqlite3*, /* An open database */ - const char *sql, /* SQL to be executed */ - char ***resultp, /* Result written to a char *[] that this points to */ - int *nrow, /* Number of result rows written here */ - int *ncolumn, /* Number of result columns written here */ - char **errmsg /* Error msg written here */ -); -void sqlite3_free_table(char **result); - -/* -** CAPI3REF: Formatted String Printing Functions -** -** These routines are workalikes of the "printf()" family of functions -** from the standard C library. -** -** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their -** results into memory obtained from [sqlite3_malloc()]. -** The strings returned by these two routines should be -** released by [sqlite3_free()]. Both routines return a -** NULL pointer if [sqlite3_malloc()] is unable to allocate enough -** memory to hold the resulting string. -** -** In sqlite3_snprintf() routine is similar to "snprintf()" from -** the standard C library. The result is written into the -** buffer supplied as the second parameter whose size is given by -** the first parameter. Note that the order of the -** first two parameters is reversed from snprintf(). This is an -** historical accident that cannot be fixed without breaking -** backwards compatibility. Note also that sqlite3_snprintf() -** returns a pointer to its buffer instead of the number of -** characters actually written into the buffer. We admit that -** the number of characters written would be a more useful return -** value but we cannot change the implementation of sqlite3_snprintf() -** now without breaking compatibility. -** -** As long as the buffer size is greater than zero, sqlite3_snprintf() -** guarantees that the buffer is always zero-terminated. The first -** parameter "n" is the total size of the buffer, including space for -** the zero terminator. So the longest string that can be completely -** written will be n-1 characters. -** -** These routines all implement some additional formatting -** options that are useful for constructing SQL statements. -** All of the usual printf formatting options apply. In addition, there -** is are "%q", "%Q", and "%z" options. -** -** The %q option works like %s in that it substitutes a null-terminated -** string from the argument list. But %q also doubles every '\'' character. -** %q is designed for use inside a string literal. By doubling each '\'' -** character it escapes that character and allows it to be inserted into -** the string. -** -** For example, so some string variable contains text as follows: -** -**
-**  char *zText = "It's a happy day!";
-** 
-** -** One can use this text in an SQL statement as follows: -** -**
-**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
-**  sqlite3_exec(db, zSQL, 0, 0, 0);
-**  sqlite3_free(zSQL);
-** 
-** -** Because the %q format string is used, the '\'' character in zText -** is escaped and the SQL generated is as follows: -** -**
-**  INSERT INTO table1 VALUES('It''s a happy day!')
-** 
-** -** This is correct. Had we used %s instead of %q, the generated SQL -** would have looked like this: -** -**
-**  INSERT INTO table1 VALUES('It's a happy day!');
-** 
-** -** This second example is an SQL syntax error. As a general rule you -** should always use %q instead of %s when inserting text into a string -** literal. -** -** The %Q option works like %q except it also adds single quotes around -** the outside of the total string. Or if the parameter in the argument -** list is a NULL pointer, %Q substitutes the text "NULL" (without single -** quotes) in place of the %Q option. So, for example, one could say: -** -**
-**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
-**  sqlite3_exec(db, zSQL, 0, 0, 0);
-**  sqlite3_free(zSQL);
-** 
-** -** The code above will render a correct SQL statement in the zSQL -** variable even if the zText variable is a NULL pointer. -** -** The "%z" formatting option works exactly like "%s" with the -** addition that after the string has been read and copied into -** the result, [sqlite3_free()] is called on the input string. -*/ -char *sqlite3_mprintf(const char*,...); -char *sqlite3_vmprintf(const char*, va_list); -char *sqlite3_snprintf(int,char*,const char*, ...); - -/* -** CAPI3REF: Memory Allocation Subsystem -** -** The SQLite core uses these three routines for all of its own -** internal memory allocation needs. (See the exception below.) -** The default implementation -** of the memory allocation subsystem uses the malloc(), realloc() -** and free() provided by the standard C library. However, if -** SQLite is compiled with the following C preprocessor macro -** -**
SQLITE_OMIT_MEMORY_ALLOCATION
-** -** then no implementation is provided for these routines by -** SQLite. The application that links against SQLite is -** expected to provide its own implementation. If the application -** does provide its own implementation for these routines, then -** it must also provide an implementations for -** [sqlite3_memory_alarm()], [sqlite3_memory_used()], and -** [sqlite3_memory_highwater()]. The alternative implementations -** for these last three routines need not actually work, but -** stub functions at least are needed to statisfy the linker. -** SQLite never calls [sqlite3_memory_highwater()] itself, but -** the symbol is included in a table as part of the -** [sqlite3_load_extension()] interface. The -** [sqlite3_memory_alarm()] and [sqlite3_memory_used()] interfaces -** are called by [sqlite3_soft_heap_limit()] and working implementations -** of both routines must be provided if [sqlite3_soft_heap_limit()] -** is to operate correctly. -** -** Exception: The windows OS interface layer calls -** the system malloc() and free() directly when converting -** filenames between the UTF-8 encoding used by SQLite -** and whatever filename encoding is used by the particular windows -** installation. Memory allocation errors are detected, but -** they are reported back as [SQLITE_CANTOPEN] or -** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. -*/ -void *sqlite3_malloc(int); -void *sqlite3_realloc(void*, int); -void sqlite3_free(void*); - -/* -** CAPI3REF: Memory Allocator Statistics -** -** In addition to the basic three allocation routines -** [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()], -** the memory allocation subsystem included with the SQLite -** sources provides the interfaces shown below. -** -** The first of these two routines returns the amount of memory -** currently outstanding (malloced but not freed). The second -** returns the largest instantaneous amount of outstanding -** memory. The highwater mark is reset if the argument is -** true. -** -** The implementation of these routines in the SQLite core -** is omitted if the application is compiled with the -** SQLITE_OMIT_MEMORY_ALLOCATION macro defined. In that case, -** the application that links SQLite must provide its own -** alternative implementation. See the documentation on -** [sqlite3_malloc()] for additional information. -*/ -sqlite3_int64 sqlite3_memory_used(void); -sqlite3_int64 sqlite3_memory_highwater(int resetFlag); - -/* -** CAPI3REF: Memory Allocation Alarms -** -** The [sqlite3_memory_alarm] routine is used to register -** a callback on memory allocation events. -** -** This routine registers or clears a callbacks that fires when -** the amount of memory allocated exceeds iThreshold. Only -** a single callback can be registered at a time. Each call -** to [sqlite3_memory_alarm()] overwrites the previous callback. -** The callback is disabled by setting xCallback to a NULL -** pointer. -** -** The parameters to the callback are the pArg value, the -** amount of memory currently in use, and the size of the -** allocation that provoked the callback. The callback will -** presumably invoke [sqlite3_free()] to free up memory space. -** The callback may invoke [sqlite3_malloc()] or [sqlite3_realloc()] -** but if it does, no additional callbacks will be invoked by -** the recursive calls. -** -** The [sqlite3_soft_heap_limit()] interface works by registering -** a memory alarm at the soft heap limit and invoking -** [sqlite3_release_memory()] in the alarm callback. Application -** programs should not attempt to use the [sqlite3_memory_alarm()] -** interface because doing so will interfere with the -** [sqlite3_soft_heap_limit()] module. This interface is exposed -** only so that applications can provide their own -** alternative implementation when the SQLite core is -** compiled with SQLITE_OMIT_MEMORY_ALLOCATION. -*/ -int sqlite3_memory_alarm( - void(*xCallback)(void *pArg, sqlite3_int64 used, int N), - void *pArg, - sqlite3_int64 iThreshold -); - - -/* -** CAPI3REF: Compile-Time Authorization Callbacks -*** -** This routine registers a authorizer callback with the SQLite library. -** The authorizer callback is invoked as SQL statements are being compiled -** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], -** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various -** points during the compilation process, as logic is being created -** to perform various actions, the authorizer callback is invoked to -** see if those actions are allowed. The authorizer callback should -** return SQLITE_OK to allow the action, [SQLITE_IGNORE] to disallow the -** specific action but allow the SQL statement to continue to be -** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be -** rejected with an error. -** -** Depending on the action, the [SQLITE_IGNORE] and [SQLITE_DENY] return -** codes might mean something different or they might mean the same -** thing. If the action is, for example, to perform a delete opertion, -** then [SQLITE_IGNORE] and [SQLITE_DENY] both cause the statement compilation -** to fail with an error. But if the action is to read a specific column -** from a specific table, then [SQLITE_DENY] will cause the entire -** statement to fail but [SQLITE_IGNORE] will cause a NULL value to be -** read instead of the actual column value. -** -** The first parameter to the authorizer callback is a copy of -** the third parameter to the sqlite3_set_authorizer() interface. -** The second parameter to the callback is an integer -** [SQLITE_COPY | action code] that specifies the particular action -** to be authorized. The available action codes are -** [SQLITE_COPY | documented separately]. The third through sixth -** parameters to the callback are strings that contain additional -** details about the action to be authorized. -** -** An authorizer is used when preparing SQL statements from an untrusted -** source, to ensure that the SQL statements do not try to access data -** that they are not allowed to see, or that they do not try to -** execute malicious statements that damage the database. For -** example, an application may allow a user to enter arbitrary -** SQL queries for evaluation by a database. But the application does -** not want the user to be able to make arbitrary changes to the -** database. An authorizer could then be put in place while the -** user-entered SQL is being prepared that disallows everything -** except SELECT statements. -** -** Only a single authorizer can be in place on a database connection -** at a time. Each call to sqlite3_set_authorizer overrides the -** previous call. A NULL authorizer means that no authorization -** callback is invoked. The default authorizer is NULL. -** -** Note that the authorizer callback is invoked only during -** [sqlite3_prepare()] or its variants. Authorization is not -** performed during statement evaluation in [sqlite3_step()]. -*/ -int sqlite3_set_authorizer( - sqlite3*, - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), - void *pUserData -); - -/* -** CAPI3REF: Authorizer Return Codes -** -** The [sqlite3_set_authorizer | authorizer callback function] must -** return either [SQLITE_OK] or one of these two constants in order -** to signal SQLite whether or not the action is permitted. See the -** [sqlite3_set_authorizer | authorizer documentation] for additional -** information. -*/ -#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 */ - -/* -** CAPI3REF: Authorizer Action Codes -** -** The [sqlite3_set_authorizer()] interface registers a callback function -** that is invoked to authorizer certain SQL statement actions. The -** second parameter to the callback is an integer code that specifies -** what action is being authorized. These are the integer action codes that -** the authorizer callback may be passed. -** -** These action code values signify what kind of operation is to be -** authorized. The 3rd and 4th parameters to the authorization callback -** function will be parameters or NULL depending on which of these -** codes is used as the second parameter. The 5th parameter to the -** authorizer callback is the name of the database ("main", "temp", -** etc.) if applicable. The 6th parameter to the authorizer callback -** is the name of the inner-most trigger or view that is responsible for -** the access attempt or NULL if this access attempt is directly from -** top-level SQL code. -*/ -/******************************************* 3rd ************ 4th ***********/ -#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ -#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ -#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ -#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ -#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ -#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ -#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ -#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ -#define SQLITE_DELETE 9 /* Table Name NULL */ -#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ -#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ -#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ -#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ -#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ -#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ -#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ -#define SQLITE_DROP_VIEW 17 /* View Name NULL */ -#define SQLITE_INSERT 18 /* Table Name NULL */ -#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ -#define SQLITE_READ 20 /* Table Name Column Name */ -#define SQLITE_SELECT 21 /* NULL NULL */ -#define SQLITE_TRANSACTION 22 /* NULL NULL */ -#define SQLITE_UPDATE 23 /* Table Name Column Name */ -#define SQLITE_ATTACH 24 /* Filename NULL */ -#define SQLITE_DETACH 25 /* Database Name NULL */ -#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ -#define SQLITE_REINDEX 27 /* Index Name NULL */ -#define SQLITE_ANALYZE 28 /* Table Name NULL */ -#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ -#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ -#define SQLITE_FUNCTION 31 /* Function Name NULL */ -#define SQLITE_COPY 0 /* No longer used */ - -/* -** CAPI3REF: Tracing And Profiling Functions -** -** These routines register callback functions that can be used for -** tracing and profiling the execution of SQL statements. -** The callback function registered by sqlite3_trace() is invoked -** at the first [sqlite3_step()] for the evaluation of an SQL statement. -** The callback function registered by sqlite3_profile() is invoked -** as each SQL statement finishes and includes -** information on how long that statement ran. -** -** The sqlite3_profile() API is currently considered experimental and -** is subject to change. -*/ -void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); -void *sqlite3_profile(sqlite3*, - void(*xProfile)(void*,const char*,sqlite3_uint64), void*); - -/* -** CAPI3REF: Query Progress Callbacks -** -** This routine configures a callback function - the progress callback - that -** is invoked periodically during long running calls to [sqlite3_exec()], -** [sqlite3_step()] and [sqlite3_get_table()]. An example use for this -** interface is to keep a GUI updated during a large query. -** -** The progress callback is invoked once for every N virtual machine opcodes, -** where N is the second argument to this function. The progress callback -** itself is identified by the third argument to this function. The fourth -** argument to this function is a void pointer passed to the progress callback -** function each time it is invoked. -** -** If a call to [sqlite3_exec()], [sqlite3_step()], or [sqlite3_get_table()] -** results in fewer than N opcodes being executed, then the progress -** callback is never invoked. -** -** Only a single progress callback function may be registered for each -** open database connection. Every call to sqlite3_progress_handler() -** overwrites the results of the previous call. -** To remove the progress callback altogether, pass NULL as the third -** argument to this function. -** -** If the progress callback returns a result other than 0, then the current -** query is immediately terminated and any database changes rolled back. -** The containing [sqlite3_exec()], [sqlite3_step()], or -** [sqlite3_get_table()] call returns SQLITE_INTERRUPT. This feature -** can be used, for example, to implement the "Cancel" button on a -** progress dialog box in a GUI. -*/ -void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); - -/* -** CAPI3REF: Opening A New Database Connection -** -** Open the sqlite database file "filename". The "filename" is UTF-8 -** encoded for [sqlite3_open()] and [sqlite3_open_v2()] and UTF-16 encoded -** in the native byte order for [sqlite3_open16()]. -** An [sqlite3*] handle is returned in *ppDb, even -** if an error occurs. If the database is opened (or created) successfully, -** then [SQLITE_OK] is returned. Otherwise an error code is returned. The -** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain -** an English language description of the error. -** -** The default encoding for the database will be UTF-8 if -** [sqlite3_open()] or [sqlite3_open_v2()] is called and -** UTF-16 if [sqlite3_open16()] is used. -** -** Whether or not an error occurs when it is opened, resources associated -** with the [sqlite3*] handle should be released by passing it to -** [sqlite3_close()] when it is no longer required. -** -** The [sqlite3_open_v2()] interface works like [sqlite3_open()] except that -** provides two additional parameters for additional control over the -** new database connection. The flags parameter can be one of: -** -**
    -**
  1. [SQLITE_OPEN_READONLY] -**
  2. [SQLITE_OPEN_READWRITE] -**
  3. [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE] -**
-** -** The first value opens the database read-only. If the database does -** not previously exist, an error is returned. The second option opens -** the database for reading and writing if possible, or reading only if -** if the file is write protected. In either case the database must already -** exist or an error is returned. The third option opens the database -** for reading and writing and creates it if it does not already exist. -** The third options is behavior that is always used for [sqlite3_open()] -** and [sqlite3_open16()]. -** -** If the filename is ":memory:", then an private -** in-memory database is created for the connection. This in-memory -** database will vanish when the database connection is closed. Future -** version of SQLite might make use of additional special filenames -** that begin with the ":" character. It is recommended that -** when a database filename really does begin with -** ":" that you prefix the filename with a pathname like "./" to -** avoid ambiguity. -** -** If the filename is an empty string, then a private temporary -** on-disk database will be created. This private database will be -** automatically deleted as soon as the database connection is closed. -** -** The fourth parameter to sqlite3_open_v2() is the name of the -** [sqlite3_vfs] object that defines the operating system -** interface that the new database connection should use. If the -** fourth parameter is a NULL pointer then the default [sqlite3_vfs] -** object is used. -** -** Note to windows users: The encoding used for the filename argument -** of [sqlite3_open()] and [sqlite3_open_v2()] must be UTF-8, not whatever -** codepage is currently defined. Filenames containing international -** characters must be converted to UTF-8 prior to passing them into -** [sqlite3_open()] or [sqlite3_open_v2()]. -*/ -int sqlite3_open( - const char *filename, /* Database filename (UTF-8) */ - sqlite3 **ppDb /* OUT: SQLite db handle */ -); -int sqlite3_open16( - const void *filename, /* Database filename (UTF-16) */ - sqlite3 **ppDb /* OUT: SQLite db handle */ -); -int sqlite3_open_v2( - const char *filename, /* Database filename (UTF-8) */ - sqlite3 **ppDb, /* OUT: SQLite db handle */ - int flags, /* Flags */ - const char *zVfs /* Name of VFS module to use */ -); - -/* -** CAPI3REF: Error Codes And Messages -** -** The sqlite3_errcode() interface returns the numeric -** [SQLITE_OK | result code] or [SQLITE_IOERR_READ | extended result code] -** for the most recent failed sqlite3_* API call associated -** with [sqlite3] handle 'db'. If a prior API call failed but the -** most recent API call succeeded, the return value from sqlite3_errcode() -** is undefined. -** -** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language -** text that describes the error, as either UTF8 or UTF16 respectively. -** Memory to hold the error message string is managed internally. The -** string may be overwritten or deallocated by subsequent calls to SQLite -** interface functions. -** -** Calls to many sqlite3_* functions set the error code and string returned -** by [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()] -** (overwriting the previous values). Note that calls to [sqlite3_errcode()], -** [sqlite3_errmsg()], and [sqlite3_errmsg16()] themselves do not affect the -** results of future invocations. Calls to API routines that do not return -** an error code (example: [sqlite3_data_count()]) do not -** change the error code returned by this routine. Interfaces that are -** not associated with a specific database connection (examples: -** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()] do not change -** the return code. -** -** Assuming no other intervening sqlite3_* API calls are made, the error -** code returned by this function is associated with the same error as -** the strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]. -*/ -int sqlite3_errcode(sqlite3 *db); -const char *sqlite3_errmsg(sqlite3*); -const void *sqlite3_errmsg16(sqlite3*); - -/* -** CAPI3REF: SQL Statement Object -** -** Instance of this object represent single SQL statements. This -** is variously known as a "prepared statement" or a -** "compiled SQL statement" or simply as a "statement". -** -** The life of a statement object goes something like this: -** -**
    -**
  1. Create the object using [sqlite3_prepare_v2()] or a related -** function. -**
  2. Bind values to host parameters using -** [sqlite3_bind_blob | sqlite3_bind_* interfaces]. -**
  3. Run the SQL by calling [sqlite3_step()] one or more times. -**
  4. Reset the statement using [sqlite3_reset()] then go back -** to step 2. Do this zero or more times. -**
  5. Destroy the object using [sqlite3_finalize()]. -**
-** -** Refer to documentation on individual methods above for additional -** information. -*/ -typedef struct sqlite3_stmt sqlite3_stmt; - -/* -** CAPI3REF: Compiling An SQL Statement -** -** To execute an SQL query, it must first be compiled into a byte-code -** program using one of these routines. -** -** The first argument "db" is an [sqlite3 | SQLite database handle] -** obtained from a prior call to [sqlite3_open()], [sqlite3_open_v2()] -** or [sqlite3_open16()]. -** The second argument "zSql" is the statement to be compiled, encoded -** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() -** interfaces uses UTF-8 and sqlite3_prepare16() and sqlite3_prepare16_v2() -** use UTF-16. -** -** If the nByte argument is less -** than zero, then zSql is read up to the first zero terminator. If -** nByte is non-negative, then it is the maximum number of -** bytes read from zSql. When nByte is non-negative, the -** zSql string ends at either the first '\000' character or -** until the nByte-th byte, whichever comes first. -** -** *pzTail is made to point to the first byte past the end of the first -** SQL statement in zSql. This routine only compiles the first statement -** in zSql, so *pzTail is left pointing to what remains uncompiled. -** -** *ppStmt is left pointing to a compiled -** [sqlite3_stmt | SQL statement structure] that can be -** executed using [sqlite3_step()]. Or if there is an error, *ppStmt may be -** set to NULL. If the input text contained no SQL (if the input is and -** empty string or a comment) then *ppStmt is set to NULL. The calling -** procedure is responsible for deleting the compiled SQL statement -** using [sqlite3_finalize()] after it has finished with it. -** -** On success, [SQLITE_OK] is returned. Otherwise an -** [SQLITE_ERROR | error code] is returned. -** -** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are -** recommended for all new programs. The two older interfaces are retained -** for backwards compatibility, but their use is discouraged. -** In the "v2" interfaces, the prepared statement -** that is returned (the [sqlite3_stmt] object) contains a copy of the -** original SQL text. This causes the [sqlite3_step()] interface to -** behave a differently in two ways: -** -**
    -**
  1. -** If the database schema changes, instead of returning [SQLITE_SCHEMA] as it -** always used to do, [sqlite3_step()] will automatically recompile the SQL -** statement and try to run it again. If the schema has changed in a way -** that makes the statement no longer valid, [sqlite3_step()] will still -** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is -** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the -** error go away. Note: use [sqlite3_errmsg()] to find the text of the parsing -** error that results in an [SQLITE_SCHEMA] return. -**
  2. -** -**
  3. -** When an error occurs, -** [sqlite3_step()] will return one of the detailed -** [SQLITE_ERROR | result codes] or -** [SQLITE_IOERR_READ | extended result codes] such as directly. -** The legacy behavior was that [sqlite3_step()] would only return a generic -** [SQLITE_ERROR] result code and you would have to make a second call to -** [sqlite3_reset()] in order to find the underlying cause of the problem. -** With the "v2" prepare interfaces, the underlying reason for the error is -** returned immediately. -**
  4. -**
-*/ -int sqlite3_prepare( - sqlite3 *db, /* Database handle */ - const char *zSql, /* SQL statement, UTF-8 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const char **pzTail /* OUT: Pointer to unused portion of zSql */ -); -int sqlite3_prepare_v2( - sqlite3 *db, /* Database handle */ - const char *zSql, /* SQL statement, UTF-8 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const char **pzTail /* OUT: Pointer to unused portion of zSql */ -); -int sqlite3_prepare16( - sqlite3 *db, /* Database handle */ - const void *zSql, /* SQL statement, UTF-16 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const void **pzTail /* OUT: Pointer to unused portion of zSql */ -); -int sqlite3_prepare16_v2( - sqlite3 *db, /* Database handle */ - const void *zSql, /* SQL statement, UTF-16 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const void **pzTail /* OUT: Pointer to unused portion of zSql */ -); - -/* -** CAPI3REF: Dynamically Typed Value Object -** -** SQLite uses dynamic typing for the values it stores. Values can -** be integers, floating point values, strings, BLOBs, or NULL. When -** passing around values internally, each value is represented as -** an instance of the sqlite3_value object. -*/ -typedef struct Mem sqlite3_value; - -/* -** CAPI3REF: SQL Function Context Object -** -** The context in which an SQL function executes is stored in an -** sqlite3_context object. A pointer to such an object is the -** first parameter to user-defined SQL functions. -*/ -typedef struct sqlite3_context sqlite3_context; - -/* -** CAPI3REF: Binding Values To Prepared Statements -** -** In the SQL strings input to [sqlite3_prepare_v2()] and its variants, -** one or more literals can be replace by a parameter in one of these -** forms: -** -**
    -**
  • ? -**
  • ?NNN -**
  • :AAA -**
  • @AAA -**
  • $VVV -**
-** -** In the parameter forms shown above NNN is an integer literal, -** AAA is an alphanumeric identifier and VVV is a variable name according -** to the syntax rules of the TCL programming language. -** The values of these parameters (also called "host parameter names") -** can be set using the sqlite3_bind_*() routines defined here. -** -** The first argument to the sqlite3_bind_*() routines always is a pointer -** to the [sqlite3_stmt] object returned from [sqlite3_prepare_v2()] or -** its variants. The second -** argument is the index of the parameter to be set. The first parameter has -** an index of 1. When the same named parameter is used more than once, second -** and subsequent -** occurrences have the same index as the first occurrence. The index for -** named parameters can be looked up using the -** [sqlite3_bind_parameter_name()] API if desired. The index for "?NNN" -** parametes is the value of NNN. -** The NNN value must be between 1 and the compile-time -** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999). -** See limits.html for additional information. -** -** The third argument is the value to bind to the parameter. -** -** In those -** routines that have a fourth argument, its value is the number of bytes -** in the parameter. To be clear: the value is the number of bytes in the -** string, not the number of characters. The number -** of bytes does not include the zero-terminator at the end of strings. -** If the fourth parameter is negative, the length of the string is -** number of bytes up to the first zero terminator. -** -** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and -** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or -** text after SQLite has finished with it. If the fifth argument is the -** special value [SQLITE_STATIC], then the library assumes that the information -** is in static, unmanaged space and does not need to be freed. If the -** fifth argument has the value [SQLITE_TRANSIENT], then SQLite makes its -** own private copy of the data immediately, before the sqlite3_bind_*() -** routine returns. -** -** The sqlite3_bind_zeroblob() routine binds a BLOB of length n that -** is filled with zeros. A zeroblob uses a fixed amount of memory -** (just an integer to hold it size) while it is being processed. -** Zeroblobs are intended to serve as place-holders for BLOBs whose -** content is later written using -** [sqlite3_blob_open | increment BLOB I/O] routines. A negative -** value for the zeroblob results in a zero-length BLOB. -** -** The sqlite3_bind_*() routines must be called after -** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and -** before [sqlite3_step()]. -** Bindings are not cleared by the [sqlite3_reset()] routine. -** Unbound parameters are interpreted as NULL. -** -** These routines return [SQLITE_OK] on success or an error code if -** anything goes wrong. [SQLITE_RANGE] is returned if the parameter -** index is out of range. [SQLITE_NOMEM] is returned if malloc fails. -** [SQLITE_MISUSE] is returned if these routines are called on a virtual -** machine that is the wrong state or which has already been finalized. -*/ -int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); -int sqlite3_bind_double(sqlite3_stmt*, int, double); -int sqlite3_bind_int(sqlite3_stmt*, int, int); -int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); -int sqlite3_bind_null(sqlite3_stmt*, int); -int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); -int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); -int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); -int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); - -/* -** CAPI3REF: Number Of Host Parameters -** -** Return the largest host parameter index in the precompiled statement given -** as the argument. When the host parameters are of the forms like ":AAA" -** or "?", then they are assigned sequential increasing numbers beginning -** with one, so the value returned is the number of parameters. However -** if the same host parameter name is used multiple times, each occurrance -** is given the same number, so the value returned in that case is the number -** of unique host parameter names. If host parameters of the form "?NNN" -** are used (where NNN is an integer) then there might be gaps in the -** numbering and the value returned by this interface is the index of the -** host parameter with the largest index value. -** -** The prepared statement must not be [sqlite3_finalize | finalized] -** prior to this routine returnning. Otherwise the results are undefined -** and probably undesirable. -*/ -int sqlite3_bind_parameter_count(sqlite3_stmt*); - -/* -** CAPI3REF: Name Of A Host Parameter -** -** This routine returns a pointer to the name of the n-th parameter in a -** [sqlite3_stmt | prepared statement]. -** Host parameters of the form ":AAA" or "@AAA" or "$VVV" have a name -** which is the string ":AAA" or "@AAA" or "$VVV". -** In other words, the initial ":" or "$" or "@" -** is included as part of the name. -** Parameters of the form "?" or "?NNN" have no name. -** -** The first bound parameter has an index of 1, not 0. -** -** If the value n is out of range or if the n-th parameter is nameless, -** then NULL is returned. The returned string is always in the -** UTF-8 encoding even if the named parameter was originally specified -** as UTF-16 in [sqlite3_prepare16()] or [sqlite3_prepare16_v2()]. -*/ -const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); - -/* -** CAPI3REF: Index Of A Parameter With A Given Name -** -** This routine returns the index of a host parameter with the given name. -** The name must match exactly. If no parameter with the given name is -** found, return 0. Parameter names must be UTF8. -*/ -int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); - -/* -** CAPI3REF: Reset All Bindings On A Prepared Statement -** -** Contrary to the intuition of many, [sqlite3_reset()] does not -** reset the [sqlite3_bind_blob | bindings] on a -** [sqlite3_stmt | prepared statement]. Use this routine to -** reset all host parameters to NULL. -*/ -int sqlite3_clear_bindings(sqlite3_stmt*); - -/* -** CAPI3REF: Number Of Columns In A Result Set -** -** Return the number of columns in the result set returned by the -** [sqlite3_stmt | compiled SQL statement]. This routine returns 0 -** if pStmt is an SQL statement that does not return data (for -** example an UPDATE). -*/ -int sqlite3_column_count(sqlite3_stmt *pStmt); - -/* -** CAPI3REF: Column Names In A Result Set -** -** These routines return the name assigned to a particular column -** in the result set of a SELECT statement. The sqlite3_column_name() -** interface returns a pointer to a UTF8 string and sqlite3_column_name16() -** returns a pointer to a UTF16 string. The first parameter is the -** [sqlite3_stmt | prepared statement] that implements the SELECT statement. -** The second parameter is the column number. The left-most column is -** number 0. -** -** The returned string pointer is valid until either the -** [sqlite3_stmt | prepared statement] is destroyed by [sqlite3_finalize()] -** or until the next call sqlite3_column_name() or sqlite3_column_name16() -** on the same column. -** -** If sqlite3_malloc() fails during the processing of either routine -** (for example during a conversion from UTF-8 to UTF-16) then a -** NULL pointer is returned. -*/ -const char *sqlite3_column_name(sqlite3_stmt*, int N); -const void *sqlite3_column_name16(sqlite3_stmt*, int N); - -/* -** CAPI3REF: Source Of Data In A Query Result -** -** These routines provide a means to determine what column of what -** table in which database a result of a SELECT statement comes from. -** The name of the database or table or column can be returned as -** either a UTF8 or UTF16 string. The _database_ routines return -** the database name, the _table_ routines return the table name, and -** the origin_ routines return the column name. -** The returned string is valid until -** the [sqlite3_stmt | prepared statement] is destroyed using -** [sqlite3_finalize()] or until the same information is requested -** again in a different encoding. -** -** The names returned are the original un-aliased names of the -** database, table, and column. -** -** The first argument to the following calls is a -** [sqlite3_stmt | compiled SQL statement]. -** These functions return information about the Nth column returned by -** the statement, where N is the second function argument. -** -** If the Nth column returned by the statement is an expression -** or subquery and is not a column value, then all of these functions -** return NULL. Otherwise, they return the -** name of the attached database, table and column that query result -** column was extracted from. -** -** As with all other SQLite APIs, those postfixed with "16" return UTF-16 -** encoded strings, the other functions return UTF-8. -** -** These APIs are only available if the library was compiled with the -** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. -** -** If two or more threads call one or more of these routines against the same -** prepared statement and column at the same time then the results are -** undefined. -*/ -const char *sqlite3_column_database_name(sqlite3_stmt*,int); -const void *sqlite3_column_database_name16(sqlite3_stmt*,int); -const char *sqlite3_column_table_name(sqlite3_stmt*,int); -const void *sqlite3_column_table_name16(sqlite3_stmt*,int); -const char *sqlite3_column_origin_name(sqlite3_stmt*,int); -const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); - -/* -** CAPI3REF: Declared Datatype Of A Query Result -** -** The first parameter is a [sqlite3_stmt | compiled SQL statement]. -** If this statement is a SELECT statement and the Nth column of the -** returned result set of that SELECT is a table column (not an -** expression or subquery) then the declared type of the table -** column is returned. If the Nth column of the result set is an -** expression or subquery, then a NULL pointer is returned. -** The returned string is always UTF-8 encoded. For example, in -** the database schema: -** -** CREATE TABLE t1(c1 VARIANT); -** -** And the following statement compiled: -** -** SELECT c1 + 1, c1 FROM t1; -** -** Then this routine would return the string "VARIANT" for the second -** result column (i==1), and a NULL pointer for the first result column -** (i==0). -** -** SQLite uses dynamic run-time typing. So just because a column -** is declared to contain a particular type does not mean that the -** data stored in that column is of the declared type. SQLite is -** strongly typed, but the typing is dynamic not static. Type -** is associated with individual values, not with the containers -** used to hold those values. -*/ -const char *sqlite3_column_decltype(sqlite3_stmt *, int i); -const void *sqlite3_column_decltype16(sqlite3_stmt*,int); - -/* -** CAPI3REF: Evaluate An SQL Statement -** -** After an [sqlite3_stmt | SQL statement] has been prepared with a call -** to either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or to one of -** the legacy interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], -** then this function must be called one or more times to evaluate the -** statement. -** -** The details of the behavior of this sqlite3_step() interface depend -** on whether the statement was prepared using the newer "v2" interface -** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy -** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the -** new "v2" interface is recommended for new applications but the legacy -** interface will continue to be supported. -** -** In the lagacy interface, the return value will be either [SQLITE_BUSY], -** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. -** With the "v2" interface, any of the other [SQLITE_OK | result code] -** or [SQLITE_IOERR_READ | extended result code] might be returned as -** well. -** -** [SQLITE_BUSY] means that the database engine was unable to acquire the -** database locks it needs to do its job. If the statement is a COMMIT -** or occurs outside of an explicit transaction, then you can retry the -** statement. If the statement is not a COMMIT and occurs within a -** explicit transaction then you should rollback the transaction before -** continuing. -** -** [SQLITE_DONE] means that the statement has finished executing -** successfully. sqlite3_step() should not be called again on this virtual -** machine without first calling [sqlite3_reset()] to reset the virtual -** machine back to its initial state. -** -** If the SQL statement being executed returns any data, then -** [SQLITE_ROW] is returned each time a new row of data is ready -** for processing by the caller. The values may be accessed using -** the [sqlite3_column_int | column access functions]. -** sqlite3_step() is called again to retrieve the next row of data. -** -** [SQLITE_ERROR] means that a run-time error (such as a constraint -** violation) has occurred. sqlite3_step() should not be called again on -** the VM. More information may be found by calling [sqlite3_errmsg()]. -** With the legacy interface, a more specific error code (example: -** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) -** can be obtained by calling [sqlite3_reset()] on the -** [sqlite3_stmt | prepared statement]. In the "v2" interface, -** the more specific error code is returned directly by sqlite3_step(). -** -** [SQLITE_MISUSE] means that the this routine was called inappropriately. -** Perhaps it was called on a [sqlite3_stmt | prepared statement] that has -** already been [sqlite3_finalize | finalized] or on one that had -** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could -** be the case that the same database connection is being used by two or -** more threads at the same moment in time. -** -** Goofy Interface Alert: -** In the legacy interface, -** the sqlite3_step() API always returns a generic error code, -** [SQLITE_ERROR], following any error other than [SQLITE_BUSY] -** and [SQLITE_MISUSE]. You must call [sqlite3_reset()] or -** [sqlite3_finalize()] in order to find one of the specific -** [SQLITE_ERROR | result codes] that better describes the error. -** We admit that this is a goofy design. The problem has been fixed -** with the "v2" interface. If you prepare all of your SQL statements -** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead -** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()], then the -** more specific [SQLITE_ERROR | result codes] are returned directly -** by sqlite3_step(). The use of the "v2" interface is recommended. -*/ -int sqlite3_step(sqlite3_stmt*); - -/* -** CAPI3REF: -** -** Return the number of values in the current row of the result set. -** -** After a call to [sqlite3_step()] that returns [SQLITE_ROW], this routine -** will return the same value as the [sqlite3_column_count()] function. -** After [sqlite3_step()] has returned an [SQLITE_DONE], [SQLITE_BUSY], or -** a [SQLITE_ERROR | error code], or before [sqlite3_step()] has been -** called on the [sqlite3_stmt | prepared statement] for the first time, -** this routine returns zero. -*/ -int sqlite3_data_count(sqlite3_stmt *pStmt); - -/* -** CAPI3REF: Fundamental Datatypes -** -** Every value in SQLite has one of five fundamental datatypes: -** -**
    -**
  • 64-bit signed integer -**
  • 64-bit IEEE floating point number -**
  • string -**
  • BLOB -**
  • NULL -**
-** -** These constants are codes for each of those types. -** -** Note that the SQLITE_TEXT constant was also used in SQLite version 2 -** for a completely different meaning. Software that links against both -** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT not -** SQLITE_TEXT. -*/ -#define SQLITE_INTEGER 1 -#define SQLITE_FLOAT 2 -#define SQLITE_BLOB 4 -#define SQLITE_NULL 5 -#ifdef SQLITE_TEXT -# undef SQLITE_TEXT -#else -# define SQLITE_TEXT 3 -#endif -#define SQLITE3_TEXT 3 - -/* -** CAPI3REF: Results Values From A Query -** -** These routines return information about -** a single column of the current result row of a query. In every -** case the first argument is a pointer to the -** [sqlite3_stmt | SQL statement] that is being -** evaluated (the [sqlite3_stmt*] that was returned from -** [sqlite3_prepare_v2()] or one of its variants) and -** the second argument is the index of the column for which information -** should be returned. The left-most column of the result set -** has an index of 0. -** -** If the SQL statement is not currently point to a valid row, or if the -** the column index is out of range, the result is undefined. -** These routines may only be called when the most recent call to -** [sqlite3_step()] has returned [SQLITE_ROW] and neither -** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently. -** If any of these routines are called after [sqlite3_reset()] or -** [sqlite3_finalize()] or after [sqlite3_step()] has returned -** something other than [SQLITE_ROW], the results are undefined. -** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] -** are called from a different thread while any of these routines -** are pending, then the results are undefined. -** -** The sqlite3_column_type() routine returns -** [SQLITE_INTEGER | datatype code] for the initial data type -** of the result column. The returned value is one of [SQLITE_INTEGER], -** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value -** returned by sqlite3_column_type() is only meaningful if no type -** conversions have occurred as described below. After a type conversion, -** the value returned by sqlite3_column_type() is undefined. Future -** versions of SQLite may change the behavior of sqlite3_column_type() -** following a type conversion. -** -** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() -** routine returns the number of bytes in that BLOB or string. -** If the result is a UTF-16 string, then sqlite3_column_bytes() converts -** the string to UTF-8 and then returns the number of bytes. -** If the result is a numeric value then sqlite3_column_bytes() uses -** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns -** the number of bytes in that string. -** The value returned does not include the zero terminator at the end -** of the string. For clarity: the value returned is the number of -** bytes in the string, not the number of characters. -** -** Strings returned by sqlite3_column_text() and sqlite3_column_text16(), -** even zero-length strings, are always zero terminated. The return -** value from sqlite3_column_blob() for a zero-length blob is an arbitrary -** pointer, possibly even a NULL pointer. -** -** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() -** but leaves the result in UTF-16 instead of UTF-8. -** The zero terminator is not included in this count. -** -** These routines attempt to convert the value where appropriate. For -** example, if the internal representation is FLOAT and a text result -** is requested, [sqlite3_snprintf()] is used internally to do the conversion -** automatically. The following table details the conversions that -** are applied: -** -**
-**
-**
Internal
Type
Requested
Type
Conversion -** -**
NULL INTEGER Result is 0 -**
NULL FLOAT Result is 0.0 -**
NULL TEXT Result is NULL pointer -**
NULL BLOB Result is NULL pointer -**
INTEGER FLOAT Convert from integer to float -**
INTEGER TEXT ASCII rendering of the integer -**
INTEGER BLOB Same as for INTEGER->TEXT -**
FLOAT INTEGER Convert from float to integer -**
FLOAT TEXT ASCII rendering of the float -**
FLOAT BLOB Same as FLOAT->TEXT -**
TEXT INTEGER Use atoi() -**
TEXT FLOAT Use atof() -**
TEXT BLOB No change -**
BLOB INTEGER Convert to TEXT then use atoi() -**
BLOB FLOAT Convert to TEXT then use atof() -**
BLOB TEXT Add a zero terminator if needed -**
-** -** -** The table above makes reference to standard C library functions atoi() -** and atof(). SQLite does not really use these functions. It has its -** on equavalent internal routines. The atoi() and atof() names are -** used in the table for brevity and because they are familiar to most -** C programmers. -** -** Note that when type conversions occur, pointers returned by prior -** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or -** sqlite3_column_text16() may be invalidated. -** Type conversions and pointer invalidations might occur -** in the following cases: -** -**

    -**
  • The initial content is a BLOB and sqlite3_column_text() -** or sqlite3_column_text16() is called. A zero-terminator might -** need to be added to the string.

  • -** -**
  • The initial content is UTF-8 text and sqlite3_column_bytes16() or -** sqlite3_column_text16() is called. The content must be converted -** to UTF-16.

  • -** -**
  • The initial content is UTF-16 text and sqlite3_column_bytes() or -** sqlite3_column_text() is called. The content must be converted -** to UTF-8.

  • -**
-** -** Conversions between UTF-16be and UTF-16le are always done in place and do -** not invalidate a prior pointer, though of course the content of the buffer -** that the prior pointer points to will have been modified. Other kinds -** of conversion are done in place when it is possible, but sometime it is -** not possible and in those cases prior pointers are invalidated. -** -** The safest and easiest to remember policy is to invoke these routines -** in one of the following ways: -** -**
    -**
  • sqlite3_column_text() followed by sqlite3_column_bytes()
  • -**
  • sqlite3_column_blob() followed by sqlite3_column_bytes()
  • -**
  • sqlite3_column_text16() followed by sqlite3_column_bytes16()
  • -**
-** -** In other words, you should call sqlite3_column_text(), sqlite3_column_blob(), -** or sqlite3_column_text16() first to force the result into the desired -** format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to -** find the size of the result. Do not mix call to sqlite3_column_text() or -** sqlite3_column_blob() with calls to sqlite3_column_bytes16(). And do not -** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes(). -** -** The pointers returned are valid until a type conversion occurs as -** described above, or until [sqlite3_step()] or [sqlite3_reset()] or -** [sqlite3_finalize()] is called. The memory space used to hold strings -** and blobs is freed automatically. Do not pass the pointers returned -** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into -** [sqlite3_free()]. -** -** If a memory allocation error occurs during the evaluation of any -** of these routines, a default value is returned. The default value -** is either the integer 0, the floating point number 0.0, or a NULL -** pointer. Subsequent calls to [sqlite3_errcode()] will return -** [SQLITE_NOMEM]. -*/ -const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); -int sqlite3_column_bytes(sqlite3_stmt*, int iCol); -int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); -double sqlite3_column_double(sqlite3_stmt*, int iCol); -int sqlite3_column_int(sqlite3_stmt*, int iCol); -sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); -const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); -const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); -int sqlite3_column_type(sqlite3_stmt*, int iCol); -sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); - -/* -** CAPI3REF: Destroy A Prepared Statement Object -** -** The sqlite3_finalize() function is called to delete a -** [sqlite3_stmt | compiled SQL statement]. If the statement was -** executed successfully, or not executed at all, then SQLITE_OK is returned. -** If execution of the statement failed then an -** [SQLITE_ERROR | error code] or [SQLITE_IOERR_READ | extended error code] -** is returned. -** -** This routine can be called at any point during the execution of the -** [sqlite3_stmt | virtual machine]. If the virtual machine has not -** completed execution when this routine is called, that is like -** encountering an error or an interrupt. (See [sqlite3_interrupt()].) -** Incomplete updates may be rolled back and transactions cancelled, -** depending on the circumstances, and the -** [SQLITE_ERROR | result code] returned will be [SQLITE_ABORT]. -*/ -int sqlite3_finalize(sqlite3_stmt *pStmt); - -/* -** CAPI3REF: Reset A Prepared Statement Object -** -** The sqlite3_reset() function is called to reset a -** [sqlite3_stmt | compiled SQL statement] object. -** back to it's initial state, ready to be re-executed. -** Any SQL statement variables that had values bound to them using -** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. -** Use [sqlite3_clear_bindings()] to reset the bindings. -*/ -int sqlite3_reset(sqlite3_stmt *pStmt); - -/* -** CAPI3REF: Create Or Redefine SQL Functions -** -** The following two functions are used to add SQL functions or aggregates -** or to redefine the behavior of existing SQL functions or aggregates. The -** difference only between the two is that the second parameter, the -** name of the (scalar) function or aggregate, is encoded in UTF-8 for -** sqlite3_create_function() and UTF-16 for sqlite3_create_function16(). -** -** The first argument is the [sqlite3 | database handle] that holds the -** SQL function or aggregate is to be added or redefined. If a single -** program uses more than one database handle internally, then SQL -** functions or aggregates must be added individually to each database -** handle with which they will be used. -** -** The second parameter is the name of the SQL function to be created -** or redefined. -** The length of the name is limited to 255 bytes, exclusive of the -** zero-terminator. Note that the name length limit is in bytes, not -** characters. Any attempt to create a function with a longer name -** will result in an SQLITE_ERROR error. -** -** The third parameter is the number of arguments that the SQL function or -** aggregate takes. If this parameter is negative, then the SQL function or -** aggregate may take any number of arguments. -** -** The fourth parameter, eTextRep, specifies what -** [SQLITE_UTF8 | text encoding] this SQL function prefers for -** its parameters. Any SQL function implementation should be able to work -** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be -** more efficient with one encoding than another. It is allowed to -** invoke sqlite3_create_function() or sqlite3_create_function16() multiple -** times with the same function but with different values of eTextRep. -** When multiple implementations of the same function are available, SQLite -** will pick the one that involves the least amount of data conversion. -** If there is only a single implementation which does not care what -** text encoding is used, then the fourth argument should be -** [SQLITE_ANY]. -** -** The fifth parameter is an arbitrary pointer. The implementation -** of the function can gain access to this pointer using -** [sqlite3_user_data()]. -** -** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are -** pointers to C-language functions that implement the SQL -** function or aggregate. A scalar SQL function requires an implementation of -** the xFunc callback only, NULL pointers should be passed as the xStep -** and xFinal parameters. An aggregate SQL function requires an implementation -** of xStep and xFinal and NULL should be passed for xFunc. To delete an -** existing SQL function or aggregate, pass NULL for all three function -** callback. -** -** It is permitted to register multiple implementations of the same -** functions with the same name but with either differing numbers of -** arguments or differing perferred text encodings. SQLite will use -** the implementation most closely matches the way in which the -** SQL function is used. -*/ -int sqlite3_create_function( - sqlite3 *, - const char *zFunctionName, - int nArg, - int eTextRep, - void*, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*) -); -int sqlite3_create_function16( - sqlite3*, - const void *zFunctionName, - int nArg, - int eTextRep, - void*, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*) -); - -/* -** CAPI3REF: Text Encodings -** -** These constant define integer codes that represent the various -** text encodings supported by SQLite. -*/ -#define SQLITE_UTF8 1 -#define SQLITE_UTF16LE 2 -#define SQLITE_UTF16BE 3 -#define SQLITE_UTF16 4 /* Use native byte order */ -#define SQLITE_ANY 5 /* sqlite3_create_function only */ -#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ - -/* -** CAPI3REF: Obsolete Functions -** -** These functions are all now obsolete. In order to maintain -** backwards compatibility with older code, we continue to support -** these functions. However, new development projects should avoid -** the use of these functions. To help encourage people to avoid -** using these functions, we are not going to tell you want they do. -*/ -int sqlite3_aggregate_count(sqlite3_context*); -int sqlite3_expired(sqlite3_stmt*); -int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); -int sqlite3_global_recover(void); -void sqlite3_thread_cleanup(void); - -/* -** CAPI3REF: Obtaining SQL Function Parameter Values -** -** The C-language implementation of SQL functions and aggregates uses -** this set of interface routines to access the parameter values on -** the function or aggregate. -** -** The xFunc (for scalar functions) or xStep (for aggregates) parameters -** to [sqlite3_create_function()] and [sqlite3_create_function16()] -** define callbacks that implement the SQL functions and aggregates. -** The 4th parameter to these callbacks is an array of pointers to -** [sqlite3_value] objects. There is one [sqlite3_value] object for -** each parameter to the SQL function. These routines are used to -** extract values from the [sqlite3_value] objects. -** -** These routines work just like the corresponding -** [sqlite3_column_blob | sqlite3_column_* routines] except that -** these routines take a single [sqlite3_value*] pointer instead -** of an [sqlite3_stmt*] pointer and an integer column number. -** -** The sqlite3_value_text16() interface extracts a UTF16 string -** in the native byte-order of the host machine. The -** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces -** extract UTF16 strings as big-endian and little-endian respectively. -** -** The sqlite3_value_numeric_type() interface attempts to apply -** numeric affinity to the value. This means that an attempt is -** made to convert the value to an integer or floating point. If -** such a conversion is possible without loss of information (in order -** words if the value is original a string that looks like a number) -** then it is done. Otherwise no conversion occurs. The -** [SQLITE_INTEGER | datatype] after conversion is returned. -** -** Please pay particular attention to the fact that the pointer that -** is returned from [sqlite3_value_blob()], [sqlite3_value_text()], or -** [sqlite3_value_text16()] can be invalidated by a subsequent call to -** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], -** or [sqlite3_value_text16()]. -** -** These routines must be called from the same thread as -** the SQL function that supplied the sqlite3_value* parameters. -** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()] -** interface, then these routines should be called from the same thread -** that ran [sqlite3_column_value()]. -*/ -const void *sqlite3_value_blob(sqlite3_value*); -int sqlite3_value_bytes(sqlite3_value*); -int sqlite3_value_bytes16(sqlite3_value*); -double sqlite3_value_double(sqlite3_value*); -int sqlite3_value_int(sqlite3_value*); -sqlite3_int64 sqlite3_value_int64(sqlite3_value*); -const unsigned char *sqlite3_value_text(sqlite3_value*); -const void *sqlite3_value_text16(sqlite3_value*); -const void *sqlite3_value_text16le(sqlite3_value*); -const void *sqlite3_value_text16be(sqlite3_value*); -int sqlite3_value_type(sqlite3_value*); -int sqlite3_value_numeric_type(sqlite3_value*); - -/* -** CAPI3REF: Obtain Aggregate Function Context -** -** The implementation of aggregate SQL functions use this routine to allocate -** a structure for storing their state. The first time this routine -** is called for a particular aggregate, a new structure of size nBytes -** is allocated, zeroed, and returned. On subsequent calls (for the -** same aggregate instance) the same buffer is returned. The implementation -** of the aggregate can use the returned buffer to accumulate data. -** -** The buffer allocated is freed automatically by SQLite whan the aggregate -** query concludes. -** -** The first parameter should be a copy of the -** [sqlite3_context | SQL function context] that is the first -** parameter to the callback routine that implements the aggregate -** function. -** -** This routine must be called from the same thread in which -** the aggregate SQL function is running. -*/ -void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); - -/* -** CAPI3REF: User Data For Functions -** -** The pUserData parameter to the [sqlite3_create_function()] -** and [sqlite3_create_function16()] routines -** used to register user functions is available to -** the implementation of the function using this call. -** -** This routine must be called from the same thread in which -** the SQL function is running. -*/ -void *sqlite3_user_data(sqlite3_context*); - -/* -** CAPI3REF: Function Auxiliary Data -** -** The following two functions may be used by scalar SQL functions to -** associate meta-data with argument values. If the same value is passed to -** multiple invocations of the same SQL function during query execution, under -** some circumstances the associated meta-data may be preserved. This may -** be used, for example, to add a regular-expression matching scalar -** function. The compiled version of the regular expression is stored as -** meta-data associated with the SQL value passed as the regular expression -** pattern. The compiled regular expression can be reused on multiple -** invocations of the same function so that the original pattern string -** does not need to be recompiled on each invocation. -** -** The sqlite3_get_auxdata() interface returns a pointer to the meta-data -** associated with the Nth argument value to the current SQL function -** call, where N is the second parameter. If no meta-data has been set for -** that value, then a NULL pointer is returned. -** -** The sqlite3_set_auxdata() is used to associate meta-data with an SQL -** function argument. The third parameter is a pointer to the meta-data -** to be associated with the Nth user function argument value. The fourth -** parameter specifies a destructor that will be called on the meta- -** data pointer to release it when it is no longer required. If the -** destructor is NULL, it is not invoked. -** -** In practice, meta-data is preserved between function calls for -** expressions that are constant at compile time. This includes literal -** values and SQL variables. -** -** These routines must be called from the same thread in which -** the SQL function is running. -*/ -void *sqlite3_get_auxdata(sqlite3_context*, int); -void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*)); - - -/* -** CAPI3REF: Constants Defining Special Destructor Behavior -** -** These are special value for the destructor that is passed in as the -** final argument to routines like [sqlite3_result_blob()]. If the destructor -** argument is SQLITE_STATIC, it means that the content pointer is constant -** and will never change. It does not need to be destroyed. The -** SQLITE_TRANSIENT value means that the content will likely change in -** the near future and that SQLite should make its own private copy of -** the content before returning. -** -** The typedef is necessary to work around problems in certain -** C++ compilers. See ticket #2191. -*/ -typedef void (*sqlite3_destructor_type)(void*); -#define SQLITE_STATIC ((sqlite3_destructor_type)0) -#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) - -/* -** CAPI3REF: Setting The Result Of An SQL Function -** -** These routines are used by the xFunc or xFinal callbacks that -** implement SQL functions and aggregates. See -** [sqlite3_create_function()] and [sqlite3_create_function16()] -** for additional information. -** -** These functions work very much like the -** [sqlite3_bind_blob | sqlite3_bind_*] family of functions used -** to bind values to host parameters in prepared statements. -** Refer to the -** [sqlite3_bind_blob | sqlite3_bind_* documentation] for -** additional information. -** -** The sqlite3_result_error() and sqlite3_result_error16() functions -** cause the implemented SQL function to throw an exception. The -** parameter to sqlite3_result_error() or sqlite3_result_error16() -** is the text of an error message. -** -** The sqlite3_result_toobig() cause the function implementation -** to throw and error indicating that a string or BLOB is to long -** to represent. -** -** These routines must be called from within the same thread as -** the SQL function associated with the [sqlite3_context] pointer. -*/ -void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); -void sqlite3_result_double(sqlite3_context*, double); -void sqlite3_result_error(sqlite3_context*, const char*, int); -void sqlite3_result_error16(sqlite3_context*, const void*, int); -void sqlite3_result_error_toobig(sqlite3_context*); -void sqlite3_result_error_nomem(sqlite3_context*); -void sqlite3_result_int(sqlite3_context*, int); -void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); -void sqlite3_result_null(sqlite3_context*); -void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); -void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); -void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); -void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); -void sqlite3_result_value(sqlite3_context*, sqlite3_value*); -void sqlite3_result_zeroblob(sqlite3_context*, int n); - -/* -** CAPI3REF: Define New Collating Sequences -** -** These functions are used to add new collation sequences to the -** [sqlite3*] handle specified as the first argument. -** -** The name of the new collation sequence is specified as a UTF-8 string -** for sqlite3_create_collation() and sqlite3_create_collation_v2() -** and a UTF-16 string for sqlite3_create_collation16(). In all cases -** the name is passed as the second function argument. -** -** The third argument must be one of the constants [SQLITE_UTF8], -** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied -** routine expects to be passed pointers to strings encoded using UTF-8, -** UTF-16 little-endian or UTF-16 big-endian respectively. -** -** A pointer to the user supplied routine must be passed as the fifth -** argument. If it is NULL, this is the same as deleting the collation -** sequence (so that SQLite cannot call it anymore). Each time the user -** supplied function is invoked, it is passed a copy of the void* passed as -** the fourth argument to sqlite3_create_collation() or -** sqlite3_create_collation16() as its first parameter. -** -** The remaining arguments to the user-supplied routine are two strings, -** each represented by a [length, data] pair and encoded in the encoding -** that was passed as the third argument when the collation sequence was -** registered. The user routine should return negative, zero or positive if -** the first string is less than, equal to, or greater than the second -** string. i.e. (STRING1 - STRING2). -** -** The sqlite3_create_collation_v2() works like sqlite3_create_collation() -** excapt that it takes an extra argument which is a destructor for -** the collation. The destructor is called when the collation is -** destroyed and is passed a copy of the fourth parameter void* pointer -** of the sqlite3_create_collation_v2(). Collations are destroyed when -** they are overridden by later calls to the collation creation functions -** or when the [sqlite3*] database handle is closed using [sqlite3_close()]. -** -** The sqlite3_create_collation_v2() interface is experimental and -** subject to change in future releases. The other collation creation -** functions are stable. -*/ -int sqlite3_create_collation( - sqlite3*, - const char *zName, - int eTextRep, - void*, - int(*xCompare)(void*,int,const void*,int,const void*) -); -int sqlite3_create_collation_v2( - sqlite3*, - const char *zName, - int eTextRep, - void*, - int(*xCompare)(void*,int,const void*,int,const void*), - void(*xDestroy)(void*) -); -int sqlite3_create_collation16( - sqlite3*, - const char *zName, - int eTextRep, - void*, - int(*xCompare)(void*,int,const void*,int,const void*) -); - -/* -** CAPI3REF: Collation Needed Callbacks -** -** To avoid having to register all collation sequences before a database -** can be used, a single callback function may be registered with the -** database handle to be called whenever an undefined collation sequence is -** required. -** -** If the function is registered using the sqlite3_collation_needed() API, -** then it is passed the names of undefined collation sequences as strings -** encoded in UTF-8. If sqlite3_collation_needed16() is used, the names -** are passed as UTF-16 in machine native byte order. A call to either -** function replaces any existing callback. -** -** When the callback is invoked, the first argument passed is a copy -** of the second argument to sqlite3_collation_needed() or -** sqlite3_collation_needed16(). The second argument is the database -** handle. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], or -** [SQLITE_UTF16LE], indicating the most desirable form of the collation -** sequence function required. The fourth parameter is the name of the -** required collation sequence. -** -** The callback function should register the desired collation using -** [sqlite3_create_collation()], [sqlite3_create_collation16()], or -** [sqlite3_create_collation_v2()]. -*/ -int sqlite3_collation_needed( - sqlite3*, - void*, - void(*)(void*,sqlite3*,int eTextRep,const char*) -); -int sqlite3_collation_needed16( - sqlite3*, - void*, - void(*)(void*,sqlite3*,int eTextRep,const void*) -); - -/* -** Specify the key for an encrypted database. This routine should be -** called right after sqlite3_open(). -** -** The code to implement this API is not available in the public release -** of SQLite. -*/ -int sqlite3_key( - sqlite3 *db, /* Database to be rekeyed */ - const void *pKey, int nKey /* The key */ -); - -/* -** Change the key on an open database. If the current database is not -** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the -** database is decrypted. -** -** The code to implement this API is not available in the public release -** of SQLite. -*/ -int sqlite3_rekey( - sqlite3 *db, /* Database to be rekeyed */ - const void *pKey, int nKey /* The new key */ -); - -/* -** CAPI3REF: Suspend Execution For A Short Time -** -** This function causes the current thread to suspend execution -** a number of milliseconds specified in its parameter. -** -** If the operating system does not support sleep requests with -** millisecond time resolution, then the time will be rounded up to -** the nearest second. The number of milliseconds of sleep actually -** requested from the operating system is returned. -** -** SQLite implements this interface by calling the xSleep() -** method of the default [sqlite3_vfs] object. -*/ -int sqlite3_sleep(int); - -/* -** CAPI3REF: Name Of The Folder Holding Temporary Files -** -** If this global variable is made to point to a string which is -** the name of a folder (a.ka. directory), then all temporary files -** created by SQLite will be placed in that directory. If this variable -** is NULL pointer, then SQLite does a search for an appropriate temporary -** file directory. -** -** It is not safe to modify this variable once a database connection -** has been opened. It is intended that this variable be set once -** as part of process initialization and before any SQLite interface -** routines have been call and remain unchanged thereafter. -*/ -SQLITE_EXTERN char *sqlite3_temp_directory; - -/* -** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode -** -** Test to see whether or not the database connection is in autocommit -** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on -** by default. Autocommit is disabled by a BEGIN statement and reenabled -** by the next COMMIT or ROLLBACK. -** -** If certain kinds of errors occur on a statement within a multi-statement -** transactions (errors including [SQLITE_FULL], [SQLITE_IOERR], -** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the -** transaction might be rolled back automatically. The only way to -** find out if SQLite automatically rolled back the transaction after -** an error is to use this function. -** -** If another thread changes the autocommit status of the database -** connection while this routine is running, then the return value -** is undefined. -*/ -int sqlite3_get_autocommit(sqlite3*); - -/* -** CAPI3REF: Find The Database Handle Associated With A Prepared Statement -** -** Return the [sqlite3*] database handle to which a -** [sqlite3_stmt | prepared statement] belongs. -** This is the same database handle that was -** the first argument to the [sqlite3_prepare_v2()] or its variants -** that was used to create the statement in the first place. -*/ -sqlite3 *sqlite3_db_handle(sqlite3_stmt*); - - -/* -** CAPI3REF: Commit And Rollback Notification Callbacks -** -** These routines -** register callback functions to be invoked whenever a transaction -** is committed or rolled back. The pArg argument is passed through -** to the callback. If the callback on a commit hook function -** returns non-zero, then the commit is converted into a rollback. -** -** If another function was previously registered, its pArg value is returned. -** Otherwise NULL is returned. -** -** Registering a NULL function disables the callback. -** -** For the purposes of this API, a transaction is said to have been -** rolled back if an explicit "ROLLBACK" statement is executed, or -** an error or constraint causes an implicit rollback to occur. The -** callback is not invoked if a transaction is automatically rolled -** back because the database connection is closed. -** -** These are experimental interfaces and are subject to change. -*/ -void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); -void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); - -/* -** CAPI3REF: Data Change Notification Callbacks -** -** Register a callback function with the database connection identified by the -** first argument to be invoked whenever a row is updated, inserted or deleted. -** Any callback set by a previous call to this function for the same -** database connection is overridden. -** -** The second argument is a pointer to the function to invoke when a -** row is updated, inserted or deleted. The first argument to the callback is -** a copy of the third argument to sqlite3_update_hook(). The second callback -** argument is one of SQLITE_INSERT, SQLITE_DELETE or SQLITE_UPDATE, depending -** on the operation that caused the callback to be invoked. The third and -** fourth arguments to the callback contain pointers to the database and -** table name containing the affected row. The final callback parameter is -** the rowid of the row. In the case of an update, this is the rowid after -** the update takes place. -** -** The update hook is not invoked when internal system tables are -** modified (i.e. sqlite_master and sqlite_sequence). -** -** If another function was previously registered, its pArg value is returned. -** Otherwise NULL is returned. -*/ -void *sqlite3_update_hook( - sqlite3*, - void(*)(void *,int ,char const *,char const *,sqlite3_int64), - void* -); - -/* -** CAPI3REF: Enable Or Disable Shared Pager Cache -** -** This routine enables or disables the sharing of the database cache -** and schema data structures between connections to the same database. -** Sharing is enabled if the argument is true and disabled if the argument -** is false. -** -** Beginning in SQLite version 3.5.0, cache sharing is enabled and disabled -** for an entire process. In prior versions of SQLite, sharing was -** enabled or disabled for each thread separately. -** -** The cache sharing mode set by this interface effects all subsequent -** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. -** Existing database connections continue use the sharing mode that was -** in effect at the time they were opened. -** -** Virtual tables cannot be used with a shared cache. When shared -** cache is enabled, the [sqlite3_create_module()] API used to register -** virtual tables will always return an error. -** -** This routine returns [SQLITE_OK] if shared cache was -** enabled or disabled successfully. An [SQLITE_ERROR | error code] -** is returned otherwise. -** -** Shared cache is disabled by default. But this might change in -** future releases of SQLite. Applications that care about shared -** cache setting should set it explicitly. -*/ -int sqlite3_enable_shared_cache(int); - -/* -** CAPI3REF: Attempt To Free Heap Memory -** -** Attempt to free N bytes of heap memory by deallocating non-essential -** memory allocations held by the database library (example: memory -** used to cache database pages to improve performance). -*/ -int sqlite3_release_memory(int); - -/* -** CAPI3REF: Impose A Limit On Heap Size -** -** Place a "soft" limit on the amount of heap memory that may be allocated -** by SQLite. If an internal allocation is requested -** that would exceed the specified limit, [sqlite3_release_memory()] is -** invoked one or more times to free up some space before the allocation -** is made. -** -** The limit is called "soft", because if [sqlite3_release_memory()] cannot -** free sufficient memory to prevent the limit from being exceeded, -** the memory is allocated anyway and the current operation proceeds. -** -** A negative or zero value for N means that there is no soft heap limit and -** [sqlite3_release_memory()] will only be called when memory is exhausted. -** The default value for the soft heap limit is zero. -** -** SQLite makes a best effort to honor the soft heap limit. But if it -** is unable to reduce memory usage below the soft limit, execution will -** continue without error or notification. This is why the limit is -** called a "soft" limit. It is advisory only. -** -** The soft heap limit is implemented using the [sqlite3_memory_alarm()] -** interface. Only a single memory alarm is available in the default -** implementation. This means that if the application also uses the -** memory alarm interface it will interfere with the operation of the -** soft heap limit and undefined behavior will result. -** -** Prior to SQLite version 3.5.0, this routine only constrained the memory -** allocated by a single thread - the same thread in which this routine -** runs. Beginning with SQLite version 3.5.0, the soft heap limit is -** applied to all threads. The value specified for the soft heap limit -** is an upper bound on the total memory allocation for all threads. In -** version 3.5.0 there is no mechanism for limiting the heap usage for -** individual threads. -*/ -void sqlite3_soft_heap_limit(int); - -/* -** CAPI3REF: Extract Metadata About A Column Of A Table -** -** This routine -** returns meta-data about a specific column of a specific database -** table accessible using the connection handle passed as the first function -** argument. -** -** The column is identified by the second, third and fourth parameters to -** this function. The second parameter is either the name of the database -** (i.e. "main", "temp" or an attached database) containing the specified -** table or NULL. If it is NULL, then all attached databases are searched -** for the table using the same algorithm as the database engine uses to -** resolve unqualified table references. -** -** The third and fourth parameters to this function are the table and column -** name of the desired column, respectively. Neither of these parameters -** may be NULL. -** -** Meta information is returned by writing to the memory locations passed as -** the 5th and subsequent parameters to this function. Any of these -** arguments may be NULL, in which case the corresponding element of meta -** information is ommitted. -** -**
-** Parameter     Output Type      Description
-** -----------------------------------
-**
-**   5th         const char*      Data type
-**   6th         const char*      Name of the default collation sequence 
-**   7th         int              True if the column has a NOT NULL constraint
-**   8th         int              True if the column is part of the PRIMARY KEY
-**   9th         int              True if the column is AUTOINCREMENT
-** 
-** -** -** The memory pointed to by the character pointers returned for the -** declaration type and collation sequence is valid only until the next -** call to any sqlite API function. -** -** If the specified table is actually a view, then an error is returned. -** -** If the specified column is "rowid", "oid" or "_rowid_" and an -** INTEGER PRIMARY KEY column has been explicitly declared, then the output -** parameters are set for the explicitly declared column. If there is no -** explicitly declared IPK column, then the output parameters are set as -** follows: -** -**
-**     data type: "INTEGER"
-**     collation sequence: "BINARY"
-**     not null: 0
-**     primary key: 1
-**     auto increment: 0
-** 
-** -** This function may load one or more schemas from database files. If an -** error occurs during this process, or if the requested table or column -** cannot be found, an SQLITE error code is returned and an error message -** left in the database handle (to be retrieved using sqlite3_errmsg()). -** -** This API is only available if the library was compiled with the -** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined. -*/ -int sqlite3_table_column_metadata( - sqlite3 *db, /* Connection handle */ - const char *zDbName, /* Database name or NULL */ - const char *zTableName, /* Table name */ - const char *zColumnName, /* Column name */ - char const **pzDataType, /* OUTPUT: Declared data type */ - char const **pzCollSeq, /* OUTPUT: Collation sequence name */ - int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ - int *pPrimaryKey, /* OUTPUT: True if column part of PK */ - int *pAutoinc /* OUTPUT: True if column is auto-increment */ -); - -/* -** CAPI3REF: Load An Extension -** -** Attempt to load an SQLite extension library contained in the file -** zFile. The entry point is zProc. zProc may be 0 in which case the -** name of the entry point defaults to "sqlite3_extension_init". -** -** Return [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. -** -** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with -** error message text. The calling function should free this memory -** by calling [sqlite3_free()]. -** -** Extension loading must be enabled using [sqlite3_enable_load_extension()] -** prior to calling this API or an error will be returned. -*/ -int sqlite3_load_extension( - sqlite3 *db, /* Load the extension into this database connection */ - const char *zFile, /* Name of the shared library containing extension */ - const char *zProc, /* Entry point. Derived from zFile if 0 */ - char **pzErrMsg /* Put error message here if not 0 */ -); - -/* -** CAPI3REF: Enable Or Disable Extension Loading -** -** So as not to open security holes in older applications that are -** unprepared to deal with extension loading, and as a means of disabling -** extension loading while evaluating user-entered SQL, the following -** API is provided to turn the [sqlite3_load_extension()] mechanism on and -** off. It is off by default. See ticket #1863. -** -** Call this routine with onoff==1 to turn extension loading on -** and call it with onoff==0 to turn it back off again. -*/ -int sqlite3_enable_load_extension(sqlite3 *db, int onoff); - -/* -** CAPI3REF: Make Arrangements To Automatically Load An Extension -** -** Register an extension entry point that is automatically invoked -** whenever a new database connection is opened using -** [sqlite3_open()], [sqlite3_open16()], or [sqlite3_open_v2()]. -** -** This API can be invoked at program startup in order to register -** one or more statically linked extensions that will be available -** to all new database connections. -** -** Duplicate extensions are detected so calling this routine multiple -** times with the same extension is harmless. -** -** This routine stores a pointer to the extension in an array -** that is obtained from malloc(). If you run a memory leak -** checker on your program and it reports a leak because of this -** array, then invoke [sqlite3_automatic_extension_reset()] prior -** to shutdown to free the memory. -** -** Automatic extensions apply across all threads. -** -** This interface is experimental and is subject to change or -** removal in future releases of SQLite. -*/ -int sqlite3_auto_extension(void *xEntryPoint); - - -/* -** CAPI3REF: Reset Automatic Extension Loading -** -** Disable all previously registered automatic extensions. This -** routine undoes the effect of all prior [sqlite3_automatic_extension()] -** calls. -** -** This call disabled automatic extensions in all threads. -** -** This interface is experimental and is subject to change or -** removal in future releases of SQLite. -*/ -void sqlite3_reset_auto_extension(void); - - -/* -****** EXPERIMENTAL - subject to change without notice ************** -** -** The interface to the virtual-table mechanism is currently considered -** to be experimental. The interface might change in incompatible ways. -** If this is a problem for you, do not use the interface at this time. -** -** When the virtual-table mechanism stablizes, we will declare the -** interface fixed, support it indefinitely, and remove this comment. -*/ - -/* -** Structures used by the virtual table interface -*/ -typedef struct sqlite3_vtab sqlite3_vtab; -typedef struct sqlite3_index_info sqlite3_index_info; -typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; -typedef struct sqlite3_module sqlite3_module; - -/* -** A module is a class of virtual tables. Each module is defined -** by an instance of the following structure. This structure consists -** mostly of methods for the module. -*/ -struct sqlite3_module { - int iVersion; - int (*xCreate)(sqlite3*, void *pAux, - int argc, const char *const*argv, - sqlite3_vtab **ppVTab, char**); - int (*xConnect)(sqlite3*, void *pAux, - int argc, const char *const*argv, - sqlite3_vtab **ppVTab, char**); - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - int (*xDisconnect)(sqlite3_vtab *pVTab); - int (*xDestroy)(sqlite3_vtab *pVTab); - int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); - int (*xClose)(sqlite3_vtab_cursor*); - int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, - int argc, sqlite3_value **argv); - int (*xNext)(sqlite3_vtab_cursor*); - int (*xEof)(sqlite3_vtab_cursor*); - int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); - int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); - int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); - int (*xBegin)(sqlite3_vtab *pVTab); - int (*xSync)(sqlite3_vtab *pVTab); - int (*xCommit)(sqlite3_vtab *pVTab); - int (*xRollback)(sqlite3_vtab *pVTab); - int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, - void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), - void **ppArg); - - int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); -}; - -/* -** The sqlite3_index_info structure and its substructures is used to -** pass information into and receive the reply from the xBestIndex -** method of an sqlite3_module. The fields under **Inputs** are the -** inputs to xBestIndex and are read-only. xBestIndex inserts its -** results into the **Outputs** fields. -** -** The aConstraint[] array records WHERE clause constraints of the -** form: -** -** column OP expr -** -** Where OP is =, <, <=, >, or >=. The particular operator is stored -** in aConstraint[].op. The index of the column is stored in -** aConstraint[].iColumn. aConstraint[].usable is TRUE if the -** expr on the right-hand side can be evaluated (and thus the constraint -** is usable) and false if it cannot. -** -** The optimizer automatically inverts terms of the form "expr OP column" -** and makes other simplifications to the WHERE clause in an attempt to -** get as many WHERE clause terms into the form shown above as possible. -** The aConstraint[] array only reports WHERE clause terms in the correct -** form that refer to the particular virtual table being queried. -** -** Information about the ORDER BY clause is stored in aOrderBy[]. -** Each term of aOrderBy records a column of the ORDER BY clause. -** -** The xBestIndex method must fill aConstraintUsage[] with information -** about what parameters to pass to xFilter. If argvIndex>0 then -** the right-hand side of the corresponding aConstraint[] is evaluated -** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit -** is true, then the constraint is assumed to be fully handled by the -** virtual table and is not checked again by SQLite. -** -** The idxNum and idxPtr values are recorded and passed into xFilter. -** sqlite3_free() is used to free idxPtr if needToFreeIdxPtr is true. -** -** The orderByConsumed means that output from xFilter will occur in -** the correct order to satisfy the ORDER BY clause so that no separate -** sorting step is required. -** -** The estimatedCost value is an estimate of the cost of doing the -** particular lookup. A full scan of a table with N entries should have -** a cost of N. A binary search of a table of N entries should have a -** cost of approximately log(N). -*/ -struct sqlite3_index_info { - /* Inputs */ - int nConstraint; /* Number of entries in aConstraint */ - struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should ignore */ - } *aConstraint; /* Table of WHERE clause constraints */ - int nOrderBy; /* Number of terms in the ORDER BY clause */ - struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *aOrderBy; /* The ORDER BY clause */ - - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if >0, constraint is part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this constraint */ - } *aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from sqlite3_malloc */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ -}; -#define SQLITE_INDEX_CONSTRAINT_EQ 2 -#define SQLITE_INDEX_CONSTRAINT_GT 4 -#define SQLITE_INDEX_CONSTRAINT_LE 8 -#define SQLITE_INDEX_CONSTRAINT_LT 16 -#define SQLITE_INDEX_CONSTRAINT_GE 32 -#define SQLITE_INDEX_CONSTRAINT_MATCH 64 - -/* -** This routine is used to register a new module name with an SQLite -** connection. Module names must be registered before creating new -** virtual tables on the module, or before using preexisting virtual -** tables of the module. -*/ -int sqlite3_create_module( - sqlite3 *db, /* SQLite connection to register module with */ - const char *zName, /* Name of the module */ - const sqlite3_module *, /* Methods for the module */ - void * /* Client data for xCreate/xConnect */ -); - -/* -** This routine is identical to the sqlite3_create_module() method above, -** except that it allows a destructor function to be specified. It is -** even more experimental than the rest of the virtual tables API. -*/ -int sqlite3_create_module_v2( - sqlite3 *db, /* SQLite connection to register module with */ - const char *zName, /* Name of the module */ - const sqlite3_module *, /* Methods for the module */ - void *, /* Client data for xCreate/xConnect */ - void(*xDestroy)(void*) /* Module destructor function */ -); - -/* -** Every module implementation uses a subclass of the following structure -** to describe a particular instance of the module. Each subclass will -** be tailored to the specific needs of the module implementation. The -** purpose of this superclass is to define certain fields that are common -** to all module implementations. -** -** Virtual tables methods can set an error message by assigning a -** string obtained from sqlite3_mprintf() to zErrMsg. The method should -** take care that any prior string is freed by a call to sqlite3_free() -** prior to assigning a new string to zErrMsg. After the error message -** is delivered up to the client application, the string will be automatically -** freed by sqlite3_free() and the zErrMsg field will be zeroed. Note -** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field -** since virtual tables are commonly implemented in loadable extensions which -** do not have access to sqlite3MPrintf() or sqlite3Free(). -*/ -struct sqlite3_vtab { - const sqlite3_module *pModule; /* The module for this virtual table */ - int nRef; /* Used internally */ - char *zErrMsg; /* Error message from sqlite3_mprintf() */ - /* Virtual table implementations will typically add additional fields */ -}; - -/* Every module implementation uses a subclass of the following structure -** to describe cursors that point into the virtual table and are used -** to loop through the virtual table. Cursors are created using the -** xOpen method of the module. Each module implementation will define -** the content of a cursor structure to suit its own needs. -** -** This superclass exists in order to define fields of the cursor that -** are common to all implementations. -*/ -struct sqlite3_vtab_cursor { - sqlite3_vtab *pVtab; /* Virtual table of this cursor */ - /* Virtual table implementations will typically add additional fields */ -}; - -/* -** The xCreate and xConnect methods of a module use the following API -** to declare the format (the names and datatypes of the columns) of -** the virtual tables they implement. -*/ -int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); - -/* -** Virtual tables can provide alternative implementations of functions -** using the xFindFunction method. But global versions of those functions -** must exist in order to be overloaded. -** -** This API makes sure a global version of a function with a particular -** name and number of parameters exists. If no such function exists -** before this API is called, a new function is created. The implementation -** of the new function always causes an exception to be thrown. So -** the new function is not good for anything by itself. Its only -** purpose is to be a place-holder function that can be overloaded -** by virtual tables. -** -** This API should be considered part of the virtual table interface, -** which is experimental and subject to change. -*/ -int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); - -/* -** The interface to the virtual-table mechanism defined above (back up -** to a comment remarkably similar to this one) is currently considered -** to be experimental. The interface might change in incompatible ways. -** If this is a problem for you, do not use the interface at this time. -** -** When the virtual-table mechanism stabilizes, we will declare the -** interface fixed, support it indefinitely, and remove this comment. -** -****** EXPERIMENTAL - subject to change without notice ************** -*/ - -/* -** CAPI3REF: A Handle To An Open BLOB -** -** An instance of the following opaque structure is used to -** represent an blob-handle. A blob-handle is created by -** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()]. -** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces -** can be used to read or write small subsections of the blob. -** The [sqlite3_blob_bytes()] interface returns the size of the -** blob in bytes. -*/ -typedef struct sqlite3_blob sqlite3_blob; - -/* -** CAPI3REF: Open A BLOB For Incremental I/O -** -** Open a handle to the blob located in row iRow,, column zColumn, -** table zTable in database zDb. i.e. the same blob that would -** be selected by: -** -**
-**     SELECT zColumn FROM zDb.zTable WHERE rowid = iRow;
-** 
-** -** If the flags parameter is non-zero, the blob is opened for -** read and write access. If it is zero, the blob is opened for read -** access. -** -** On success, [SQLITE_OK] is returned and the new -** [sqlite3_blob | blob handle] is written to *ppBlob. -** Otherwise an error code is returned and -** any value written to *ppBlob should not be used by the caller. -** This function sets the database-handle error code and message -** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()]. -*/ -int sqlite3_blob_open( - sqlite3*, - const char *zDb, - const char *zTable, - const char *zColumn, - sqlite3_int64 iRow, - int flags, - sqlite3_blob **ppBlob -); - -/* -** CAPI3REF: Close A BLOB Handle -** -** Close an open [sqlite3_blob | blob handle]. -*/ -int sqlite3_blob_close(sqlite3_blob *); - -/* -** CAPI3REF: Return The Size Of An Open BLOB -** -** Return the size in bytes of the blob accessible via the open -** [sqlite3_blob | blob-handle] passed as an argument. -*/ -int sqlite3_blob_bytes(sqlite3_blob *); - -/* -** CAPI3REF: Read Data From A BLOB Incrementally -** -** This function is used to read data from an open -** [sqlite3_blob | blob-handle] into a caller supplied buffer. -** n bytes of data are copied into buffer -** z from the open blob, starting at offset iOffset. -** -** On success, SQLITE_OK is returned. Otherwise, an -** [SQLITE_ERROR | SQLite error code] or an -** [SQLITE_IOERR_READ | extended error code] is returned. -*/ -int sqlite3_blob_read(sqlite3_blob *, void *z, int n, int iOffset); - -/* -** CAPI3REF: Write Data Into A BLOB Incrementally -** -** This function is used to write data into an open -** [sqlite3_blob | blob-handle] from a user supplied buffer. -** n bytes of data are copied from the buffer -** pointed to by z into the open blob, starting at offset iOffset. -** -** If the [sqlite3_blob | blob-handle] passed as the first argument -** was not opened for writing (the flags parameter to [sqlite3_blob_open()] -*** was zero), this function returns [SQLITE_READONLY]. -** -** This function may only modify the contents of the blob, it is -** not possible to increase the size of a blob using this API. If -** offset iOffset is less than n bytes from the end of the blob, -** [SQLITE_ERROR] is returned and no data is written. -** -** On success, SQLITE_OK is returned. Otherwise, an -** [SQLITE_ERROR | SQLite error code] or an -** [SQLITE_IOERR_READ | extended error code] is returned. -*/ -int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); - -/* -** CAPI3REF: Virtual File System Objects -** -** A virtual filesystem (VFS) is an [sqlite3_vfs] object -** that SQLite uses to interact -** with the underlying operating system. Most builds come with a -** single default VFS that is appropriate for the host computer. -** New VFSes can be registered and existing VFSes can be unregistered. -** The following interfaces are provided. -** -** The sqlite3_vfs_find() interface returns a pointer to a VFS given its -** name. Names are case sensitive. If there is no match, a NULL -** pointer is returned. If zVfsName is NULL then the default -** VFS is returned. -** -** New VFSes are registered with sqlite3_vfs_register(). Each -** new VFS becomes the default VFS if the makeDflt flag is set. -** The same VFS can be registered multiple times without injury. -** To make an existing VFS into the default VFS, register it again -** with the makeDflt flag set. If two different VFSes with the -** same name are registered, the behavior is undefined. If a -** VFS is registered with a name that is NULL or an empty string, -** then the behavior is undefined. -** -** Unregister a VFS with the sqlite3_vfs_unregister() interface. -** If the default VFS is unregistered, another VFS is chosen as -** the default. The choice for the new VFS is arbitrary. -*/ -sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); -int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); -int sqlite3_vfs_unregister(sqlite3_vfs*); - -/* -** CAPI3REF: Mutexes -** -** The SQLite core uses these routines for thread -** synchronization. Though they are intended for internal -** use by SQLite, code that links against SQLite is -** permitted to use any of these routines. -** -** The SQLite source code contains multiple implementations -** of these mutex routines. An appropriate implementation -** is selected automatically at compile-time. The following -** implementations are available in the SQLite core: -** -**
    -**
  • SQLITE_MUTEX_OS2 -**
  • SQLITE_MUTEX_PTHREAD -**
  • SQLITE_MUTEX_W32 -**
  • SQLITE_MUTEX_NOOP -**
-** -** The SQLITE_MUTEX_NOOP implementation is a set of routines -** that does no real locking and is appropriate for use in -** a single-threaded application. The SQLITE_MUTEX_OS2, -** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations -** are appropriate for use on os/2, unix, and windows. -** -** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor -** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex -** implementation is included with the library. The -** mutex interface routines defined here become external -** references in the SQLite library for which implementations -** must be provided by the application. This facility allows an -** application that links against SQLite to provide its own mutex -** implementation without having to modify the SQLite core. -** -** The sqlite3_mutex_alloc() routine allocates a new -** mutex and returns a pointer to it. If it returns NULL -** that means that a mutex could not be allocated. SQLite -** will unwind its stack and return an error. The argument -** to sqlite3_mutex_alloc() is one of these integer constants: -** -**
    -**
  • SQLITE_MUTEX_FAST -**
  • SQLITE_MUTEX_RECURSIVE -**
  • SQLITE_MUTEX_STATIC_MASTER -**
  • SQLITE_MUTEX_STATIC_MEM -**
  • SQLITE_MUTEX_STATIC_MEM2 -**
  • SQLITE_MUTEX_STATIC_PRNG -**
  • SQLITE_MUTEX_STATIC_LRU -**
-** -** The first two constants cause sqlite3_mutex_alloc() to create -** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE -** is used but not necessarily so when SQLITE_MUTEX_FAST is used. -** The mutex implementation does not need to make a distinction -** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does -** not want to. But SQLite will only request a recursive mutex in -** cases where it really needs one. If a faster non-recursive mutex -** implementation is available on the host platform, the mutex subsystem -** might return such a mutex in response to SQLITE_MUTEX_FAST. -** -** The other allowed parameters to sqlite3_mutex_alloc() each return -** a pointer to a static preexisting mutex. Four static mutexes are -** used by the current version of SQLite. Future versions of SQLite -** may add additional static mutexes. Static mutexes are for internal -** use by SQLite only. Applications that use SQLite mutexes should -** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or -** SQLITE_MUTEX_RECURSIVE. -** -** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST -** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() -** returns a different mutex on every call. But for the static -** mutex types, the same mutex is returned on every call that has -** the same type number. -** -** The sqlite3_mutex_free() routine deallocates a previously -** allocated dynamic mutex. SQLite is careful to deallocate every -** dynamic mutex that it allocates. The dynamic mutexes must not be in -** use when they are deallocated. Attempting to deallocate a static -** mutex results in undefined behavior. SQLite never deallocates -** a static mutex. -** -** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt -** to enter a mutex. If another thread is already within the mutex, -** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return -** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK -** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can -** be entered multiple times by the same thread. In such cases the, -** mutex must be exited an equal number of times before another thread -** can enter. If the same thread tries to enter any other kind of mutex -** more than once, the behavior is undefined. SQLite will never exhibit -** such behavior in its own use of mutexes. -** -** Some systems (ex: windows95) do not the operation implemented by -** sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() will -** always return SQLITE_BUSY. The SQLite core only ever uses -** sqlite3_mutex_try() as an optimization so this is acceptable behavior. -** -** The sqlite3_mutex_leave() routine exits a mutex that was -** previously entered by the same thread. The behavior -** is undefined if the mutex is not currently entered by the -** calling thread or is not currently allocated. SQLite will -** never do either. -** -** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. -*/ -sqlite3_mutex *sqlite3_mutex_alloc(int); -void sqlite3_mutex_free(sqlite3_mutex*); -void sqlite3_mutex_enter(sqlite3_mutex*); -int sqlite3_mutex_try(sqlite3_mutex*); -void sqlite3_mutex_leave(sqlite3_mutex*); - -/* -** CAPI3REF: Mutex Verifcation Routines -** -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines -** are intended for use inside assert() statements. The SQLite core -** never uses these routines except inside an assert() and applications -** are advised to follow the lead of the core. The core only -** provides implementations for these routines when it is compiled -** with the SQLITE_DEBUG flag. External mutex implementations -** are only required to provide these routines if SQLITE_DEBUG is -** defined and if NDEBUG is not defined. -** -** These routines should return true if the mutex in their argument -** is held or not held, respectively, by the calling thread. -** -** The implementation is not required to provided versions of these -** routines that actually work. -** If the implementation does not provide working -** versions of these routines, it should at least provide stubs -** that always return true so that one does not get spurious -** assertion failures. -** -** If the argument to sqlite3_mutex_held() is a NULL pointer then -** the routine should return 1. This seems counter-intuitive since -** clearly the mutex cannot be held if it does not exist. But the -** the reason the mutex does not exist is because the build is not -** using mutexes. And we do not want the assert() containing the -** call to sqlite3_mutex_held() to fail, so a non-zero return is -** the appropriate thing to do. The sqlite3_mutex_notheld() -** interface should also return 1 when given a NULL pointer. -*/ -int sqlite3_mutex_held(sqlite3_mutex*); -int sqlite3_mutex_notheld(sqlite3_mutex*); - -/* -** CAPI3REF: Mutex Types -** -** The [sqlite3_mutex_alloc()] interface takes a single argument -** which is one of these integer constants. -*/ -#define SQLITE_MUTEX_FAST 0 -#define SQLITE_MUTEX_RECURSIVE 1 -#define SQLITE_MUTEX_STATIC_MASTER 2 -#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ -#define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ -#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ -#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ - -/* -** CAPI3REF: Low-Level Control Of Database Files -** -** The [sqlite3_file_control()] interface makes a direct call to the -** xFileControl method for the [sqlite3_io_methods] object associated -** with a particular database identified by the second argument. The -** name of the database is the name assigned to the database by the -** ATTACH SQL command that opened the -** database. To control the main database file, use the name "main" -** or a NULL pointer. The third and fourth parameters to this routine -** are passed directly through to the second and third parameters of -** the xFileControl method. The return value of the xFileControl -** method becomes the return value of this routine. -** -** If the second parameter (zDbName) does not match the name of any -** open database file, then SQLITE_ERROR is returned. This error -** code is not remembered and will not be recalled by [sqlite3_errcode()] -** or [sqlite3_errmsg()]. The underlying xFileControl method might -** also return SQLITE_ERROR. There is no way to distinguish between -** an incorrect zDbName and an SQLITE_ERROR return from the underlying -** xFileControl method. -** -** See also: [SQLITE_FCNTL_LOCKSTATE] -*/ -int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); - -/* -** Undo the hack that converts floating point types to integer for -** builds on processors without floating point support. -*/ -#ifdef SQLITE_OMIT_FLOATING_POINT -# undef double -#endif - -#ifdef __cplusplus -} /* End of the 'extern "C"' block */ -#endif -#endif diff --git a/extensions/sqlite/sqlite-source/sqlite3ext.h b/extensions/sqlite/sqlite-source/sqlite3ext.h deleted file mode 100644 index ba4f9d6e..00000000 --- a/extensions/sqlite/sqlite-source/sqlite3ext.h +++ /dev/null @@ -1,350 +0,0 @@ -/* -** 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. -** -** @(#) $Id$ -*/ -#ifndef _SQLITE3EXT_H_ -#define _SQLITE3EXT_H_ -#include "sqlite3.h" - -typedef struct sqlite3_api_routines sqlite3_api_routines; - -/* -** The following structure hold 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 others 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 char*,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 * (*snprintf)(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*); -}; - -/* -** The following macros redefine the API routines so that they are -** redirected throught 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. -*/ -#ifndef SQLITE_CORE -#define sqlite3_aggregate_context sqlite3_api->aggregate_context -#define sqlite3_aggregate_count sqlite3_api->aggregate_count -#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 -#define sqlite3_expired sqlite3_api->expired -#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 -#define sqlite3_global_recover sqlite3_api->global_recover -#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->snprintf -#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 -#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings -#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_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 -#endif /* SQLITE_CORE */ - -#define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api; -#define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v; - -#endif /* _SQLITE3EXT_H_ */ diff --git a/extensions/sqlite/sqlite-source/sqliteInt.h b/extensions/sqlite/sqlite-source/sqliteInt.h deleted file mode 100644 index c458d5ba..00000000 --- a/extensions/sqlite/sqlite-source/sqliteInt.h +++ /dev/null @@ -1,1972 +0,0 @@ -/* -** 2001 September 15 -** -** 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. -** -************************************************************************* -** Internal interface definitions for SQLite. -** -** @(#) $Id$ -*/ -#ifndef _SQLITEINT_H_ -#define _SQLITEINT_H_ -#include "sqliteLimit.h" - -/* -** For testing purposes, the various size limit constants are really -** variables that we can modify in the testfixture. -*/ -#ifdef SQLITE_TEST - #undef SQLITE_MAX_LENGTH - #undef SQLITE_MAX_COLUMN - #undef SQLITE_MAX_SQL_LENGTH - #undef SQLITE_MAX_EXPR_DEPTH - #undef SQLITE_MAX_COMPOUND_SELECT - #undef SQLITE_MAX_VDBE_OP - #undef SQLITE_MAX_FUNCTION_ARG - #undef SQLITE_MAX_VARIABLE_NUMBER - #undef SQLITE_MAX_PAGE_SIZE - #undef SQLITE_MAX_PAGE_COUNT - #undef SQLITE_MAX_LIKE_PATTERN_LENGTH - - #define SQLITE_MAX_LENGTH sqlite3MAX_LENGTH - #define SQLITE_MAX_COLUMN sqlite3MAX_COLUMN - #define SQLITE_MAX_SQL_LENGTH sqlite3MAX_SQL_LENGTH - #define SQLITE_MAX_EXPR_DEPTH sqlite3MAX_EXPR_DEPTH - #define SQLITE_MAX_COMPOUND_SELECT sqlite3MAX_COMPOUND_SELECT - #define SQLITE_MAX_VDBE_OP sqlite3MAX_VDBE_OP - #define SQLITE_MAX_FUNCTION_ARG sqlite3MAX_FUNCTION_ARG - #define SQLITE_MAX_VARIABLE_NUMBER sqlite3MAX_VARIABLE_NUMBER - #define SQLITE_MAX_PAGE_SIZE sqlite3MAX_PAGE_SIZE - #define SQLITE_MAX_PAGE_COUNT sqlite3MAX_PAGE_COUNT - #define SQLITE_MAX_LIKE_PATTERN_LENGTH sqlite3MAX_LIKE_PATTERN_LENGTH - - extern int sqlite3MAX_LENGTH; - extern int sqlite3MAX_COLUMN; - extern int sqlite3MAX_SQL_LENGTH; - extern int sqlite3MAX_EXPR_DEPTH; - extern int sqlite3MAX_COMPOUND_SELECT; - extern int sqlite3MAX_VDBE_OP; - extern int sqlite3MAX_FUNCTION_ARG; - extern int sqlite3MAX_VARIABLE_NUMBER; - extern int sqlite3MAX_PAGE_SIZE; - extern int sqlite3MAX_PAGE_COUNT; - extern int sqlite3MAX_LIKE_PATTERN_LENGTH; -#endif - - -/* -** The SQLITE_THREADSAFE macro must be defined as either 0 or 1. -** Older versions of SQLite used an optional THREADSAFE macro. -** We support that for legacy -*/ -#if !defined(SQLITE_THREADSAFE) -#if defined(THREADSAFE) -# define SQLITE_THREADSAFE THREADSAFE -#else -# define SQLITE_THREADSAFE 1 -#endif -#endif - -/* -** We need to define _XOPEN_SOURCE as follows in order to enable -** recursive mutexes on most unix systems. But Mac OS X is different. -** The _XOPEN_SOURCE define causes problems for Mac OS X we are told, -** so it is omitted there. See ticket #2673. -** -** Later we learn that _XOPEN_SOURCE is poorly or incorrectly -** implemented on some systems. So we avoid defining it at all -** if it is already defined or if it is unneeded because we are -** not doing a threadsafe build. Ticket #2681. -*/ -#if !defined(_XOPEN_SOURCE) && !defined(__MACOS__) && SQLITE_THREADSAFE -# define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */ -#endif - -#if defined(SQLITE_TCL) || defined(TCLSH) -# include -#endif - -/* -** Many people are failing to set -DNDEBUG=1 when compiling SQLite. -** Setting NDEBUG makes the code smaller and run faster. So the following -** lines are added to automatically set NDEBUG unless the -DSQLITE_DEBUG=1 -** option is set. Thus NDEBUG becomes an opt-in rather than an opt-out -** feature. -*/ -#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) -# define NDEBUG 1 -#endif - -/* -** These #defines should enable >2GB file support on Posix if the -** underlying operating system supports it. If the OS lacks -** large file support, or if the OS is windows, these should be no-ops. -** -** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch -** on the compiler command line. This is necessary if you are compiling -** on a recent machine (ex: RedHat 7.2) but you want your code to work -** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2 -** without this option, LFS is enable. But LFS does not exist in the kernel -** in RedHat 6.0, so the code won't work. Hence, for maximum binary -** portability you should omit LFS. -** -** Similar is true for MacOS. LFS is only supported on MacOS 9 and later. -*/ -#ifndef SQLITE_DISABLE_LFS -# define _LARGE_FILE 1 -# ifndef _FILE_OFFSET_BITS -# define _FILE_OFFSET_BITS 64 -# endif -# define _LARGEFILE_SOURCE 1 -#endif - -#include "sqlite3.h" -#include "hash.h" -#include "parse.h" -#include -#include -#include -#include -#include - -#define sqlite3_isnan(X) ((X)!=(X)) - -/* -** If compiling for a processor that lacks floating point support, -** substitute integer for floating-point -*/ -#ifdef SQLITE_OMIT_FLOATING_POINT -# define double sqlite_int64 -# define LONGDOUBLE_TYPE sqlite_int64 -# ifndef SQLITE_BIG_DBL -# define SQLITE_BIG_DBL (0x7fffffffffffffff) -# endif -# define SQLITE_OMIT_DATETIME_FUNCS 1 -# define SQLITE_OMIT_TRACE 1 -# undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT -#endif -#ifndef SQLITE_BIG_DBL -# define SQLITE_BIG_DBL (1e99) -#endif - -/* -** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0 -** afterward. Having this macro allows us to cause the C compiler -** to omit code used by TEMP tables without messy #ifndef statements. -*/ -#ifdef SQLITE_OMIT_TEMPDB -#define OMIT_TEMPDB 1 -#else -#define OMIT_TEMPDB 0 -#endif - -/* -** If the following macro is set to 1, then NULL values are considered -** distinct when determining whether or not two entries are the same -** in a UNIQUE index. This is the way PostgreSQL, Oracle, DB2, MySQL, -** OCELOT, and Firebird all work. The SQL92 spec explicitly says this -** is the way things are suppose to work. -** -** If the following macro is set to 0, the NULLs are indistinct for -** a UNIQUE index. In this mode, you can only have a single NULL entry -** for a column declared UNIQUE. This is the way Informix and SQL Server -** work. -*/ -#define NULL_DISTINCT_FOR_UNIQUE 1 - -/* -** The "file format" number is an integer that is incremented whenever -** the VDBE-level file format changes. The following macros define the -** the default file format for new databases and the maximum file format -** that the library can read. -*/ -#define SQLITE_MAX_FILE_FORMAT 4 -#ifndef SQLITE_DEFAULT_FILE_FORMAT -# define SQLITE_DEFAULT_FILE_FORMAT 1 -#endif - -/* -** Provide a default value for TEMP_STORE in case it is not specified -** on the command-line -*/ -#ifndef TEMP_STORE -# define TEMP_STORE 1 -#endif - -/* -** GCC does not define the offsetof() macro so we'll have to do it -** ourselves. -*/ -#ifndef offsetof -#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) -#endif - -/* -** Check to see if this machine uses EBCDIC. (Yes, believe it or -** not, there are still machines out there that use EBCDIC.) -*/ -#if 'A' == '\301' -# define SQLITE_EBCDIC 1 -#else -# define SQLITE_ASCII 1 -#endif - -/* -** Integers of known sizes. These typedefs might change for architectures -** where the sizes very. Preprocessor macros are available so that the -** types can be conveniently redefined at compile-type. Like this: -** -** cc '-DUINTPTR_TYPE=long long int' ... -*/ -#ifndef UINT32_TYPE -# define UINT32_TYPE unsigned int -#endif -#ifndef UINT16_TYPE -# define UINT16_TYPE unsigned short int -#endif -#ifndef INT16_TYPE -# define INT16_TYPE short int -#endif -#ifndef UINT8_TYPE -# define UINT8_TYPE unsigned char -#endif -#ifndef INT8_TYPE -# define INT8_TYPE signed char -#endif -#ifndef LONGDOUBLE_TYPE -# define LONGDOUBLE_TYPE long double -#endif -typedef sqlite_int64 i64; /* 8-byte signed integer */ -typedef sqlite_uint64 u64; /* 8-byte unsigned integer */ -typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ -typedef UINT16_TYPE u16; /* 2-byte unsigned integer */ -typedef INT16_TYPE i16; /* 2-byte signed integer */ -typedef UINT8_TYPE u8; /* 1-byte unsigned integer */ -typedef UINT8_TYPE i8; /* 1-byte signed integer */ - -/* -** Macros to determine whether the machine is big or little endian, -** evaluated at runtime. -*/ -#ifdef SQLITE_AMALGAMATION -const int sqlite3One; -#else -extern const int sqlite3one; -#endif -#if defined(i386) || defined(__i386__) || defined(_M_IX86) -# define SQLITE_BIGENDIAN 0 -# define SQLITE_LITTLEENDIAN 1 -# define SQLITE_UTF16NATIVE SQLITE_UTF16LE -#else -# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) -# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) -# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) -#endif - -/* -** An instance of the following structure is used to store the busy-handler -** callback for a given sqlite handle. -** -** The sqlite.busyHandler member of the sqlite struct contains the busy -** callback for the database handle. Each pager opened via the sqlite -** handle is passed a pointer to sqlite.busyHandler. The busy-handler -** callback is currently invoked only from within pager.c. -*/ -typedef struct BusyHandler BusyHandler; -struct BusyHandler { - int (*xFunc)(void *,int); /* The busy callback */ - void *pArg; /* First arg to busy callback */ - int nBusy; /* Incremented with each busy call */ -}; - -/* -** Defer sourcing vdbe.h and btree.h until after the "u8" and -** "BusyHandler typedefs. -*/ -#include "btree.h" -#include "vdbe.h" -#include "pager.h" - - -/* -** Name of the master database table. The master database table -** is a special table that holds the names and attributes of all -** user tables and indices. -*/ -#define MASTER_NAME "sqlite_master" -#define TEMP_MASTER_NAME "sqlite_temp_master" - -/* -** The root-page of the master database table. -*/ -#define MASTER_ROOT 1 - -/* -** The name of the schema table. -*/ -#define SCHEMA_TABLE(x) ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME) - -/* -** A convenience macro that returns the number of elements in -** an array. -*/ -#define ArraySize(X) (sizeof(X)/sizeof(X[0])) - -/* -** Forward references to structures -*/ -typedef struct AggInfo AggInfo; -typedef struct AuthContext AuthContext; -typedef struct CollSeq CollSeq; -typedef struct Column Column; -typedef struct Db Db; -typedef struct Schema Schema; -typedef struct Expr Expr; -typedef struct ExprList ExprList; -typedef struct FKey FKey; -typedef struct FuncDef FuncDef; -typedef struct IdList IdList; -typedef struct Index Index; -typedef struct KeyClass KeyClass; -typedef struct KeyInfo KeyInfo; -typedef struct Module Module; -typedef struct NameContext NameContext; -typedef struct Parse Parse; -typedef struct Select Select; -typedef struct SrcList SrcList; -typedef struct Table Table; -typedef struct TableLock TableLock; -typedef struct Token Token; -typedef struct TriggerStack TriggerStack; -typedef struct TriggerStep TriggerStep; -typedef struct Trigger Trigger; -typedef struct WhereInfo WhereInfo; -typedef struct WhereLevel WhereLevel; - -#include "os.h" -#include "mutex.h" - -/* -** Each database file to be accessed by the system is an instance -** of the following structure. There are normally two of these structures -** in the sqlite.aDb[] array. aDb[0] is the main database file and -** aDb[1] is the database file used to hold temporary tables. Additional -** databases may be attached. -*/ -struct Db { - char *zName; /* Name of this database */ - Btree *pBt; /* The B*Tree structure for this database file */ - u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */ - u8 safety_level; /* How aggressive at synching data to disk */ - void *pAux; /* Auxiliary data. Usually NULL */ - void (*xFreeAux)(void*); /* Routine to free pAux */ - Schema *pSchema; /* Pointer to database schema (possibly shared) */ -}; - -/* -** An instance of the following structure stores a database schema. -** -** If there are no virtual tables configured in this schema, the -** Schema.db variable is set to NULL. After the first virtual table -** has been added, it is set to point to the database connection -** used to create the connection. Once a virtual table has been -** added to the Schema structure and the Schema.db variable populated, -** only that database connection may use the Schema to prepare -** statements. -*/ -struct Schema { - int schema_cookie; /* Database schema version number for this file */ - Hash tblHash; /* All tables indexed by name */ - Hash idxHash; /* All (named) indices indexed by name */ - Hash trigHash; /* All triggers indexed by name */ - Hash aFKey; /* Foreign keys indexed by to-table */ - Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ - u8 file_format; /* Schema format version for this file */ - u8 enc; /* Text encoding used by this database */ - u16 flags; /* Flags associated with this schema */ - int cache_size; /* Number of pages to use in the cache */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3 *db; /* "Owner" connection. See comment above */ -#endif -}; - -/* -** These macros can be used to test, set, or clear bits in the -** Db.flags field. -*/ -#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))==(P)) -#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))!=0) -#define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->flags|=(P) -#define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->flags&=~(P) - -/* -** Allowed values for the DB.flags field. -** -** The DB_SchemaLoaded flag is set after the database schema has been -** read into internal hash tables. -** -** DB_UnresetViews means that one or more views have column names that -** have been filled out. If the schema changes, these column names might -** changes and so the view will need to be reset. -*/ -#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */ -#define DB_UnresetViews 0x0002 /* Some views have defined column names */ -#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ - - -/* -** Each database is an instance of the following structure. -** -** The sqlite.lastRowid records the last insert rowid generated by an -** insert statement. Inserts on views do not affect its value. Each -** trigger has its own context, so that lastRowid can be updated inside -** triggers as usual. The previous value will be restored once the trigger -** exits. Upon entering a before or instead of trigger, lastRowid is no -** longer (since after version 2.8.12) reset to -1. -** -** The sqlite.nChange does not count changes within triggers and keeps no -** context. It is reset at start of sqlite3_exec. -** The sqlite.lsChange represents the number of changes made by the last -** insert, update, or delete statement. It remains constant throughout the -** length of a statement and is then updated by OP_SetCounts. It keeps a -** context stack just like lastRowid so that the count of changes -** within a trigger is not seen outside the trigger. Changes to views do not -** affect the value of lsChange. -** The sqlite.csChange keeps track of the number of current changes (since -** the last statement) and is used to update sqlite_lsChange. -** -** The member variables sqlite.errCode, sqlite.zErrMsg and sqlite.zErrMsg16 -** store the most recent error code and, if applicable, string. The -** internal function sqlite3Error() is used to set these variables -** consistently. -*/ -struct sqlite3 { - sqlite3_vfs *pVfs; /* OS Interface */ - int nDb; /* Number of backends currently in use */ - Db *aDb; /* All backends */ - int flags; /* Miscellanous flags. See below */ - int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ - int errCode; /* Most recent error code (SQLITE_*) */ - int errMask; /* & result codes with this before returning */ - u8 autoCommit; /* The auto-commit flag. */ - u8 temp_store; /* 1: file 2: memory 0: default */ - u8 mallocFailed; /* True if we have seen a malloc failure */ - int nTable; /* Number of tables in the database */ - CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ - i64 lastRowid; /* ROWID of most recent insert (see above) */ - i64 priorNewRowid; /* Last randomly generated ROWID */ - int magic; /* Magic number for detect library misuse */ - int nChange; /* Value returned by sqlite3_changes() */ - int nTotalChange; /* Value returned by sqlite3_total_changes() */ - sqlite3_mutex *mutex; /* Connection mutex */ - struct sqlite3InitInfo { /* Information used during initialization */ - int iDb; /* When back is being initialized */ - int newTnum; /* Rootpage of table being initialized */ - u8 busy; /* TRUE if currently initializing */ - } init; - int nExtension; /* Number of loaded extensions */ - void **aExtension; /* Array of shared libraray handles */ - struct Vdbe *pVdbe; /* List of active virtual machines */ - int activeVdbeCnt; /* Number of vdbes currently executing */ - void (*xTrace)(void*,const char*); /* Trace function */ - void *pTraceArg; /* Argument to the trace function */ - void (*xProfile)(void*,const char*,u64); /* Profiling function */ - void *pProfileArg; /* Argument to profile function */ - void *pCommitArg; /* Argument to xCommitCallback() */ - int (*xCommitCallback)(void*); /* Invoked at every commit. */ - void *pRollbackArg; /* Argument to xRollbackCallback() */ - void (*xRollbackCallback)(void*); /* Invoked at every commit. */ - void *pUpdateArg; - void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64); - void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); - void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); - void *pCollNeededArg; - sqlite3_value *pErr; /* Most recent error message */ - char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ - char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ - union { - int isInterrupted; /* True if sqlite3_interrupt has been called */ - double notUsed1; /* Spacer */ - } u1; -#ifndef SQLITE_OMIT_AUTHORIZATION - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); - /* Access authorization function */ - void *pAuthArg; /* 1st argument to the access auth function */ -#endif -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - int (*xProgress)(void *); /* The progress callback */ - void *pProgressArg; /* Argument to the progress callback */ - int nProgressOps; /* Number of opcodes for progress callback */ -#endif -#ifndef SQLITE_OMIT_VIRTUALTABLE - Hash aModule; /* populated by sqlite3_create_module() */ - Table *pVTab; /* vtab with active Connect/Create method */ - sqlite3_vtab **aVTrans; /* Virtual tables with open transactions */ - int nVTrans; /* Allocated size of aVTrans */ -#endif - Hash aFunc; /* All functions that can be in SQL exprs */ - Hash aCollSeq; /* All collating sequences */ - BusyHandler busyHandler; /* Busy callback */ - int busyTimeout; /* Busy handler timeout, in msec */ - Db aDbStatic[2]; /* Static space for the 2 default backends */ -#ifdef SQLITE_SSE - sqlite3_stmt *pFetch; /* Used by SSE to fetch stored statements */ -#endif - u8 dfltLockMode; /* Default locking-mode for attached dbs */ -}; - -/* -** A macro to discover the encoding of a database. -*/ -#define ENC(db) ((db)->aDb[0].pSchema->enc) - -/* -** Possible values for the sqlite.flags and or Db.flags fields. -** -** On sqlite.flags, the SQLITE_InTrans value means that we have -** executed a BEGIN. On Db.flags, SQLITE_InTrans means a statement -** transaction is active on that particular database file. -*/ -#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ -#define SQLITE_InTrans 0x00000008 /* True if in a transaction */ -#define SQLITE_InternChanges 0x00000010 /* Uncommitted Hash table changes */ -#define SQLITE_FullColNames 0x00000020 /* Show full column names on SELECT */ -#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */ -#define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */ - /* DELETE, or UPDATE and return */ - /* the count using a callback. */ -#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ - /* result set is empty */ -#define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */ -#define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */ -#define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */ -#define SQLITE_NoReadlock 0x00001000 /* Readlocks are omitted when - ** accessing read-only databases */ -#define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */ -#define SQLITE_ReadUncommitted 0x00004000 /* For shared-cache mode */ -#define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */ -#define SQLITE_FullFSync 0x00010000 /* Use full fsync on the backend */ -#define SQLITE_LoadExtension 0x00020000 /* Enable load_extension */ - -#define SQLITE_RecoveryMode 0x00040000 /* Ignore schema errors */ -#define SQLITE_SharedCache 0x00080000 /* Cache sharing is enabled */ -#define SQLITE_Vtab 0x00100000 /* There exists a virtual table */ - -/* -** Possible values for the sqlite.magic field. -** The numbers are obtained at random and have no special meaning, other -** than being distinct from one another. -*/ -#define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */ -#define SQLITE_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */ -#define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */ -#define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */ - -/* -** Each SQL function is defined by an instance of the following -** structure. A pointer to this structure is stored in the sqlite.aFunc -** hash table. When multiple functions have the same name, the hash table -** points to a linked list of these structures. -*/ -struct FuncDef { - i16 nArg; /* Number of arguments. -1 means unlimited */ - u8 iPrefEnc; /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */ - u8 needCollSeq; /* True if sqlite3GetFuncCollSeq() might be called */ - u8 flags; /* Some combination of SQLITE_FUNC_* */ - void *pUserData; /* User data parameter */ - FuncDef *pNext; /* Next function with same name */ - void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */ - void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */ - void (*xFinalize)(sqlite3_context*); /* Aggregate finializer */ - char zName[1]; /* SQL name of the function. MUST BE LAST */ -}; - -/* -** Each SQLite module (virtual table definition) is defined by an -** instance of the following structure, stored in the sqlite3.aModule -** hash table. -*/ -struct Module { - const sqlite3_module *pModule; /* Callback pointers */ - const char *zName; /* Name passed to create_module() */ - void *pAux; /* pAux passed to create_module() */ - void (*xDestroy)(void *); /* Module destructor function */ -}; - -/* -** Possible values for FuncDef.flags -*/ -#define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */ -#define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */ -#define SQLITE_FUNC_EPHEM 0x04 /* Ephermeral. Delete with VDBE */ - -/* -** information about each column of an SQL table is held in an instance -** of this structure. -*/ -struct Column { - char *zName; /* Name of this column */ - Expr *pDflt; /* Default value of this column */ - char *zType; /* Data type for this column */ - char *zColl; /* Collating sequence. If NULL, use the default */ - u8 notNull; /* True if there is a NOT NULL constraint */ - u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */ - char affinity; /* One of the SQLITE_AFF_... values */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - u8 isHidden; /* True if this column is 'hidden' */ -#endif -}; - -/* -** A "Collating Sequence" is defined by an instance of the following -** structure. Conceptually, a collating sequence consists of a name and -** a comparison routine that defines the order of that sequence. -** -** There may two seperate implementations of the collation function, one -** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that -** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine -** native byte order. When a collation sequence is invoked, SQLite selects -** the version that will require the least expensive encoding -** translations, if any. -** -** The CollSeq.pUser member variable is an extra parameter that passed in -** as the first argument to the UTF-8 comparison function, xCmp. -** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function, -** xCmp16. -** -** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the -** collating sequence is undefined. Indices built on an undefined -** collating sequence may not be read or written. -*/ -struct CollSeq { - char *zName; /* Name of the collating sequence, UTF-8 encoded */ - u8 enc; /* Text encoding handled by xCmp() */ - u8 type; /* One of the SQLITE_COLL_... values below */ - void *pUser; /* First argument to xCmp() */ - int (*xCmp)(void*,int, const void*, int, const void*); - void (*xDel)(void*); /* Destructor for pUser */ -}; - -/* -** Allowed values of CollSeq flags: -*/ -#define SQLITE_COLL_BINARY 1 /* The default memcmp() collating sequence */ -#define SQLITE_COLL_NOCASE 2 /* The built-in NOCASE collating sequence */ -#define SQLITE_COLL_REVERSE 3 /* The built-in REVERSE collating sequence */ -#define SQLITE_COLL_USER 0 /* Any other user-defined collating sequence */ - -/* -** A sort order can be either ASC or DESC. -*/ -#define SQLITE_SO_ASC 0 /* Sort in ascending order */ -#define SQLITE_SO_DESC 1 /* Sort in ascending order */ - -/* -** Column affinity types. -** -** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and -** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve -** the speed a little by number the values consecutively. -** -** But rather than start with 0 or 1, we begin with 'a'. That way, -** when multiple affinity types are concatenated into a string and -** used as the P3 operand, they will be more readable. -** -** Note also that the numeric types are grouped together so that testing -** for a numeric type is a single comparison. -*/ -#define SQLITE_AFF_TEXT 'a' -#define SQLITE_AFF_NONE 'b' -#define SQLITE_AFF_NUMERIC 'c' -#define SQLITE_AFF_INTEGER 'd' -#define SQLITE_AFF_REAL 'e' - -#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) - -/* -** Each SQL table is represented in memory by an instance of the -** following structure. -** -** Table.zName is the name of the table. The case of the original -** CREATE TABLE statement is stored, but case is not significant for -** comparisons. -** -** Table.nCol is the number of columns in this table. Table.aCol is a -** pointer to an array of Column structures, one for each column. -** -** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of -** the column that is that key. Otherwise Table.iPKey is negative. Note -** that the datatype of the PRIMARY KEY must be INTEGER for this field to -** be set. An INTEGER PRIMARY KEY is used as the rowid for each row of -** the table. If a table has no INTEGER PRIMARY KEY, then a random rowid -** is generated for each row of the table. Table.hasPrimKey is true if -** the table has any PRIMARY KEY, INTEGER or otherwise. -** -** Table.tnum is the page number for the root BTree page of the table in the -** database file. If Table.iDb is the index of the database table backend -** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that -** holds temporary tables and indices. If Table.isEphem -** is true, then the table is stored in a file that is automatically deleted -** when the VDBE cursor to the table is closed. In this case Table.tnum -** refers VDBE cursor number that holds the table open, not to the root -** page number. Transient tables are used to hold the results of a -** sub-query that appears instead of a real table name in the FROM clause -** of a SELECT statement. -*/ -struct Table { - char *zName; /* Name of the table */ - int nCol; /* Number of columns in this table */ - Column *aCol; /* Information about each column */ - int iPKey; /* If not less then 0, use aCol[iPKey] as the primary key */ - Index *pIndex; /* List of SQL indexes on this table. */ - int tnum; /* Root BTree node for this table (see note above) */ - Select *pSelect; /* NULL for tables. Points to definition if a view. */ - int nRef; /* Number of pointers to this Table */ - Trigger *pTrigger; /* List of SQL triggers on this table */ - FKey *pFKey; /* Linked list of all foreign keys in this table */ - char *zColAff; /* String defining the affinity of each column */ -#ifndef SQLITE_OMIT_CHECK - Expr *pCheck; /* The AND of all CHECK constraints */ -#endif -#ifndef SQLITE_OMIT_ALTERTABLE - int addColOffset; /* Offset in CREATE TABLE statement to add a new column */ -#endif - u8 readOnly; /* True if this table should not be written by the user */ - u8 isEphem; /* True if created using OP_OpenEphermeral */ - u8 hasPrimKey; /* True if there exists a primary key */ - u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ - u8 autoInc; /* True if the integer primary key is autoincrement */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - u8 isVirtual; /* True if this is a virtual table */ - u8 isCommit; /* True once the CREATE TABLE has been committed */ - Module *pMod; /* Pointer to the implementation of the module */ - sqlite3_vtab *pVtab; /* Pointer to the module instance */ - int nModuleArg; /* Number of arguments to the module */ - char **azModuleArg; /* Text of all module args. [0] is module name */ -#endif - Schema *pSchema; /* Schema that contains this table */ -}; - -/* -** Test to see whether or not a table is a virtual table. This is -** done as a macro so that it will be optimized out when virtual -** table support is omitted from the build. -*/ -#ifndef SQLITE_OMIT_VIRTUALTABLE -# define IsVirtual(X) ((X)->isVirtual) -# define IsHiddenColumn(X) ((X)->isHidden) -#else -# define IsVirtual(X) 0 -# define IsHiddenColumn(X) 0 -#endif - -/* -** Each foreign key constraint is an instance of the following structure. -** -** A foreign key is associated with two tables. The "from" table is -** the table that contains the REFERENCES clause that creates the foreign -** key. The "to" table is the table that is named in the REFERENCES clause. -** Consider this example: -** -** CREATE TABLE ex1( -** a INTEGER PRIMARY KEY, -** b INTEGER CONSTRAINT fk1 REFERENCES ex2(x) -** ); -** -** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2". -** -** Each REFERENCES clause generates an instance of the following structure -** which is attached to the from-table. The to-table need not exist when -** the from-table is created. The existance of the to-table is not checked -** until an attempt is made to insert data into the from-table. -** -** The sqlite.aFKey hash table stores pointers to this structure -** given the name of a to-table. For each to-table, all foreign keys -** associated with that table are on a linked list using the FKey.pNextTo -** field. -*/ -struct FKey { - Table *pFrom; /* The table that constains the REFERENCES clause */ - FKey *pNextFrom; /* Next foreign key in pFrom */ - char *zTo; /* Name of table that the key points to */ - FKey *pNextTo; /* Next foreign key that points to zTo */ - int nCol; /* Number of columns in this key */ - struct sColMap { /* Mapping of columns in pFrom to columns in zTo */ - int iFrom; /* Index of column in pFrom */ - char *zCol; /* Name of column in zTo. If 0 use PRIMARY KEY */ - } *aCol; /* One entry for each of nCol column s */ - u8 isDeferred; /* True if constraint checking is deferred till COMMIT */ - u8 updateConf; /* How to resolve conflicts that occur on UPDATE */ - u8 deleteConf; /* How to resolve conflicts that occur on DELETE */ - u8 insertConf; /* How to resolve conflicts that occur on INSERT */ -}; - -/* -** SQLite supports many different ways to resolve a constraint -** error. ROLLBACK processing means that a constraint violation -** causes the operation in process to fail and for the current transaction -** to be rolled back. ABORT processing means the operation in process -** fails and any prior changes from that one operation are backed out, -** but the transaction is not rolled back. FAIL processing means that -** the operation in progress stops and returns an error code. But prior -** changes due to the same operation are not backed out and no rollback -** occurs. IGNORE means that the particular row that caused the constraint -** error is not inserted or updated. Processing continues and no error -** is returned. REPLACE means that preexisting database rows that caused -** a UNIQUE constraint violation are removed so that the new insert or -** update can proceed. Processing continues and no error is reported. -** -** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys. -** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the -** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign -** key is set to NULL. CASCADE means that a DELETE or UPDATE of the -** referenced table row is propagated into the row that holds the -** foreign key. -** -** The following symbolic values are used to record which type -** of action to take. -*/ -#define OE_None 0 /* There is no constraint to check */ -#define OE_Rollback 1 /* Fail the operation and rollback the transaction */ -#define OE_Abort 2 /* Back out changes but do no rollback transaction */ -#define OE_Fail 3 /* Stop the operation but leave all prior changes */ -#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */ -#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */ - -#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */ -#define OE_SetNull 7 /* Set the foreign key value to NULL */ -#define OE_SetDflt 8 /* Set the foreign key value to its default */ -#define OE_Cascade 9 /* Cascade the changes */ - -#define OE_Default 99 /* Do whatever the default action is */ - - -/* -** An instance of the following structure is passed as the first -** argument to sqlite3VdbeKeyCompare and is used to control the -** comparison of the two index keys. -** -** If the KeyInfo.incrKey value is true and the comparison would -** otherwise be equal, then return a result as if the second key -** were larger. -*/ -struct KeyInfo { - sqlite3 *db; /* The database connection */ - u8 enc; /* Text encoding - one of the TEXT_Utf* values */ - u8 incrKey; /* Increase 2nd key by epsilon before comparison */ - int nField; /* Number of entries in aColl[] */ - u8 *aSortOrder; /* If defined an aSortOrder[i] is true, sort DESC */ - CollSeq *aColl[1]; /* Collating sequence for each term of the key */ -}; - -/* -** Each SQL index is represented in memory by an -** instance of the following structure. -** -** The columns of the table that are to be indexed are described -** by the aiColumn[] field of this structure. For example, suppose -** we have the following table and index: -** -** CREATE TABLE Ex1(c1 int, c2 int, c3 text); -** CREATE INDEX Ex2 ON Ex1(c3,c1); -** -** In the Table structure describing Ex1, nCol==3 because there are -** three columns in the table. In the Index structure describing -** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed. -** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the -** first column to be indexed (c3) has an index of 2 in Ex1.aCol[]. -** The second column to be indexed (c1) has an index of 0 in -** Ex1.aCol[], hence Ex2.aiColumn[1]==0. -** -** The Index.onError field determines whether or not the indexed columns -** must be unique and what to do if they are not. When Index.onError=OE_None, -** it means this is not a unique index. Otherwise it is a unique index -** and the value of Index.onError indicate the which conflict resolution -** algorithm to employ whenever an attempt is made to insert a non-unique -** element. -*/ -struct Index { - char *zName; /* Name of this index */ - int nColumn; /* Number of columns in the table used by this index */ - int *aiColumn; /* Which columns are used by this index. 1st is 0 */ - unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */ - Table *pTable; /* The SQL table being indexed */ - int tnum; /* Page containing root of this index in database file */ - u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ - u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ - char *zColAff; /* String defining the affinity of each column */ - Index *pNext; /* The next index associated with the same table */ - Schema *pSchema; /* Schema containing this index */ - u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */ - char **azColl; /* Array of collation sequence names for index */ -}; - -/* -** Each token coming out of the lexer is an instance of -** this structure. Tokens are also used as part of an expression. -** -** Note if Token.z==0 then Token.dyn and Token.n are undefined and -** may contain random values. Do not make any assuptions about Token.dyn -** and Token.n when Token.z==0. -*/ -struct Token { - const unsigned char *z; /* Text of the token. Not NULL-terminated! */ - unsigned dyn : 1; /* True for malloced memory, false for static */ - unsigned n : 31; /* Number of characters in this token */ -}; - -/* -** An instance of this structure contains information needed to generate -** code for a SELECT that contains aggregate functions. -** -** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a -** pointer to this structure. The Expr.iColumn field is the index in -** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate -** code for that node. -** -** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the -** original Select structure that describes the SELECT statement. These -** fields do not need to be freed when deallocating the AggInfo structure. -*/ -struct AggInfo { - u8 directMode; /* Direct rendering mode means take data directly - ** from source tables rather than from accumulators */ - u8 useSortingIdx; /* In direct mode, reference the sorting index rather - ** than the source table */ - int sortingIdx; /* Cursor number of the sorting index */ - ExprList *pGroupBy; /* The group by clause */ - int nSortingColumn; /* Number of columns in the sorting index */ - struct AggInfo_col { /* For each column used in source tables */ - Table *pTab; /* Source table */ - int iTable; /* Cursor number of the source table */ - int iColumn; /* Column number within the source table */ - int iSorterColumn; /* Column number in the sorting index */ - int iMem; /* Memory location that acts as accumulator */ - Expr *pExpr; /* The original expression */ - } *aCol; - int nColumn; /* Number of used entries in aCol[] */ - int nColumnAlloc; /* Number of slots allocated for aCol[] */ - int nAccumulator; /* Number of columns that show through to the output. - ** Additional columns are used only as parameters to - ** aggregate functions */ - struct AggInfo_func { /* For each aggregate function */ - Expr *pExpr; /* Expression encoding the function */ - FuncDef *pFunc; /* The aggregate function implementation */ - int iMem; /* Memory location that acts as accumulator */ - int iDistinct; /* Ephermeral table used to enforce DISTINCT */ - } *aFunc; - int nFunc; /* Number of entries in aFunc[] */ - int nFuncAlloc; /* Number of slots allocated for aFunc[] */ -}; - -/* -** Each node of an expression in the parse tree is an instance -** of this structure. -** -** Expr.op is the opcode. The integer parser token codes are reused -** as opcodes here. For example, the parser defines TK_GE to be an integer -** code representing the ">=" operator. This same integer code is reused -** to represent the greater-than-or-equal-to operator in the expression -** tree. -** -** Expr.pRight and Expr.pLeft are subexpressions. Expr.pList is a list -** of argument if the expression is a function. -** -** Expr.token is the operator token for this node. For some expressions -** that have subexpressions, Expr.token can be the complete text that gave -** rise to the Expr. In the latter case, the token is marked as being -** a compound token. -** -** An expression of the form ID or ID.ID refers to a column in a table. -** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is -** the integer cursor number of a VDBE cursor pointing to that table and -** Expr.iColumn is the column number for the specific column. If the -** expression is used as a result in an aggregate SELECT, then the -** value is also stored in the Expr.iAgg column in the aggregate so that -** it can be accessed after all aggregates are computed. -** -** If the expression is a function, the Expr.iTable is an integer code -** representing which function. If the expression is an unbound variable -** marker (a question mark character '?' in the original SQL) then the -** Expr.iTable holds the index number for that variable. -** -** If the expression is a subquery then Expr.iColumn holds an integer -** register number containing the result of the subquery. If the -** subquery gives a constant result, then iTable is -1. If the subquery -** gives a different answer at different times during statement processing -** then iTable is the address of a subroutine that computes the subquery. -** -** The Expr.pSelect field points to a SELECT statement. The SELECT might -** be the right operand of an IN operator. Or, if a scalar SELECT appears -** in an expression the opcode is TK_SELECT and Expr.pSelect is the only -** operand. -** -** If the Expr is of type OP_Column, and the table it is selecting from -** is a disk table or the "old.*" pseudo-table, then pTab points to the -** corresponding table definition. -*/ -struct Expr { - u8 op; /* Operation performed by this node */ - char affinity; /* The affinity of the column or 0 if not a column */ - u16 flags; /* Various flags. See below */ - CollSeq *pColl; /* The collation type of the column or 0 */ - Expr *pLeft, *pRight; /* Left and right subnodes */ - ExprList *pList; /* A list of expressions used as function arguments - ** or in " IN (aCol[] or ->aFunc[] */ - int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ - Select *pSelect; /* When the expression is a sub-select. Also the - ** right side of " IN (