Unknown ❤ RESPAWN.ZAFEST.RO | VIP FREE | FREE FOR ALL ❤ 0/32
Romania XPlayZM.CSBlackDevil.COM # Zombie Plague UltimateX [ Respawn + FDL + VIP 22-12PM + POINTS] ® 21/32
Promover servidor

Add install-sqlite-module-amxx/en.md

Browse Source
Daemon666 committed parent 90d33ba53a commit 1dee2fc1884dff0924b7dec2dfbb3a6f05d968fc
1 changed file with 125 additions and 0 deletions
+125 -0 install-sqlite-module-amxx/en.md A
@@ -0,0 +1,125 @@
1 +---
2 +title: "How to Use the SQLite Module in AMX Mod X"
3 +excerpt: "Enable the SQLite module in AMX Mod X, where the .sq3 file lives, when SQLite beats MySQL, and how to avoid the locking problems."
4 +category: "installation"
5 +tags: "amxmodx, sqlite"
6 +image: ""
7 +read_time: "8 min read"
8 +---
9 +<p>The SQLite module gives AMX Mod X a real SQL database with no server, no credentials, and no network. It uses the same <code>sqlx</code> API as MySQL, so the same plugin code works against either backend — only the connection tuple changes. For a single game server that needs to persist points, ranks, shop purchases or settings, SQLite is often the correct choice and MySQL is over-engineering.</p>
10 +
11 +<h2>When SQLite is the right call</h2>
12 +<table>
13 +<thead><tr><th>Situation</th><th>Use</th></tr></thead>
14 +<tbody>
15 +<tr><td>One server, data local to it</td><td><strong>SQLite</strong></td></tr>
16 +<tr><td>Several servers sharing ranks/bans</td><td>MySQL</td></tr>
17 +<tr><td>A web panel reads the data live</td><td>MySQL</td></tr>
18 +<tr><td>You want zero moving parts</td><td><strong>SQLite</strong></td></tr>
19 +<tr><td>Heavy concurrent writes from many processes</td><td>MySQL</td></tr>
20 +</tbody>
21 +</table>
22 +<p>SQLite is also a strictly better choice than <code>nvault</code> for anything structured. nVault is a flat key/value store with no queries and a well-earned reputation for corruption; see <a href="/tutorials/fix-nvault-corrupted">nVault corruption</a>.</p>
23 +
24 +<h2>1. Enable the module</h2>
25 +<p><code>addons/amxmodx/configs/modules.ini</code>:</p>
26 +<pre>fun
27 +engine
28 +fakemeta
29 +cstrike
30 +csx
31 +hamsandwich
32 +sqlite</pre>
33 +<p>Check the file is there and is 32-bit:</p>
34 +<pre>ls -la /home/steam/hlds/cstrike/addons/amxmodx/modules/sqlite_amxx_i386.so
35 +file /home/steam/hlds/cstrike/addons/amxmodx/modules/sqlite_amxx_i386.so</pre>
36 +<p>You do <strong>not</strong> need to install SQLite on the host. The module carries its own engine. Restart the server — modules load at startup, not on map change.</p>
37 +
38 +<h2>2. Where the database file lives</h2>
39 +<p>The SQLite module puts databases under:</p>
40 +<pre>cstrike/addons/amxmodx/data/sqlite/</pre>
41 +<p>The directory must exist and must be writable by the user running HLDS. If it is not, every query fails and — depending on the plugin — you get silence, not an error.</p>
42 +<pre>mkdir -p /home/steam/hlds/cstrike/addons/amxmodx/data/sqlite
43 +chown -R steam:steam /home/steam/hlds/cstrike/addons/amxmodx/data
44 +chmod 755 /home/steam/hlds/cstrike/addons/amxmodx/data/sqlite</pre>
45 +
46 +<h2>3. Connect from a plugin</h2>
47 +<p>Same <code>sqlx</code> API as MySQL. The only difference is the tuple: for SQLite the "database" is the file name and the host/user/pass are ignored.</p>
48 +<pre>#include &lt;amxmodx&gt;
49 +#include &lt;sqlx&gt;
50 +
51 +new Handle:g_tuple
52 +
53 +public plugin_init()
54 +{
55 + register_plugin("SQLite Example", "1.0", "you")
56 +
57 + // For SQLite the 4th argument is the database file (created if absent)
58 + g_tuple = SQL_MakeDbTuple("", "", "", "server_stats")
59 +
60 + SQL_ThreadQuery(g_tuple, "OnTableReady",
61 + "CREATE TABLE IF NOT EXISTS points ( \
62 + steamid TEXT PRIMARY KEY, \
63 + name TEXT, \
64 + points INTEGER DEFAULT 0 \
65 + )")
66 +}
67 +
68 +public OnTableReady(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime)
69 +{
70 + if (failstate != TQUERY_SUCCESS)
71 + log_amx("SQLite error %d: %s", errnum, error)
72 +}</pre>
73 +<p>Set <code>amx_sql_type</code> to <code>sqlite</code> in <code>configs/sql.cfg</code> if you use a plugin that reads the backend from there:</p>
74 +<pre>amx_sql_type "sqlite"
75 +amx_sql_db "server_stats"</pre>
76 +<p>That produces <code>data/sqlite/server_stats.sq3</code>.</p>
77 +
78 +<h2>4. Writing rows safely</h2>
79 +<p>Always escape values that come from a player. Names contain quotes, semicolons and worse, and SQLite is as injectable as MySQL:</p>
80 +<pre>new name[64], escaped[128], steamid[35], q[256]
81 +get_user_name(id, name, charsmax(name))
82 +get_user_authid(id, steamid, charsmax(steamid))
83 +
84 +SQL_QuoteString(Empty_Handle, escaped, charsmax(escaped), name)
85 +
86 +formatex(q, charsmax(q),
87 + "INSERT OR REPLACE INTO points (steamid, name, points) VALUES ('%s', '%s', %d)",
88 + steamid, escaped, points)
89 +
90 +SQL_ThreadQuery(g_tuple, "OnSaved", q)</pre>
91 +<p><code>INSERT OR REPLACE</code> is SQLite's upsert; MySQL uses <code>ON DUPLICATE KEY UPDATE</code>. This is the one place the two backends genuinely differ in a plugin, and it is why "SQLite and MySQL are drop-in interchangeable" is only 95% true.</p>
92 +
93 +<h2>5. Inspecting the database</h2>
94 +<p>Install the <code>sqlite3</code> CLI on the host (this is for <em>you</em>, not for the module):</p>
95 +<pre>sudo apt install -y sqlite3
96 +cd /home/steam/hlds/cstrike/addons/amxmodx/data/sqlite
97 +sqlite3 server_stats.sq3
98 +
99 +sqlite&gt; .tables
100 +sqlite&gt; SELECT * FROM points ORDER BY points DESC LIMIT 10;
101 +sqlite&gt; .quit</pre>
102 +<p>Do not run write queries against the file while the server is running. SQLite locks the whole database on write, and a long external transaction will make the game server's queries fail.</p>
103 +
104 +<h2>Common errors</h2>
105 +<ul>
106 +<li><strong><code>database is locked</code></strong> — two writers. Usually you left a <code>sqlite3</code> shell open with an uncommitted transaction, or two game servers point at the same <code>.sq3</code> file. One server, one file.</li>
107 +<li><strong><code>unable to open database file</code></strong> — <code>data/sqlite/</code> does not exist, or is not writable by the HLDS user. Check with <code>sudo -u steam touch data/sqlite/test</code>.</li>
108 +<li><strong><code>Module failed to load</code></strong> — the <code>.so</code> is missing or is not 32-bit. See <a href="/tutorials/fix-amxx-module-failed-to-load">the module load fix</a>.</li>
109 +<li><strong><code>no such table: points</code></strong> — the plugin queried before its <code>CREATE TABLE</code> callback completed. Threaded queries are asynchronous; chain the first read off the create callback rather than firing both from <code>plugin_init()</code>.</li>
110 +<li><strong>Data disappears after a restart</strong> — you are writing to a path inside a container without a volume, or the file is being recreated because the plugin's <code>CREATE TABLE</code> is missing <code>IF NOT EXISTS</code> and failing silently.</li>
111 +</ul>
112 +
113 +<h2>Backups</h2>
114 +<p>The whole database is one file, which is the best thing about SQLite:</p>
115 +<pre>sqlite3 server_stats.sq3 ".backup '/home/steam/backups/stats-$(date +%F).sq3'"</pre>
116 +<p>Use <code>.backup</code>, not <code>cp</code> — copying a file that is being written produces a corrupt database. Put that in cron.</p>
117 +
118 +<h2>Verification</h2>
119 +<ol>
120 +<li><code>amxx modules</code> lists SQLite as <code>running</code>.</li>
121 +<li>The <code>.sq3</code> file appears in <code>data/sqlite/</code> after the first map.</li>
122 +<li><code>sqlite3 file.sq3 ".tables"</code> shows your plugin's tables.</li>
123 +<li>A value written in-game survives a map change and a full restart.</li>
124 +</ol>
125 +<p>If you later outgrow one server, the same plugin code moves to <a href="/tutorials/install-mysql-module-amxx">the MySQL module</a> with a different tuple and an upsert rewrite.</p>
0 126