99 */
1010package net .sf .jsqlparser .statement .grant ;
1111
12- import java .util .AbstractList ;
1312import java .util .ArrayList ;
1413import java .util .Arrays ;
1514import java .util .Collection ;
1615import java .util .Collections ;
1716import java .util .List ;
18- import java .util .Optional ;
1917import java .util .function .Consumer ;
2018import java .util .stream .Collectors ;
2119import net .sf .jsqlparser .expression .Expression ;
2220import net .sf .jsqlparser .statement .Statement ;
2321import net .sf .jsqlparser .statement .StatementVisitor ;
22+ import net .sf .jsqlparser .statement .create .user .RoleSelection ;
2423
2524public class Grant implements Statement {
2625 private PrivilegeClause clause = new PrivilegeClause ();
27- private GrantOption option ;
26+ private final List <GrantOption > options = new ArrayList <>();
27+ private Grantee asUser ;
28+ private RoleSelection withRole ;
2829
2930 public PrivilegeClause getClause () {
3031 return clause ;
@@ -34,12 +35,46 @@ public void setClause(PrivilegeClause clause) {
3435 this .clause = clause ;
3536 }
3637
38+ /**
39+ * The {@code WITH} options as a mutable list: {@code GRANT OPTION}, {@code ADMIN OPTION} or
40+ * PostgreSQL membership options such as {@code INHERIT TRUE, SET FALSE}.
41+ */
42+ public List <GrantOption > getOptions () {
43+ return options ;
44+ }
45+
46+ public void setOptions (Collection <? extends GrantOption > options ) {
47+ List <GrantOption > copy = options == null ? new ArrayList <>() : new ArrayList <>(options );
48+ this .options .clear ();
49+ this .options .addAll (copy );
50+ }
51+
52+ /** The first {@code WITH} option, or null; see {@link #getOptions()}. */
3753 public GrantOption getOption () {
38- return option ;
54+ return options . isEmpty () ? null : options . get ( 0 ) ;
3955 }
4056
57+ /** Replaces all {@code WITH} options with the given option, or removes them for null. */
4158 public void setOption (GrantOption option ) {
42- this .option = option ;
59+ setOptions (option == null ? null : Collections .singletonList (option ));
60+ }
61+
62+ /** The MySQL {@code AS user} account, or null when omitted. */
63+ public Grantee getAsUser () {
64+ return asUser ;
65+ }
66+
67+ public void setAsUser (Grantee asUser ) {
68+ this .asUser = asUser ;
69+ }
70+
71+ /** The MySQL {@code WITH ROLE} selection of the {@code AS user} clause, or null. */
72+ public RoleSelection getWithRole () {
73+ return withRole ;
74+ }
75+
76+ public void setWithRole (RoleSelection withRole ) {
77+ this .withRole = withRole ;
4378 }
4479
4580 public List <Privilege > getPrivilegeItems () {
@@ -50,6 +85,7 @@ public void setPrivilegeItems(List<Privilege> privileges) {
5085 clause .setPrivileges (privileges );
5186 }
5287
88+ /** The target, or null for a role membership. */
5389 public PrivilegeTarget getTarget () {
5490 return clause .getTarget ();
5591 }
@@ -67,14 +103,16 @@ public void setRoles(List<String> roles) {
67103 }
68104
69105 public String getRole () {
70- return clause .getRoles ().isEmpty () ? null : clause .getRoles ().get (0 );
106+ return clause .getRoleItems ().isEmpty () ? null : clause .getRoles ().get (0 );
71107 }
72108
109+ /** Makes this a membership of the given role, which has neither privileges nor a target. */
73110 public void setRole (String role ) {
74111 clause .setRoles (new ArrayList <>());
75112 if (role != null ) {
76113 clause .getRoles ().add (role );
77114 clause .setPrivileges (null );
115+ clause .setTarget (null );
78116 }
79117 }
80118
@@ -83,32 +121,7 @@ public List<String> getPrivileges() {
83121 if (clause .getPrivileges () == null ) {
84122 return null ;
85123 }
86- return new AbstractList <String >() {
87- @ Override
88- public int size () {
89- return clause .getPrivileges ().size ();
90- }
91-
92- @ Override
93- public String get (int index ) {
94- return clause .getPrivileges ().get (index ).toString ();
95- }
96-
97- @ Override
98- public String set (int index , String value ) {
99- return clause .getPrivileges ().set (index , new Privilege (value )).toString ();
100- }
101-
102- @ Override
103- public void add (int index , String value ) {
104- clause .getPrivileges ().add (index , new Privilege (value ));
105- }
106-
107- @ Override
108- public String remove (int index ) {
109- return clause .getPrivileges ().remove (index ).toString ();
110- }
111- };
124+ return new StringListView <>(() -> clause .getPrivileges (), Privilege ::new );
112125 }
113126
114127 public void setPrivileges (List <String > privileges ) {
@@ -122,12 +135,22 @@ public void setPrivileges(List<String> privileges) {
122135 clause .setPrivileges (items );
123136 }
124137
138+ /**
139+ * The first named target as dotted text. MySQL wildcard levels keep their wildcard, for example
140+ * {@code db.*} or {@code *.*}.
141+ */
125142 public String getObjectName () {
126- if ( clause .getTarget (). getNames (). isEmpty ()
127- || clause . getTarget (). getNames (). get ( 0 ). isEmpty () ) {
143+ PrivilegeTarget target = clause .getTarget ();
144+ if ( target == null ) {
128145 return null ;
129146 }
130- List <String > parts = clause .getTarget ().getNames ().get (0 );
147+ if (target .getWildcard () != null ) {
148+ return target .getTargetText ();
149+ }
150+ if (target .getNames ().isEmpty () || target .getNames ().get (0 ).isEmpty ()) {
151+ return null ;
152+ }
153+ List <String > parts = target .getNames ().get (0 );
131154 return parts .stream ().map (part -> part == null ? "" : part )
132155 .collect (Collectors .joining ("." ));
133156 }
@@ -136,14 +159,19 @@ public void setObjectName(String objectName) {
136159 setObjectName (Collections .singletonList (objectName ));
137160 }
138161
162+ /** Names the first target, replacing a MySQL wildcard level. */
139163 public void setObjectName (List <String > objectName ) {
140164 List <String > parts = new ArrayList <>(objectName );
141165 getObjectNameParts ().clear ();
142166 getObjectNameParts ().addAll (parts );
167+ clause .getTarget ().setWildcard (null );
143168 }
144169
145170 /** Mutable parts of the first named target, retained for compatibility. */
146171 public List <String > getObjectNameParts () {
172+ if (clause .getTarget () == null ) {
173+ clause .setTarget (new PrivilegeTarget ());
174+ }
147175 if (clause .getTarget ().getNames ().isEmpty ()) {
148176 clause .getTarget ().getNames ().add (new ArrayList <>());
149177 }
@@ -161,11 +189,18 @@ public void setUsers(List<String> users) {
161189 public void appendTo (StringBuilder sql , Consumer <Expression > visitor ) {
162190 sql .append ("GRANT " );
163191 clause .appendTo (sql , false , visitor );
164- if (option != null ) {
165- sql .append (" WITH " ).append (option );
192+ if (!options .isEmpty ()) {
193+ sql .append (" WITH " ).append (
194+ options .stream ().map (Object ::toString ).collect (Collectors .joining (", " )));
195+ }
196+ if (asUser != null ) {
197+ sql .append (" AS " ).append (asUser );
198+ if (withRole != null ) {
199+ sql .append (" WITH ROLE " ).append (withRole );
200+ }
166201 }
167- if (clause .getGrantedBy () != null ) {
168- sql .append (" GRANTED BY " ).append (clause .getGrantedBy ());
202+ if (clause .getGrantor () != null ) {
203+ sql .append (" GRANTED BY " ).append (clause .getGrantor ());
169204 }
170205 }
171206
@@ -222,14 +257,17 @@ public Grant addPrivileges(Collection<String> privileges) {
222257 }
223258
224259 public Grant addUsers (String ... users ) {
225- List <String > collection = Optional .ofNullable (getUsers ()).orElseGet (ArrayList ::new );
226- Collections .addAll (collection , users );
227- return this .withUsers (collection );
260+ return addUsers (Arrays .asList (users ));
228261 }
229262
230263 public Grant addUsers (Collection <String > users ) {
231- List <String > collection = Optional .ofNullable (getUsers ()).orElseGet (ArrayList ::new );
232- collection .addAll (users );
233- return this .withUsers (collection );
264+ List <String > additions = new ArrayList <>(users );
265+ if (clause .getGranteeItems () == null ) {
266+ clause .setGranteeItems (new ArrayList <>());
267+ }
268+ for (String user : additions ) {
269+ clause .getGranteeItems ().add (Grantee .valueOf (user ));
270+ }
271+ return this ;
234272 }
235273}
0 commit comments