11package info .unterrainer .commons .httpserver .daos ;
22
33import java .time .LocalDateTime ;
4+ import java .util .HashMap ;
45import java .util .List ;
56import java .util .Map ;
67import java .util .Map .Entry ;
@@ -25,6 +26,8 @@ public class JpqlCoreDao<P extends BasicJpa> implements CoreDao<P, EntityManager
2526 protected final Class <P > type ;
2627 @ Getter
2728 protected JpqlTransactionManager transactionManager ;
29+ @ Getter
30+ protected TenantData tenantData ;
2831
2932 public JpqlCoreDao (final EntityManagerFactory emf , final Class <P > type ) {
3033 super ();
@@ -34,64 +37,75 @@ public JpqlCoreDao(final EntityManagerFactory emf, final Class<P> type) {
3437 }
3538
3639 @ Override
37- public P create (final EntityManager em , final P entity ) {
40+ public P create (final EntityManager em , final P entity , final Set < Long > tenantIds ) {
3841 LocalDateTime time = DateUtils .nowUtc ();
42+
43+ if (hasTenantData ())create entries ...
44+
3945 entity .setCreatedOn (time );
4046 entity .setEditedOn (time );
4147 em .persist (entity );
4248 return entity ;
4349 }
4450
4551 @ Override
46- public void delete (final EntityManager em , final Long id ) {
47- em .createQuery (String .format ("DELETE FROM %s AS o WHERE o.id = :id" , type .getSimpleName ()))
48- .setParameter ("id" , id )
49- .executeUpdate ();
52+ public void delete (final EntityManager em , final Long id , final Set <Long > tenantIds ) {
53+ Map <String , Object > params = new HashMap <>();
54+ params .put ("id" , id );
55+ params = addTenantParams (params , tenantIds );
56+ Query query = em .createQuery (
57+ String .format ("DELETE FROM %s AS o " + addTenantJoin (null ) + " WHERE " + addTenantWhere ("o.id = :id" ),
58+ type .getSimpleName ()));
59+ for (Entry <String , Object > entry : params .entrySet ())
60+ query .setParameter (entry .getKey (), entry .getValue ());
61+ query .executeUpdate ();
5062 }
5163
5264 @ Override
53- public P getById (final EntityManager em , final Long id ) {
65+ public P getById (final EntityManager em , final Long id , final Set < Long > tenantIds ) {
5466 try {
55- return getQuery (em , "o" , null , "o.id = :id" , Map .of ("id" , id ), type , null , false , null ).getSingleResult ();
67+ return getQuery (em , "o" , null , "o.id = :id" , Map .of ("id" , id ), type , null , false , null , tenantIds )
68+ .getSingleResult ();
5669 } catch (NoResultException e ) {
5770 return null ;
5871 }
5972 }
6073
6174 @ Override
6275 public ListJson <P > getList (final EntityManager em , final Long offset , final Long size , final String selectClause ,
63- final String joinClause , final String whereClause , final ParamMap params , final String orderByClause ) {
76+ final String joinClause , final String whereClause , final ParamMap params , final String orderByClause ,
77+ final Set <Long > tenantIds ) {
6478 ListJson <P > r = new ListJson <>();
65- r .setEntries (
66- getList (em ,
67- getQuery (em , selectClause , joinClause , whereClause ,
68- params == null ? null : params .getParameters (), type , orderByClause , false , null ),
69- offset , size ));
79+ r .setEntries (getList (em , getQuery (em , selectClause , joinClause , whereClause ,
80+ params == null ? null : params .getParameters (), type , orderByClause , false , null , tenantIds ), offset ,
81+ size ));
7082 r .setCount ((Long ) getCountQuery (em , selectClause , joinClause , whereClause ,
71- params == null ? null : params .getParameters (), null ).getSingleResult ());
83+ params == null ? null : params .getParameters (), null , tenantIds ).getSingleResult ());
7284 return r ;
7385 }
7486
7587 @ Override
76- public P update (final EntityManager em , final P entity ) {
88+ public P update (final EntityManager em , final P entity , final Set < Long > tenantIds ) {
7789 LocalDateTime time = DateUtils .nowUtc ();
7890 entity .setEditedOn (time );
7991 return em .merge (entity );
8092 }
8193
82- <T > TypedQuery <T > getQuery (final EntityManager em , final String selectClause , final String joinClause ,
83- final String whereClause , final Map <String , Object > params , final Class <T > type , final String orderBy ,
84- final boolean lockPessimistic , final Set <AsyncState > asyncStates ) {
94+ <T > TypedQuery <T > getQuery (final EntityManager em , final String selectClause , String joinClause , String whereClause ,
95+ Map <String , Object > params , final Class <T > type , final String orderBy , final boolean lockPessimistic ,
96+ final Set < AsyncState > asyncStates , final Set <Long > tenantIds ) {
8597 String query = "SELECT " ;
8698 if (selectClause == null || selectClause .isBlank ())
8799 query += "o" ;
88100 else
89101 query += selectClause ;
90102 query += " FROM %s AS o" ;
91103
104+ joinClause = addTenantJoin (joinClause );
92105 if (joinClause != null && !joinClause .isBlank ())
93106 query += " " + joinClause ;
94107
108+ whereClause = addTenantWhere (whereClause );
95109 query += buildWhereClause (whereClause , asyncStates );
96110
97111 if (orderBy == null )
@@ -110,20 +124,25 @@ else if (!orderBy.isBlank())
110124 if (lockPessimistic )
111125 q .setLockMode (LockModeType .PESSIMISTIC_WRITE );
112126 q = addAsyncStatesParamsToQuery (asyncStates , q );
127+
128+ params = addTenantParams (params , tenantIds );
113129 if (params != null )
114130 for (Entry <String , Object > e : params .entrySet ())
115131 q .setParameter (e .getKey (), e .getValue ());
116132 return q ;
117133 }
118134
119- <T > TypedQuery <T > getDeleteQuery (final EntityManager em , final String joinClause , final String whereClause ,
120- final Map <String , Object > params ) {
135+ <T > TypedQuery <T > getDeleteQuery (final EntityManager em , String joinClause , String whereClause ,
136+ Map <String , Object > params , final Set < Long > tenantIds ) {
121137 String query = "DELETE FROM %s AS o" ;
122138
139+ joinClause = addTenantJoin (joinClause );
123140 if (joinClause != null && !joinClause .isBlank ())
124141 query += " " + joinClause ;
125142
143+ whereClause = addTenantWhere (whereClause );
126144 query += buildWhereClause (whereClause , null );
145+ params = addTenantParams (params , tenantIds );
127146
128147 query = String .format (query , this .type .getSimpleName ());
129148
@@ -137,17 +156,22 @@ <T> TypedQuery<T> getDeleteQuery(final EntityManager em, final String joinClause
137156 return q ;
138157 }
139158
140- Query getCountQuery (final EntityManager em , final String selectClause , final String joinClause ,
141- final String whereClause , final Map <String , Object > params , final Set <AsyncState > asyncStates ) {
159+ Query getCountQuery (final EntityManager em , final String selectClause , String joinClause , String whereClause ,
160+ Map <String , Object > params , final Set <AsyncState > asyncStates , final Set < Long > tenantIds ) {
142161 String query = "SELECT COUNT(" ;
143162 if (selectClause == null || selectClause .isBlank ())
144163 query += "o.id" ;
145164 else
146165 query += selectClause ;
147166 query += ") FROM %s AS o" ;
167+
168+ joinClause = addTenantJoin (joinClause );
148169 if (joinClause != null && !joinClause .isBlank ())
149170 query += " " + joinClause ;
171+
172+ whereClause = addTenantWhere (whereClause );
150173 query += buildWhereClause (whereClause , asyncStates );
174+ params = addTenantParams (params , tenantIds );
151175
152176 Query q = em .createQuery (String .format (query , this .type .getSimpleName ()));
153177
@@ -170,18 +194,52 @@ <T> List<T> getList(final EntityManager em, final TypedQuery<T> query, final lon
170194 return query .getResultList ();
171195 }
172196
173- private boolean isAllowed (final EntityManager em , final TenantData tenantData ) {
174- TypedQuery <Long > query = getQuery (em , "o.id" ,
175- "RIGHT JOIN " + tenantData .getJpa ().getClass ().getSimpleName () + " tenantTable on o.id = tenantTable."
176- + tenantData .getReferenceField (),
177- "tenantTable." + tenantData .getReferenceField () + " IS NULL OR tenantTable." + tenantData .getIdField ()
178- + " = :tenantId" ,
179- null , Long .class , null , false , null );
197+ private boolean isAllowed (final EntityManager em , final Set <Long > tenantIds ) {
198+ if (!hasTenantData () || tenantIds == null || tenantIds .contains (null ))
199+ return true ;
200+ TypedQuery <Long > query = getQuery (em , "o.id" , null , null , null , Long .class , null , false , null , tenantIds );
180201 query .setMaxResults (1 );
181202 List <Long > list = query .getResultList ();
182203 return list != null && list .size () > 0 ;
183204 }
184205
206+ private String addTenantJoin (final String joinClause ) {
207+ if (!hasTenantData ())
208+ return joinClause ;
209+
210+ String r = joinClause ;
211+ if (joinClause == null || joinClause .isBlank ())
212+ r = "" ;
213+
214+ r += String .format (" LEFT JOIN %s tenantTable on o.id = tenantTable.%s" , tenantData .getType ().getSimpleName (),
215+ tenantData .getReferenceField ());
216+ return r ;
217+ }
218+
219+ private String addTenantWhere (final String whereClause ) {
220+ if (!hasTenantData ())
221+ return whereClause ;
222+
223+ String r = "" ;
224+ if (whereClause != null && !whereClause .isBlank ())
225+ r = "( " + whereClause + ") AND " ;
226+
227+ r += String .format ("( tenantTable.%1$s IS NULL OR tenantTable.%1$s IN (:tenantIds) )" , tenantData .getIdField ());
228+ return r ;
229+ }
230+
231+ private Map <String , Object > addTenantParams (final Map <String , Object > map , final Set <Long > tenantIds ) {
232+ if (!hasTenantData () || tenantIds .isEmpty ())
233+ return map ;
234+ map .put ("tenantIds" , tenantIds );
235+ return map ;
236+ }
237+
238+ private boolean hasTenantData () {
239+ return tenantData != null && tenantData .getType () != null && tenantData .getReferenceField () != null
240+ && tenantData .getIdField () != null ;
241+ }
242+
185243 private boolean isSet (final String str ) {
186244 return str != null && !str .isBlank ();
187245 }
0 commit comments