diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 3aff78a71b8..dc95f1f11ae 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -78,7 +78,7 @@ ext.deps = [ intellijJavaPlugin: fileTree(dir: "$rootDir/lib/intellij-core/plugins/java/lib", include: [ 'java-api.jar', ]), - sqlitePsi: "com.alecstrong:sqlite-psi-core:0.2.4", + sqlitePsi: "com.alecstrong:sqlite-psi-core:0.3.0", moshi: "com.squareup.moshi:moshi:$versions.moshi", moshiKotlinCodegen: "com.squareup.moshi:moshi-kotlin-codegen:$versions.moshi", sqliteJdbc: "org.xerial:sqlite-jdbc:3.21.0.1", diff --git a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightEnvironment.kt b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightEnvironment.kt index 43ad59fc329..56fd4d10af9 100644 --- a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightEnvironment.kt +++ b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightEnvironment.kt @@ -18,6 +18,7 @@ package com.squareup.sqldelight.core import com.alecstrong.sql.psi.core.DialectPreset import com.alecstrong.sql.psi.core.SqlAnnotationHolder import com.alecstrong.sql.psi.core.SqlCoreEnvironment +import com.alecstrong.sql.psi.core.SqlFileBase import com.alecstrong.sql.psi.core.psi.SqlCreateTableStmt import com.alecstrong.sql.psi.core.psi.SqlStmt import com.intellij.mock.MockModule @@ -132,6 +133,14 @@ class SqlDelightEnvironment( return CompilationStatus.Success() } + override fun forSourceFiles(action: (SqlFileBase) -> Unit) { + super.forSourceFiles { file -> + if (file.fileType == SqlDelightFileType || properties.deriveSchemaFromMigrations) { + action(file) + } + } + } + fun forMigrationFiles(body: (MigrationFile) -> Unit) { val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) val psiManager = PsiManager.getInstance(projectEnvironment.project) @@ -262,6 +271,11 @@ class SqlDelightEnvironment( return@lazy virtualDirectories.map { psiManager.findDirectory(it)!! } } + override fun ordering(file: MigrationFile): Int? { + if (!properties.deriveSchemaFromMigrations) return null + return file.virtualFile.nameWithoutExtension.filter { it in '0'..'9' }.toInt() + } + override fun packageName(file: SqlDelightFile): String { fun PsiFileSystemItem.relativePathUnder(ancestor: PsiDirectory): List? { if (this.virtualFile.path == ancestor.virtualFile.path) return emptyList() diff --git a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightFileIndex.kt b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightFileIndex.kt index 940eca09193..2f08d22f2a5 100644 --- a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightFileIndex.kt +++ b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightFileIndex.kt @@ -24,6 +24,7 @@ import com.intellij.openapi.vfs.VirtualFileFilter import com.intellij.psi.PsiDirectory import com.intellij.psi.PsiManager import com.intellij.psi.impl.PsiManagerEx +import com.squareup.sqldelight.core.lang.MigrationFile import com.squareup.sqldelight.core.lang.SqlDelightFile import com.squareup.sqldelight.core.lang.SqlDelightFileType @@ -60,6 +61,11 @@ interface SqlDelightFileIndex { */ val contentRoot: VirtualFile + /** + * @return The integer ordering this migration file will be run in. + */ + fun ordering(file: MigrationFile): Int? + /** * @return The package name for a given SqlDelight file. Equal to the relative path under its * fixture's sqldelight directory. diff --git a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightFileIndexImpl.kt b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightFileIndexImpl.kt index 04caa910164..398e0b88bd0 100644 --- a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightFileIndexImpl.kt +++ b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightFileIndexImpl.kt @@ -1,6 +1,7 @@ package com.squareup.sqldelight.core import com.intellij.openapi.vfs.VirtualFile +import com.squareup.sqldelight.core.lang.MigrationFile import com.squareup.sqldelight.core.lang.SqlDelightFile class SqlDelightFileIndexImpl : SqlDelightFileIndex { @@ -16,6 +17,7 @@ class SqlDelightFileIndexImpl : SqlDelightFileIndex { get() = throw UnsupportedOperationException() override val dependencies: List get() = throw UnsupportedOperationException() + override fun ordering(file: MigrationFile) = throw UnsupportedOperationException() override fun packageName(file: SqlDelightFile) = throw UnsupportedOperationException() override fun sourceFolders( file: VirtualFile, diff --git a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightPropertiesFile.kt b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightPropertiesFile.kt index 50b6ec355d1..f4591d13e49 100644 --- a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightPropertiesFile.kt +++ b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/SqlDelightPropertiesFile.kt @@ -50,7 +50,8 @@ data class SqlDelightDatabaseProperties( val outputDirectory: String, val className: String, val dependencies: List, - val dialectPreset: DialectPreset = DialectPreset.SQLITE_3_18 + val dialectPreset: DialectPreset = DialectPreset.SQLITE_3_18, + val deriveSchemaFromMigrations: Boolean = false ) { fun toJson(): String { return adapter.toJson(this) diff --git a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/lang/MigrationFile.kt b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/lang/MigrationFile.kt index 2d3804e1dd1..8271114e745 100644 --- a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/lang/MigrationFile.kt +++ b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/lang/MigrationFile.kt @@ -13,5 +13,7 @@ class MigrationFile( override val packageName = SqlDelightFileIndex.getInstance(module).packageName + override val order = SqlDelightFileIndex.getInstance(module).ordering(this) + override fun getFileType() = MigrationFileType } diff --git a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/lang/SqlDelightQueriesFile.kt b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/lang/SqlDelightQueriesFile.kt index 1de01335e29..a7497a0d676 100644 --- a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/lang/SqlDelightQueriesFile.kt +++ b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/lang/SqlDelightQueriesFile.kt @@ -21,7 +21,6 @@ import com.alecstrong.sql.psi.core.psi.SqlAnnotatedElement import com.alecstrong.sql.psi.core.psi.SqlStmt import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.FileViewProvider -import com.intellij.psi.PsiFile import com.intellij.psi.util.PsiTreeUtil import com.squareup.sqldelight.core.SqlDelightFileIndex import com.squareup.sqldelight.core.compiler.model.NamedExecute @@ -68,7 +67,9 @@ class SqlDelightQueriesFile( .map { NamedExecute(it.identifier, it.statement) } } - internal val triggers by lazy { triggers() } + internal val triggers by lazy { triggers(this) } + + override val order = null override fun getVirtualFile(): VirtualFile? { if (myOriginalFile != null) return myOriginalFile.virtualFile @@ -84,7 +85,7 @@ class SqlDelightQueriesFile( } } - public override fun iterateSqlFiles(iterator: (PsiFile) -> Boolean) { + public override fun iterateSqlFiles(iterator: (SqlFileBase) -> Boolean) { val sourceFolders = SqlDelightFileIndex.getInstance(module).sourceFolders(this) if (sourceFolders.isEmpty()) { iterator(this) @@ -93,6 +94,7 @@ class SqlDelightQueriesFile( sourceFolders.forEach { sqldelightDirectory -> if (!PsiTreeUtil.findChildrenOfAnyType(sqldelightDirectory, SqlFileBase::class.java) .all { + if (it is MigrationFile && it.order == null) return@all true if (originalFile == it) { iterator(this@SqlDelightQueriesFile) } else { diff --git a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/lang/psi/sqlTypeName.kt b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/lang/psi/sqlTypeName.kt index f9c24121565..014048976f2 100644 --- a/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/lang/psi/sqlTypeName.kt +++ b/sqldelight-compiler/src/main/kotlin/com/squareup/sqldelight/core/lang/psi/sqlTypeName.kt @@ -44,7 +44,8 @@ private fun MySqlTypeName.type(): IntermediateType { bigIntDataType != null -> IntermediateType(IntermediateType.SqliteType.INTEGER, LONG) fixedPointDataType != null -> IntermediateType(IntermediateType.SqliteType.INTEGER) jsonDataType != null -> IntermediateType(IntermediateType.SqliteType.TEXT) - stringDataType != null -> IntermediateType(IntermediateType.SqliteType.TEXT) + enumSetType != null -> IntermediateType(IntermediateType.SqliteType.TEXT) + characterType != null -> IntermediateType(IntermediateType.SqliteType.TEXT) else -> throw AssertionError("Unknown kotlin type for sql type $this") } } diff --git a/sqldelight-idea-plugin/src/main/kotlin/com/squareup/sqldelight/intellij/FileIndex.kt b/sqldelight-idea-plugin/src/main/kotlin/com/squareup/sqldelight/intellij/FileIndex.kt index f5f75c8c4a7..078c0da87c1 100644 --- a/sqldelight-idea-plugin/src/main/kotlin/com/squareup/sqldelight/intellij/FileIndex.kt +++ b/sqldelight-idea-plugin/src/main/kotlin/com/squareup/sqldelight/intellij/FileIndex.kt @@ -20,6 +20,7 @@ import com.intellij.psi.PsiDirectory import com.intellij.psi.util.PsiTreeUtil import com.squareup.sqldelight.core.SqlDelightDatabaseProperties import com.squareup.sqldelight.core.SqlDelightFileIndex +import com.squareup.sqldelight.core.lang.MigrationFile import com.squareup.sqldelight.core.lang.SqlDelightFile import com.squareup.sqldelight.intellij.util.isAncestorOf import java.io.File @@ -35,6 +36,11 @@ class FileIndex( override val className = properties.className override val dependencies = properties.dependencies + override fun ordering(file: MigrationFile): Int? { + if (!properties.deriveSchemaFromMigrations) return null + return file.virtualFile.nameWithoutExtension.filter { it in '0'..'9' }.toInt() + } + override fun packageName(file: SqlDelightFile): String { val original = if (file.parent == null) { file.originalFile as SqlDelightFile diff --git a/sqldelight-idea-plugin/src/test/kotlin/com/squareup/sqldelight/intellij/SqlDelightFixtureTestCase.kt b/sqldelight-idea-plugin/src/test/kotlin/com/squareup/sqldelight/intellij/SqlDelightFixtureTestCase.kt index e9d0766088b..7224b51ab39 100644 --- a/sqldelight-idea-plugin/src/test/kotlin/com/squareup/sqldelight/intellij/SqlDelightFixtureTestCase.kt +++ b/sqldelight-idea-plugin/src/test/kotlin/com/squareup/sqldelight/intellij/SqlDelightFixtureTestCase.kt @@ -24,6 +24,7 @@ import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase import com.squareup.sqldelight.core.SqlDelightDatabaseName import com.squareup.sqldelight.core.SqlDelightFileIndex import com.squareup.sqldelight.core.SqldelightParserUtil +import com.squareup.sqldelight.core.lang.MigrationFile import com.squareup.sqldelight.core.lang.SqlDelightFile abstract class SqlDelightFixtureTestCase : LightCodeInsightFixtureTestCase() { @@ -49,6 +50,8 @@ abstract class SqlDelightFixtureTestCase : LightCodeInsightFixtureTestCase() { override val outputDirectory = "" override val dependencies = emptyList() + override fun ordering(file: MigrationFile) = null + override fun sourceFolders( file: SqlDelightFile, includeDependencies: Boolean diff --git a/test-util/src/main/kotlin/com/squareup/sqldelight/test/util/TestEnvironment.kt b/test-util/src/main/kotlin/com/squareup/sqldelight/test/util/TestEnvironment.kt index e7982ee603d..92ccc1cf6be 100644 --- a/test-util/src/main/kotlin/com/squareup/sqldelight/test/util/TestEnvironment.kt +++ b/test-util/src/main/kotlin/com/squareup/sqldelight/test/util/TestEnvironment.kt @@ -8,7 +8,10 @@ import com.squareup.sqldelight.core.SqlDelightDatabaseProperties import com.squareup.sqldelight.core.SqlDelightEnvironment import java.io.File -internal class TestEnvironment(private val outputDirectory: File = File("output")) { +internal class TestEnvironment( + private val outputDirectory: File = File("output"), + private val deriveSchemaFromMigrations: Boolean = false +) { fun build(root: String): SqlCoreEnvironment { return build(root, object : SqlAnnotationHolder { override fun createErrorAnnotation(element: PsiElement, s: String) { @@ -17,7 +20,10 @@ internal class TestEnvironment(private val outputDirectory: File = File("output" }) } - fun build(root: String, annotationHolder: SqlAnnotationHolder): SqlDelightEnvironment { + fun build( + root: String, + annotationHolder: SqlAnnotationHolder + ): SqlDelightEnvironment { val environment = SqlDelightEnvironment( sourceFolders = listOf(File(root)), dependencyFolders = emptyList(), @@ -27,7 +33,8 @@ internal class TestEnvironment(private val outputDirectory: File = File("output" dependencies = emptyList(), compilationUnits = emptyList(), outputDirectory = outputDirectory.absolutePath, - dialectPreset = DialectPreset.SQLITE_3_18 + dialectPreset = DialectPreset.SQLITE_3_18, + deriveSchemaFromMigrations = deriveSchemaFromMigrations ), outputDirectory = outputDirectory, // hyphen in the name tests that our module name sanitizing works correctly