easycoder 250722.5__tar.gz → 250723.2__tar.gz
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.
Potentially problematic release.
This version of easycoder might be problematic. Click here for more details.
- {easycoder-250722.5 → easycoder-250723.2}/.gitignore +0 -1
- {easycoder-250722.5 → easycoder-250723.2}/PKG-INFO +3 -2
- {easycoder-250722.5 → easycoder-250723.2}/easycoder/__init__.py +1 -1
- {easycoder-250722.5 → easycoder-250723.2}/easycoder/ec_core.py +2 -1
- easycoder-250723.2/easycoder/ec_keyboard.py +392 -0
- {easycoder-250722.5 → easycoder-250723.2}/easycoder/ec_pyside.py +3 -1
- easycoder-250723.2/plugins/sql.py +164 -0
- easycoder-250723.2/test.py +5 -0
- easycoder-250723.2/testsql.py +7 -0
- easycoder-250723.2/testui.py +7 -0
- {easycoder-250722.5 → easycoder-250723.2}/LICENSE +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/README.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/backdrop.jpg +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/README.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/README.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/boolean.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/empty.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/ends.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/even.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/exists.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/greater.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/hasProperty.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/includes.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/is.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/less.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/list.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/none.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/not.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/numeric.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/object.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/odd.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/starts.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/conditions/string.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/add.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/append.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/assert.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/begin.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/clear.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/close.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/create.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/debug.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/decrement.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/delete.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/divide.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/exit.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/file.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/fork.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/get.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/go.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/gosub.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/if.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/import.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/increment.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/index.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/init.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/input.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/load.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/lock.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/log.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/module.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/multiply.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/negate.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/on.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/open.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/pop.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/post.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/print.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/push.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/put.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/read.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/release.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/replace.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/return.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/run.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/save.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/script.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/send.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/set.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/shuffle.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/split.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/stack.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/stop.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/system.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/take.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/toggle.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/truncate.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/unlock.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/use.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/variable.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/wait.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/while.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/keywords/write.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/arg.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/args.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/cos.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/datime.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/decode.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/element.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/elements.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/empty.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/encode.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/error.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/files.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/float.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/from.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/hash.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/index.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/integer.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/json.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/keys.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/left.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/length.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/lowercase.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/memory.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/modification.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/modulo.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/newline.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/now.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/position.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/property.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/random.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/right.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/sin.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/stringify.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/tab.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/tan.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/timestamp.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/today.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/trim.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/type.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/uppercase.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/value.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/core/values/weekday.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/README.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/keywords/attach.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/keywords/close.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/keywords/create.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/keywords/ellipse.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/keywords/image.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/keywords/move.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/keywords/on.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/keywords/rectangle.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/keywords/render.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/keywords/run.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/keywords/set.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/keywords/text.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/values/attribute.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/doc/graphics/values/window.md +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/easycoder/ec_classes.py +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/easycoder/ec_compiler.py +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/easycoder/ec_condition.py +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/easycoder/ec_handler.py +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/easycoder/ec_program.py +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/easycoder/ec_timestamp.py +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/easycoder/ec_value.py +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/images/Semoigo Dawn.jpg +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/json/graphics-demo.json +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/plugins/ec_keyboard.py +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/plugins/ec_p100.py +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/plugins/ec_pyside6.py +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/plugins/points.py +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/pyproject.toml +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/scripts/benchmark.ecs +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/scripts/config.ecg +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/scripts/ec_keyboard.py +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/scripts/findxr.ecs +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/scripts/fizzbuzz.ecs +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/scripts/hello.ecs +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/scripts/points.ecs +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/scripts/test.ecs +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/scripts/tests.ecs +0 -0
- {easycoder-250722.5 → easycoder-250723.2}/testrc.py +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: easycoder
|
|
3
|
-
Version:
|
|
3
|
+
Version: 250723.2
|
|
4
4
|
Summary: Rapid scripting in English
|
|
5
5
|
Keywords: compiler,scripting,prototyping,programming,coding,python,low code,hypertalk,computer language,learn to code
|
|
6
6
|
Author-email: Graham Trott <gtanyware@gmail.com>
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
License-File: LICENSE
|
|
9
10
|
Requires-Dist: pytz
|
|
10
11
|
Requires-Dist: requests
|
|
11
12
|
Requires-Dist: psutil
|
|
@@ -2,7 +2,6 @@ import json, math, hashlib, threading, os, subprocess, sys, time
|
|
|
2
2
|
import numbers, base64, binascii, random, requests, paramiko
|
|
3
3
|
from psutil import Process
|
|
4
4
|
from datetime import datetime
|
|
5
|
-
from random import randrange
|
|
6
5
|
from .ec_classes import FatalError, RuntimeWarning, RuntimeError, AssertionError, NoValueError, NoValueRuntimeError, Condition, Object
|
|
7
6
|
from .ec_handler import Handler
|
|
8
7
|
from .ec_timestamp import getTimestamp
|
|
@@ -1804,6 +1803,8 @@ class Core(Handler):
|
|
|
1804
1803
|
from .ec_pyside import Graphics
|
|
1805
1804
|
self.program.graphics = Graphics
|
|
1806
1805
|
self.program.useClass(Graphics)
|
|
1806
|
+
# from .ec_keyboard import Keyboard
|
|
1807
|
+
# self.program.useClass(Keyboard)
|
|
1807
1808
|
return True
|
|
1808
1809
|
return False
|
|
1809
1810
|
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
|
|
2
|
+
from .ec_handler import Handler
|
|
3
|
+
from PySide6.QtWidgets import (
|
|
4
|
+
QDialog,
|
|
5
|
+
QVBoxLayout,
|
|
6
|
+
QHBoxLayout,
|
|
7
|
+
QPushButton,
|
|
8
|
+
QWidget,
|
|
9
|
+
QStackedWidget,
|
|
10
|
+
QSpacerItem,
|
|
11
|
+
QSizePolicy,
|
|
12
|
+
QGraphicsDropShadowEffect
|
|
13
|
+
)
|
|
14
|
+
from PySide6.QtGui import QFont, QIcon
|
|
15
|
+
from PySide6.QtCore import Qt, QTimer
|
|
16
|
+
|
|
17
|
+
class Keyboard(Handler):
|
|
18
|
+
|
|
19
|
+
def __init__(self, program, receiver, parent=None):
|
|
20
|
+
Handler.__init__(self, program.compiler)
|
|
21
|
+
|
|
22
|
+
self.program = program
|
|
23
|
+
|
|
24
|
+
dialog = QDialog()
|
|
25
|
+
|
|
26
|
+
# dialog.setWindowTitle('')
|
|
27
|
+
dialog.setWindowFlags(Qt.FramelessWindowHint)
|
|
28
|
+
dialog.setModal(True)
|
|
29
|
+
dialog.setFixedSize(500, 250)
|
|
30
|
+
dialog.setStyleSheet('background-color: white;border:1px solid black;')
|
|
31
|
+
|
|
32
|
+
# Add drop shadow
|
|
33
|
+
shadow = QGraphicsDropShadowEffect(dialog)
|
|
34
|
+
shadow.setBlurRadius(40)
|
|
35
|
+
shadow.setOffset(0, 4)
|
|
36
|
+
shadow.setColor(Qt.black)
|
|
37
|
+
dialog.setGraphicsEffect(shadow)
|
|
38
|
+
|
|
39
|
+
# Add the keyboard
|
|
40
|
+
layout = QVBoxLayout(dialog)
|
|
41
|
+
layout.addWidget(VirtualKeyboard(42, receiver, dialog.reject))
|
|
42
|
+
|
|
43
|
+
# Position at bottom of parent window
|
|
44
|
+
dialog.show() # Ensure geometry is calculated
|
|
45
|
+
if parent:
|
|
46
|
+
parent_pos = parent.mapToGlobal(parent.rect().bottomLeft())
|
|
47
|
+
x = parent_pos.x() + (parent.width - dialog.width()) / 2
|
|
48
|
+
y = parent_pos.y() - dialog.height() - 40
|
|
49
|
+
dialog.move(x, y)
|
|
50
|
+
|
|
51
|
+
dialog.exec()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class TextReceiver():
|
|
55
|
+
def __init__(self, field):
|
|
56
|
+
self.field = field
|
|
57
|
+
|
|
58
|
+
def add_character(self, char):
|
|
59
|
+
"""
|
|
60
|
+
Add a character to the text field.
|
|
61
|
+
|
|
62
|
+
:param char: A single character to add to the field.
|
|
63
|
+
"""
|
|
64
|
+
char = char.replace('&&', '&')
|
|
65
|
+
if len(char) == 1:
|
|
66
|
+
self.field.setText(self.field.text() + char)
|
|
67
|
+
else:
|
|
68
|
+
raise ValueError("Only single characters are allowed.")
|
|
69
|
+
|
|
70
|
+
def backspace(self):
|
|
71
|
+
"""
|
|
72
|
+
Remove the last character from the text field.
|
|
73
|
+
If the field is already empty, do nothing.
|
|
74
|
+
"""
|
|
75
|
+
current_text = self.field.text()
|
|
76
|
+
if current_text:
|
|
77
|
+
self.field.setText(current_text[:-1])
|
|
78
|
+
|
|
79
|
+
def get_content(self):
|
|
80
|
+
"""
|
|
81
|
+
Return the current content of the text field.
|
|
82
|
+
|
|
83
|
+
:return: The current text in the field.
|
|
84
|
+
"""
|
|
85
|
+
return self.field.text()
|
|
86
|
+
|
|
87
|
+
class KeyboardButton(QPushButton):
|
|
88
|
+
def __init__(self, width, height, onClick, text=None, icon=None):
|
|
89
|
+
if text != None: text = text.replace('&','&&')
|
|
90
|
+
super().__init__(text)
|
|
91
|
+
self.setFixedSize(width, height)
|
|
92
|
+
self.setFont(QFont("Arial", height // 2)) # Font size is half the button height
|
|
93
|
+
self.setStyleSheet(f"""
|
|
94
|
+
QPushButton {{
|
|
95
|
+
background-color: white;
|
|
96
|
+
border: none;
|
|
97
|
+
border-radius: {int(height * 0.2)}px; /* Rounded corners */
|
|
98
|
+
}}
|
|
99
|
+
QPushButton:pressed {{
|
|
100
|
+
background-color: #ddd; /* Slightly darker background when pressed */
|
|
101
|
+
}}
|
|
102
|
+
""")
|
|
103
|
+
|
|
104
|
+
if icon:
|
|
105
|
+
self.setIcon(QIcon(icon))
|
|
106
|
+
self.setIconSize(self.size())
|
|
107
|
+
|
|
108
|
+
self.clicked.connect(lambda: self.animate_button(onClick, text))
|
|
109
|
+
|
|
110
|
+
def animate_button(self, onClick, text):
|
|
111
|
+
# Move the button 2 pixels down and right
|
|
112
|
+
self.move(self.x() + 2, self.y() + 2)
|
|
113
|
+
QTimer.singleShot(200, lambda: self.move(self.x() - 2, self.y() - 2)) # Move back after 200ms
|
|
114
|
+
onClick(text)
|
|
115
|
+
|
|
116
|
+
class KeyboardRow(QHBoxLayout):
|
|
117
|
+
def __init__(self, items):
|
|
118
|
+
super().__init__()
|
|
119
|
+
for item in items:
|
|
120
|
+
if isinstance(item, QWidget):
|
|
121
|
+
self.addWidget(item)
|
|
122
|
+
elif isinstance(item, QSpacerItem):
|
|
123
|
+
self.addSpacerItem(item)
|
|
124
|
+
|
|
125
|
+
class KeyboardView(QVBoxLayout):
|
|
126
|
+
def __init__(self, rows):
|
|
127
|
+
super().__init__()
|
|
128
|
+
for row in rows:
|
|
129
|
+
self.addLayout(row)
|
|
130
|
+
|
|
131
|
+
class VirtualKeyboard(QStackedWidget):
|
|
132
|
+
def __init__(self, buttonHeight, textField, onFinished=None):
|
|
133
|
+
super().__init__()
|
|
134
|
+
self.buttonHeight = buttonHeight
|
|
135
|
+
self.textField = textField
|
|
136
|
+
self.onFinished = onFinished
|
|
137
|
+
self.setStyleSheet('background-color: #ccc;border:none;')
|
|
138
|
+
|
|
139
|
+
# Create the 4 keyboard layouts
|
|
140
|
+
self.addKeyboardLayout0()
|
|
141
|
+
self.addKeyboardLayout1()
|
|
142
|
+
self.addKeyboardLayout2()
|
|
143
|
+
self.addKeyboardLayout3()
|
|
144
|
+
|
|
145
|
+
def addKeyboardLayout0(self):
|
|
146
|
+
rowList = []
|
|
147
|
+
|
|
148
|
+
# Row 1: Numbers
|
|
149
|
+
# row1 = KeyboardRow([KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '1234567890'])
|
|
150
|
+
# rowList.append(row1)
|
|
151
|
+
|
|
152
|
+
# Row 2: qwertyuiop
|
|
153
|
+
row2 = KeyboardRow([
|
|
154
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
155
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'qwertyuiop'],
|
|
156
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
157
|
+
])
|
|
158
|
+
rowList.append(row2)
|
|
159
|
+
|
|
160
|
+
# Row 3: asdfghjkl with horizontal stretches
|
|
161
|
+
row3 = KeyboardRow([
|
|
162
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
163
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'asdfghjkl'],
|
|
164
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
165
|
+
])
|
|
166
|
+
rowList.append(row3)
|
|
167
|
+
|
|
168
|
+
# Row 4: Shift, ZXC..., Backspace
|
|
169
|
+
row4 = KeyboardRow([
|
|
170
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
171
|
+
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickShift, None, 'img/up.png'),
|
|
172
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
173
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'zxcvbnm'],
|
|
174
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
175
|
+
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickBack, None, 'img/back.png'),
|
|
176
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
177
|
+
])
|
|
178
|
+
rowList.append(row4)
|
|
179
|
+
|
|
180
|
+
# Row 5: Numbers, Space, Enter
|
|
181
|
+
row5 = KeyboardRow([
|
|
182
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
183
|
+
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickNumbers, None, 'img/numbers.png'),
|
|
184
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
185
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
|
|
186
|
+
KeyboardButton(self.buttonHeight * 5, self.buttonHeight, self.onClickSpace, None, 'skeyboard/pace.png'),
|
|
187
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, "."),
|
|
188
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
189
|
+
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
|
|
190
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
191
|
+
])
|
|
192
|
+
rowList.append(row5)
|
|
193
|
+
|
|
194
|
+
# Add the rows to the KeyboardView
|
|
195
|
+
keyboardView = KeyboardView(rowList)
|
|
196
|
+
container = QWidget()
|
|
197
|
+
container.setLayout(keyboardView)
|
|
198
|
+
self.addWidget(container)
|
|
199
|
+
|
|
200
|
+
def addKeyboardLayout1(self):
|
|
201
|
+
rowList = []
|
|
202
|
+
|
|
203
|
+
# Row 1: Numbers
|
|
204
|
+
# row1 = KeyboardRow([KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '1234567890'])
|
|
205
|
+
# rowList.append(row1)
|
|
206
|
+
|
|
207
|
+
# Row 2: Uppercase QWERTY
|
|
208
|
+
row2 = KeyboardRow([
|
|
209
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
210
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'QWERTYUIOP'],
|
|
211
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
212
|
+
])
|
|
213
|
+
rowList.append(row2)
|
|
214
|
+
|
|
215
|
+
# Row 3: Uppercase ASDFGHJKL with horizontal stretches
|
|
216
|
+
row3 = KeyboardRow([
|
|
217
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
218
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'ASDFGHJKL'],
|
|
219
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
220
|
+
])
|
|
221
|
+
rowList.append(row3)
|
|
222
|
+
|
|
223
|
+
# Row 4: Shift, Uppercase ZXC..., Backspace
|
|
224
|
+
row4 = KeyboardRow([
|
|
225
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
226
|
+
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickShift, None, 'img/up.png'),
|
|
227
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
228
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'ZXCVBNM'],
|
|
229
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
230
|
+
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickBack, None, 'img/back.png'),
|
|
231
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
232
|
+
])
|
|
233
|
+
rowList.append(row4)
|
|
234
|
+
|
|
235
|
+
# Row 5: Numbers, Space, Enter
|
|
236
|
+
row5 = KeyboardRow([
|
|
237
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
238
|
+
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickNumbers, None, 'img/numbers.png'),
|
|
239
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
240
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
|
|
241
|
+
KeyboardButton(self.buttonHeight * 5, self.buttonHeight, self.onClickSpace, None, 'img/space.png'),
|
|
242
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, "."),
|
|
243
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
244
|
+
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
|
|
245
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
246
|
+
])
|
|
247
|
+
rowList.append(row5)
|
|
248
|
+
|
|
249
|
+
# Add the rows to the KeyboardView
|
|
250
|
+
keyboardView = KeyboardView(rowList)
|
|
251
|
+
container = QWidget()
|
|
252
|
+
container.setLayout(keyboardView)
|
|
253
|
+
self.addWidget(container)
|
|
254
|
+
|
|
255
|
+
def addKeyboardLayout2(self):
|
|
256
|
+
rowList = []
|
|
257
|
+
|
|
258
|
+
# Row 1: Numbers
|
|
259
|
+
row1 = KeyboardRow([
|
|
260
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
261
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '1234567890'],
|
|
262
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
263
|
+
])
|
|
264
|
+
rowList.append(row1)
|
|
265
|
+
|
|
266
|
+
# Row 2: Symbols
|
|
267
|
+
row2 = KeyboardRow([
|
|
268
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
269
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '@#£&_-()=%'],
|
|
270
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
271
|
+
])
|
|
272
|
+
rowList.append(row2)
|
|
273
|
+
|
|
274
|
+
# Row 3: Symbols with horizontal stretches
|
|
275
|
+
row3 = KeyboardRow([
|
|
276
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
277
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickSymbols, None, 'img/symbols.png'),
|
|
278
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
279
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '"*\'/:!?+'],
|
|
280
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
281
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickBack, None, 'img/back.png'),
|
|
282
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
283
|
+
])
|
|
284
|
+
rowList.append(row3)
|
|
285
|
+
|
|
286
|
+
# Row 4: Numbers, Space, Enter
|
|
287
|
+
row4 = KeyboardRow([
|
|
288
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
289
|
+
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickLetters, None, 'img/letters.png'),
|
|
290
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
291
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
|
|
292
|
+
KeyboardButton(self.buttonHeight * 6, self.buttonHeight, self.onClickSpace, None, 'img/space.png'),
|
|
293
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, "."),
|
|
294
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
295
|
+
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
|
|
296
|
+
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
297
|
+
])
|
|
298
|
+
rowList.append(row4)
|
|
299
|
+
|
|
300
|
+
# Add the rows to the KeyboardView
|
|
301
|
+
keyboardView = KeyboardView(rowList)
|
|
302
|
+
container = QWidget()
|
|
303
|
+
container.setLayout(keyboardView)
|
|
304
|
+
self.addWidget(container)
|
|
305
|
+
|
|
306
|
+
def addKeyboardLayout3(self):
|
|
307
|
+
rowList = []
|
|
308
|
+
|
|
309
|
+
# Row 1: Extended symbols
|
|
310
|
+
row1 = KeyboardRow([
|
|
311
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
312
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '$€¥¢©®µ~¿¡'],
|
|
313
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
314
|
+
])
|
|
315
|
+
rowList.append(row1)
|
|
316
|
+
|
|
317
|
+
# Row 2: Additional symbols
|
|
318
|
+
row2 = KeyboardRow([
|
|
319
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
320
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '¼½¾[]{}<>^'],
|
|
321
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
322
|
+
])
|
|
323
|
+
rowList.append(row2)
|
|
324
|
+
|
|
325
|
+
# Row 3: Symbols with horizontal stretches
|
|
326
|
+
row3 = KeyboardRow([
|
|
327
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
328
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickNumbers, None, 'img/numbers.png'),
|
|
329
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
330
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '`;÷\\∣|¬±'],
|
|
331
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
332
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickBack, None, 'img/back.png'),
|
|
333
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
334
|
+
])
|
|
335
|
+
rowList.append(row3)
|
|
336
|
+
|
|
337
|
+
# Row 4: Numbers, Space, Enter
|
|
338
|
+
row4 = KeyboardRow([
|
|
339
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
340
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickLetters, None, 'img/letters.png'),
|
|
341
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
342
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
|
|
343
|
+
KeyboardButton(self.buttonHeight * 3, self.buttonHeight, self.onClickSpace, None, 'img/space.png'),
|
|
344
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
345
|
+
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '✕§¶°'],
|
|
346
|
+
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
|
|
347
|
+
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
348
|
+
])
|
|
349
|
+
rowList.append(row4)
|
|
350
|
+
|
|
351
|
+
# Add the rows to the KeyboardView
|
|
352
|
+
keyboardView = KeyboardView(rowList)
|
|
353
|
+
container = QWidget()
|
|
354
|
+
container.setLayout(keyboardView)
|
|
355
|
+
self.addWidget(container)
|
|
356
|
+
|
|
357
|
+
# Callback functions
|
|
358
|
+
def onClickChar(self,keycode):
|
|
359
|
+
# print(f"Key pressed: {keycode}")
|
|
360
|
+
self.textField.add_character(keycode)
|
|
361
|
+
|
|
362
|
+
def onClickShift(self,keycode):
|
|
363
|
+
# print("Shift pressed")
|
|
364
|
+
if self.currentIndex() == 0:
|
|
365
|
+
self.setCurrentIndex(1)
|
|
366
|
+
elif self.currentIndex() == 1:
|
|
367
|
+
self.setCurrentIndex(0)
|
|
368
|
+
|
|
369
|
+
def onClickLetters(self,keycode):
|
|
370
|
+
# print("Letters pressed")
|
|
371
|
+
self.setCurrentIndex(0)
|
|
372
|
+
|
|
373
|
+
def onClickNumbers(self,keycode):
|
|
374
|
+
# print("Numbers pressed")
|
|
375
|
+
self.setCurrentIndex(2)
|
|
376
|
+
|
|
377
|
+
def onClickSymbols(self,keycode):
|
|
378
|
+
# print("Symbols pressed")
|
|
379
|
+
self.setCurrentIndex(3)
|
|
380
|
+
|
|
381
|
+
def onClickBack(self,keycode):
|
|
382
|
+
# print("Backspace pressed")
|
|
383
|
+
self.textField.backspace()
|
|
384
|
+
|
|
385
|
+
def onClickSpace(self,keycode):
|
|
386
|
+
# print("Space pressed")
|
|
387
|
+
self.textField.add_character(' ')
|
|
388
|
+
|
|
389
|
+
def onClickEnter(self,keycode):
|
|
390
|
+
# print("Enter pressed")
|
|
391
|
+
# print(self.textField.get_content())
|
|
392
|
+
if self.onFinished: self.onFinished()
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import sys
|
|
2
|
-
from
|
|
2
|
+
from .ec_handler import Handler
|
|
3
|
+
from .ec_classes import RuntimeError
|
|
4
|
+
from .ec_keyboard import Keyboard
|
|
3
5
|
from PySide6.QtCore import Qt, QTimer
|
|
4
6
|
from PySide6.QtGui import QPixmap
|
|
5
7
|
from PySide6.QtWidgets import (
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
from easycoder import Handler, FatalError, RuntimeError, json
|
|
2
|
+
|
|
3
|
+
class SQL(Handler):
|
|
4
|
+
|
|
5
|
+
def __init__(self, compiler):
|
|
6
|
+
Handler.__init__(self, compiler)
|
|
7
|
+
|
|
8
|
+
def getName(self):
|
|
9
|
+
return 'sql'
|
|
10
|
+
|
|
11
|
+
#############################################################################
|
|
12
|
+
# Keyword handlers
|
|
13
|
+
|
|
14
|
+
# create {table} {name} [with ...]
|
|
15
|
+
# {name} {flag(s)} {type} [default {value}] [and ..]
|
|
16
|
+
def k_create(self, command):
|
|
17
|
+
if self.nextIsSymbol():
|
|
18
|
+
record = self.getSymbolRecord()
|
|
19
|
+
if record['keyword'] == 'table':
|
|
20
|
+
command['target'] = record['name']
|
|
21
|
+
command['tableName'] = self.nextValue()
|
|
22
|
+
keys = []
|
|
23
|
+
while self.peek() in ['key', 'include']:
|
|
24
|
+
item = {}
|
|
25
|
+
token = self.nextToken()
|
|
26
|
+
if token == 'include':
|
|
27
|
+
item['include'] = self.nextValue()
|
|
28
|
+
else:
|
|
29
|
+
item['name'] = self.nextValue()
|
|
30
|
+
token = self.peek()
|
|
31
|
+
if token == 'primary':
|
|
32
|
+
item['primary'] = True
|
|
33
|
+
self.nextToken()
|
|
34
|
+
if token == 'secondary':
|
|
35
|
+
item['secondary'] = True
|
|
36
|
+
self.nextToken()
|
|
37
|
+
elif token == 'required':
|
|
38
|
+
item['required'] = True
|
|
39
|
+
self.nextToken()
|
|
40
|
+
elif token == 'auto':
|
|
41
|
+
item['required'] = True
|
|
42
|
+
self.nextToken()
|
|
43
|
+
item['type'] = self.nextToken()
|
|
44
|
+
if self.peek() in ['default', '=']:
|
|
45
|
+
self.nextToken()
|
|
46
|
+
item['default'] = self.nextValue()
|
|
47
|
+
elif self.peek() == 'check':
|
|
48
|
+
self.nextToken()
|
|
49
|
+
item['check'] = self.nextValue()
|
|
50
|
+
keys.append(item)
|
|
51
|
+
command['keys'] = keys
|
|
52
|
+
self.add(command)
|
|
53
|
+
return True
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
def r_create(self, command):
|
|
57
|
+
record = self.getVariable(command['target'])
|
|
58
|
+
self.putSymbolValue(record, command)
|
|
59
|
+
return self.nextPC()
|
|
60
|
+
|
|
61
|
+
def k_get(self, command):
|
|
62
|
+
if self.nextIsSymbol():
|
|
63
|
+
record = self.getSymbolRecord()
|
|
64
|
+
if record['hasValue']:
|
|
65
|
+
command['target'] = record['name']
|
|
66
|
+
self.skip('from')
|
|
67
|
+
if self.nextIsSymbol():
|
|
68
|
+
record = self.getSymbolRecord()
|
|
69
|
+
if record['keyword'] == 'table':
|
|
70
|
+
command['entity'] = record['name']
|
|
71
|
+
if self.peek() == 'as':
|
|
72
|
+
self.nextToken()
|
|
73
|
+
command['form'] = self.nextToken()
|
|
74
|
+
else: command['form'] = 'sql'
|
|
75
|
+
self.add(command)
|
|
76
|
+
return True
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
def r_get(self, command):
|
|
80
|
+
target = self.getVariable(command['target'])
|
|
81
|
+
entity = self.getVariable(command['entity'])
|
|
82
|
+
form = command['form']
|
|
83
|
+
keyword = entity['keyword']
|
|
84
|
+
if keyword == 'table':
|
|
85
|
+
value = self.getSymbolValue(entity)
|
|
86
|
+
tableName = self.getRuntimeValue(value['tableName'])
|
|
87
|
+
output = []
|
|
88
|
+
if form == 'sql':
|
|
89
|
+
# -------------------------------------------------------------
|
|
90
|
+
# Here are the rules for generating SQL
|
|
91
|
+
output.append(f'DROP TABLE IF EXISTS {tableName} CASCADE;')
|
|
92
|
+
output.append(f'CREATE TABLE {tableName} {{')
|
|
93
|
+
secondary = False
|
|
94
|
+
includes = []
|
|
95
|
+
keys = entity['value'][entity['index']]['keys']
|
|
96
|
+
for index, key in enumerate(keys):
|
|
97
|
+
item = []
|
|
98
|
+
if 'include' in key:
|
|
99
|
+
name = self.getRuntimeValue(key['include'])
|
|
100
|
+
includes.append(f'{name}_id')
|
|
101
|
+
item = f'{name}_id BIGINT REFERENCES {name}'
|
|
102
|
+
else:
|
|
103
|
+
if 'secondary' in key:
|
|
104
|
+
secondary = True
|
|
105
|
+
output.append(' id BIGSERIAL PRIMARY KEY,')
|
|
106
|
+
item.append(self.getRuntimeValue(key['name']))
|
|
107
|
+
type = key['type']
|
|
108
|
+
if type == 'string': type = 'text'
|
|
109
|
+
elif type == 'datetime': type = 'timestamptz'
|
|
110
|
+
elif type == 'u64': type = 'bigint'
|
|
111
|
+
item.append(type.upper())
|
|
112
|
+
if secondary:
|
|
113
|
+
item.append('UNIQUE NOT NULL')
|
|
114
|
+
secondary = False
|
|
115
|
+
if 'primary' in key: item.append('PRIMARY KEY')
|
|
116
|
+
if 'required' in key: item.append('NOT NULL')
|
|
117
|
+
if 'default' in key:
|
|
118
|
+
default = self.getRuntimeValue(key['default'])
|
|
119
|
+
item.append(f'DEFAULT \'{default}\'')
|
|
120
|
+
if 'check' in key:
|
|
121
|
+
check = self.getRuntimeValue(key['check'])
|
|
122
|
+
item.append(f'CHECK ({check})')
|
|
123
|
+
item = ' '.join(item)
|
|
124
|
+
if index < len(keys) - 1 or len(includes) > 0: item = f'{item},'
|
|
125
|
+
output.append(f' {item}')
|
|
126
|
+
if len(includes) > 0:
|
|
127
|
+
includes = ', '.join(includes)
|
|
128
|
+
item = f' PRIMARY KEY ({includes})'
|
|
129
|
+
output.append(item)
|
|
130
|
+
output.append('};')
|
|
131
|
+
# -------------------------------------------------------------
|
|
132
|
+
v = {}
|
|
133
|
+
v['type'] = 'text'
|
|
134
|
+
v['content'] = '\n'.join(output)
|
|
135
|
+
self.putSymbolValue(target, v)
|
|
136
|
+
return self.nextPC()
|
|
137
|
+
|
|
138
|
+
def k_table(self, command):
|
|
139
|
+
return self.compileVariable(command, False)
|
|
140
|
+
|
|
141
|
+
def r_table(self, command):
|
|
142
|
+
return self.nextPC()
|
|
143
|
+
|
|
144
|
+
#############################################################################
|
|
145
|
+
# Compile a value in this domain
|
|
146
|
+
def compileValue(self):
|
|
147
|
+
return None
|
|
148
|
+
|
|
149
|
+
#############################################################################
|
|
150
|
+
# Modify a value or leave it unchanged.
|
|
151
|
+
def modifyValue(self, value):
|
|
152
|
+
return value
|
|
153
|
+
|
|
154
|
+
#############################################################################
|
|
155
|
+
# Value handlers
|
|
156
|
+
|
|
157
|
+
#############################################################################
|
|
158
|
+
# Compile a condition
|
|
159
|
+
def compileCondition(self):
|
|
160
|
+
condition = {}
|
|
161
|
+
return condition
|
|
162
|
+
|
|
163
|
+
#############################################################################
|
|
164
|
+
# Condition handlers
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|