diff --git a/src/main/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlFileToAnnotationAction.kt b/src/main/kotlin/org/domaframework/doma/intellij/action/dao/AbstractConvertSqlFileToAnnotationAction.kt similarity index 50% rename from src/main/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlFileToAnnotationAction.kt rename to src/main/kotlin/org/domaframework/doma/intellij/action/dao/AbstractConvertSqlFileToAnnotationAction.kt index a3589d5e..daf19cb8 100644 --- a/src/main/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlFileToAnnotationAction.kt +++ b/src/main/kotlin/org/domaframework/doma/intellij/action/dao/AbstractConvertSqlFileToAnnotationAction.kt @@ -22,55 +22,40 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import com.intellij.psi.PsiMethod -import com.intellij.psi.util.PsiTreeUtil -import org.domaframework.doma.intellij.bundle.MessageBundle -import org.domaframework.doma.intellij.common.dao.findDaoMethod -import org.domaframework.doma.intellij.common.dao.getDaoClass -import org.domaframework.doma.intellij.common.isJavaOrKotlinFileType -import org.domaframework.doma.intellij.common.isSupportFileType import org.domaframework.doma.intellij.common.psi.PsiDaoMethod import org.domaframework.doma.intellij.common.util.PluginLoggerUtil /** - * Intention action to convert SQL file to @Sql annotation + * Abstract base class for converting SQL file to @Sql annotation */ -class ConvertSqlFileToAnnotationAction : PsiElementBaseIntentionAction() { - override fun getFamilyName(): String = MessageBundle.message("convert.sql.file.to.annotation.family") - - override fun getText(): String = MessageBundle.message("convert.sql.file.to.annotation.text") - +abstract class AbstractConvertSqlFileToAnnotationAction : PsiElementBaseIntentionAction() { override fun isAvailable( project: Project, editor: Editor?, element: PsiElement, ): Boolean { - val file = element.containingFile ?: return false - if (isJavaOrKotlinFileType(file) && getDaoClass(file) != null) { - return checkOnMethod(element, project) - } - - if (isSupportFileType(file)) { - return checkOnSqlFile(element, project) + if (!isTargetFile(element)) { + return false } - return false - } - - private fun checkOnMethod( - element: PsiElement, - project: Project, - ): Boolean { - val daoMethod = PsiTreeUtil.getParentOfType(element, PsiMethod::class.java) ?: return false + val daoMethod = getDaoMethod(element) ?: return false return checkAvailable(project, daoMethod) } - private fun checkOnSqlFile( - element: PsiElement, - project: Project, - ): Boolean { - val daoMethod = findDaoMethod(element.containingFile) ?: return false - return checkAvailable(project, daoMethod) - } + /** + * Check if the element is in a target file type for this action + */ + protected abstract fun isTargetFile(element: PsiElement): Boolean + + /** + * Get the DAO method from the element + */ + protected abstract fun getDaoMethod(element: PsiElement): PsiMethod? + + /** + * Get the action name for logging + */ + protected abstract fun getActionName(): String private fun checkAvailable( project: Project, @@ -101,42 +86,7 @@ class ConvertSqlFileToAnnotationAction : PsiElementBaseIntentionAction() { // Do nothing when previewing if (IntentionPreviewUtils.isIntentionPreviewActive()) return - val file = element.containingFile - if (isJavaOrKotlinFileType(file)) { - return processOnMethod(element, project) - } - - // Process if the file type is SQL - if (isSupportFileType(file)) { - return processOnSqlFile(element, project) - } - } - - private fun processOnMethod( - element: PsiElement, - project: Project, - ) { - val daoMethod = PsiTreeUtil.getParentOfType(element, PsiMethod::class.java) ?: return - - val startTime = System.nanoTime() - val converter = SqlAnnotationConverter(project, daoMethod) - WriteCommandAction.runWriteCommandAction(project) { - converter.convertToSqlAnnotation() - } - - PluginLoggerUtil.countLogging( - className = this::class.java.simpleName, - actionName = "convertSqlFileToAnnotationOnMethod", - inputName = "IntentionAction", - start = startTime, - ) - } - - private fun processOnSqlFile( - element: PsiElement, - project: Project, - ) { - val daoMethod = findDaoMethod(element.containingFile) ?: return + val daoMethod = getDaoMethod(element) ?: return val startTime = System.nanoTime() val converter = SqlAnnotationConverter(project, daoMethod) @@ -146,7 +96,7 @@ class ConvertSqlFileToAnnotationAction : PsiElementBaseIntentionAction() { PluginLoggerUtil.countLogging( className = this::class.java.simpleName, - actionName = "convertSqlFileToAnnotationOnSQL", + actionName = getActionName(), inputName = "IntentionAction", start = startTime, ) diff --git a/src/main/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlFileToAnnotationFromDaoAction.kt b/src/main/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlFileToAnnotationFromDaoAction.kt new file mode 100644 index 00000000..ae30f534 --- /dev/null +++ b/src/main/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlFileToAnnotationFromDaoAction.kt @@ -0,0 +1,41 @@ +/* + * Copyright Doma Tools Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.domaframework.doma.intellij.action.dao + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod +import com.intellij.psi.util.PsiTreeUtil +import org.domaframework.doma.intellij.bundle.MessageBundle +import org.domaframework.doma.intellij.common.dao.getDaoClass +import org.domaframework.doma.intellij.common.isJavaOrKotlinFileType + +/** + * Intention action to convert SQL file to @Sql annotation from DAO files + */ +class ConvertSqlFileToAnnotationFromDaoAction : AbstractConvertSqlFileToAnnotationAction() { + override fun getFamilyName(): String = MessageBundle.message("convert.sql.file.to.annotation.from.dao.family") + + override fun getText(): String = MessageBundle.message("convert.sql.file.to.annotation.from.dao.text") + + override fun isTargetFile(element: PsiElement): Boolean { + val file = element.containingFile ?: return false + return isJavaOrKotlinFileType(file) && getDaoClass(file) != null + } + + override fun getDaoMethod(element: PsiElement): PsiMethod? = PsiTreeUtil.getParentOfType(element, PsiMethod::class.java) + + override fun getActionName(): String = "convertSqlFileToAnnotationFromDao" +} diff --git a/src/main/kotlin/org/domaframework/doma/intellij/action/sql/ConvertSqlFileToAnnotationFromSqlAction.kt b/src/main/kotlin/org/domaframework/doma/intellij/action/sql/ConvertSqlFileToAnnotationFromSqlAction.kt new file mode 100644 index 00000000..5424188a --- /dev/null +++ b/src/main/kotlin/org/domaframework/doma/intellij/action/sql/ConvertSqlFileToAnnotationFromSqlAction.kt @@ -0,0 +1,41 @@ +/* + * Copyright Doma Tools Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.domaframework.doma.intellij.action.sql + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod +import org.domaframework.doma.intellij.action.dao.AbstractConvertSqlFileToAnnotationAction +import org.domaframework.doma.intellij.bundle.MessageBundle +import org.domaframework.doma.intellij.common.dao.findDaoMethod +import org.domaframework.doma.intellij.common.isSupportFileType + +/** + * Intention action to convert SQL file to @Sql annotation from SQL files + */ +class ConvertSqlFileToAnnotationFromSqlAction : AbstractConvertSqlFileToAnnotationAction() { + override fun getFamilyName(): String = MessageBundle.message("convert.sql.file.to.annotation.from.sql.family") + + override fun getText(): String = MessageBundle.message("convert.sql.file.to.annotation.from.sql.text") + + override fun isTargetFile(element: PsiElement): Boolean { + val file = element.containingFile ?: return false + return isSupportFileType(file) + } + + override fun getDaoMethod(element: PsiElement): PsiMethod? = findDaoMethod(element.containingFile) + + override fun getActionName(): String = "convertSqlFileToAnnotationFromSql" +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index c90dbae8..eeecc60f 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -102,13 +102,13 @@ DomaSql - org.domaframework.doma.intellij.action.dao.ConvertSqlFileToAnnotationAction + org.domaframework.doma.intellij.action.sql.ConvertSqlFileToAnnotationFromSqlAction Doma tools true JAVA - org.domaframework.doma.intellij.action.dao.ConvertSqlFileToAnnotationAction + org.domaframework.doma.intellij.action.dao.ConvertSqlFileToAnnotationFromDaoAction Doma tools true diff --git a/src/main/resources/intentionDescriptions/ConvertSqlFileToAnnotationAction/description.html b/src/main/resources/intentionDescriptions/ConvertSqlFileToAnnotationAction/description.html deleted file mode 100644 index 082a1a46..00000000 --- a/src/main/resources/intentionDescriptions/ConvertSqlFileToAnnotationAction/description.html +++ /dev/null @@ -1,9 +0,0 @@ - - -

-This action converts SQL statements from SQL files into Sql annotations for DAO methods.
-By selecting an SQL file and executing the action, the corresponding SQL will be embedded as an annotation in the appropriate DAO method.
-This makes it easier to manage SQL directly within the source code and improves code readability and maintainability. -

- - \ No newline at end of file diff --git a/src/main/resources/intentionDescriptions/ConvertSqlFileToAnnotationFromDaoAction/description.html b/src/main/resources/intentionDescriptions/ConvertSqlFileToAnnotationFromDaoAction/description.html new file mode 100644 index 00000000..d1bd8a86 --- /dev/null +++ b/src/main/resources/intentionDescriptions/ConvertSqlFileToAnnotationFromDaoAction/description.html @@ -0,0 +1,9 @@ + + +

+ This action converts SQL statements from SQL files into Sql annotations for DAO methods.
+ By selecting a DAO method and executing the action, the corresponding SQL will be embedded as an annotation in the appropriate DAO method.
+ This makes it easier to manage SQL directly within the source code and improves code readability and maintainability. +

+ + \ No newline at end of file diff --git a/src/main/resources/intentionDescriptions/ConvertSqlFileToAnnotationFromSqlAction/description.html b/src/main/resources/intentionDescriptions/ConvertSqlFileToAnnotationFromSqlAction/description.html new file mode 100644 index 00000000..a02dbead --- /dev/null +++ b/src/main/resources/intentionDescriptions/ConvertSqlFileToAnnotationFromSqlAction/description.html @@ -0,0 +1,9 @@ + + +

+ This action converts SQL statements from SQL files into Sql annotations for DAO methods.
+ By selecting an SQL file and executing the action, the corresponding SQL will be embedded as an annotation in the appropriate DAO method.
+ This makes it easier to manage SQL directly within the source code and improves code readability and maintainability. +

+ + \ No newline at end of file diff --git a/src/main/resources/messages/DomaToolsBundle.properties b/src/main/resources/messages/DomaToolsBundle.properties index 52d39b7b..37c85408 100644 --- a/src/main/resources/messages/DomaToolsBundle.properties +++ b/src/main/resources/messages/DomaToolsBundle.properties @@ -41,7 +41,9 @@ inspection.invalid.dao.annotation.option.embeddable=Field [{0}] specified in [{1 inspection.invalid.dao.annotation.option.primitive=Field path [{0}] specified in [{2}] option is invalid. Field [{1}] is a primitive type and does not have nested properties convert.sql.annotation.to.file.family=Convert @Sql annotation to SQL file convert.sql.annotation.to.file.text=Convert to SQL file (set sqlFile=true) -convert.sql.file.to.annotation.family=Convert SQL file to @Sql annotation -convert.sql.file.to.annotation.text=Convert to @Sql annotation (set sqlFile=false) +convert.sql.file.to.annotation.from.dao.family=Convert SQL file to @Sql annotation +convert.sql.file.to.annotation.from.dao.text=Convert SQL file to @Sql annotation +convert.sql.file.to.annotation.from.sql.family=Convert to @Sql annotation +convert.sql.file.to.annotation.from.sql.text=Convert to @Sql annotation in DAO method inspection.invalid.sql.function.call.parameter.count=Function {0} definition with {1} parameters not found inspection.invalid.sql.function.call.parameter.type.mismatch=Function {0} parameter type mismatch. Actual types: ({1})
Definition candidates:
{2} \ No newline at end of file diff --git a/src/main/resources/messages/DomaToolsBundle_ja.properties b/src/main/resources/messages/DomaToolsBundle_ja.properties index 46393dd8..229311aa 100644 --- a/src/main/resources/messages/DomaToolsBundle_ja.properties +++ b/src/main/resources/messages/DomaToolsBundle_ja.properties @@ -41,7 +41,9 @@ inspection.invalid.dao.annotation.option.embeddable=[{1}]\u30AA\u30D7\u30B7\u30E inspection.invalid.dao.annotation.option.primitive=[{2}]\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u6307\u5B9A\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30EB\u30C9\u30D1\u30B9[{0}]\u306F\u7121\u52B9\u3067\u3059\u3002\u30D5\u30A3\u30FC\u30EB\u30C9[{1}]\u306F\u30D7\u30EA\u30DF\u30C6\u30A3\u30D6\u578B\u3067\u3042\u308A\u3001\u30CD\u30B9\u30C8\u3055\u308C\u305F\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u6301\u3061\u307E\u305B\u3093 convert.sql.annotation.to.file.family=@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u3092SQL\u30D5\u30A1\u30A4\u30EB\u306B\u5909\u63DB convert.sql.annotation.to.file.text=SQL\u30D5\u30A1\u30A4\u30EB\u306B\u5909\u63DB (sqlFile=true\u306B\u8A2D\u5B9A) -convert.sql.file.to.annotation.family=SQL\u30D5\u30A1\u30A4\u30EB\u3092@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u5909\u63DB -convert.sql.file.to.annotation.text=@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u5909\u63DB (sqlFile=false\u306B\u8A2D\u5B9A) +convert.sql.file.to.annotation.from.dao.family=SQL\u30D5\u30A1\u30A4\u30EB\u3092@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u5909\u63DB +convert.sql.file.to.annotation.from.dao.text=@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u5909\u63DB (sqlFile=false\u306B\u8A2D\u5B9A) +convert.sql.file.to.annotation.from.sql.family=SQL\u30D5\u30A1\u30A4\u30EB\u3092@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u5909\u63DB +convert.sql.file.to.annotation.from.sql.text=@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u5909\u63DB (sqlFile=false\u306B\u8A2D\u5B9A) inspection.invalid.sql.function.call.parameter.count=\u95a2\u6570{0}\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u6570\u304c{1}\u306e\u5b9a\u7fa9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093 inspection.invalid.sql.function.call.parameter.type.mismatch=\u95a2\u6570{0}\u306e\u5f15\u6570\u306e\u578b\u304c\u4e00\u81f4\u3057\u307e\u305b\u3093\u3002\u5b9f\u969b\u306e\u578b: ({1})
\u5b9a\u7fa9\u5019\u88dc:
{2} \ No newline at end of file diff --git a/src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlActionTest.kt b/src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlActionTest.kt index 133ad96a..bed0ea05 100644 --- a/src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlActionTest.kt +++ b/src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlActionTest.kt @@ -19,6 +19,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.psi.PsiDocumentManager import org.domaframework.doma.intellij.DomaSqlTest +import kotlin.reflect.KClass abstract class ConvertSqlActionTest : DomaSqlTest() { protected fun doConvertAction( @@ -45,17 +46,18 @@ abstract class ConvertSqlActionTest : DomaSqlTest() { myFixture.checkResultByFile("java/doma/example/dao/$sqlConversionPackage/$daoName.after.java") } - protected fun doConvertActionTest( + protected fun doConvertActionTest( daoName: String, sqlToAnnotationPackage: String, convertFamilyName: String, + convertActionClass: KClass, ) { addDaoJavaFile("$sqlToAnnotationPackage/$daoName.java") val daoClass = findDaoClass("$sqlToAnnotationPackage.$daoName") myFixture.configureFromExistingVirtualFile(daoClass.containingFile.virtualFile) val intentions = myFixture.availableIntentions - val convertIntention = intentions.find { it is ConvertSqlFileToAnnotationAction } + val convertIntention = intentions.find { convertActionClass.java.isInstance(it) } assertNull("$convertFamilyName intention should NOT be available without @Sql annotation", convertIntention) } diff --git a/src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlAnnotationToFileActionTest.kt b/src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlAnnotationToFileActionTest.kt index 58cd7d97..408b730d 100644 --- a/src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlAnnotationToFileActionTest.kt +++ b/src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlAnnotationToFileActionTest.kt @@ -16,11 +16,12 @@ package org.domaframework.doma.intellij.action.dao import com.intellij.openapi.fileEditor.FileEditorManager +import org.domaframework.doma.intellij.bundle.MessageBundle class ConvertSqlAnnotationToFileActionTest : ConvertSqlActionTest() { private val sqlConversionPackage = "sqltofile" - private val convertActionName = "Convert to SQL file (set sqlFile=true)" - private val convertFamilyName = "Convert @Sql annotation to SQL file" + private val convertActionName = MessageBundle.message("convert.sql.annotation.to.file.text") + private val convertFamilyName = MessageBundle.message("convert.sql.annotation.to.file.family") fun testIntentionAvailableForSelectWithSqlAnnotation() { val daoName = "SelectWithSqlAnnotationDao" @@ -109,12 +110,12 @@ class ConvertSqlAnnotationToFileActionTest : ConvertSqlActionTest() { fun testIntentionNotAvailableForMethodWithoutSqlAnnotation() { val daoName = "NoSqlAnnotationDao" - doConvertActionTest(daoName, sqlConversionPackage, convertFamilyName) + doConvertActionTest(daoName, sqlConversionPackage, convertFamilyName, ConvertSqlFileToAnnotationFromDaoAction::class) } fun testIntentionNotAvailableForUnsupportedAnnotation() { val daoName = "UnsupportedAnnotationDao" - doConvertActionTest(daoName, sqlConversionPackage, convertFamilyName) + doConvertActionTest(daoName, sqlConversionPackage, convertFamilyName, ConvertSqlFileToAnnotationFromDaoAction::class) } private fun doTest( diff --git a/src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlFileToAnnotationActionTest.kt b/src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlFileToAnnotationActionTest.kt index f48c6c7d..07f05ed1 100644 --- a/src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlFileToAnnotationActionTest.kt +++ b/src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlFileToAnnotationActionTest.kt @@ -17,11 +17,13 @@ package org.domaframework.doma.intellij.action.dao import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.psi.PsiDocumentManager +import org.domaframework.doma.intellij.action.sql.ConvertSqlFileToAnnotationFromSqlAction +import org.domaframework.doma.intellij.bundle.MessageBundle class ConvertSqlFileToAnnotationActionTest : ConvertSqlActionTest() { private val sqlToAnnotationPackage = "sqltoannotation" - private val convertActionName = "Convert to @Sql annotation (set sqlFile=false)" - private val convertFamilyName = "Convert SQL file to @Sql annotation" + private val convertActionName = MessageBundle.message("convert.sql.file.to.annotation.from.sql.text") + private val convertFamilyName = MessageBundle.message("convert.sql.file.to.annotation.from.sql.family") fun testIntentionAvailableForSelectWithSqlFile() { val daoName = "SelectWithSqlFileDao" @@ -84,7 +86,7 @@ class ConvertSqlFileToAnnotationActionTest : ConvertSqlActionTest() { myFixture.configureFromExistingVirtualFile(daoClass.containingFile.virtualFile) val intentions = myFixture.availableIntentions - val convertIntention = intentions.find { it is ConvertSqlFileToAnnotationAction } + val convertIntention = intentions.find { it is ConvertSqlFileToAnnotationFromSqlAction } assertNull( "$convertFamilyName intention should NOT be available when @Sql annotation already exists", @@ -99,9 +101,12 @@ class ConvertSqlFileToAnnotationActionTest : ConvertSqlActionTest() { myFixture.configureFromExistingVirtualFile(daoClass.containingFile.virtualFile) val intentions = myFixture.availableIntentions - val convertIntention = intentions.find { it is ConvertSqlFileToAnnotationAction } + val convertIntention = intentions.find { it is ConvertSqlFileToAnnotationFromSqlAction } - assertNull("$convertFamilyName intention should NOT be available when SQL file doesn't exist", convertIntention) + assertNull( + "$convertFamilyName intention should NOT be available when SQL file doesn't exist", + convertIntention, + ) } fun testSqlFormattingInAnnotation() { @@ -113,7 +118,12 @@ class ConvertSqlFileToAnnotationActionTest : ConvertSqlActionTest() { fun testSelectWithSqlFileConvertAnnotation() { val daoName = "SelectWithSqlFileConvertAnnotationDao" val sqlFileName = "selectEmployee.sql" - doConvertActionTest(daoName, sqlToAnnotationPackage, convertFamilyName) + doConvertActionTest( + daoName, + sqlToAnnotationPackage, + convertFamilyName, + ConvertSqlFileToAnnotationFromDaoAction::class, + ) // Test SQL File Removed val generatedSql = findSqlFile("$sqlToAnnotationPackage/$daoName/$sqlFileName") assertTrue("SQL File [$sqlFileName] should exists ", generatedSql == null)