2323 */
2424final class RecordManager
2525{
26+ private const ID_COLUMN = 'id ' ;
27+ private const DEFAULT_ALIAS = 't ' ;
28+ private const ALL_COLUMNS = '* ' ;
29+
2630 /**
2731 * Create RecordManager.
2832 */
@@ -33,83 +37,130 @@ public function __construct(
3337 ) {
3438 }
3539
40+ /**
41+ * Execute operations within a transaction
42+ *
43+ * @template T
44+ * @param callable(): T $callback
45+ * @return T
46+ * @throws \Exception
47+ */
48+ private function executeInTransaction (callable $ callback ): mixed
49+ {
50+ $ this ->connection ->beginTransaction ();
51+ try {
52+ $ result = $ callback ();
53+ $ this ->connection ->commit ();
54+ return $ result ;
55+ } catch (\Exception $ e ) {
56+ $ this ->connection ->rollBack ();
57+ throw $ e ;
58+ }
59+ }
60+
3661 /**
3762 * Create a new record.
3863 */
3964 public function insert (Model $ model ): mixed
4065 {
41- if ($ this ->config ->isUsingUUID ()) {
42- $ model ->set ('id ' , Uuid::uuid4 ()->toString ());
43- }
44- $ this ->connection ->insert ($ model ->getName (), $ model ->getSelfProperties ());
45- if ($ this ->config ->isUsingUUID ()) {
46- return $ model ->get ('id ' );
47- }
66+ return $ this ->executeInTransaction (function () use ($ model ) {
67+ if ($ this ->config ->isUsingUUID ()) {
68+ $ model ->set (self ::ID_COLUMN , Uuid::uuid4 ()->toString ());
69+ }
70+
71+ $ this ->connection ->insert (
72+ $ model ->getName (),
73+ $ model ->getSelfProperties ()
74+ );
75+
76+ if ($ this ->config ->isUsingUUID ()) {
77+ return $ model ->get (self ::ID_COLUMN );
78+ }
4879
49- return (int ) $ this ->connection ->lastInsertId ();
80+ return (int ) $ this ->connection ->lastInsertId ();
81+ });
5082 }
5183
5284 /**
5385 * Update a record.
5486 */
5587 public function update (Model $ model ): mixed
5688 {
57- $ this ->connection ->update ($ model ->getName (), $ model ->getSelfProperties (), ['id ' => $ model ->getId ()]);
58-
59- return $ model ->getId ();
89+ return $ this ->executeInTransaction (function () use ($ model ) {
90+ $ this ->connection ->update (
91+ $ model ->getName (),
92+ $ model ->getSelfProperties (),
93+ [self ::ID_COLUMN => $ model ->getId ()]
94+ );
95+ return $ model ->getId ();
96+ });
6097 }
6198
6299 /**
63100 * Delete a record.
64101 */
65102 public function delete (Model $ model ): mixed
66103 {
67- $ this ->connection ->delete ($ model ->getName (), ['id ' => $ model ->getId ()]);
68-
69- return $ model ->getId ();
104+ return $ this ->executeInTransaction (function () use ($ model ) {
105+ $ this ->connection ->delete (
106+ $ model ->getName (),
107+ [self ::ID_COLUMN => $ model ->getId ()]
108+ );
109+ return $ model ->getId ();
110+ });
70111 }
71112
72113 /**
73114 * Get single record by id.
74115 */
75116 public function getById (string $ table , mixed $ id ): ?Model
76117 {
77- $ query = (new QueryBuilder ($ this ->connection , $ this ->modelManager ))
78- ->select ('* ' )
79- ->from ($ table , 't ' )
80- ->where ('t.id = ? ' )
81- ->setParameter (0 , $ id );
82-
83- return $ query ->first ();
118+ return $ this ->executeInTransaction (function () use ($ table , $ id ) {
119+ return $ this ->createQueryBuilder ()
120+ ->select (self ::ALL_COLUMNS )
121+ ->from ($ table , self ::DEFAULT_ALIAS )
122+ ->where (self ::DEFAULT_ALIAS . '. ' . self ::ID_COLUMN . ' = ? ' )
123+ ->setParameter (0 , $ id )
124+ ->first ();
125+ });
84126 }
85127
86128 /**
87129 * Get all records.
88130 */
89131 public function getAll (string $ tableName ): Collection
90132 {
91- return (new QueryBuilder ($ this ->connection , $ this ->modelManager ))
92- ->select ('* ' )
93- ->from ($ tableName , 't ' )
94- ->get ();
133+ return $ this ->executeInTransaction (function () use ($ tableName ) {
134+ return $ this ->createQueryBuilder ()
135+ ->select (self ::ALL_COLUMNS )
136+ ->from ($ tableName , self ::DEFAULT_ALIAS )
137+ ->get ();
138+ });
139+ }
140+
141+ /**
142+ * Create a new QueryBuilder instance
143+ */
144+ private function createQueryBuilder (): QueryBuilder
145+ {
146+ return new QueryBuilder ($ this ->connection , $ this ->modelManager );
95147 }
96148
97149 /**
98- * get query builder from db.
150+ * Get query builder from db.
99151 */
100152 public function find (string $ name ): QueryBuilder
101153 {
102- return ( new QueryBuilder ( $ this ->connection , $ this -> modelManager ) )
103- ->select (' * ' )
104- ->from ($ name , ' t ' );
154+ return $ this ->createQueryBuilder ( )
155+ ->select (self :: ALL_COLUMNS )
156+ ->from ($ name , self :: DEFAULT_ALIAS );
105157 }
106158
107159 /**
108- * get query builder from db.
160+ * Get query builder from db.
109161 */
110162 public function select (string $ expression ): QueryBuilder
111163 {
112- return (new QueryBuilder ($ this ->connection , $ this ->modelManager ))
113- ->select ($ expression );
164+ return $ this ->createQueryBuilder ()->select ($ expression );
114165 }
115166}
0 commit comments