├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── lib ├── compileSimple.sql └── make.js ├── package.json └── samples ├── .atom-build-oracle.json ├── folderTraverse.sql ├── pkg.sql └── view.sql /.gitignore: -------------------------------------------------------------------------------- 1 | /.atom-build-oracle.json 2 | tmp/* 3 | node_modules/* 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 1.6.1 4 | 5 | * Resolve bug with installing dependencies 6 | 7 | ## 1.6.0 8 | 9 | * Add support for compiling an untitled file 10 | 11 | ## 1.5.2 12 | 13 | * Enable `sqlblanklines` 14 | 15 | ## 1.5.1 16 | 17 | * Add default port (Issue [#32](https://github.com/tschf/atom-build-oracle/issues/32)) 18 | * Call sqlplus with the -L argument 19 | 20 | ## 1.5.0 21 | 22 | * Add support for `connectString` (and with it, tnsnames.ora) 23 | 24 | ## 1.4.0 25 | 26 | * Add DYLD_LIBRARY_PATH setting for OS X 27 | 28 | ## 1.3.0 29 | 30 | * Set up dependencies to install `atom-build` 31 | * Remove redundant installation instructions 32 | 33 | ## 1.0.0 34 | 35 | * Publish to APM 36 | * Add config for `NLS_LANG` 37 | * Add error matching to report on failed builds 38 | * Support relative paths 39 | 40 | ## 0.1.0 41 | 42 | Initial version. Add core functionality to compile code. 43 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015, Trent Schafer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Oracle compiler for Atom 2 | 3 | [![apm](https://img.shields.io/apm/l/build-oracle.svg?style=flat-square)](https://atom.io/packages/build-oracle) 4 | [![apm](https://img.shields.io/apm/v/build-oracle.svg?style=flat-square)](https://atom.io/packages/build-oracle) 5 | [![apm](https://img.shields.io/apm/dm/build-oracle.svg?style=flat-square)](https://atom.io/packages/build-oracle) 6 | 7 | Uses the [atom-build](https://atom.io/packages/build) package to execute Oracle compilations in the Atom editor. 8 | 9 | This package requires [atom-build](https://atom.io/packages/build) to be installed. 10 | 11 | ## Prerequisites 12 | 13 | To be able to compile your code, you need either `SQL*Plus` or `SQLcl` available on your system - preferably in your PATH. `SQL*Plus` requires more steps to get set up (such as installing the instant client), but you will get much faster compile times so that is the preferred interpreter (`SQLcl` is Java based, so launching the JVM each time adds to the compile time). 14 | 15 | ### SQL*Plus set up 16 | 17 | #### OS X 18 | 19 | You may face issues depending on how you set up the instant client. The [typical guide](https://docs.oracle.com/cd/E11882_01/install.112/e38228/inst_task.htm#BABHEBIG) involves setting an environment variable `DYLD_LIBRARY_PATH`. Unforunately, in OS X El Capitan, this variable is not passed in as an environment variable into Atom (this is a part of security measure known as System Integrity Protection). You can also see that this is not output if you run the `env` command on the terminal. 20 | 21 | If you followed those general steps, you will likely be getting this error (or very similar): 22 | 23 | ``` 24 | dyld: Library not loaded: /ade/dosulliv_sqlplus_mac/oracle/sqlplus/lib/libsqlplus.dylib 25 | Referenced from: /opt/Oracle/instantclient_11_2/sqlplus 26 | Reason: image not found 27 | Trace/BPT trap: 5 28 | ``` 29 | 30 | Two ways around this. 31 | 32 | * In the settings for this plugin, set the path where your client files are (copy what you have for your existing DYLD_LIBRARY_PATH). 33 | 34 | ![](https://cloud.githubusercontent.com/assets/1747643/17292725/1f61b8a2-582f-11e6-940f-b9c7ae7ff42e.png) 35 | 36 | * Or, instead of setting `DYLD_LIBRARY_PATH`, you can make all the libaries available in a location that `SQL*Plus` knows where to look for them. Two common locations are `~/lib` or `/usr/local/lib`. So, assuming you placed the instant client at `/opt/Oracle/instantclient_11_2`, run the following: 37 | 38 | ```bash 39 | sudo mkdir -p /usr/local/lib 40 | sudo ln -s /opt/Oracle/instantclient_11_2/libclntsh.dylib.11.1 /usr/local/lib/libclntsh.dylib.11.1 41 | sudo ln -s /opt/Oracle/instantclient_11_2/libnnz11.dylib /usr/local/lib/libnnz11.dylib 42 | sudo ln -s /opt/Oracle/instantclient_11_2/libociei.dylib /usr/local/lib/libociei.dylib 43 | sudo ln -s /opt/Oracle/instantclient_11_2/libsqlplus.dylib /usr/local/lib/libsqlplus.dylib 44 | sudo ln -s /opt/Oracle/instantclient_11_2/libsqlplusic.dylib /usr/local/lib/libsqlplusic.dylib 45 | ``` 46 | 47 | Ensure your `PATH` is set up with the instant client directory on it so that `sqlplus` is on it. In your `~/.bash_profile` add the line: 48 | 49 | ```bash 50 | export PATH=/opt/Oracle/instantclient_11_2:$PATH 51 | ``` 52 | 53 | I went with `/usr/local/lib` rather than `~/lib` so to not fill up my home directory. Aside from that difference, this is much as what is described on the [download page](http://www.oracle.com/technetwork/topics/intel-macsoft-096467.html) of the instant client (down the bottom of the page). 54 | 55 | If you previously set up `DYLD_LIBRARY_PATH` you can unset that and you should be good to go. 56 | 57 | #### Ubuntu/Linux 58 | 59 | To be able to run SQL*Plus from Atom, Atom needs to have all the relevant enviornment variables set up. I followed the installation from this [guide](https://help.ubuntu.com/community/Oracle%20Instant%20Client). The guide mentions to set environment variables in a system wide location or `~/.bash_profile`. The guide suggests to install it in a system wide location since you typically only have one Oracle client installed per system. That is a good approach also for Atom, as it will ensure Atom picks up the relevant environment variables. I found that environment variables set in `~/.bash_profile` are not picked up by the (GUI) terminal, and upon further digging I found that `~/.bash_profile` is only picked up when launching a virtual console - see this [post](http://askubuntu.com/questions/121073/why-bash-profile-is-not-getting-sourced-when-opening-a-terminal). The other location you may be tempted to use is `~/.bashrc`, however this is also not a good place as Atom doesn't seem to pick up the environment set up in there, see this [comment](https://github.com/joefitzgerald/go-plus/issues/386#issuecomment-199359955). 60 | 61 | So, to sum it up. Either place your Oracle variables in a script at `/etc/profile.d/oracle.sh` (globally set), or place them in `~/.profile` which will get picked up by Atom. 62 | 63 | ### SQLcl set up 64 | 65 | #### Windows 66 | 67 | An issue you may face on Windows is if you try and compile code containing unicode characters, they won't persist when compiling with SQLcl. The reason is that the JVM doesn't default to UTF-8 encoding on Windows. 68 | 69 | To get around this, ensure you point to sql.bat (instead of sql.exe) and also that you have checked "Enforce UTF-8" in the package settings, similar to: 70 | 71 | ![screenshot from 2016-08-28 17-49-57](https://cloud.githubusercontent.com/assets/1747643/18032450/6bcbdfbe-6d48-11e6-87f0-a471ff298301.png) 72 | 73 | When `Enforce UTF-8 encoding` is on, the environment variable `JAVA_OPTS` will be set to `-Dfile.encoding=UTF-8`. This is also discussed on Stack overflow: http://stackoverflow.com/questions/361975/setting-the-default-java-character-encoding 74 | 75 | ## Installation 76 | 77 | Install through apm or in Atom itself, where the name of the package is `build-oracle`. 78 | 79 | ``` 80 | apm install build-oracle 81 | ``` 82 | 83 | Once installed, you will want to access the settings and set the relevant path for your SQL interpreter. That will be either SQLcl or SQL*Plus. For me, I have `sqlplus` in my `path` so no change is necessary (there is an issue where PATH may not be correctly set in Atom, in that case you should set the full path of `sqlplus`). If I wanted to point it to the binary for `SQLcl`, which isn't in my `path`, I would set the configuration to `/opt/sqlcl/bin/sql`. 84 | 85 | ![](https://cloud.githubusercontent.com/assets/1747643/11413201/79fcaa10-943a-11e5-881f-1715ef163e29.png) 86 | 87 | ## Usage instructions 88 | 89 | In your project root directory, add a JSON file named `.atom-build-oracle.json`, where you can define build targets for your project. This contents of the file expects an array of objects, which supports the following parameters: 90 | 91 | |Property name | Description | Example | 92 | |--- |--- | --- | 93 | | targetName | A descriptive name of the build target. This is so you know to which environment you'll be compiling to. | hr: dev| 94 | | connectString | The connect string you would used to connect to `sqlplus` on the command line.
**note 1:** You *must* specify a password at this stage.
**note 2:** `connectString` is the preferred field to use. | - hr/hr@//server:port/sid
- hr/hr@XE1 | 95 | | host | The server of the database | example.com | 96 | | port | The database port | 1521 (default) | 97 | | sid | The database SID or service name | XE | 98 | | user | The schema name you connect to | hr | 99 | | password | The password of the schema | oracle | 100 | 101 | note: `connectString` is built from the other server details if you ommit that setting. 102 | 103 | Examples: 104 | 105 | Connect string: 106 | 107 | Suppose I have the following TNS entry defined: 108 | 109 | ``` 110 | XE1 = 111 | (DESCRIPTION = 112 | (ADDRESS_LIST = 113 | (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.101)(PORT = 1521)) 114 | 115 | ) 116 | (CONNECT_DATA = 117 | (SERVICE_NAME = XE) 118 | ) 119 | ) 120 | ``` 121 | 122 | My build file becomes: 123 | 124 | ```json 125 | [ 126 | { 127 | "targetName" : "hr: dev", 128 | "connectString" : "hr/hr@XE1" 129 | } 130 | ] 131 | ``` 132 | 133 | Individual details: 134 | ```json 135 | [ 136 | { 137 | "targetName" : "hr: dev", 138 | "host" : "example.com", 139 | "sid" : "xe", 140 | "port" : 1521, 141 | "user" : "hr", 142 | "password" : "hr" 143 | } 144 | ] 145 | ``` 146 | 147 | Where you can specify any number of build targets. 148 | If your database server uses service names instead of SID, you can enter the service name in the property "sid" nonetheless. 149 | 150 | Since this file contains sensitive information (password) you will likely also want to add an entry to your `.gitignore` file so this is not published. 151 | 152 | ```conf 153 | .atom-build-oracle.json 154 | ``` 155 | 156 | It's worth noting, that to get the build system to recognise the above configuration, you will need to reload atom (only the first time). This can be done in the menu `View->Reload` or with the keyboard shortcut `ctrl+alt+r`. 157 | 158 | This plugin is an extension to the `build` system, providing the necessary scripts to compile Oracle code. The build triggers are determined as part of the over-arching `build` package. To build the active file is done with the keyboard shortcut `ctrl+alt+b` or `cmd+alt+b` or `f9`. By default, this will be the first entry in your build config file. The active build target can be switched with `f7`, which will also trigger a build on the active file: 159 | 160 | ![](https://cloud.githubusercontent.com/assets/1747643/15595301/2eeb787e-2401-11e6-9b89-f138d261c122.png) 161 | 162 | The build panel (with build output) can be toggled with `f8`. 163 | -------------------------------------------------------------------------------- /lib/compileSimple.sql: -------------------------------------------------------------------------------- 1 | set linesize 200 2 | 3 | set serveroutput on 4 | set verify off 5 | set sqlblanklines on 6 | 7 | COLUMN MY_USER FORMAT A20 8 | COLUMN DB FORMAT A15 9 | COLUMN NOW FORMAT A40 10 | 11 | prompt Database connection information 12 | 13 | --Show the details of the connection for confirmation 14 | select user MY_USER, ora_database_name DB, systimestamp NOW from dual; 15 | 16 | prompt 17 | prompt Compiling script: &1 18 | prompt 19 | @"&1" 20 | 21 | COLUMN MY_USER CLEAR 22 | COLUMN DB CLEAR 23 | COLUMN NOW CLEAR 24 | 25 | show error 26 | 27 | exit 28 | -------------------------------------------------------------------------------- /lib/make.js: -------------------------------------------------------------------------------- 1 | 'use babel'; 2 | 'use strict'; 3 | 4 | import path from 'path'; 5 | import fs from 'fs'; 6 | import tmp from 'tmp'; 7 | 8 | export function provideBuilder(){ 9 | 10 | // Var to Keep track of the temporary file created when compiling against 11 | // an untitled file. Reason for this is that the `doMatch` function (which 12 | // returns a list of errors) doesn't have context to the build config. 13 | var _untitledFileDest; 14 | 15 | return class OracleBuildConfig { 16 | 17 | constructor(cwd){ 18 | this.cwd = cwd; 19 | 20 | // Assume we have a saved file. 21 | // We need to keep track of this so that we can act in the pre and 22 | // post build phases to restore the configuration if necessary. 23 | this._savedFile = true; 24 | } 25 | 26 | getNiceName(){ 27 | return 'Oracle Build Config'; 28 | } 29 | 30 | isEligible(){ 31 | this.oracleBuildConfig = path.join(this.cwd, '.atom-build-oracle.json'); 32 | 33 | return fs.existsSync(this.oracleBuildConfig); 34 | } 35 | 36 | // preBuild: Before running the build, check out the active tab to see 37 | // if it is indeed a saved file or not. If it isn't, we want to save it 38 | // to a temporary file and point the build configuration to this new file 39 | preBuild(){ 40 | 41 | // The only time the temp file will be opened is when there is an 42 | // issue in the compilation. Set an explanatory message that can 43 | // be added to the top of the untitled file contents when creating 44 | // the temporary file. 45 | const tmpFileWarning = [ 46 | `-- This file was auto generated on ${new Date()} by`, 47 | `-- the \`build-oracle\` Atom plugin as the plugin requires a saved file to `, 48 | `-- compile and report any compilation errors. `, 49 | `-- `, 50 | `-- This file will be discarded upon exit from Atom; If you want to keep the `, 51 | `-- script you should save the file somewhere more practical.` 52 | ].join("\n"); 53 | 54 | let fileBuffer = atom.workspace.getActivePaneItem(); 55 | let isSavedFile = fileBuffer.buffer.file ? true : false; 56 | 57 | if (!isSavedFile){ 58 | this._savedFile = false; 59 | // this._configInstance.savedFile = false; 60 | 61 | // the script being compiled is the last argument passed in to 62 | // the execute build command. 63 | const SQL_SCRIPT_INDEX = this.args.length-1; 64 | 65 | let untitledFile = tmp.fileSync({"postfix": ".sql"}); 66 | _untitledFileDest = untitledFile.name; 67 | 68 | fs.writeFileSync(untitledFile.fd, `${tmpFileWarning}\n\n${fileBuffer.buffer.cachedText}`); 69 | 70 | // Set the build configuration to point to the created temporary file. 71 | this.args[SQL_SCRIPT_INDEX] = untitledFile.name; 72 | delete this.cwd; 73 | } 74 | } 75 | 76 | // postBuild: After the build has completed, we want to restore the 77 | // build configuration, to it's original state (which by default, compiles 78 | // the currently active file and the current working directory to the 79 | // path of the file). 80 | postBuild(buildOutcome, stdOut, stdErr){ 81 | 82 | // If we operated on an untitled file, we need to restore 83 | // the configuration 84 | if (!this._savedFile) { 85 | // the script being compiled is the last argument passed in to 86 | // the execute build command. 87 | const SQL_SCRIPT_INDEX = this.args.length-1; 88 | 89 | this._savedFile = true; 90 | this.args[SQL_SCRIPT_INDEX] = '{FILE_ACTIVE}'; 91 | this.cwd = '{FILE_ACTIVE_PATH}'; 92 | _untitledFileDest = undefined; 93 | } 94 | 95 | } 96 | 97 | settings(){ 98 | this.settingsFetched = new Date(); 99 | var pkgDir = this.getPackagePath(); 100 | let sqlPath = this.getPackageSetting('sqlPath'); 101 | let nlsLang = this.getPackageSetting('nlsLang'); 102 | let dyldLibraryPath = this.getPackageSetting('dyldLibraryPath'); 103 | let enforceUtf8 = isWindows() ? this.getPackageSetting('enforceUtf8') : false; 104 | 105 | //OS X (El Capitan) needs this env variable set in order to find 106 | //the libraries to run SQL*Plus, and there is a security measure 107 | //which prevents it being passed into Atom. 108 | if (dyldLibraryPath){ 109 | process.env.DYLD_LIBRARY_PATH = dyldLibraryPath; 110 | } 111 | 112 | if (!process.env.NLS_LANG && nlsLang){ 113 | process.env.NLS_LANG = nlsLang; 114 | } 115 | 116 | //encforceUtf8: workaround for Windows is to set an environment variable 117 | //that the JVM will pick up so that UTF-8 encodings will work. 118 | //Only relevant for Windows. 119 | //See: http://stackoverflow.com/questions/361975/setting-the-default-java-character-encoding 120 | //https://github.com/tschf/atom-build-oracle/issues/29 121 | if (enforceUtf8){ 122 | let encodingString = '-Dfile.encoding=UTF-8 '; 123 | if (process.env.JAVA_OPTS) { 124 | encodingString += process.env.JAVA_OPTS; 125 | } 126 | 127 | process.env.JAVA_OPTS = encodingString; 128 | } 129 | 130 | var parsedConfig = this.getFileJson(this.oracleBuildConfig); 131 | var buildTargets = []; 132 | 133 | for (var i = 0; i < parsedConfig.length; i++){ 134 | let currentTarget = parsedConfig[i]; 135 | 136 | let user = currentTarget.user; 137 | let pass = currentTarget.password; 138 | let host = currentTarget.host; 139 | let port = currentTarget.port ? currentTarget.port.toString() : "1521"; 140 | let sid = currentTarget.sid; 141 | let connectString = currentTarget.connectString; 142 | let thisConfig = {}; 143 | 144 | if (!connectString){ 145 | connectString = `${user}/${pass}@//${host}:${port}/${sid}`; 146 | } 147 | thisConfig.name = 'Oracle Build::' + currentTarget.targetName; 148 | 149 | let compileScript = path.join(pkgDir, 'lib', 'compileSimple.sql'); 150 | thisConfig.exec = sqlPath 151 | thisConfig.args = [ 152 | "-L", 153 | connectString, 154 | '@' + compileScript, 155 | '{FILE_ACTIVE}' 156 | ]; 157 | thisConfig.sh = false; 158 | thisConfig.cwd = "{FILE_ACTIVE_PATH}"; 159 | thisConfig.functionMatch = this.doMatch; 160 | thisConfig.preBuild = this.preBuild; 161 | thisConfig.postBuild = this.postBuild; 162 | 163 | // custom attributes not a part of the provider 164 | // _savedFile: keep track if we are compiling on a saved file 165 | // or not. This will allow us to act in the pre and post build 166 | // changing the build config. 167 | thisConfig._savedFile = true; 168 | 169 | buildTargets.push(thisConfig); 170 | } 171 | 172 | return buildTargets; 173 | } 174 | 175 | doMatch(buildOutput){ 176 | 177 | const buildOutputLines = buildOutput.split(/\n/); 178 | const errors = []; 179 | 180 | for(let i = 0; i < buildOutputLines.length; i++){ 181 | const currentLine = buildOutputLines[i]; 182 | const oraErrorMatches = currentLine.match(/((PLS|ORA)-[\d]+:.+$)/g); 183 | const dyldErrorMatches = currentLine.match(/dyld: Library not loaded:/g) 184 | const currentFile = _untitledFileDest ? _untitledFileDest : atom.workspace.getActivePaneItem().buffer.file.path; 185 | 186 | if (oraErrorMatches && oraErrorMatches.length > 0){ 187 | errors.push({ 188 | message: oraErrorMatches[0] + ' (Please review the build output for more detailed information)', 189 | file: currentFile, 190 | type: 'Error', 191 | severity: 'error' 192 | }); 193 | } else if (dyldErrorMatches && dyldErrorMatches.length > 0){ 194 | errors.push({ 195 | message: 'DYLD_LIBRARY_PATH is not set. Try setting in the build-oracle settings.', 196 | file: currentFile, 197 | type: 'Error', 198 | severity: 'error' 199 | }); 200 | } 201 | } 202 | 203 | return errors; 204 | } 205 | 206 | on(evt, evtCallback){ 207 | //As as 25.11.2015, `on` only provides the `refresh` evt 208 | if (evt !== "refresh"){ 209 | return; 210 | } 211 | 212 | this.fsWatcher = fs.watch(this.oracleBuildConfig, () => { 213 | var minTime = 1000;//1 second 214 | 215 | //Make sure a reasonable time has passed before calling the 216 | //refresh callback again 217 | if (new Date() - this.settingsFetched > minTime){ 218 | //calling `refreshTargets` in `atom-build/lib/build.js` 219 | evtCallback(); 220 | } 221 | }); 222 | 223 | this.sqlPathObserver = atom.config.observe('build-oracle.sqlPath', (val) => { 224 | //first call, assign the current setting value 225 | if (!(this.sqlPath)){ 226 | this.sqlPath = val; 227 | } else { 228 | //only if its changed should we `refreshTargets` 229 | if (this.sqlPath !== val){ 230 | this.sqlPath = val; 231 | evtCallback(); 232 | } 233 | } 234 | }); 235 | 236 | this.nlsLangObserver = atom.config.observe('build-oracle.nlsLang', (val) => { 237 | //first call, assign the current setting value 238 | if (!(this.nlsLang)){ 239 | this.nlsLang = val; 240 | } else { 241 | //only if its changed should we `refreshTargets` 242 | if (this.nlsLang !== val){ 243 | this.nlsLang = val; 244 | evtCallback(); 245 | } 246 | } 247 | }); 248 | 249 | this.dyldLibraryPathObserver = atom.config.observe('build-oracle.dyldLibraryPath', (val) => { 250 | //first call, assign the current setting value 251 | if (!(this.dyldLibraryPath)){ 252 | this.dyldLibraryPath = val; 253 | } else { 254 | //only if its changed should we `refreshTargets` 255 | if (this.dyldLibraryPath !== val){ 256 | this.dyldLibraryPath = val; 257 | evtCallback(); 258 | } 259 | } 260 | }); 261 | 262 | this.enforceUtf8Observer = atom.config.observe('build-oracle.enforceUtf8', (val) => { 263 | //first call assign the current settings val 264 | if (!(this.hasOwnProperty('enforceUtf8'))){ 265 | this.enforceUtf8 = val; 266 | } else { 267 | //only if it changes should we `refreshTargets` 268 | if (this.enforceUtf8 !== val) { 269 | this.enforceUtf8 = val; 270 | evtCallback(); 271 | } 272 | 273 | } 274 | }); 275 | } 276 | 277 | off(){ 278 | //Called before a new refresh, so the existing fileWatch can be switched off 279 | if (this.fsWatcher){ 280 | this.fsWatcher.close(); 281 | this.fsWatcher = undefined; 282 | } 283 | 284 | if (this.sqlPathObserver){ 285 | this.sqlPathObserver.dispose(); 286 | this.sqlPathObserver = undefined; 287 | } 288 | 289 | if (this.nlsLangObserver){ 290 | this.nlsLangObserver.dispose(); 291 | this.nlsLangObserver = undefined; 292 | } 293 | 294 | if (this.dyldLibraryPathObserver) { 295 | this.dyldLibraryPathObserver.dispose(); 296 | this.dyldLibraryPathObserver = undefined; 297 | } 298 | 299 | if (this.enforceUtf8Observer) { 300 | this.enforceUtf8Observer.dispose(); 301 | this.enforceUtf8Observer = undefined; 302 | } 303 | } 304 | 305 | //Helper functions 306 | getPluginName(){ 307 | return 'build-oracle'; 308 | } 309 | 310 | getPackagePath(){ 311 | var pkgManager = atom.packages; 312 | 313 | return pkgManager.resolvePackagePath(this.getPluginName()); 314 | } 315 | 316 | getPackageSetting(propertyName){ 317 | var pluginName = this.getPluginName(); 318 | var settingValue = atom.config.get(`${pluginName}.${propertyName}`); 319 | 320 | return settingValue; 321 | } 322 | 323 | getFileJson(path){ 324 | delete require.cache[path]; 325 | 326 | return require(path); 327 | } 328 | } 329 | 330 | }; 331 | 332 | function isWindows(){ 333 | return /^win/.test(process.platform); 334 | } 335 | 336 | function isOsx(){ 337 | return /^darwin$/.test(process.platform); 338 | } 339 | 340 | export function activate(){ 341 | //Install package deps, see: https://github.com/steelbrain/package-deps 342 | require('atom-package-deps').install('build-oracle'); 343 | }; 344 | 345 | function config(){ 346 | 347 | let buildConfig = {}; 348 | let settingIndex = 0; 349 | 350 | buildConfig.sqlPath = { 351 | title: 'Path to SQL interpreter', 352 | type: 'string', 353 | default: 'sqlplus', 354 | description: 'Specify the path to SQL*Plus (or SQLcl). If its in your path, the basename is acceptable', 355 | order: ++settingIndex 356 | }; 357 | 358 | buildConfig.nlsLang = { 359 | title: 'NLS_LANG', 360 | type: 'string', 361 | default: '.AL32UTF8', 362 | description: 'Specify the NLS_LANG to ensure the correct encoding is used. Format is: [NLS_LANGUAGE]_[NLS_TERRITORY].[NLS_CHARACTERSET].', 363 | order: ++settingIndex 364 | }; 365 | 366 | if (isOsx()){ 367 | buildConfig.dyldLibraryPath = { 368 | title: 'DYLD_LIBRARY_PATH', 369 | type: 'string', 370 | default: '', 371 | description: 'Specify the DYLD_LIBRARY_PATH so SQL*Plus can run properly', 372 | order: ++settingIndex 373 | } 374 | } 375 | 376 | //SQLcl on Windows doesn't seem to support UTF-8 encoding. Need a work around 377 | //in order to enable it. 378 | if (isWindows()){ 379 | buildConfig.enforceUtf8 = { 380 | title: 'Enforce UTF-8 encoding', 381 | type: 'boolean', 382 | default: true, 383 | description: 'Enable UTF-8 encoding in the JVM (Used for SQLcl on Windows. Only works with sql.bat)', 384 | order: ++settingIndex 385 | } 386 | } 387 | 388 | return buildConfig; 389 | } 390 | 391 | module.exports.config = config(); 392 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "build-oracle", 3 | "version": "1.6.1", 4 | "description": "Build Oracle PL/SQL code", 5 | "repository": "https://github.com/tschf/atom-build-oracle", 6 | "license": "MIT", 7 | "engines": { 8 | "atom": "^1.0.0" 9 | }, 10 | "providedServices": { 11 | "builder": { 12 | "description": "Runs SQL*Plus", 13 | "versions": { 14 | "2.0.0": "provideBuilder" 15 | } 16 | } 17 | }, 18 | "dependencies": { 19 | "atom-package-deps": "4.6.0", 20 | "tmp": "^0.0.31" 21 | }, 22 | "package-deps": [ 23 | "build" 24 | ], 25 | "keywords": [ 26 | "build", 27 | "compile", 28 | "sqlcl", 29 | "sql*plus", 30 | "sqlplus", 31 | "productivity", 32 | "oracle", 33 | "pl/sql", 34 | "plsql" 35 | ], 36 | "main": "lib/make.js" 37 | } 38 | -------------------------------------------------------------------------------- /samples/.atom-build-oracle.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "targetName" : "hr: dev", 4 | "host" : "example.com", 5 | "sid" : "xe", 6 | "port" : 1521, 7 | "user" : "hr", 8 | "password" : "hr" 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /samples/folderTraverse.sql: -------------------------------------------------------------------------------- 1 | PROMPT Creating views 2 | @../samples/view.sql 3 | -------------------------------------------------------------------------------- /samples/pkg.sql: -------------------------------------------------------------------------------- 1 | create or replace package foo 2 | as 3 | 4 | lc_bar NUMBER := 1001; 5 | 6 | end foo; 7 | / 8 | -------------------------------------------------------------------------------- /samples/view.sql: -------------------------------------------------------------------------------- 1 | create or replace view v_atom_build_view as 2 | select 'Accent char is: ù.' simple_string 3 | from dual; 4 | 5 | select * 6 | from v_atom_build_view; 7 | 8 | drop view v_atom_build_view; 9 | --------------------------------------------------------------------------------