Class VariablePrefix
An example of a collision may be an input field (it will become a method parameter) which has the same name as a jOOQ table. In the query Graphitron may create an alias for this table, while also having a method parameter that inherits the name of the input field. Such code may result in uncompilable code at best or produce incorrect query results at worst.
The risk of collisions would be even higher for instance if the DB/GraphQL-domain was code-related. To prevent such issues we use variable prefixes for all variables in the generated code. These make it impossible to accidentally or intentionally produce naming collisions, given that the prefixes are not substrings of each other.
Here is a more rigorous explanation and proof for why this is needed:
Assume two variable names N and M (which are based on user-defined configuration beyond our control or other factors such as DB-schema).
These two variables exist in their corresponding namespaces with their own prefixes P and Q where P ≠ Q and where there exists no string S such that P = S + Q or Q = S + P.
Let us take a look at the possibilities:
1. No prefixes are applied. Here, a conflict immediately emerges in the case N = M. As such, this solution is unacceptable.
2. Prefixes are applied to only one namespace, P. This means that the resulting variable X in the code will be X = P + N.
One can easily engineer a problem case by assuming that M consists of two substrings concatenated such that M = P + N.
Since prefixes in the name space Q are not applied (are empty), we get that the generated variable Y will be Y = M = P + N = X, and so we have another collision.
Thus, this solution is also unacceptable.
3. Prefixes are applied for all namespaces. This time the generated variables will be X = P + N and Y = Q + M.
Let us disprove that there exist a case where X = Y. If X = Y, then P + N = Q + M. We have three possibilities:
* N = M results in P + N = Q + N and P = Q which is a contradiction with our premise P ≠ Q. So we have that N ≠ M.
* The next possibility is that the prefixes have the same length |P| = |Q|.
For this to be true and for the strings to still be equal, every character in P must match the one at the same index in Q, thus resulting in P = Q, contradicting P ≠ Q.
* Lastly, for |P| ≠ |Q| one of them must be shorter, so let us use |P| < |Q|. This would be equivalent for |Q| < |P|. Since P + N = Q + M, Q must use P as a prefix.
This means that Q = P + S where S is a non-empty string. This contradicts our second premise that there must not exist a string S such that P = S + Q or Q = S + P.
With this solution there can not exist a case where X = Y and variable naming collisions are impossible.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final Stringstatic final Stringstatic final Stringstatic final Stringstatic final Stringstatic final Stringstatic final Stringstatic final Stringstatic final Stringstatic final Stringstatic final Stringstatic final Stringstatic final Stringstatic final Stringstatic final String -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic StringaliasPrefix(String name) static StringcontextFieldPrefix(String name) static StringinputPrefix(String name) static StringinsertHelperPrefix(String name) static StringinternalPrefix(String name) static StringjoinStepPrefix(String name) static StringlistedOutputPrefix(String name) static Stringstatic StringnamedIteratorPrefix(String name) static StringoutputPrefix(String name) static StringprefixName(String prefix, String name) static StringqueryPrefix(String name) static StringresolverKeyPrefix(String name) static StringservicePrefix(String name) static StringsourcePrefix(String name)
-
Field Details
-
INTERNAL_VARIABLE
- See Also:
-
METHOD_INPUT
- See Also:
-
METHOD_OUTPUT
- See Also:
-
METHOD_LIST_OUTPUT
- See Also:
-
OPERATION_SOURCE
- See Also:
-
DATA_FETCHER_KEYS
- See Also:
-
DATA_FETCHER_SERVICE
- See Also:
-
DATA_FETCHER_QUERY
- See Also:
-
SELECT_JOIN_STEP
- See Also:
-
INSERT_HELPER
- See Also:
-
NAMED_ITERATOR
- See Also:
-
NAMED_ITERATOR_INDEX
- See Also:
-
ALIAS
- See Also:
-
CONTEXT_FIELD
- See Also:
-
SEPARATOR
- See Also:
-
-
Constructor Details
-
VariablePrefix
public VariablePrefix()
-
-
Method Details
-
internalPrefix
- Returns:
- This name formatted as an internal variable to avoid namespace collisions.
-
inputPrefix
- Returns:
- This name formatted as an input variable to avoid namespace collisions.
-
outputPrefix
- Returns:
- This name formatted as an output variable to avoid namespace collisions.
-
listedOutputPrefix
- Returns:
- This name formatted as a listed output variable to avoid namespace collisions.
-
sourcePrefix
- Returns:
- This name formatted as an operation source variable to avoid namespace collisions.
-
resolverKeyPrefix
- Returns:
- This name formatted as a resolver key variable to avoid namespace collisions.
-
aliasPrefix
- Returns:
- This name formatted as an alias variable to avoid namespace collisions.
-
contextFieldPrefix
- Returns:
- This name formatted as a context variable to avoid namespace collisions.
-
namedIteratorPrefix
- Returns:
- This name formatted as an iterator variable to avoid namespace collisions.
-
namedIndexIteratorPrefix
- Returns:
- This name formatted as an index iterator variable to avoid namespace collisions.
-
servicePrefix
- Returns:
- This name formatted as a service class object reference to avoid namespace collisions.
-
queryPrefix
- Returns:
- This name formatted as a query class object reference to avoid namespace collisions.
-
joinStepPrefix
- Returns:
- This name formatted as an operation query select join step variable to avoid namespace collisions.
-
insertHelperPrefix
- Returns:
- This name formatted as an insert mutation helpervariable to avoid namespace collisions.
-
prefixName
- Returns:
- This name prefixed with the provided prefix.
-