zexus 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +0 -0
- package/README.md +2513 -0
- package/bin/zexus +2 -0
- package/bin/zpics +2 -0
- package/bin/zpm +2 -0
- package/bin/zx +2 -0
- package/bin/zx-deploy +2 -0
- package/bin/zx-dev +2 -0
- package/bin/zx-run +2 -0
- package/package.json +66 -0
- package/scripts/README.md +24 -0
- package/scripts/postinstall.js +44 -0
- package/shared_config.json +24 -0
- package/src/README.md +1525 -0
- package/src/tests/run_zexus_tests.py +117 -0
- package/src/tests/test_all_phases.zx +346 -0
- package/src/tests/test_blockchain_features.zx +306 -0
- package/src/tests/test_complexity_features.zx +321 -0
- package/src/tests/test_core_integration.py +185 -0
- package/src/tests/test_phase10_ecosystem.zx +177 -0
- package/src/tests/test_phase1_modifiers.zx +87 -0
- package/src/tests/test_phase2_plugins.zx +80 -0
- package/src/tests/test_phase3_security.zx +97 -0
- package/src/tests/test_phase4_vfs.zx +116 -0
- package/src/tests/test_phase5_types.zx +117 -0
- package/src/tests/test_phase6_metaprogramming.zx +125 -0
- package/src/tests/test_phase7_optimization.zx +132 -0
- package/src/tests/test_phase9_advanced_types.zx +157 -0
- package/src/tests/test_security_features.py +419 -0
- package/src/tests/test_security_features.zx +276 -0
- package/src/tests/test_simple_zx.zx +1 -0
- package/src/tests/test_verification_simple.zx +69 -0
- package/src/zexus/__init__.py +28 -0
- package/src/zexus/__main__.py +5 -0
- package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/advanced_types.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/builtin_modules.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/complexity_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/concurrency_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/config.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/dependency_injection.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/ecosystem.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/environment.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/error_reporter.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/hybrid_orchestrator.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/metaprogramming.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/optimization.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/plugin_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/policy_engine.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/stdlib_integration.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/strategy_recovery.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/type_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/virtual_filesystem.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/zexus_token.cpython-312.pyc +0 -0
- package/src/zexus/advanced_types.py +401 -0
- package/src/zexus/blockchain/__init__.py +40 -0
- package/src/zexus/blockchain/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/crypto.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/ledger.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/transaction.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/crypto.py +463 -0
- package/src/zexus/blockchain/ledger.py +255 -0
- package/src/zexus/blockchain/transaction.py +267 -0
- package/src/zexus/builtin_modules.py +284 -0
- package/src/zexus/builtin_plugins.py +317 -0
- package/src/zexus/capability_system.py +372 -0
- package/src/zexus/cli/__init__.py +2 -0
- package/src/zexus/cli/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
- package/src/zexus/cli/main.py +707 -0
- package/src/zexus/cli/zpm.py +203 -0
- package/src/zexus/compare_interpreter_compiler.py +146 -0
- package/src/zexus/compiler/__init__.py +169 -0
- package/src/zexus/compiler/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/compiler/bytecode.py +266 -0
- package/src/zexus/compiler/compat_runtime.py +277 -0
- package/src/zexus/compiler/lexer.py +257 -0
- package/src/zexus/compiler/parser.py +779 -0
- package/src/zexus/compiler/semantic.py +118 -0
- package/src/zexus/compiler/zexus_ast.py +454 -0
- package/src/zexus/complexity_system.py +575 -0
- package/src/zexus/concurrency_system.py +493 -0
- package/src/zexus/config.py +201 -0
- package/src/zexus/crypto_bridge.py +19 -0
- package/src/zexus/dependency_injection.py +423 -0
- package/src/zexus/ecosystem.py +434 -0
- package/src/zexus/environment.py +101 -0
- package/src/zexus/environment_manager.py +119 -0
- package/src/zexus/error_reporter.py +314 -0
- package/src/zexus/evaluator/__init__.py +12 -0
- package/src/zexus/evaluator/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/integration.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/bytecode_compiler.py +700 -0
- package/src/zexus/evaluator/core.py +891 -0
- package/src/zexus/evaluator/expressions.py +827 -0
- package/src/zexus/evaluator/functions.py +3989 -0
- package/src/zexus/evaluator/integration.py +396 -0
- package/src/zexus/evaluator/statements.py +4303 -0
- package/src/zexus/evaluator/utils.py +126 -0
- package/src/zexus/evaluator_original.py +2041 -0
- package/src/zexus/external_bridge.py +16 -0
- package/src/zexus/find_affected_imports.sh +155 -0
- package/src/zexus/hybrid_orchestrator.py +152 -0
- package/src/zexus/input_validation.py +259 -0
- package/src/zexus/lexer.py +571 -0
- package/src/zexus/logging.py +89 -0
- package/src/zexus/lsp/__init__.py +9 -0
- package/src/zexus/lsp/completion_provider.py +207 -0
- package/src/zexus/lsp/definition_provider.py +22 -0
- package/src/zexus/lsp/hover_provider.py +71 -0
- package/src/zexus/lsp/server.py +269 -0
- package/src/zexus/lsp/symbol_provider.py +31 -0
- package/src/zexus/metaprogramming.py +321 -0
- package/src/zexus/module_cache.py +89 -0
- package/src/zexus/module_manager.py +107 -0
- package/src/zexus/object.py +973 -0
- package/src/zexus/optimization.py +424 -0
- package/src/zexus/parser/__init__.py +31 -0
- package/src/zexus/parser/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
- package/src/zexus/parser/integration.py +86 -0
- package/src/zexus/parser/parser.py +3977 -0
- package/src/zexus/parser/strategy_context.py +7254 -0
- package/src/zexus/parser/strategy_structural.py +1033 -0
- package/src/zexus/persistence.py +391 -0
- package/src/zexus/plugin_system.py +290 -0
- package/src/zexus/policy_engine.py +365 -0
- package/src/zexus/profiler/__init__.py +5 -0
- package/src/zexus/profiler/profiler.py +233 -0
- package/src/zexus/purity_system.py +398 -0
- package/src/zexus/runtime/__init__.py +20 -0
- package/src/zexus/runtime/async_runtime.py +324 -0
- package/src/zexus/search_old_imports.sh +65 -0
- package/src/zexus/security.py +1407 -0
- package/src/zexus/stack_trace.py +233 -0
- package/src/zexus/stdlib/__init__.py +27 -0
- package/src/zexus/stdlib/blockchain.py +341 -0
- package/src/zexus/stdlib/compression.py +167 -0
- package/src/zexus/stdlib/crypto.py +124 -0
- package/src/zexus/stdlib/datetime.py +163 -0
- package/src/zexus/stdlib/db_mongo.py +199 -0
- package/src/zexus/stdlib/db_mysql.py +162 -0
- package/src/zexus/stdlib/db_postgres.py +163 -0
- package/src/zexus/stdlib/db_sqlite.py +133 -0
- package/src/zexus/stdlib/encoding.py +230 -0
- package/src/zexus/stdlib/fs.py +195 -0
- package/src/zexus/stdlib/http.py +219 -0
- package/src/zexus/stdlib/http_server.py +248 -0
- package/src/zexus/stdlib/json_module.py +61 -0
- package/src/zexus/stdlib/math.py +360 -0
- package/src/zexus/stdlib/os_module.py +265 -0
- package/src/zexus/stdlib/regex.py +148 -0
- package/src/zexus/stdlib/sockets.py +253 -0
- package/src/zexus/stdlib/test_framework.zx +208 -0
- package/src/zexus/stdlib/test_runner.zx +119 -0
- package/src/zexus/stdlib_integration.py +341 -0
- package/src/zexus/strategy_recovery.py +256 -0
- package/src/zexus/syntax_validator.py +356 -0
- package/src/zexus/testing/zpics.py +407 -0
- package/src/zexus/testing/zpics_runtime.py +369 -0
- package/src/zexus/type_system.py +374 -0
- package/src/zexus/validation_system.py +569 -0
- package/src/zexus/virtual_filesystem.py +355 -0
- package/src/zexus/vm/__init__.py +8 -0
- package/src/zexus/vm/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/memory_manager.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/memory_pool.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/peephole_optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/profiler.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/register_allocator.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/register_vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/ssa_converter.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/async_optimizer.py +420 -0
- package/src/zexus/vm/bytecode.py +428 -0
- package/src/zexus/vm/bytecode_converter.py +297 -0
- package/src/zexus/vm/cache.py +532 -0
- package/src/zexus/vm/jit.py +720 -0
- package/src/zexus/vm/memory_manager.py +520 -0
- package/src/zexus/vm/memory_pool.py +511 -0
- package/src/zexus/vm/optimizer.py +478 -0
- package/src/zexus/vm/parallel_vm.py +899 -0
- package/src/zexus/vm/peephole_optimizer.py +452 -0
- package/src/zexus/vm/profiler.py +527 -0
- package/src/zexus/vm/register_allocator.py +462 -0
- package/src/zexus/vm/register_vm.py +520 -0
- package/src/zexus/vm/ssa_converter.py +757 -0
- package/src/zexus/vm/vm.py +1392 -0
- package/src/zexus/zexus_ast.py +1782 -0
- package/src/zexus/zexus_token.py +253 -0
- package/src/zexus/zpm/__init__.py +15 -0
- package/src/zexus/zpm/installer.py +116 -0
- package/src/zexus/zpm/package_manager.py +208 -0
- package/src/zexus/zpm/publisher.py +98 -0
- package/src/zexus/zpm/registry.py +110 -0
- package/src/zexus.egg-info/PKG-INFO +2235 -0
- package/src/zexus.egg-info/SOURCES.txt +876 -0
- package/src/zexus.egg-info/dependency_links.txt +1 -0
- package/src/zexus.egg-info/entry_points.txt +3 -0
- package/src/zexus.egg-info/not-zip-safe +1 -0
- package/src/zexus.egg-info/requires.txt +14 -0
- package/src/zexus.egg-info/top_level.txt +2 -0
- package/zexus.json +14 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""MySQL database driver for Zexus.
|
|
2
|
+
Requires mysql-connector-python: pip install mysql-connector-python
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
import mysql.connector
|
|
7
|
+
from mysql.connector import Error
|
|
8
|
+
MYSQL_AVAILABLE = True
|
|
9
|
+
except ImportError:
|
|
10
|
+
MYSQL_AVAILABLE = False
|
|
11
|
+
print("Warning: mysql-connector-python not installed. MySQL support unavailable.")
|
|
12
|
+
print("Install with: pip install mysql-connector-python")
|
|
13
|
+
|
|
14
|
+
from typing import Any, List, Dict, Optional, Tuple
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MySQLConnection:
|
|
18
|
+
"""MySQL database connection."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, host: str = 'localhost', port: int = 3306,
|
|
21
|
+
database: str = 'mysql', user: str = 'root',
|
|
22
|
+
password: str = ''):
|
|
23
|
+
"""Create MySQL connection.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
host: Database host
|
|
27
|
+
port: Database port
|
|
28
|
+
database: Database name
|
|
29
|
+
user: Username
|
|
30
|
+
password: Password
|
|
31
|
+
"""
|
|
32
|
+
self.host = host
|
|
33
|
+
self.port = port
|
|
34
|
+
self.database = database
|
|
35
|
+
self.user = user
|
|
36
|
+
self.password = password
|
|
37
|
+
self.conn = None
|
|
38
|
+
self.cursor = None
|
|
39
|
+
self.in_transaction: bool = False # Track explicit transaction state
|
|
40
|
+
|
|
41
|
+
def connect(self) -> bool:
|
|
42
|
+
"""Open connection to database."""
|
|
43
|
+
if not MYSQL_AVAILABLE:
|
|
44
|
+
print("MySQL driver not available (mysql-connector-python not installed)")
|
|
45
|
+
return False
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
self.conn = mysql.connector.connect(
|
|
49
|
+
host=self.host,
|
|
50
|
+
port=self.port,
|
|
51
|
+
database=self.database,
|
|
52
|
+
user=self.user,
|
|
53
|
+
password=self.password
|
|
54
|
+
)
|
|
55
|
+
self.cursor = self.conn.cursor(dictionary=True)
|
|
56
|
+
return True
|
|
57
|
+
except Error as e:
|
|
58
|
+
print(f"MySQL connect error: {e}")
|
|
59
|
+
return False
|
|
60
|
+
|
|
61
|
+
def execute(self, query: str, params: Optional[Tuple] = None) -> bool:
|
|
62
|
+
"""Execute a query (INSERT, UPDATE, DELETE, CREATE, etc)."""
|
|
63
|
+
try:
|
|
64
|
+
if not self.cursor or not self.conn:
|
|
65
|
+
print("MySQL error: Not connected to database")
|
|
66
|
+
return False
|
|
67
|
+
|
|
68
|
+
if params:
|
|
69
|
+
self.cursor.execute(query, params)
|
|
70
|
+
else:
|
|
71
|
+
self.cursor.execute(query)
|
|
72
|
+
|
|
73
|
+
# Only auto-commit if we're not in an explicit transaction
|
|
74
|
+
if not self.in_transaction:
|
|
75
|
+
self.conn.commit()
|
|
76
|
+
return True
|
|
77
|
+
except Error as e:
|
|
78
|
+
print(f"MySQL execute error: {e}")
|
|
79
|
+
if not self.in_transaction:
|
|
80
|
+
self.conn.rollback() if self.conn else None
|
|
81
|
+
return False
|
|
82
|
+
|
|
83
|
+
def query(self, sql: str, params: Optional[Tuple] = None) -> List[Dict[str, Any]]:
|
|
84
|
+
"""Execute a SELECT query and return results."""
|
|
85
|
+
try:
|
|
86
|
+
if not self.cursor or not self.conn:
|
|
87
|
+
print("MySQL error: Not connected to database")
|
|
88
|
+
return []
|
|
89
|
+
|
|
90
|
+
if params:
|
|
91
|
+
self.cursor.execute(sql, params)
|
|
92
|
+
else:
|
|
93
|
+
self.cursor.execute(sql)
|
|
94
|
+
|
|
95
|
+
# Fetch all rows as dictionaries
|
|
96
|
+
rows = self.cursor.fetchall()
|
|
97
|
+
return rows if rows else []
|
|
98
|
+
|
|
99
|
+
except Error as e:
|
|
100
|
+
print(f"MySQL query error: {e}")
|
|
101
|
+
return []
|
|
102
|
+
|
|
103
|
+
def query_one(self, sql: str, params: Optional[Tuple] = None) -> Optional[Dict[str, Any]]:
|
|
104
|
+
"""Execute a SELECT query and return first result."""
|
|
105
|
+
results = self.query(sql, params)
|
|
106
|
+
return results[0] if results else None
|
|
107
|
+
|
|
108
|
+
def last_insert_id(self) -> int:
|
|
109
|
+
"""Get the last inserted row ID."""
|
|
110
|
+
return self.cursor.lastrowid if self.cursor else 0
|
|
111
|
+
|
|
112
|
+
def affected_rows(self) -> int:
|
|
113
|
+
"""Get number of affected rows from last query."""
|
|
114
|
+
return self.cursor.rowcount if self.cursor else 0
|
|
115
|
+
|
|
116
|
+
def begin_transaction(self) -> bool:
|
|
117
|
+
"""Begin a transaction."""
|
|
118
|
+
try:
|
|
119
|
+
if self.conn:
|
|
120
|
+
self.conn.start_transaction()
|
|
121
|
+
self.in_transaction = True
|
|
122
|
+
return True
|
|
123
|
+
return False
|
|
124
|
+
except Error as e:
|
|
125
|
+
print(f"MySQL begin transaction error: {e}")
|
|
126
|
+
return False
|
|
127
|
+
|
|
128
|
+
def commit(self) -> bool:
|
|
129
|
+
"""Commit current transaction."""
|
|
130
|
+
try:
|
|
131
|
+
if self.conn:
|
|
132
|
+
self.conn.commit()
|
|
133
|
+
self.in_transaction = False
|
|
134
|
+
return True
|
|
135
|
+
return False
|
|
136
|
+
except Error as e:
|
|
137
|
+
print(f"MySQL commit error: {e}")
|
|
138
|
+
return False
|
|
139
|
+
|
|
140
|
+
def rollback(self) -> bool:
|
|
141
|
+
"""Rollback current transaction."""
|
|
142
|
+
try:
|
|
143
|
+
if self.conn:
|
|
144
|
+
self.conn.rollback()
|
|
145
|
+
self.in_transaction = False
|
|
146
|
+
return True
|
|
147
|
+
return False
|
|
148
|
+
except Error as e:
|
|
149
|
+
print(f"MySQL rollback error: {e}")
|
|
150
|
+
return False
|
|
151
|
+
|
|
152
|
+
def close(self) -> bool:
|
|
153
|
+
"""Close database connection."""
|
|
154
|
+
try:
|
|
155
|
+
if self.cursor:
|
|
156
|
+
self.cursor.close()
|
|
157
|
+
if self.conn:
|
|
158
|
+
self.conn.close()
|
|
159
|
+
return True
|
|
160
|
+
except Error as e:
|
|
161
|
+
print(f"MySQL close error: {e}")
|
|
162
|
+
return False
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"""PostgreSQL database driver for Zexus.
|
|
2
|
+
Requires psycopg2: pip install psycopg2-binary
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
import psycopg2
|
|
7
|
+
from psycopg2.extras import RealDictCursor
|
|
8
|
+
POSTGRES_AVAILABLE = True
|
|
9
|
+
except ImportError:
|
|
10
|
+
POSTGRES_AVAILABLE = False
|
|
11
|
+
print("Warning: psycopg2 not installed. PostgreSQL support unavailable.")
|
|
12
|
+
print("Install with: pip install psycopg2-binary")
|
|
13
|
+
|
|
14
|
+
from typing import Any, List, Dict, Optional, Tuple
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class PostgreSQLConnection:
|
|
18
|
+
"""PostgreSQL database connection."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, host: str = 'localhost', port: int = 5432,
|
|
21
|
+
database: str = 'postgres', user: str = 'postgres',
|
|
22
|
+
password: str = ''):
|
|
23
|
+
"""Create PostgreSQL connection.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
host: Database host
|
|
27
|
+
port: Database port
|
|
28
|
+
database: Database name
|
|
29
|
+
user: Username
|
|
30
|
+
password: Password
|
|
31
|
+
"""
|
|
32
|
+
self.host = host
|
|
33
|
+
self.port = port
|
|
34
|
+
self.database = database
|
|
35
|
+
self.user = user
|
|
36
|
+
self.password = password
|
|
37
|
+
self.conn = None
|
|
38
|
+
self.cursor = None
|
|
39
|
+
self.in_transaction: bool = False # Track explicit transaction state
|
|
40
|
+
|
|
41
|
+
def connect(self) -> bool:
|
|
42
|
+
"""Open connection to database."""
|
|
43
|
+
if not POSTGRES_AVAILABLE:
|
|
44
|
+
print("PostgreSQL driver not available (psycopg2 not installed)")
|
|
45
|
+
return False
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
self.conn = psycopg2.connect(
|
|
49
|
+
host=self.host,
|
|
50
|
+
port=self.port,
|
|
51
|
+
database=self.database,
|
|
52
|
+
user=self.user,
|
|
53
|
+
password=self.password
|
|
54
|
+
)
|
|
55
|
+
self.cursor = self.conn.cursor(cursor_factory=RealDictCursor)
|
|
56
|
+
return True
|
|
57
|
+
except Exception as e:
|
|
58
|
+
print(f"PostgreSQL connect error: {e}")
|
|
59
|
+
return False
|
|
60
|
+
|
|
61
|
+
def execute(self, query: str, params: Optional[Tuple] = None) -> bool:
|
|
62
|
+
"""Execute a query (INSERT, UPDATE, DELETE, CREATE, etc)."""
|
|
63
|
+
try:
|
|
64
|
+
if not self.cursor or not self.conn:
|
|
65
|
+
print("PostgreSQL error: Not connected to database")
|
|
66
|
+
return False
|
|
67
|
+
|
|
68
|
+
if params:
|
|
69
|
+
self.cursor.execute(query, params)
|
|
70
|
+
else:
|
|
71
|
+
self.cursor.execute(query)
|
|
72
|
+
|
|
73
|
+
# Only auto-commit if we're not in an explicit transaction
|
|
74
|
+
if not self.in_transaction:
|
|
75
|
+
self.conn.commit()
|
|
76
|
+
return True
|
|
77
|
+
except Exception as e:
|
|
78
|
+
print(f"PostgreSQL execute error: {e}")
|
|
79
|
+
if not self.in_transaction:
|
|
80
|
+
self.conn.rollback() if self.conn else None
|
|
81
|
+
return False
|
|
82
|
+
|
|
83
|
+
def query(self, sql: str, params: Optional[Tuple] = None) -> List[Dict[str, Any]]:
|
|
84
|
+
"""Execute a SELECT query and return results."""
|
|
85
|
+
try:
|
|
86
|
+
if not self.cursor or not self.conn:
|
|
87
|
+
print("PostgreSQL error: Not connected to database")
|
|
88
|
+
return []
|
|
89
|
+
|
|
90
|
+
if params:
|
|
91
|
+
self.cursor.execute(sql, params)
|
|
92
|
+
else:
|
|
93
|
+
self.cursor.execute(sql)
|
|
94
|
+
|
|
95
|
+
# Convert rows to dictionaries
|
|
96
|
+
rows = self.cursor.fetchall()
|
|
97
|
+
return [dict(row) for row in rows]
|
|
98
|
+
|
|
99
|
+
except Exception as e:
|
|
100
|
+
print(f"PostgreSQL query error: {e}")
|
|
101
|
+
return []
|
|
102
|
+
|
|
103
|
+
def query_one(self, sql: str, params: Optional[Tuple] = None) -> Optional[Dict[str, Any]]:
|
|
104
|
+
"""Execute a SELECT query and return first result."""
|
|
105
|
+
results = self.query(sql, params)
|
|
106
|
+
return results[0] if results else None
|
|
107
|
+
|
|
108
|
+
def last_insert_id(self) -> int:
|
|
109
|
+
"""Get the last inserted row ID (requires RETURNING id clause)."""
|
|
110
|
+
return self.cursor.lastrowid if self.cursor and hasattr(self.cursor, 'lastrowid') else 0
|
|
111
|
+
|
|
112
|
+
def affected_rows(self) -> int:
|
|
113
|
+
"""Get number of affected rows from last query."""
|
|
114
|
+
return self.cursor.rowcount if self.cursor else 0
|
|
115
|
+
|
|
116
|
+
def begin_transaction(self) -> bool:
|
|
117
|
+
"""Begin a transaction."""
|
|
118
|
+
try:
|
|
119
|
+
if self.conn:
|
|
120
|
+
# PostgreSQL auto-starts transactions, just ensure we're not in autocommit
|
|
121
|
+
self.conn.autocommit = False
|
|
122
|
+
self.in_transaction = True
|
|
123
|
+
return True
|
|
124
|
+
return False
|
|
125
|
+
except Exception as e:
|
|
126
|
+
print(f"PostgreSQL begin transaction error: {e}")
|
|
127
|
+
return False
|
|
128
|
+
|
|
129
|
+
def commit(self) -> bool:
|
|
130
|
+
"""Commit current transaction."""
|
|
131
|
+
try:
|
|
132
|
+
if self.conn:
|
|
133
|
+
self.conn.commit()
|
|
134
|
+
self.in_transaction = False
|
|
135
|
+
return True
|
|
136
|
+
return False
|
|
137
|
+
except Exception as e:
|
|
138
|
+
print(f"PostgreSQL commit error: {e}")
|
|
139
|
+
return False
|
|
140
|
+
|
|
141
|
+
def rollback(self) -> bool:
|
|
142
|
+
"""Rollback current transaction."""
|
|
143
|
+
try:
|
|
144
|
+
if self.conn:
|
|
145
|
+
self.conn.rollback()
|
|
146
|
+
self.in_transaction = False
|
|
147
|
+
return True
|
|
148
|
+
return False
|
|
149
|
+
except Exception as e:
|
|
150
|
+
print(f"PostgreSQL rollback error: {e}")
|
|
151
|
+
return False
|
|
152
|
+
|
|
153
|
+
def close(self) -> bool:
|
|
154
|
+
"""Close database connection."""
|
|
155
|
+
try:
|
|
156
|
+
if self.cursor:
|
|
157
|
+
self.cursor.close()
|
|
158
|
+
if self.conn:
|
|
159
|
+
self.conn.close()
|
|
160
|
+
return True
|
|
161
|
+
except Exception as e:
|
|
162
|
+
print(f"PostgreSQL close error: {e}")
|
|
163
|
+
return False
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""SQLite database driver for Zexus."""
|
|
2
|
+
|
|
3
|
+
import sqlite3
|
|
4
|
+
from typing import Any, List, Dict, Optional, Tuple
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SQLiteConnection:
|
|
8
|
+
"""SQLite database connection."""
|
|
9
|
+
|
|
10
|
+
def __init__(self, database: str):
|
|
11
|
+
"""Create SQLite connection.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
database: Path to SQLite database file, or ':memory:' for in-memory DB
|
|
15
|
+
"""
|
|
16
|
+
self.database = database
|
|
17
|
+
self.conn: Optional[sqlite3.Connection] = None
|
|
18
|
+
self.cursor: Optional[sqlite3.Cursor] = None
|
|
19
|
+
self.in_transaction: bool = False # Track explicit transaction state
|
|
20
|
+
|
|
21
|
+
def connect(self) -> bool:
|
|
22
|
+
"""Open connection to database."""
|
|
23
|
+
try:
|
|
24
|
+
self.conn = sqlite3.connect(self.database)
|
|
25
|
+
# Disable automatic transaction management - we'll handle it manually
|
|
26
|
+
self.conn.isolation_level = None
|
|
27
|
+
self.conn.row_factory = sqlite3.Row # Enable column access by name
|
|
28
|
+
self.cursor = self.conn.cursor()
|
|
29
|
+
return True
|
|
30
|
+
except Exception as e:
|
|
31
|
+
print(f"SQLite connect error: {e}")
|
|
32
|
+
return False
|
|
33
|
+
|
|
34
|
+
def execute(self, query: str, params: Optional[Tuple] = None) -> bool:
|
|
35
|
+
"""Execute a query (INSERT, UPDATE, DELETE, CREATE, etc)."""
|
|
36
|
+
try:
|
|
37
|
+
if not self.cursor or not self.conn:
|
|
38
|
+
print("SQLite error: Not connected to database")
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
if params:
|
|
42
|
+
self.cursor.execute(query, params)
|
|
43
|
+
else:
|
|
44
|
+
self.cursor.execute(query)
|
|
45
|
+
|
|
46
|
+
# Only auto-commit if we're not in an explicit transaction
|
|
47
|
+
if not self.in_transaction:
|
|
48
|
+
self.conn.commit()
|
|
49
|
+
return True
|
|
50
|
+
except Exception as e:
|
|
51
|
+
print(f"SQLite execute error: {e}")
|
|
52
|
+
if not self.in_transaction:
|
|
53
|
+
self.conn.rollback() if self.conn else None
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
def query(self, sql: str, params: Optional[Tuple] = None) -> List[Dict[str, Any]]:
|
|
57
|
+
"""Execute a SELECT query and return results."""
|
|
58
|
+
try:
|
|
59
|
+
if not self.cursor or not self.conn:
|
|
60
|
+
print("SQLite error: Not connected to database")
|
|
61
|
+
return []
|
|
62
|
+
|
|
63
|
+
if params:
|
|
64
|
+
self.cursor.execute(sql, params)
|
|
65
|
+
else:
|
|
66
|
+
self.cursor.execute(sql)
|
|
67
|
+
|
|
68
|
+
# Convert rows to dictionaries
|
|
69
|
+
rows = self.cursor.fetchall()
|
|
70
|
+
return [dict(row) for row in rows]
|
|
71
|
+
|
|
72
|
+
except Exception as e:
|
|
73
|
+
print(f"SQLite query error: {e}")
|
|
74
|
+
return []
|
|
75
|
+
|
|
76
|
+
def query_one(self, sql: str, params: Optional[Tuple] = None) -> Optional[Dict[str, Any]]:
|
|
77
|
+
"""Execute a SELECT query and return first result."""
|
|
78
|
+
results = self.query(sql, params)
|
|
79
|
+
return results[0] if results else None
|
|
80
|
+
|
|
81
|
+
def last_insert_id(self) -> int:
|
|
82
|
+
"""Get the last inserted row ID."""
|
|
83
|
+
return self.cursor.lastrowid if self.cursor else 0
|
|
84
|
+
|
|
85
|
+
def affected_rows(self) -> int:
|
|
86
|
+
"""Get number of affected rows from last query."""
|
|
87
|
+
return self.cursor.rowcount if self.cursor else 0
|
|
88
|
+
|
|
89
|
+
def begin_transaction(self) -> bool:
|
|
90
|
+
"""Begin a transaction."""
|
|
91
|
+
try:
|
|
92
|
+
# SQLite doesn't support nested transactions
|
|
93
|
+
# If we're already in a transaction, just return True
|
|
94
|
+
if self.in_transaction:
|
|
95
|
+
return True
|
|
96
|
+
self.conn.execute("BEGIN TRANSACTION")
|
|
97
|
+
self.in_transaction = True
|
|
98
|
+
return True
|
|
99
|
+
except Exception as e:
|
|
100
|
+
print(f"SQLite begin transaction error: {e}")
|
|
101
|
+
return False
|
|
102
|
+
|
|
103
|
+
def commit(self) -> bool:
|
|
104
|
+
"""Commit current transaction."""
|
|
105
|
+
try:
|
|
106
|
+
self.conn.commit()
|
|
107
|
+
self.in_transaction = False
|
|
108
|
+
return True
|
|
109
|
+
except Exception as e:
|
|
110
|
+
print(f"SQLite commit error: {e}")
|
|
111
|
+
return False
|
|
112
|
+
|
|
113
|
+
def rollback(self) -> bool:
|
|
114
|
+
"""Rollback current transaction."""
|
|
115
|
+
try:
|
|
116
|
+
self.conn.rollback()
|
|
117
|
+
self.in_transaction = False
|
|
118
|
+
return True
|
|
119
|
+
except Exception as e:
|
|
120
|
+
print(f"SQLite rollback error: {e}")
|
|
121
|
+
return False
|
|
122
|
+
|
|
123
|
+
def close(self) -> bool:
|
|
124
|
+
"""Close database connection."""
|
|
125
|
+
try:
|
|
126
|
+
if self.cursor:
|
|
127
|
+
self.cursor.close()
|
|
128
|
+
if self.conn:
|
|
129
|
+
self.conn.close()
|
|
130
|
+
return True
|
|
131
|
+
except Exception as e:
|
|
132
|
+
print(f"SQLite close error: {e}")
|
|
133
|
+
return False
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"""Encoding module for Zexus standard library."""
|
|
2
|
+
|
|
3
|
+
import base64
|
|
4
|
+
import binascii
|
|
5
|
+
import json
|
|
6
|
+
from typing import Dict, Any
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class EncodingModule:
|
|
10
|
+
"""Provides encoding/decoding operations."""
|
|
11
|
+
|
|
12
|
+
# Base64 encoding/decoding
|
|
13
|
+
@staticmethod
|
|
14
|
+
def base64_encode(data: str) -> str:
|
|
15
|
+
"""Encode string to base64."""
|
|
16
|
+
return base64.b64encode(data.encode()).decode('ascii')
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def base64_decode(data: str) -> str:
|
|
20
|
+
"""Decode base64 to string."""
|
|
21
|
+
return base64.b64decode(data).decode('utf-8')
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def base64_urlsafe_encode(data: str) -> str:
|
|
25
|
+
"""Encode string to URL-safe base64."""
|
|
26
|
+
return base64.urlsafe_b64encode(data.encode()).decode('ascii')
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def base64_urlsafe_decode(data: str) -> str:
|
|
30
|
+
"""Decode URL-safe base64 to string."""
|
|
31
|
+
return base64.urlsafe_b64decode(data).decode('utf-8')
|
|
32
|
+
|
|
33
|
+
# Base32 encoding/decoding
|
|
34
|
+
@staticmethod
|
|
35
|
+
def base32_encode(data: str) -> str:
|
|
36
|
+
"""Encode string to base32."""
|
|
37
|
+
return base64.b32encode(data.encode()).decode('ascii')
|
|
38
|
+
|
|
39
|
+
@staticmethod
|
|
40
|
+
def base32_decode(data: str) -> str:
|
|
41
|
+
"""Decode base32 to string."""
|
|
42
|
+
return base64.b32decode(data).decode('utf-8')
|
|
43
|
+
|
|
44
|
+
# Base16/Hex encoding/decoding
|
|
45
|
+
@staticmethod
|
|
46
|
+
def hex_encode(data: str) -> str:
|
|
47
|
+
"""Encode string to hexadecimal."""
|
|
48
|
+
return data.encode().hex()
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def hex_decode(data: str) -> str:
|
|
52
|
+
"""Decode hexadecimal to string."""
|
|
53
|
+
return bytes.fromhex(data).decode('utf-8')
|
|
54
|
+
|
|
55
|
+
@staticmethod
|
|
56
|
+
def base16_encode(data: str) -> str:
|
|
57
|
+
"""Encode string to base16."""
|
|
58
|
+
return base64.b16encode(data.encode()).decode('ascii')
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def base16_decode(data: str) -> str:
|
|
62
|
+
"""Decode base16 to string."""
|
|
63
|
+
return base64.b16decode(data).decode('utf-8')
|
|
64
|
+
|
|
65
|
+
# Base85 encoding/decoding
|
|
66
|
+
@staticmethod
|
|
67
|
+
def base85_encode(data: str) -> str:
|
|
68
|
+
"""Encode string to base85."""
|
|
69
|
+
return base64.b85encode(data.encode()).decode('ascii')
|
|
70
|
+
|
|
71
|
+
@staticmethod
|
|
72
|
+
def base85_decode(data: str) -> str:
|
|
73
|
+
"""Decode base85 to string."""
|
|
74
|
+
return base64.b85decode(data).decode('utf-8')
|
|
75
|
+
|
|
76
|
+
# ASCII85 encoding/decoding
|
|
77
|
+
@staticmethod
|
|
78
|
+
def ascii85_encode(data: str) -> str:
|
|
79
|
+
"""Encode string to ASCII85."""
|
|
80
|
+
return base64.a85encode(data.encode()).decode('ascii')
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def ascii85_decode(data: str) -> str:
|
|
84
|
+
"""Decode ASCII85 to string."""
|
|
85
|
+
return base64.a85decode(data).decode('utf-8')
|
|
86
|
+
|
|
87
|
+
# URL encoding/decoding
|
|
88
|
+
@staticmethod
|
|
89
|
+
def url_encode(data: str) -> str:
|
|
90
|
+
"""URL encode string."""
|
|
91
|
+
import urllib.parse
|
|
92
|
+
return urllib.parse.quote(data)
|
|
93
|
+
|
|
94
|
+
@staticmethod
|
|
95
|
+
def url_decode(data: str) -> str:
|
|
96
|
+
"""URL decode string."""
|
|
97
|
+
import urllib.parse
|
|
98
|
+
return urllib.parse.unquote(data)
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
def url_encode_plus(data: str) -> str:
|
|
102
|
+
"""URL encode with + for spaces."""
|
|
103
|
+
import urllib.parse
|
|
104
|
+
return urllib.parse.quote_plus(data)
|
|
105
|
+
|
|
106
|
+
@staticmethod
|
|
107
|
+
def url_decode_plus(data: str) -> str:
|
|
108
|
+
"""URL decode with + for spaces."""
|
|
109
|
+
import urllib.parse
|
|
110
|
+
return urllib.parse.unquote_plus(data)
|
|
111
|
+
|
|
112
|
+
# HTML encoding/decoding
|
|
113
|
+
@staticmethod
|
|
114
|
+
def html_encode(data: str) -> str:
|
|
115
|
+
"""HTML encode string."""
|
|
116
|
+
import html
|
|
117
|
+
return html.escape(data)
|
|
118
|
+
|
|
119
|
+
@staticmethod
|
|
120
|
+
def html_decode(data: str) -> str:
|
|
121
|
+
"""HTML decode string."""
|
|
122
|
+
import html
|
|
123
|
+
return html.unescape(data)
|
|
124
|
+
|
|
125
|
+
# Unicode operations
|
|
126
|
+
@staticmethod
|
|
127
|
+
def unicode_encode(data: str, encoding: str = 'utf-8') -> str:
|
|
128
|
+
"""Encode string to bytes (hex representation)."""
|
|
129
|
+
return data.encode(encoding).hex()
|
|
130
|
+
|
|
131
|
+
@staticmethod
|
|
132
|
+
def unicode_decode(data: str, encoding: str = 'utf-8') -> str:
|
|
133
|
+
"""Decode bytes (hex representation) to string."""
|
|
134
|
+
return bytes.fromhex(data).decode(encoding)
|
|
135
|
+
|
|
136
|
+
@staticmethod
|
|
137
|
+
def unicode_normalize(data: str, form: str = 'NFC') -> str:
|
|
138
|
+
"""Normalize Unicode string (NFC, NFD, NFKC, NFKD)."""
|
|
139
|
+
import unicodedata
|
|
140
|
+
return unicodedata.normalize(form, data)
|
|
141
|
+
|
|
142
|
+
# Binary/ASCII operations
|
|
143
|
+
@staticmethod
|
|
144
|
+
def to_binary(data: str) -> str:
|
|
145
|
+
"""Convert string to binary representation."""
|
|
146
|
+
return ' '.join(format(ord(c), '08b') for c in data)
|
|
147
|
+
|
|
148
|
+
@staticmethod
|
|
149
|
+
def from_binary(data: str) -> str:
|
|
150
|
+
"""Convert binary representation to string."""
|
|
151
|
+
binary_values = data.split()
|
|
152
|
+
return ''.join(chr(int(b, 2)) for b in binary_values)
|
|
153
|
+
|
|
154
|
+
@staticmethod
|
|
155
|
+
def to_ascii_codes(data: str) -> list:
|
|
156
|
+
"""Convert string to ASCII codes."""
|
|
157
|
+
return [ord(c) for c in data]
|
|
158
|
+
|
|
159
|
+
@staticmethod
|
|
160
|
+
def from_ascii_codes(codes: list) -> str:
|
|
161
|
+
"""Convert ASCII codes to string."""
|
|
162
|
+
return ''.join(chr(code) for code in codes)
|
|
163
|
+
|
|
164
|
+
# ROT13
|
|
165
|
+
@staticmethod
|
|
166
|
+
def rot13(data: str) -> str:
|
|
167
|
+
"""ROT13 encoding/decoding."""
|
|
168
|
+
import codecs
|
|
169
|
+
return codecs.encode(data, 'rot_13')
|
|
170
|
+
|
|
171
|
+
# CRC32 checksum
|
|
172
|
+
@staticmethod
|
|
173
|
+
def crc32(data: str) -> int:
|
|
174
|
+
"""Calculate CRC32 checksum."""
|
|
175
|
+
return binascii.crc32(data.encode()) & 0xffffffff
|
|
176
|
+
|
|
177
|
+
# Adler32 checksum
|
|
178
|
+
@staticmethod
|
|
179
|
+
def adler32(data: str) -> int:
|
|
180
|
+
"""Calculate Adler32 checksum."""
|
|
181
|
+
import zlib
|
|
182
|
+
return zlib.adler32(data.encode()) & 0xffffffff
|
|
183
|
+
|
|
184
|
+
# JSON encoding/decoding (for convenience)
|
|
185
|
+
@staticmethod
|
|
186
|
+
def json_encode(obj: Any, pretty: bool = False) -> str:
|
|
187
|
+
"""Encode object to JSON."""
|
|
188
|
+
if pretty:
|
|
189
|
+
return json.dumps(obj, indent=2, ensure_ascii=False)
|
|
190
|
+
return json.dumps(obj, ensure_ascii=False)
|
|
191
|
+
|
|
192
|
+
@staticmethod
|
|
193
|
+
def json_decode(data: str) -> Any:
|
|
194
|
+
"""Decode JSON to object."""
|
|
195
|
+
return json.loads(data)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
# Export functions for easy access
|
|
199
|
+
base64_encode = EncodingModule.base64_encode
|
|
200
|
+
base64_decode = EncodingModule.base64_decode
|
|
201
|
+
base64_urlsafe_encode = EncodingModule.base64_urlsafe_encode
|
|
202
|
+
base64_urlsafe_decode = EncodingModule.base64_urlsafe_decode
|
|
203
|
+
base32_encode = EncodingModule.base32_encode
|
|
204
|
+
base32_decode = EncodingModule.base32_decode
|
|
205
|
+
hex_encode = EncodingModule.hex_encode
|
|
206
|
+
hex_decode = EncodingModule.hex_decode
|
|
207
|
+
base16_encode = EncodingModule.base16_encode
|
|
208
|
+
base16_decode = EncodingModule.base16_decode
|
|
209
|
+
base85_encode = EncodingModule.base85_encode
|
|
210
|
+
base85_decode = EncodingModule.base85_decode
|
|
211
|
+
ascii85_encode = EncodingModule.ascii85_encode
|
|
212
|
+
ascii85_decode = EncodingModule.ascii85_decode
|
|
213
|
+
url_encode = EncodingModule.url_encode
|
|
214
|
+
url_decode = EncodingModule.url_decode
|
|
215
|
+
url_encode_plus = EncodingModule.url_encode_plus
|
|
216
|
+
url_decode_plus = EncodingModule.url_decode_plus
|
|
217
|
+
html_encode = EncodingModule.html_encode
|
|
218
|
+
html_decode = EncodingModule.html_decode
|
|
219
|
+
unicode_encode = EncodingModule.unicode_encode
|
|
220
|
+
unicode_decode = EncodingModule.unicode_decode
|
|
221
|
+
unicode_normalize = EncodingModule.unicode_normalize
|
|
222
|
+
to_binary = EncodingModule.to_binary
|
|
223
|
+
from_binary = EncodingModule.from_binary
|
|
224
|
+
to_ascii_codes = EncodingModule.to_ascii_codes
|
|
225
|
+
from_ascii_codes = EncodingModule.from_ascii_codes
|
|
226
|
+
rot13 = EncodingModule.rot13
|
|
227
|
+
crc32 = EncodingModule.crc32
|
|
228
|
+
adler32 = EncodingModule.adler32
|
|
229
|
+
json_encode = EncodingModule.json_encode
|
|
230
|
+
json_decode = EncodingModule.json_decode
|