ngapakin 1.0.0__py3-none-any.whl

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.
framework/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ """
2
+ Larapak Framework - MVC Web Framework for NgapakIn Language.
3
+ """
4
+
5
+ __version__ = "1.0.0"
framework/auth.py ADDED
@@ -0,0 +1,75 @@
1
+ # Authentication System for Larapak
2
+
3
+ from framework.database import db_manager
4
+
5
+ class Auth:
6
+ def __init__(self, vm=None):
7
+ self.vm = vm
8
+
9
+ @property
10
+ def sesi(self):
11
+ if self.vm and "sesi" in self.vm.globals:
12
+ return self.vm.globals["sesi"]
13
+ return None
14
+
15
+ def user(self):
16
+ ses = self.sesi
17
+ if not ses:
18
+ return None
19
+ user_id = ses.get("auth_user_id")
20
+ if not user_id:
21
+ return None
22
+
23
+ if self.vm and "User" in self.vm.globals:
24
+ User = self.vm.globals["User"]
25
+ # Call User.golek(user_id)
26
+ # golek is a classmethod on Model, which wraps it.
27
+ # In Python, we can call it using __func__ since Model.golek is a classmethod
28
+ from framework.model import Model
29
+ return Model.golek.__func__(User, user_id)
30
+ return None
31
+
32
+ def cek(self):
33
+ return self.user() is not None
34
+
35
+ def check(self):
36
+ return self.cek()
37
+
38
+ def mlebu(self, email, password):
39
+ """Login user with email and password."""
40
+ if self.vm and "User" in self.vm.globals:
41
+ User = self.vm.globals["User"]
42
+ from framework.model import Model
43
+ # Query user using ModelQueryBuilder
44
+ # We will make sure Model.nek works and returns a user.
45
+ # Or we can query directly via SQL for safety inside auth:
46
+ table = Model.get_table_name(User)
47
+ row = db_manager.execute(f"SELECT * FROM {table} WHERE email = ?", [email]).fetchone()
48
+ if row:
49
+ user_dict = dict(row)
50
+ if user_dict.get("password") == password:
51
+ ses = self.sesi
52
+ if ses:
53
+ ses.set("auth_user_id", user_dict.get("id"))
54
+
55
+ # Instantiate user object
56
+ from ngapak.vm import NgapakInstance
57
+ instance = User() if hasattr(User, 'attributes') else User.__new__(User)
58
+ if isinstance(instance, NgapakInstance):
59
+ instance.fields.update(user_dict)
60
+ else:
61
+ instance.__dict__.update(user_dict)
62
+ return True
63
+ return False
64
+
65
+ def login(self, email, password):
66
+ return self.mlebu(email, password)
67
+
68
+ def metu(self):
69
+ """Logout current user."""
70
+ ses = self.sesi
71
+ if ses:
72
+ ses.forget("auth_user_id")
73
+
74
+ def logout(self):
75
+ self.metu()
framework/cache.py ADDED
@@ -0,0 +1,72 @@
1
+ # Cache Manager for Larapak
2
+
3
+ import time
4
+ import json
5
+ from framework.database import db_manager
6
+
7
+ class Cache:
8
+ def __init__(self):
9
+ self._ensure_table()
10
+
11
+ def _ensure_table(self):
12
+ db_manager.execute_write(
13
+ "CREATE TABLE IF NOT EXISTS cache (key VARCHAR(255) PRIMARY KEY, value TEXT, expiration INTEGER)"
14
+ )
15
+
16
+ def pasang(self, key, value, seconds=None):
17
+ expiration = None
18
+ if seconds is not None:
19
+ expiration = int(time.time() + seconds)
20
+
21
+ serialized = json.dumps(value)
22
+ db_manager.execute_write(
23
+ "INSERT OR REPLACE INTO cache (key, value, expiration) VALUES (?, ?, ?)",
24
+ [key, serialized, expiration]
25
+ )
26
+ return True
27
+
28
+ def set(self, key, value, seconds=None):
29
+ return self.pasang(key, value, seconds)
30
+
31
+ def entuk(self, key, default=None):
32
+ row = db_manager.execute("SELECT value, expiration FROM cache WHERE key = ?", [key]).fetchone()
33
+ if not row:
34
+ return default
35
+
36
+ expiration = row["expiration"]
37
+ if expiration is not None and expiration <= time.time():
38
+ # Expired, remove it
39
+ self.lalekna(key)
40
+ return default
41
+
42
+ try:
43
+ return json.loads(row["value"])
44
+ except Exception:
45
+ return default
46
+
47
+ def get(self, key, default=None):
48
+ return self.entuk(key, default)
49
+
50
+ def lalekna(self, key):
51
+ db_manager.execute_write("DELETE FROM cache WHERE key = ?", [key])
52
+ return True
53
+
54
+ def forget(self, key):
55
+ return self.lalekna(key)
56
+
57
+ def remove(self, key):
58
+ return self.lalekna(key)
59
+
60
+ def resiki(self):
61
+ db_manager.execute_write("DELETE FROM cache")
62
+ return True
63
+
64
+ def clear(self):
65
+ return self.resiki()
66
+
67
+ def nduwe(self, key):
68
+ val = self.entuk(key, None)
69
+ return val is not None
70
+
71
+ def has(self, key):
72
+ return self.nduwe(key)
framework/container.py ADDED
@@ -0,0 +1,42 @@
1
+ # Service Container for Larapak Web Framework
2
+
3
+ class Container:
4
+ def __init__(self):
5
+ self.bindings = {}
6
+ self.instances = {}
7
+ self.vm = None # Injected by VM
8
+
9
+ def bind(self, name, factory):
10
+ """Bind a dependency resolver function to a name."""
11
+ self.bindings[name] = factory
12
+
13
+ def singleton(self, name, factory):
14
+ """Bind a singleton dependency resolver."""
15
+ def singleton_factory():
16
+ if name not in self.instances:
17
+ if self.vm and callable(factory):
18
+ # If it's a VM function, invoke it
19
+ self.instances[name] = self.vm.execute_callable(factory, [])
20
+ else:
21
+ self.instances[name] = factory()
22
+ return self.instances[name]
23
+ self.bindings[name] = singleton_factory
24
+
25
+ def make(self, name):
26
+ """Resolve dependency by name."""
27
+ if name in self.instances:
28
+ return self.instances[name]
29
+
30
+ if name in self.bindings:
31
+ factory = self.bindings[name]
32
+ # Check if it is a VM function
33
+ if self.vm and hasattr(factory, 'chunk'):
34
+ res = self.vm.execute_callable(factory, [])
35
+ return res
36
+ elif callable(factory):
37
+ res = factory()
38
+ return res
39
+ else:
40
+ return factory
41
+
42
+ raise KeyError(f"Dependency '{name}' tidak ditemukan di Service Container.")
@@ -0,0 +1,51 @@
1
+ # Controller resolution and loader for Larapak
2
+
3
+ import os
4
+ from ngapak import Lexer, Parser, Compiler, NgapakError
5
+
6
+ class ControllerLoader:
7
+ def __init__(self, controllers_path, vm):
8
+ self.controllers_path = controllers_path
9
+ self.vm = vm
10
+ self.loaded_controllers = {}
11
+
12
+ def call_action(self, action_str, req, res):
13
+ """Invoke controller action method (e.g. 'HomeController@index') on VM."""
14
+ parts = action_str.split("@")
15
+ if len(parts) < 2:
16
+ raise ValueError(f"Format aksi controller tidak valid: '{action_str}'")
17
+
18
+ controller_name = parts[0]
19
+ action_name = parts[1]
20
+
21
+ # Load and run controller file once to register its functions in VM globals
22
+ if controller_name not in self.loaded_controllers:
23
+ filepath = os.path.join(self.controllers_path, f"{controller_name}.ngpk")
24
+ if not os.path.exists(filepath):
25
+ raise FileNotFoundError(f"Controller '{controller_name}' tidak ditemukan di '{filepath}'")
26
+
27
+ with open(filepath, "r", encoding="utf-8") as f:
28
+ source = f.read()
29
+
30
+ lexer = Lexer(source, filepath)
31
+ tokens = lexer.tokenize()
32
+ parser = Parser(tokens, filepath)
33
+ ast = parser.parse()
34
+
35
+ compiler = Compiler(filepath)
36
+ main_fn = compiler.compile(ast)
37
+
38
+ # Execute the controller file main scope to define functions
39
+ self.vm.execute_callable(main_fn, [])
40
+ self.loaded_controllers[controller_name] = True
41
+
42
+ # Retrieve action function from VM globals
43
+ if action_name not in self.vm.globals:
44
+ raise AttributeError(f"Aksi '{action_name}' tidak ditemukan di Controller '{controller_name}'.")
45
+
46
+ action_fn = self.vm.globals[action_name]
47
+
48
+ # Call the controller function on VM: action(req, res)
49
+ # Returns the Response object modified or returned by the function
50
+ result_response = self.vm.execute_callable(action_fn, [req, res])
51
+ return result_response
framework/database.py ADDED
@@ -0,0 +1,58 @@
1
+ # Database Connection & Transaction Manager for Larapak
2
+
3
+ import os
4
+ import sqlite3
5
+
6
+ class DatabaseConnection:
7
+ def __init__(self, db_path="database.sqlite"):
8
+ self.db_path = db_path
9
+ self._conn = None
10
+ self.query_log = []
11
+ self.log_queries = True
12
+
13
+ def get_connection(self):
14
+ if self._conn is None:
15
+ # Ensure folder exists
16
+ db_dir = os.path.dirname(self.db_path)
17
+ if db_dir and not os.path.exists(db_dir):
18
+ os.makedirs(db_dir, exist_ok=True)
19
+ self._conn = sqlite3.connect(self.db_path, check_same_thread=False)
20
+ self._conn.row_factory = sqlite3.Row
21
+ return self._conn
22
+
23
+ def execute(self, sql, params=None):
24
+ params = params or []
25
+ if self.log_queries:
26
+ print(f"[SQL] {sql} | Params: {params}")
27
+ self.query_log.append((sql, params))
28
+
29
+ conn = self.get_connection()
30
+ cursor = conn.cursor()
31
+ cursor.execute(sql, params)
32
+ return cursor
33
+
34
+ def execute_write(self, sql, params=None):
35
+ params = params or []
36
+ cursor = self.execute(sql, params)
37
+ conn = self.get_connection()
38
+ conn.commit()
39
+ return cursor.lastrowid
40
+
41
+ def begin_transaction(self):
42
+ self.execute("BEGIN")
43
+
44
+ def commit(self):
45
+ self.execute("COMMIT")
46
+
47
+ def rollback(self):
48
+ self.execute("ROLLBACK")
49
+
50
+ def close(self):
51
+ if self._conn:
52
+ self._conn.close()
53
+ self._conn = None
54
+
55
+ from .env import env
56
+
57
+ # Global db connection
58
+ db_manager = DatabaseConnection(env("DB_DATABASE", "database.sqlite"))
framework/env.py ADDED
@@ -0,0 +1,44 @@
1
+ # Environment Configuration Loader for Larapak (.env)
2
+
3
+ import os
4
+
5
+ _ENV_LOADED = False
6
+
7
+ def load_env(env_file=".env"):
8
+ """Loads key-value pairs from .env file into os.environ."""
9
+ global _ENV_LOADED
10
+ if not os.path.exists(env_file):
11
+ return
12
+
13
+ with open(env_file, "r", encoding="utf-8") as f:
14
+ for line in f:
15
+ line = line.strip()
16
+ # Skip empty lines and comments
17
+ if not line or line.startswith("#"):
18
+ continue
19
+ if "=" in line:
20
+ key, val = line.split("=", 1)
21
+ key = key.strip()
22
+ val = val.strip()
23
+ # Strip wrapping single or double quotes
24
+ if (val.startswith('"') and val.endswith('"')) or (val.startswith("'") and val.endswith("'")):
25
+ val = val[1:-1]
26
+ # Only set if not already overridden by system environment
27
+ if key not in os.environ:
28
+ os.environ[key] = val
29
+
30
+ _ENV_LOADED = True
31
+
32
+ def env(key, default=None):
33
+ """Retrieves an environment variable with optional fallback default."""
34
+ if not _ENV_LOADED:
35
+ load_env()
36
+ val = os.environ.get(key, default)
37
+ # Type conversions for standard boolean and null strings
38
+ if val == "bener" or val == "true" or val == "True":
39
+ return True
40
+ if val == "salah" or val == "false" or val == "False":
41
+ return False
42
+ if val == "kosong" or val == "null" or val == "None":
43
+ return None
44
+ return val
framework/event.py ADDED
@@ -0,0 +1,30 @@
1
+ # Event Dispatcher for Larapak
2
+
3
+ class Event:
4
+ def __init__(self, vm=None):
5
+ self.vm = vm
6
+ self.listeners = {}
7
+
8
+ def rungokna(self, event_name, listener):
9
+ if event_name not in self.listeners:
10
+ self.listeners[event_name] = []
11
+ self.listeners[event_name].append(listener)
12
+
13
+ def listen(self, event_name, listener):
14
+ self.rungokna(event_name, listener)
15
+
16
+ def kirim(self, event_name, data=None):
17
+ if event_name not in self.listeners:
18
+ return
19
+
20
+ for listener in self.listeners[event_name]:
21
+ # Call the listener
22
+ if hasattr(listener, 'chunk'):
23
+ # Ngapak VM Function
24
+ if self.vm:
25
+ self.vm.execute_callable(listener, [data] if data is not None else [])
26
+ elif callable(listener):
27
+ listener(data) if data is not None else listener()
28
+
29
+ def dispatch(self, event_name, data=None):
30
+ self.kirim(event_name, data)
@@ -0,0 +1,62 @@
1
+ # Middleware pipeline execution for Larapak
2
+
3
+ import os
4
+ from ngapak import Lexer, Parser, Compiler, NgapakError
5
+
6
+ class MiddlewarePipeline:
7
+ def __init__(self, middleware_path, vm):
8
+ self.middleware_path = middleware_path
9
+ self.vm = vm
10
+ self.middleware_map = {
11
+ "auth": "AuthMiddleware" # Map shorthand aliases
12
+ }
13
+ self.loaded_middleware = {}
14
+
15
+ def execute_chain(self, middleware_names, req, res, destination):
16
+ """Execute middleware list sequentially, ending at destination controller call."""
17
+ idx = 0
18
+
19
+ def next_step(current_req, current_res):
20
+ nonlocal idx
21
+ if idx < len(middleware_names):
22
+ name = middleware_names[idx]
23
+ idx += 1
24
+ return self.run_middleware(name, current_req, current_res, next_step)
25
+ else:
26
+ return destination(current_req, current_res)
27
+
28
+ return next_step(req, res)
29
+
30
+ def run_middleware(self, name, req, res, next_cb):
31
+ class_name = self.middleware_map.get(name, name)
32
+
33
+ # Load and run middleware file once to register its functions
34
+ if class_name not in self.loaded_middleware:
35
+ filepath = os.path.join(self.middleware_path, f"{class_name}.ngpk")
36
+ if not os.path.exists(filepath):
37
+ raise FileNotFoundError(f"Middleware '{class_name}' tidak ditemukan di '{filepath}'")
38
+
39
+ with open(filepath, "r", encoding="utf-8") as f:
40
+ source = f.read()
41
+
42
+ lexer = Lexer(source, filepath)
43
+ tokens = lexer.tokenize()
44
+ parser = Parser(tokens, filepath)
45
+ ast = parser.parse()
46
+
47
+ compiler = Compiler(filepath)
48
+ main_fn = compiler.compile(ast)
49
+
50
+ self.vm.execute_callable(main_fn, [])
51
+ self.loaded_middleware[class_name] = True
52
+
53
+ # Middlewares define a global function called 'tangani(req, res, lanjut)'
54
+ if "tangani" not in self.vm.globals:
55
+ return next_cb(req, res)
56
+
57
+ tangani_fn = self.vm.globals["tangani"]
58
+
59
+ # Run middleware tangani(req, res, next_cb) on VM.
60
+ # next_cb is passed directly as Python callback.
61
+ res_obj = self.vm.execute_callable(tangani_fn, [req, res, next_cb])
62
+ return res_obj
framework/model.py ADDED
@@ -0,0 +1,232 @@
1
+ # Base ORM Model for Larapak (Eloquent-like)
2
+
3
+ from .database import db_manager
4
+ from .query_builder import QueryBuilder
5
+ from ngapak.vm import NgapakClass, NgapakInstance
6
+
7
+ class Model:
8
+ active_vm = None
9
+ tabel = None
10
+ fillable = []
11
+
12
+ @classmethod
13
+ def get_table_name(cls, class_obj):
14
+ if isinstance(class_obj, NgapakClass):
15
+ return class_obj.attributes.get("tabel", f"{class_obj.name.lower()}s")
16
+ return getattr(class_obj, "tabel", f"{class_obj.__name__.lower()}s")
17
+
18
+ @classmethod
19
+ def get_fillable(cls, class_obj):
20
+ if isinstance(class_obj, NgapakClass):
21
+ return class_obj.attributes.get("fillable", [])
22
+ return getattr(class_obj, "fillable", [])
23
+
24
+ @classmethod
25
+ def kabeh(cls):
26
+ # cls is the class object (e.g. NgapakClass 'User' or Model subclass)
27
+ table = Model.get_table_name(cls)
28
+ rows = QueryBuilder(table).kabeh()
29
+
30
+ instances = []
31
+ for row in rows:
32
+ instance = cls() if isinstance(cls, NgapakClass) else cls.__new__(cls)
33
+ if isinstance(instance, NgapakInstance):
34
+ instance.fields.update(row)
35
+ else:
36
+ instance.__dict__.update(row)
37
+ instances.append(instance)
38
+ return instances
39
+
40
+ @classmethod
41
+ def golek(cls, record_id):
42
+ table = Model.get_table_name(cls)
43
+ row = QueryBuilder(table).nek("id", "==", record_id).golek()
44
+ if not row:
45
+ return None
46
+
47
+ instance = cls() if isinstance(cls, NgapakClass) else cls.__new__(cls)
48
+ if isinstance(instance, NgapakInstance):
49
+ instance.fields.update(row)
50
+ else:
51
+ instance.__dict__.update(row)
52
+ return instance
53
+
54
+ @classmethod
55
+ def gawe(cls, data):
56
+ table = Model.get_table_name(cls)
57
+ fillable = Model.get_fillable(cls)
58
+
59
+ # Filter fields based on fillable
60
+ filtered_data = {}
61
+ if fillable:
62
+ for k, v in data.items():
63
+ if k in fillable:
64
+ filtered_data[k] = v
65
+ else:
66
+ filtered_data = data
67
+
68
+ record_id = QueryBuilder(table).tambah(filtered_data)
69
+
70
+ # Reload instance from DB to get autogenerated fields/defaults
71
+ return Model.golek.__func__(cls, record_id)
72
+
73
+ # Instance Methods
74
+ def simpen(self):
75
+ # self is NgapakInstance or Model subclass
76
+ cls = self.ngapak_class if isinstance(self, NgapakInstance) else self.__class__
77
+ table = Model.get_table_name(cls)
78
+
79
+ fields = self.fields if isinstance(self, NgapakInstance) else self.__dict__
80
+
81
+ if "id" in fields and fields["id"] is not None:
82
+ # Update
83
+ QueryBuilder(table).nek("id", "==", fields["id"]).anyari(fields)
84
+ else:
85
+ # Insert
86
+ record_id = QueryBuilder(table).tambah(fields)
87
+ fields["id"] = record_id
88
+ return self
89
+
90
+ def busak(self):
91
+ cls = self.ngapak_class if isinstance(self, NgapakInstance) else self.__class__
92
+ table = Model.get_table_name(cls)
93
+ fields = self.fields if isinstance(self, NgapakInstance) else self.__dict__
94
+
95
+ if "id" in fields and fields["id"] is not None:
96
+ QueryBuilder(table).nek("id", "==", fields["id"]).busak()
97
+ fields["id"] = None
98
+ return self
99
+
100
+ # Relationship Methods
101
+ def hasOne(self, related_class_name, foreign_key=None, local_key="id"):
102
+ if not Model.active_vm:
103
+ return None
104
+
105
+ related_class = Model.active_vm.globals.get(related_class_name)
106
+ if not related_class:
107
+ raise ValueError(f"Model '{related_class_name}' tidak ditemukan di VM globals.")
108
+
109
+ related_table = Model.get_table_name(related_class)
110
+
111
+ # Resolve foreign key
112
+ cls = self.ngapak_class if isinstance(self, NgapakInstance) else self.__class__
113
+ if foreign_key is None:
114
+ foreign_key = f"{cls.name.lower()}_id"
115
+
116
+ fields = self.fields if isinstance(self, NgapakInstance) else self.__dict__
117
+ local_val = fields.get(local_key)
118
+
119
+ row = QueryBuilder(related_table).nek(foreign_key, "==", local_val).golek()
120
+ if not row:
121
+ return None
122
+
123
+ instance = related_class() if isinstance(related_class, NgapakClass) else related_class.__new__(related_class)
124
+ if isinstance(instance, NgapakInstance):
125
+ instance.fields.update(row)
126
+ else:
127
+ instance.__dict__.update(row)
128
+ return instance
129
+
130
+ def hasMany(self, related_class_name, foreign_key=None, local_key="id"):
131
+ if not Model.active_vm:
132
+ return []
133
+
134
+ related_class = Model.active_vm.globals.get(related_class_name)
135
+ if not related_class:
136
+ raise ValueError(f"Model '{related_class_name}' tidak ditemukan di VM globals.")
137
+
138
+ related_table = Model.get_table_name(related_class)
139
+
140
+ # Resolve foreign key
141
+ cls = self.ngapak_class if isinstance(self, NgapakInstance) else self.__class__
142
+ if foreign_key is None:
143
+ foreign_key = f"{cls.name.lower()}_id"
144
+
145
+ fields = self.fields if isinstance(self, NgapakInstance) else self.__dict__
146
+ local_val = fields.get(local_key)
147
+
148
+ rows = QueryBuilder(related_table).nek(foreign_key, "==", local_val).kabeh()
149
+
150
+ instances = []
151
+ for row in rows:
152
+ instance = related_class() if isinstance(related_class, NgapakClass) else related_class.__new__(related_class)
153
+ if isinstance(instance, NgapakInstance):
154
+ instance.fields.update(row)
155
+ else:
156
+ instance.__dict__.update(row)
157
+ instances.append(instance)
158
+ return instances
159
+
160
+ def belongsTo(self, related_class_name, foreign_key=None, owner_key="id"):
161
+ if not Model.active_vm:
162
+ return None
163
+
164
+ related_class = Model.active_vm.globals.get(related_class_name)
165
+ if not related_class:
166
+ raise ValueError(f"Model '{related_class_name}' tidak ditemukan di VM globals.")
167
+
168
+ related_table = Model.get_table_name(related_class)
169
+
170
+ # Resolve foreign key
171
+ if foreign_key is None:
172
+ foreign_key = f"{related_class_name.lower()}_id"
173
+
174
+ fields = self.fields if isinstance(self, NgapakInstance) else self.__dict__
175
+ foreign_val = fields.get(foreign_key)
176
+
177
+ row = QueryBuilder(related_table).nek(owner_key, "==", foreign_val).golek()
178
+ if not row:
179
+ return None
180
+
181
+ instance = related_class() if isinstance(related_class, NgapakClass) else related_class.__new__(related_class)
182
+ if isinstance(instance, NgapakInstance):
183
+ instance.fields.update(row)
184
+ else:
185
+ instance.__dict__.update(row)
186
+ return instance
187
+
188
+ @classmethod
189
+ def nek(cls, kolom, op, nilai=None):
190
+ table = Model.get_table_name(cls)
191
+ qb = ModelQueryBuilder(cls, table)
192
+ return qb.nek(kolom, op, nilai)
193
+
194
+ @classmethod
195
+ def neng(cls, kolom, op, nilai=None):
196
+ return cls.nek(kolom, op, nilai)
197
+
198
+
199
+ class ModelQueryBuilder(QueryBuilder):
200
+ def __init__(self, cls, table):
201
+ super().__init__(table)
202
+ self.cls = cls
203
+
204
+ def siji(self):
205
+ row = self.golek()
206
+ if not row:
207
+ return None
208
+ instance = self.cls() if isinstance(self.cls, NgapakClass) else self.cls.__new__(self.cls)
209
+ if isinstance(instance, NgapakInstance):
210
+ instance.fields.update(row)
211
+ else:
212
+ instance.__dict__.update(row)
213
+ return instance
214
+
215
+ def first(self):
216
+ return self.siji()
217
+
218
+ def kabeh(self):
219
+ rows = super().kabeh()
220
+ instances = []
221
+ for row in rows:
222
+ instance = self.cls() if isinstance(self.cls, NgapakClass) else self.cls.__new__(self.cls)
223
+ if isinstance(instance, NgapakInstance):
224
+ instance.fields.update(row)
225
+ else:
226
+ instance.__dict__.update(row)
227
+ instances.append(instance)
228
+ return instances
229
+
230
+ def all(self):
231
+ return self.kabeh()
232
+