Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preview Data panel implementation #67

Merged
merged 8 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.github.ramonvermeulen.dbtToolkit
import com.intellij.openapi.util.Key

val JS_TRIGGERED_KEY: Key<Boolean> = Key.create("JS_TRIGGERED_KEY")
val SUPPORTED_LINEAGE_EXTENSIONS = setOf("sql", "csv")
const val DBT_DOCS_FILE = "index.html"
const val DBT_MANIFEST_FILE = "manifest.json"
const val DBT_CATALOG_FILE = "catalog.json"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,8 @@ import com.intellij.openapi.vfs.VirtualFile
class DbtToolkitFileListener(project: Project) : FileEditorManagerListener {
private val activeFileService = project.service<ActiveFileService>()

companion object {
val SUPPORTED_EXTENSIONS = setOf("sql", "csv")
}

override fun selectionChanged(event: FileEditorManagerEvent) {
if (SUPPORTED_EXTENSIONS.contains(event.newFile?.extension)) {
if (event.newFile != null) {
activeFileService.setActiveFile(event.newFile as VirtualFile)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,21 @@ class DbtCommandExecutorService(private var project: Project) {
}

@Synchronized
fun executeCommand(command: List<String>) {
fun executeCommand(command: List<String>): Pair<Int, String> {
val latch = CountDownLatch(1)

var output: Pair<Int, String> = Pair(-1, "")
showLoadingIndicator("Executing dbt ${command.joinToString(" ")}...") {
try {
if (!venvInitializerService.isInitialized) {
venvInitializerService.initializeEnvironment()
}
val process = processExecutorService.executeCommand(command)
outputHandler.handleOutput(process)
output = outputHandler.handleOutput(process)
} finally {
latch.countDown()
}
}

latch.await()
return output
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ProcessOutputHandlerService(project: Project) {
private val loggingService = project.service<LoggingService>()
private val notificationService = project.service<NotificationService>()

fun handleOutput(process: Process) {
fun handleOutput(process: Process): Pair<Int, String> {
val exitCode =
if (process.waitFor(settings.state.settingsDbtCommandTimeout, TimeUnit.SECONDS)) {
process.exitValue()
Expand All @@ -41,5 +41,6 @@ class ProcessOutputHandlerService(project: Project) {
} else {
loggingService.log(stdout, ConsoleViewContentType.NORMAL_OUTPUT)
}
return Pair(exitCode, output)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.github.ramonvermeulen.dbtToolkit.ui.console.ConsoleOutputPanel
import com.github.ramonvermeulen.dbtToolkit.ui.panels.CompiledSqlPanel
import com.github.ramonvermeulen.dbtToolkit.ui.panels.DocsPanel
import com.github.ramonvermeulen.dbtToolkit.ui.panels.LineagePanel
import com.github.ramonvermeulen.dbtToolkit.ui.panels.PreviewDataPanel
import com.intellij.openapi.components.service
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
Expand Down Expand Up @@ -35,6 +36,7 @@ class DbtToolkitMainToolWindow : ToolWindowFactory, DumbAware {
"lineage" to PanelInfo({ LineagePanel(project) }, false),
"docs" to PanelInfo({ DocsPanel(project) }, true),
"compiled sql" to PanelInfo({ CompiledSqlPanel(project) }, true),
"preview data" to PanelInfo({ PreviewDataPanel(project) }, true),
"console (read-only)" to PanelInfo({ ConsoleOutputPanel(project) }, false),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ class CompiledSqlPanel(project: Project) : IdeaPanel, Disposable, ActiveFileList
activeFile = file
val compiledFile = findCompiledFile(file)
displayCompiledFile(compiledFile)
SwingUtilities.invokeLater {
recompileButton.isEnabled = true
recompileButton.text = "Re-compile model"
}
} else {
SwingUtilities.invokeLater {
recompileButton.isEnabled = false
recompileButton.text = "Open a SQL file"
ApplicationManager.getApplication().runWriteAction {
document.setText("")
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.github.ramonvermeulen.dbtToolkit.LINEAGE_PANEL_APP_DIR_NAME
import com.github.ramonvermeulen.dbtToolkit.LINEAGE_PANEL_CSS
import com.github.ramonvermeulen.dbtToolkit.LINEAGE_PANEL_INDEX
import com.github.ramonvermeulen.dbtToolkit.LINEAGE_PANEL_JS
import com.github.ramonvermeulen.dbtToolkit.SUPPORTED_LINEAGE_EXTENSIONS
import com.github.ramonvermeulen.dbtToolkit.models.LineageInfo
import com.github.ramonvermeulen.dbtToolkit.models.toJson
import com.github.ramonvermeulen.dbtToolkit.services.ActiveFileListener
Expand Down Expand Up @@ -161,7 +162,7 @@ class LineagePanel(private val project: Project) :
// subscribers
override fun activeFileChanged(file: VirtualFile?) {
ApplicationManager.getApplication().executeOnPooledThread {
if (file != null) {
if (file != null && SUPPORTED_LINEAGE_EXTENSIONS.contains(file.extension)) {
activeFile = file
refreshLineageInfo(file, false)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package com.github.ramonvermeulen.dbtToolkit.ui.panels

import com.github.ramonvermeulen.dbtToolkit.services.ActiveFileListener
import com.github.ramonvermeulen.dbtToolkit.services.ActiveFileService
import com.github.ramonvermeulen.dbtToolkit.services.DbtCommandExecutorService
import com.github.ramonvermeulen.dbtToolkit.ui.IdeaPanel
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.service
import com.intellij.openapi.editor.EditorFactory
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileTypes.FileTypeManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import java.awt.BorderLayout
import javax.swing.JButton
import javax.swing.JComponent
import javax.swing.JPanel
import javax.swing.SwingUtilities

class PreviewDataPanel(project: Project) : IdeaPanel, Disposable, ActiveFileListener {
private val dbtCommandExecutorService = project.service<DbtCommandExecutorService>()
private val mainPanel = JPanel(BorderLayout())
private val previewDataButton = JButton("Preview Data")
private var document = EditorFactory.getInstance().createDocument("")
private var activeFile: VirtualFile? = null

init {
project.messageBus.connect().subscribe(ActiveFileService.TOPIC, this)
val fileType = FileTypeManager.getInstance().getFileTypeByExtension("txt")
val editor = EditorFactory.getInstance().createEditor(document, project, fileType, true)
val editorTextField = editor.component
// to set the initial file, since the subscription is only set-up after
// opening the panel (lazy) for the first time
activeFileChanged(FileEditorManager.getInstance(project).selectedFiles.firstOrNull())
previewDataButton.addActionListener { handleRecompileButtonClick() }
mainPanel.add(previewDataButton, BorderLayout.NORTH)
mainPanel.add(editorTextField, BorderLayout.CENTER)
}

private fun handleRecompileButtonClick() {
SwingUtilities.invokeLater {
previewDataButton.isEnabled = false
previewDataButton.text = "Sending query to DWH..."
}
ApplicationManager.getApplication().executeOnPooledThread {
try {
if (activeFile != null) {
// save the active file on disk before sending Query, IDE can have an open buffer
ApplicationManager.getApplication().invokeLater {
ApplicationManager.getApplication().runWriteAction {
FileDocumentManager.getInstance().getDocument(activeFile!!).let {
FileDocumentManager.getInstance().saveDocument(it!!)
}
}
}
}
} finally {
previewData()
}
}
}

override fun activeFileChanged(file: VirtualFile?) {
if (file != null && file.extension == "sql") {
activeFile = file
SwingUtilities.invokeLater {
previewDataButton.isEnabled = true
previewDataButton.text = "Preview Data"
}
} else {
SwingUtilities.invokeLater {
previewDataButton.isEnabled = false
previewDataButton.text = "Open a SQL file"
ApplicationManager.getApplication().runWriteAction {
document.setText("")
}
}
}
}

private fun previewData() {
ApplicationManager.getApplication().executeOnPooledThread {
val output =
dbtCommandExecutorService.executeCommand(
listOf("show", "--no-populate-cache", "--select", activeFile!!.nameWithoutExtension, "--limit", "10"),
)
if (output.first == 0) {
val data = output.second.split("\n").takeLast(16).joinToString("\n").trimEnd()
SwingUtilities.invokeLater {
ApplicationManager.getApplication().runWriteAction {
document.setText(data)
previewDataButton.isEnabled = true
previewDataButton.text = "Preview Data"
}
}
} else {
SwingUtilities.invokeLater {
ApplicationManager.getApplication().runWriteAction {
document.setText(
"Error occured during execution of \"dbt show\" command. " +
"Please check the logs in the console tab.",
)
previewDataButton.isEnabled = true
previewDataButton.text = "Preview Data"
}
}
}
}
}

override fun getContent(): JComponent {
return mainPanel
}

override fun dispose() {
// Implement your dispose logic here
}
}
Loading