public static void clearErrors(OracleSql db) { string version = getDatamodelVersion(db); Int32 error_count = 0; if (db.GetMetaConnection() != null) { string cmdQuery = "update " + sqlmakeRegistryTableName + " set path = 'CLEARED." + version + "', sdate_u=sysdate, suser_u='" + Environment.UserName + "@" + Environment.MachineName + "' where path = 'ERRORS." + version + "'"; OracleCommand cmd = new OracleCommand(cmdQuery, db.GetMetaConnection()); error_count = cmd.ExecuteNonQuery(); cmd.Dispose(); } if (error_count == 0) { Log.ExitError("No errors to clear"); } else Log.Info("clearErrors", "{0} error(s) cleared", error_count); }
public static void ExecuteTask() { OracleSql db = new OracleSql(); db.OpenMetaConnection(Settings.getUserId(true)); List<SqlErrorObject> errorList = RegistryTable.listErrors(db); foreach (SqlErrorObject sqlErrorObject in errorList) { Console.WriteLine(""); Console.WriteLine("PROMPT {0}", sqlErrorObject.sqlShortSummary); Console.WriteLine("REM Sequence id: {0}", sqlErrorObject.errorSeq); Console.WriteLine("REM {0}, Line no: {1}", sqlErrorObject.filename, sqlErrorObject.lineNo); Console.WriteLine("REM {0}", sqlErrorObject.errorMessage); Console.WriteLine(sqlErrorObject.sqlText); Console.WriteLine("/"); } }
public void checkRegistryTables(OracleSql db) { int tableVersion = -1; if (db.GetMetaConnection() != null) tableVersion = getRegistryTableVersion(db.GetMetaConnection()); if (tableVersion == -1) installRegistryTables(db); if (tableVersion > sqlmakeRegistryTableVersion) { Log.Warning("checkRegistryTables", "You are using an old version of sqlmake executable."); Log.Warning("checkRegistryTables", "Target schema was installed with a newer verions."); Log.ExitError("Please upgrade to a newer version."); } if (tableVersion > sqlmakeRegistryTableVersion) upgradeRegistryTables(db); }
public void addNewUpgrade(OracleSql db, string version, int error_count, string scriptName) { db.Prompt("Setting datamodel version to " + version + "..."); db.Exec( "insert into " + sqlmakeRegistryTableName + " (path, name, value, sdate_i, suser_i, value_v1)" + "values ('VERSION', 'UPGRADE', '" + version + "', sysdate, '" + Environment.UserName + "@" + Environment.MachineName + "' " + ", '" + scriptName + "')", "Write setup tables", "Version upgrade"); db.Exec("commit", "Write setup tables", "Commit"); }
public static void Run(string p_conn, string p_dir, bool debugFlag, bool syncToFilesystem, bool syncToDb, string outputFile) { OracleSql db = new OracleSql(); db.OpenMetaConnection(p_conn); if (outputFile == "") db.OpenConnection(p_conn); else db.SpoolOn(outputFile); Run(db, p_dir, debugFlag, syncToFilesystem, syncToDb, outputFile); // Close and Dispose OracleConnection object db.Close(); }
public static void RunPrivateSynonyms(OracleSql db, string p_dir) { Log.Info("synonym", "Loading synonyms command list"); ArrayList list = buildSynonymsList(p_dir, db.GetMetaConnection()); Log.Info("synonym", "Sorting command list"); list.Sort(); Log.Info("synonym", "Reconciling synonyms"); Console.WriteLine("Reconciling synonyms:"); bool missingIndicator = false; string sqlSynonym = ""; int errCount = 0; foreach (SynonymObject obj in list) { if (obj.filename != null && obj.existsInSchema == false) { missingIndicator = true; sqlSynonym = String.Format("create or replace synonym {0} for {1}", obj.synonymName, obj.synonymTarget); errCount += db.Exec(sqlSynonym, "synonym", "create or replace synonym"); } if (obj.filename == null && obj.existsInSchema == true) { missingIndicator = true; sqlSynonym = String.Format("drop synonym {0}", obj.synonymName); errCount += db.Exec(sqlSynonym, "synonym", "drop synonym"); } if (obj.different) { missingIndicator = true; sqlSynonym = String.Format("create or replace synonym {0} for {1}", obj.synonymName, obj.synonymTarget); errCount += db.Exec(sqlSynonym, "synonym", "create or replace synonym"); } } if (!missingIndicator) Console.WriteLine(" No changes necessary"); if (errCount > 0) { Log.Error("synonym", "Error(s) found while reconciling synonyms"); Log.ExitError("Synonyms reconcile failed"); } }
public static void RunObjectGrants(OracleSql db, string p_dir) { Log.Verbose("grants", "Loading grants command list"); ArrayList list = buildGrantsList(p_dir, db.GetMetaConnection()); Log.Verbose("grants", "Sorting command list"); list.Sort(); Log.Info("grants", "Reconciling object grants"); bool missingIndicator = false; string sqlGrant = ""; int errCount = 0; foreach (GrantObject obj in list) { if (obj.grantType == "OBJECT") { if (obj.filename != null && obj.existsInSchema == false) { missingIndicator = true; sqlGrant = String.Format("grant {0} on {4}{1} to {2}{3}", obj.privilege, obj.tableName, obj.grantee, obj.getAdminOption(), appendDotIfNotEmpty(obj.grantor)); errCount += db.Exec(sqlGrant, "grants", "grant privileege"); } if (obj.filename == null && obj.existsInSchema == true) { missingIndicator = true; sqlGrant = String.Format("revoke {0} on {1} from {2}", obj.privilege, obj.tableName, obj.grantee); errCount += db.Exec(sqlGrant, "grants", "revoke privileege"); } if (obj.different) { missingIndicator = true; //Console.WriteLine(" revoke {0} on {1} from {2};", obj.privilege, obj.tableName, obj.grantee); //Console.WriteLine(" grant {0} on {1} to {2}{3};", obj.privilege, obj.tableName, obj.grantee, obj.getAdminOption()); sqlGrant = String.Format("revoke {0} on {1} from {2}", obj.privilege, obj.tableName, obj.grantee); errCount += db.Exec(sqlGrant, "grants", "revoke privileege"); sqlGrant = String.Format("grant {0} on {1} to {2}{3}", obj.privilege, obj.tableName, obj.grantee, obj.getAdminOption()); errCount += db.Exec(sqlGrant, "grants", "grant privileege"); } } } if (!missingIndicator) Console.WriteLine(" No changes necessary"); if (errCount > 0) { Log.Error("grants", "Error(s) found while reconciling object grants"); Log.ExitError("Grants reconcile failed"); } }
static void upgradeRegistryTables(OracleSql db) { int tableVersion = getRegistryTableVersion(db.GetMetaConnection()); if (tableVersion < 2) { db.Exec(insertInitialPlsqlRow, "Upgrade setup tables", "Insert initial plsql row"); db.Exec(ddl_sqlmakeRegistryComment, "Upgrade setup tables", "Create comment on registry table"); db.Exec("commit", "Upgrade setup tables", "Commit"); } }
public static string getBuildNumber(OracleSql db) { string buildNumber = "-1"; if (db.GetMetaConnection() != null) { string cmdQuery = "select to_number(value) value from " + sqlmakeRegistryTableName + " where path = 'BUILD' and name = 'NUMBER'"; OracleCommand cmd = new OracleCommand(cmdQuery, db.GetMetaConnection()); buildNumber = Convert.ToString(cmd.ExecuteScalar()); cmd.Dispose(); if (buildNumber == "") buildNumber = "-1"; } return buildNumber; }
static void Main(string[] args) { start = DateTime.Now; Console.WriteLine("SQLMake, Copyright Mitja Golouh 2008-2012, [email protected]"); Console.WriteLine("Revision 10"); if (args.Length == 0) { Help(); Environment.Exit(0); } Log.Verbose("program", "Log started -------------------------------------------------------"); int argIndex = 0; bool somethingFound = true; // First read swithces do { somethingFound = true; switch (peekNextArg(argIndex, args, "Optional parameters").ToUpper()) { case "/D": argIndex++; Settings.setDebugFlag(true); break; case "/R": argIndex++; Settings.setRecurseFlag(true); break; case "/DB": argIndex++; Settings.setTargetIsDbFlag(true); Settings.setTargetIsFilesystemFlag(false); break; case "/FS": argIndex++; Settings.setTargetIsDbFlag(false); Settings.setTargetIsFilesystemFlag(true); break; default: somethingFound = false; break; } } while (somethingFound && (argIndex <= args.Length - 1)); if (Settings.getTargetIsDbFlag(false) && Settings.getTargetIsFilesystemFlag(false)) { throw new ArgumentException("Switches /DB and /FS can not be used at same time"); } OracleSql db; // Then read action string actionName = getNextArg(ref argIndex, args, "Action"); //And finally read key/value pairs do { string param = peekNextArg(argIndex, args, "Key=Value"); if (param != "") { somethingFound = true; string keyName; string keyValue; keyName = ""; keyValue = ""; int eqSignPosition = param.IndexOf('='); if (eqSignPosition > 0) { keyName = param.Substring(0, eqSignPosition).ToUpper(); keyValue = param.Substring(eqSignPosition + 1); switch (keyName.ToUpper()) { case "SPOOL": argIndex++; Settings.setSpoolOutput(keyValue); break; case "OUTSCRIPT": argIndex++; Settings.setSpoolOutput(keyValue); break; case "VAR": argIndex++; string varParameter = getNextArg(ref argIndex, args, "SQL*Plus variable name=value"); string varName = varParameter.Substring(0, varParameter.IndexOf('=')); string varValue = varParameter.Substring(varParameter.IndexOf('=') + 1); Settings.addSqlplusVariable(varName, varValue); // Console.WriteLine("{0}={1}", varName, varValue); break; case "CONFIG": argIndex++; Settings.setConfig(keyValue); if (!File.Exists(Settings.getConfig(true))) { Log.Error("program", "Config file does not exist: {0}", Settings.getConfig(true)); Program.Exit(1, "SQLMake is unable to start"); } break; case "USERID": argIndex++; Settings.setUserId(OracleSql.convertConnectionString2NetSyntax(keyValue)); break; case "SANDBOXPATTERN": argIndex++; Settings.setSandboxPattern(keyValue); break; case "SCRIPTS": // this is old alias for srcscriptsdir Console.WriteLine("This is deprecated parameter. Use srcscriptsdir instead."); argIndex++; Settings.setSourceScriptsDir(keyValue); if (!Directory.Exists(Settings.getSourceScriptsDir(true))) { Log.Error("program", "Source scripts directory does not exist: {0}", Settings.getSourceScriptsDir(true)); Program.Exit(1, "SQLMake is unable to start"); } break; case "SRCSCRIPTSDIR": argIndex++; Settings.setSourceScriptsDir(keyValue); if (!Directory.Exists(Settings.getSourceScriptsDir(true))) { Log.Error("program", "Source scripts directory does not exist: {0}", Settings.getSourceScriptsDir(true)); Program.Exit(1, "SQLMake is unable to start"); } break; case "SCRIPT": argIndex++; Settings.setScript(keyValue); if (!File.Exists(Settings.getScript(true))) { Log.Error("program", "SQL script does not exist: {0}", Settings.getScript(true)); Program.Exit(1, "SQLMake is unable to start"); } break; case "UPGRADETO": argIndex++; Settings.setUpgradeTo(keyValue); break; default: Log.Error("program", "Unexpected input parameter {0}", param); Program.Exit(1, "SQLMake is unable to start"); break; } } else break; } } while (somethingFound && (argIndex <= args.Length - 1)); Settings.loadSettings(); switch (actionName.ToUpper()) { case "-CHECKCONNECTION": Console.WriteLine("Action: Check Oracle DB connection"); Console.WriteLine(); CheckConnection.Check(Settings.getUserId(true)); break; case "-PLSQL": if (!Settings.getTargetIsDbFlag(false) && !Settings.getTargetIsFilesystemFlag(false)) { Console.WriteLine("Action: List PLSQL differences between database schema and scripts"); Console.WriteLine(); PlsqlMake.Run(Settings.getUserId(true), Settings.getSourceScriptsDir(true), Settings.getDebugFlag(true), false, false, ""); } if (Settings.getTargetIsDbFlag(false) && !Settings.getTargetIsFilesystemFlag(false)) { Console.WriteLine("Action: Sync PL/SQL differences to database"); Console.WriteLine(); PlsqlMake.Run(Settings.getUserId(true), Settings.getSourceScriptsDir(true), false, false, true, Settings.getSpoolOutput(false)); } if (!Settings.getTargetIsDbFlag(false) && Settings.getTargetIsFilesystemFlag(false)) { Console.WriteLine("Action: Sync PL/SQL differences to filesystem"); Console.WriteLine(); PlsqlMake.Run(Settings.getUserId(true), Settings.getSourceScriptsDir(true), false, true, false, ""); } break; case "-SCANNER": Console.WriteLine("Action: SQLPlus Scanner"); Console.WriteLine(); RunScanner(Settings.getScript(true)); break; case "-INSTALL": Console.WriteLine("Action: Installs schema based on install scripts"); Console.WriteLine(); Install.Go(Settings.getUserId(false), Settings.getSpoolOutput(false), Settings.getSourceScriptsDir(true), Settings.getRecurseFlag(true)); break; case "-UPGRADE": Console.WriteLine("Action: Upgrades schema based on upgrade scripts"); Console.WriteLine(); Upgrade.Go(Settings.getUserId(true), Settings.getSpoolOutput(false), Settings.getSourceScriptsDir(true), Settings.getRecurseFlag(true), Settings.getUpgradeTo(false)); break; case "-STATUS": Console.WriteLine("Action: Prints target schema status"); Console.WriteLine(); db = new OracleSql(); db.OpenMetaConnection(Settings.getUserId(true)); RegistryTable.status(db); break; case "-LIST_ERRORS": Console.WriteLine("Action: Lists all errors from last install"); Console.WriteLine(); ListErrorsCmdline.ExecuteTask(); break; case "-CLEAR_ERRORS": Console.WriteLine("Action: Clear all errors from last install"); Console.WriteLine(); db = new OracleSql(); db.OpenMetaConnection(Settings.getUserId(true)); RegistryTable.clearErrors(db); break; case "-CLEAR_ERROR": Console.WriteLine("Action: Clear error with [sequenceNumber] from last install"); Console.WriteLine(); db = new OracleSql(); db.OpenMetaConnection(Settings.getUserId(true)); RegistryTable.clearError(db, int.Parse(getNextArg(ref argIndex, args, "Error sequence number"))); break; case "-CRAWL": Console.WriteLine("Action: Crawl and print links"); Console.WriteLine(); Crawl.Run("START", Settings.getScript(true), Path.GetDirectoryName(Settings.getScript(true)),0); break; case "-STATS": Console.WriteLine("Action: Prints stats"); Console.WriteLine(); //Stats.Print(args[argIndex + 1], includeList, SearchOption.AllDirectories); Stats.BasicStats(Settings.getSourceScriptsDir(true), SearchOption.AllDirectories); break; case "-LIST_CHANGES": Console.WriteLine("Action: List all changes of an database object"); Console.WriteLine(); ListChanges(getNextArg(ref argIndex, args, "Database object name").ToUpper()); break; case "-GRANTS": db = new OracleSql(); db.OpenMetaConnection(Settings.getUserId(true)); if (Settings.getTargetIsDbFlag(false)) db.OpenConnection(Settings.getUserId(true)); db.setEcho(EchoFlag.on); Grants.RunObjectGrants(db, Settings.getSourceScriptsDir(true)); break; case "-SYSGRANTS": db = new OracleSql(); db.OpenMetaConnection(Settings.getUserId(true)); if (Settings.getTargetIsDbFlag(false)) db.OpenConnection(Settings.getUserId(true)); db.setEcho(EchoFlag.on); Grants.RunSystemGrants(db, Settings.getSourceScriptsDir(true)); break; case "-SYNONYMS": db = new OracleSql(); db.OpenMetaConnection(Settings.getUserId(true)); if (Settings.getTargetIsDbFlag(false)) db.OpenConnection(Settings.getUserId(true)); db.setEcho(EchoFlag.on); Synonym.RunPrivateSynonyms(db, Settings.getSourceScriptsDir(true)); break; case "-TEST": Console.WriteLine("Action: Test"); Console.WriteLine(); Console.WriteLine(VersionStringManipulation.extractVersionStringFromTextualFile(Settings.getSourceScriptsDir(true), Settings.getRecurseFlag(true), Settings.getDatamodelVersionFilename(true), Settings.getDatamodelVersionSearchPattern(true), Settings.getDatamodelVersionIdDefinition(true))) ; break; default: Log.Error("program", "Unknown action: {0}", actionName); Program.Exit(1, "SQLMake is unable to start"); break; } Log.Verbose("program", "Sqlmake finished successfuly"); DateTime end = DateTime.Now; TimeSpan duration = end - start; Log.Info("program", "Elapsed time " + duration.TotalSeconds + " sec"); }
public static void Go(string conn, string outputFile, string scriptFolder, bool recurseFlag, string upgradeTo) { // find upgrade folder (should be just one) string configUpgradeFolderName = Settings.getUpgradeFolderName(true); string configIgnoreDirList = Settings.getIgnoreDirList(true); string configIgnoreFileList = Settings.getIgnoreFileList(true); string[] upgradeFolderList = Directory.GetDirectories(scriptFolder, configUpgradeFolderName, SearchOption.AllDirectories); if (upgradeFolderList.Length == 0) { Log.Error("upgrade", "Upgrade directory not found"); Log.ExitError("Upgrade failed"); } // make a list of all upgrade scripts ArrayList upgradeScriptList = new ArrayList(); // there can be more than one upgrade folder foreach (string folder in upgradeFolderList) { ArrayList unfilteredUpgradeScriptList = new ArrayList(); unfilteredUpgradeScriptList.AddRange(FolderSearch.Search(folder, true, "*.sql", configIgnoreDirList, configIgnoreFileList)); // remove all scripts > upgradeTo if (upgradeTo != "") { foreach (string upgradeScript in unfilteredUpgradeScriptList) { if (RegistryTable.compareVersion(UpgradeScriptnameComparer.extractUpgradeScriptVersion(upgradeScript), upgradeTo) <= 0) upgradeScriptList.Add(upgradeScript); } } else { upgradeScriptList.AddRange(unfilteredUpgradeScriptList); } } // sort in ascending order upgradeScriptList.Sort(new UpgradeScriptnameComparer()); string maxDatamodelVersion = UpgradeScriptnameComparer.extractUpgradeScriptVersion((string)upgradeScriptList[upgradeScriptList.Count - 1]); //Console.WriteLine(maxDatamodelVersion); Log.Verbose("upgrade", "Open connection to database"); // Open connections if (conn == "") { Log.Error("upgrade", "Upgrade can not be done in offline mode"); Log.ExitError("Upgrade failed"); } OracleSql db = new OracleSql(); db.OpenMetaConnection(conn); if (outputFile == "") db.OpenConnection(conn); else db.SpoolOn(outputFile); Log.Verbose("upgrade", "DB object successfuly created..."); Log.Verbose("upgrade", "Extract version info from sqlmake registry"); // Extract current datamodel version RegistryTable registryTable = new RegistryTable(); string currDatamodelVersion = RegistryTable.getDatamodelVersion(db); int currErrCount = RegistryTable.getErrorCount(db, currDatamodelVersion); Log.Verbose("upgrade", "Current schema datamodel version is {0}", currDatamodelVersion); if (currErrCount > 0) { Log.Error("upgrade", "Previous install/upgrade finished with {0} error(s)", currErrCount); // TODO: force command line switch to force upgrade even if errors are found Log.ExitError("Upgrade failed"); } if (RegistryTable.compareVersion(maxDatamodelVersion, currDatamodelVersion) == -1) { Log.Error("upgrade", "Datamodel is newer then scripts on filesystem. No upgrade is necessary"); Log.ExitError("Skipping upgrade script deployment"); } if (RegistryTable.compareVersion(maxDatamodelVersion, currDatamodelVersion) == 1) { Log.Info("upgrade", "Upgrading data model ..."); foreach (string upgradeScript in upgradeScriptList) { string scriptVersion = UpgradeScriptnameComparer.extractUpgradeScriptVersion(upgradeScript); if (RegistryTable.compareVersion(currDatamodelVersion, scriptVersion) == -1) { Log.Info("upgrade", ""); int errCount = SqlScript.RunLogErrors(db, upgradeScript, scriptVersion, registryTable); currDatamodelVersion = scriptVersion; registryTable.addNewUpgrade(db, currDatamodelVersion, errCount, upgradeScript); if (errCount > 0) { Log.Error("upgrade", "Errors found during upgrade to version {0}", currDatamodelVersion); Log.ExitError("Upgrade failed"); } else { Log.Info("upgrade", "Installation of upgrade script {0} successful", Path.GetFileName(upgradeScript)); } } } Log.Info("upgrade", ""); Console.ForegroundColor = ConsoleColor.Green; Log.Info("upgrade", "All upgrade scripts applied"); Console.ResetColor(); } else { Log.Info("upgrade", "Datamodel is up to date. No upgrade is necessary"); } }
public static int RunLogErrors(OracleSql db, string filename, string datamodelVersion, RegistryTable registryTable) { Log.Info("SqlScript", "Execute script {0}", filename); int errCount = 0; ArrayList cmdList = new ArrayList(SqlScript.Load(filename)); foreach (SqlObject cmd in cmdList) { if (cmd.commandType == "SQL" || cmd.commandType == "PLSQL") { db.Comment(String.Format(" [Line {0} to {1}] {2}", cmd.lineStart, cmd.lineEnd, cmd.filename)); string installingWhat = ""; if (cmd.secondaryObjectName == "") installingWhat = String.Format(" {0} {1} {2}...", cmd.action.ToLower(), cmd.objectType.ToLower(), cmd.objectName.ToLower()); else installingWhat = String.Format(" {0} {1} {2} on {3}...", cmd.action.ToLower(), cmd.objectType.ToLower(), cmd.secondaryObjectName.ToLower(), cmd.objectName.ToLower()); db.Prompt(installingWhat); int errCode = db.Exec(cmd.sqlText, "sqlScript", "run"); if (errCode != 0) { errCount++; registryTable.addError(db, datamodelVersion, cmd.seqInFile, cmd.filename, cmd.lineStart, db.lastErrm, cmd.sqlText, installingWhat); } } } return errCount; }
public static void Run(OracleSql db, string p_dir, bool debugFlag, bool syncToFilesystem, bool syncToDb, string outputFile) { Log.Info("plsqlmake", "Loading plsql command list"); ArrayList list = buildFileList(p_dir, db.GetMetaConnection()); Log.Info("plsqlmake", ""); Log.Info("plsqlmake", "PL/SQL differences"); Log.Info("plsqlmake", " Object only on filesystem"); bool missingIndicator = false; foreach (PlsqlObject obj in list) { if (obj.filename != null && obj.existsInSchema == false) { //Console.WriteLine(" {0} {1} ({2})", obj.name.ToLower(), obj.filetype, obj.filename); missingIndicator = true; if (!syncToFilesystem && !syncToDb) Log.Info("plsqlmake", " @{2}", obj.objectName.ToLower(), obj.objectType, obj.filename); if (syncToFilesystem) { Log.Info("plsqlmake", " Deleting {0}", obj.filename); FileInfo fi = new FileInfo(obj.filename); fi.MoveTo(obj.filename + ".bak"); } if (syncToDb) { Log.Info("plsqlmake", " Creating {0} {1}", obj.objectType, obj.objectName); if (obj.objectType != "VIEW") db.Exec("create or replace " + extractPlsql(obj.plsqlText, obj.filename), "syncToDb", "Create " + obj.objectType + " " + obj.objectName); else db.Exec("create or replace " + obj.objectType + " " + obj.objectName + " as\n" + extractPlsql(obj.plsqlText, obj.filename), "syncToDb", "Create " + obj.objectType + " " + obj.objectName); } } } if (!missingIndicator) Log.Info("plsqlmake", " None"); Log.Info("plsqlmake", " Object only in DB"); bool extraIndicator = false; foreach (PlsqlObject obj in list) { if (obj.filename == null && obj.existsInSchema == true) { extraIndicator = true; if (!syncToFilesystem && !syncToDb) Log.Info("plsqlmake", " {0} {1}", obj.objectName.ToLower(), obj.objectType); if (syncToFilesystem) { Log.Info("plsqlmake", " Added {0}\\{1}{2}", p_dir, obj.objectName.ToLower(), obj.getExtFromObjectType().ToLower()); System.IO.File.WriteAllText(p_dir + "\\" + obj.objectName.ToLower() + obj.getExtFromObjectType().ToLower(), "create or replace " + db.getPLSQLfromDB(obj.objectName, obj.objectType) + "\n/", Encoding.Default); } if (syncToDb) { Log.Info("plsqlmake", " Droping {0} {1}", obj.objectType, obj.objectName); try { if (obj.objectType == "TYPE" && getDependantTypesCount(obj.objectName, db) > 0) { db.Exec("drop " + obj.objectType + " " + obj.objectName + " force", "syncToDb", "Drop " + obj.objectType + " " + obj.objectName); } else db.ExecUnmanaged("drop " + obj.objectType + " " + obj.objectName, "syncToDb", "Drop " + obj.objectType + " " + obj.objectName); } catch (OracleException e) { // handle ORA-04043: object {objectName} does not exist // when package is droped, package body is automatically droped // resulting in ORA-04043 if (!(e.Code == 2303 || e.Code == 4043 || e.Code == 4042)) { Log.Warning("oracleSql", "Error when executing SQL command\r\n{0}\r\n{1}", e.Message, "Drop " + obj.objectType + " " + obj.objectName); } } } } } if (!extraIndicator) Log.Info("plsqlmake", " None"); Log.Info("plsqlmake", " Different objects"); bool diffIndicator = false; foreach (PlsqlObject obj in list) { if (obj.filename != null && obj.existsInSchema == true) { obj.file_md5 = getMd5Hash(extractPlsql(obj.plsqlText, obj.filename)); string dbText = db.getPLSQLfromDB(obj.objectName, obj.objectType); obj.plsql_md5 = getMd5Hash(dbText); //Console.WriteLine(" File hash: {0} Db hash: {1}", obj.file_md5, obj.plsql_md5); if (obj.file_md5 != obj.plsql_md5) { diffIndicator = true; if (!syncToFilesystem && !syncToDb) Log.Info("plsqlmake", " {0} {1} ({2})", obj.objectName.ToLower(), obj.objectType, obj.filename); if (syncToFilesystem) { Log.Info("plsqlmake", " Modified {0}", obj.filename); FileInfo fi = new FileInfo(obj.filename); FileInfo fiBak = new FileInfo(obj.filename + ".bak"); fiBak.Delete(); fi.MoveTo(obj.filename + ".bak"); System.IO.File.WriteAllText(obj.filename, "create or replace " + dbText + "\n/", Encoding.Default); } if (syncToDb) { ArrayList grantsList = new ArrayList(); db.Prompt(String.Format(" Modified {0} {1}", obj.objectType, obj.objectName)); if (obj.objectType == "TYPE" && getDependantTypesCount(obj.objectName, db) > 0) { /*foreach (PlsqlObject typeBody in list) { if (typeBody.objectType == "TYPE BODY" && typeBody.objectName = obj.objectName) { typeBody. } }*/ grantsList = Grants.buildObjectGrantsList(db.GetMetaConnection(), obj.objectName); db.Exec("drop " + obj.objectType + " " + obj.objectName + " force", "syncToDb", "Drop " + obj.objectType + " " + obj.objectName); } try { if (obj.objectType != "VIEW") db.ExecUnmanaged("create or replace " + extractPlsql(obj.plsqlText, obj.filename), "syncToDb", "Replace " + obj.objectType + " " + obj.objectName); else db.ExecUnmanaged("create or replace " + obj.objectType + " " + obj.objectName + " as\n" + extractPlsql(obj.plsqlText, obj.filename), "syncToDb", "Replace " + obj.objectType + " " + obj.objectName); Grants.executeGrantList(db, grantsList); } catch (OracleException e) { // handle ORA-02303: cannot drop or replace a type with type or table dependents // we check for type dependency but it is not working when type is referenced via private synony // in another schema if (e.Code != 2303) { string lastErrm = e.Message; Log.Warning("oracleSql", "Error when executing SQL command\r\n{0}\r\n{1}", e.Message, "create or replace " + extractPlsql(obj.plsqlText, obj.filename)); } // retry operation grantsList = Grants.buildObjectGrantsList(db.GetMetaConnection(), obj.objectName); db.Exec("drop " + obj.objectType + " " + obj.objectName + " force", "syncToDb", "Drop " + obj.objectType + " " + obj.objectName); db.Exec("create or replace " + extractPlsql(obj.plsqlText, obj.filename), "syncToDb", "Replace " + obj.objectType + " " + obj.objectName); } if (obj.objectType == "TYPE") { Grants.executeGrantList(db, grantsList); } } if (debugFlag) { Log.Debug("plsqlMake","Write db and filesystem PLSQL text to file:"); Log.Debug("plsqlMake", " {0}", obj.objectName + " " + obj.objectType + ".file.log"); Log.Debug("plsqlMake", " {0}", obj.objectName + " " + obj.objectType + ".db.log"); Log.Debug("plsqlMake", " File hash: {0} Db hash: {1}", obj.file_md5, obj.plsql_md5); System.IO.File.WriteAllText(obj.objectName + " " + obj.objectType + ".file.log", extractPlsql(obj.plsqlText, obj.filename), Encoding.Default); System.IO.File.WriteAllText(obj.objectName + " " + obj.objectType + ".db.log", dbText, Encoding.Default); } } // if (getMd5Hash(getPLSQLfromDB(obj.objectName, obj.objectType, con)) != obj.plsql_md5) // { // System.IO.File.WriteAllText(obj.objectName + " " + obj.objectType + ".db.log", dbText, Encoding.Default); // Console.WriteLine(obj.objectName + " " + obj.objectType + " File hash: {0} Db hash: {1}", obj.file_md5, getPLSQLfromDBCryptoAPI(obj.objectName, obj.objectType, con)); // } } } if (!diffIndicator) Log.Info("plsqlmake", " None"); int equalObjectsCount = 0; foreach (PlsqlObject obj in list) { if (obj.filename != null && obj.existsInSchema == true) { if (obj.file_md5 == obj.plsql_md5) equalObjectsCount++; } } Log.Info("plsqlmake", " Equal objects count:"); Log.Info("plsqlmake", " {0} object(s)", equalObjectsCount); if (syncToDb) { bool failedInstall = false; int invalidCount = db.RecompileInvalidObjects(); if (invalidCount > 0) { failedInstall = true; Log.Error("sync2db", "{0} invalid object(s) found after recompilation", invalidCount); foreach (string objectName in db.GetInvalidObjectsList()) Log.Error("sync2db", " {0}", objectName); } if (failedInstall) { db.Close(); Log.ExitError("Sync plsql to database failed"); } } }
public void setBuildNumber(OracleSql db, string version) { db.Prompt("Setting datamodel version to " + version + "..."); db.Exec("update " + sqlmakeRegistryTableName + " " + "set value = " + version + ",sdate_u = sysdate" + ",suser_u = '" + Environment.UserName + "@" + Environment.MachineName + "' " + "where path = 'BUILD' and name = 'NUMBER'", "Write setup tables", "New plsql version"); db.Exec("commit", "Write setup tables", "Commit"); }
// Datamodel version can be 1.2.3.4 // Therefore order by is complicated to correctly sort by each part of version number public static string getDatamodelVersion(OracleSql db) { string datamodelVersion = "-1"; if (db.GetMetaConnection() != null) { string cmdQuery = "select value\n" + "from\n" + "(\n" + "select value from " + sqlmakeRegistryTableName + " where path = 'VERSION'\n" + "order by\n" + " to_number(substr(value,1,decode(instr(value,'.',1,1),0,length(value),instr(value,'.',1,1)-1))) desc nulls last,\n" + " to_number(decode(instr(value,'.',1,1),0,null,substr(value,instr(value,'.',1,1)+1,decode(instr(value,'.',1,2),0,length(value),instr(value,'.',1,2)-instr(value,'.',1,1)-1)))) desc nulls last,\n" + " to_number(decode(instr(value,'.',1,2),0,null,substr(value,instr(value,'.',1,2)+1,decode(instr(value,'.',1,3),0,length(value),instr(value,'.',1,3)-instr(value,'.',1,2)-1)))) desc nulls last,\n" + " to_number(decode(instr(value,'.',1,3),0,null,substr(value,instr(value,'.',1,3)+1,decode(instr(value,'.',1,4),0,length(value),instr(value,'.',1,4)-instr(value,'.',1,3)-1)))) desc nulls last,\n" + " to_number(decode(instr(value,'.',1,4),0,null,substr(value,instr(value,'.',1,4)+1,decode(instr(value,'.',1,5),0,length(value),instr(value,'.',1,5)-instr(value,'.',1,4)-1)))) desc nulls last,\n" + " to_number(decode(instr(value,'.',1,5),0,null,substr(value,instr(value,'.',1,5)+1,decode(instr(value,'.',1,6),0,length(value),instr(value,'.',1,6)-instr(value,'.',1,5)-1)))) desc nulls last\n" + ")\n" + " where rownum = 1"; OracleCommand cmd = new OracleCommand(cmdQuery, db.GetMetaConnection()); datamodelVersion = Convert.ToString(cmd.ExecuteScalar()); cmd.Dispose(); } return datamodelVersion; }
public void setDatamodelVersion(OracleSql db, string version) { db.Exec("update " + sqlmakeRegistryTableName + " " + "set value = " + version + ",sdate_u = sysdate" + ",suser_u = '" + Environment.UserName + "@" + Environment.MachineName + "' " + "where path = 'VERSION' and name = 'INSTALL'", "Write setup tables", "New datamodel version"); db.Exec("commit", "Write setup tables", "Commit"); }
public static int getErrorCount(OracleSql db, string version) { Int32 error_count = 0; if (db.GetMetaConnection() != null) { string cmdQuery = "select count(*) from " + sqlmakeRegistryTableName + " where path = 'ERRORS." + version + "'"; OracleCommand cmd = new OracleCommand(cmdQuery, db.GetMetaConnection()); error_count = Convert.ToInt32(cmd.ExecuteScalar()); cmd.Dispose(); } return error_count; }
void installRegistryTables(OracleSql db) { db.Prompt("Creating sqlmake registry table ..."); db.Exec(ddl_sqlmakeRegistryTable, "Install setup tables", "Create registry table"); db.Exec(ddl_sqlmakeRegistryPk, "Install setup tables", "Create registry table primary key"); db.Exec(ddl_sqlmakeRegistryComment, "Install setup tables", "Create comment on registry table"); db.Exec(insertInitialDatamodelRow, "Install setup tables", "Insert initial datamodel row"); db.Exec(insertInitialPlsqlRow, "Install setup tables", "Insert initial plsql row"); db.Exec("commit", "Install setup tables", "Commit"); }
public static List<SqlErrorObject> listErrors(OracleSql db) { string version = getDatamodelVersion(db); string cmdQuery = "select * from sqlmake where path = 'ERRORS."+version+"' order by to_number(value)"; OracleCommand cmd = new OracleCommand(cmdQuery, db.GetMetaConnection()); OracleDataReader r = cmd.ExecuteReader(); List<SqlErrorObject> sqlList = new List<SqlErrorObject>(); while (r.Read()) { sqlList.Add(new SqlErrorObject(int.Parse(r.GetString(2)), r.GetString(7), r.GetString(8), r.GetInt32(11), r.GetString(9), r.GetString(10))); } return sqlList; }
public static void executeGrantList(OracleSql db, ArrayList grantsList) { foreach (GrantObject obj in grantsList) { if (obj.grantType == "OBJECT") db.Exec(String.Format("grant {0} on {3} to {1} {2}", obj.privilege, obj.grantee, obj.getAdminOption(), obj.tableName), "grants", "executeGrantList"); else Log.Warning("grants", "Non object grants currently not suported in executeGrantList: {0}", obj.ToString()); } }
public static void status(OracleSql db) { // check for registry table int regTableVersion = getRegistryTableVersion(db.GetMetaConnection()); if (regTableVersion == -1) { Console.ForegroundColor = ConsoleColor.Yellow; Log.Warning("status", "Target schema is not using sqlmake tool"); Log.Warning("status", "No status available"); Console.ResetColor(); Log.ExitError(""); } string dbModelVersion = getDatamodelVersion(db); string dbBuildNumber = getBuildNumber(db); int errorCount = getErrorCount(db, dbModelVersion); int clearedCount = getClearedCount(db, dbModelVersion); List<string> invalidObjects = db.GetInvalidObjectsList(); if (dbModelVersion == "-1") Log.Warning("status", "Current data model version : Unknown"); else if (dbModelVersion == "0") Log.Warning("status", "Current data model version : Last installation procedure was terminted"); else Log.Info("status", "Current data model version : {0}", dbModelVersion); //if (dbBuildNumber == "-1") Log.Warning("status", "Current build number : Unknown"); //else if (dbBuildNumber == "0") Log.Warning("status", "Current build number : Last build deployment was terminted"); //else Log.Info("status", "Current build number : {0}", dbBuildNumber); Log.Error("status", "Errors during last deployment: {0}", errorCount); if (clearedCount > 0) Log.Info("status", "Errors cleared after install : {0}", clearedCount); Log.Error("status", "Invalid object(s) found : {0}", invalidObjects.Count); foreach (string invalidObject in invalidObjects) Log.Error("status", " "+invalidObject); if (errorCount > 0 || invalidObjects.Count > 0) { Log.ExitError("Schema deployment is invalid"); } else { Console.ForegroundColor = ConsoleColor.Green; Log.Info("status", "Installation successful"); Console.ResetColor(); } }
public static void RunSystemGrants(OracleSql db, string p_dir) { Log.Info("grants", "Loading grants command list"); ArrayList list = buildGrantsList(p_dir, db.GetMetaConnection()); Log.Info("grants", "Sorting command list"); list.Sort(); Log.Info("grants", "Reconcile system grants"); Console.WriteLine("Reconciling system grants"); bool missingIndicator = false; string sqlGrant = ""; int errCount = 0; foreach (GrantObject obj in list) { if (obj.grantType == "SYSTEM") { if (obj.filename != null && obj.existsInSchema == false) { missingIndicator = true; sqlGrant = String.Format("grant {0} to {1} {2}", obj.privilege, obj.grantee, obj.getAdminOption()); errCount += db.Exec(sqlGrant, "grants", "grant system privileege"); } if (obj.filename == null && obj.existsInSchema == true) { missingIndicator = true; sqlGrant = String.Format("revoke {0} from {1}", obj.privilege, obj.grantee); errCount += db.Exec(sqlGrant, "grants", "revoke system privileege"); } if (obj.different) { missingIndicator = true; sqlGrant = String.Format("revoke {0} from {1}", obj.privilege, obj.grantee); errCount += db.Exec(sqlGrant, "grants", "revoke system privileege"); sqlGrant = String.Format("grant {0} to {1} {2}", obj.privilege, obj.grantee, obj.getAdminOption()); errCount += db.Exec(sqlGrant, "grants", "grant system privileege"); } } } if (!missingIndicator) Console.WriteLine(" No changes necessary"); if (errCount > 0) { Log.Error("grants", "Error(s) found while reconciling system grants"); Log.ExitError("System grants reconcile failed"); } }
public void addError(OracleSql db, string version, int sequenceNo, string scriptName, int lineNo, string errm, string sqlText, string sqlShortSummary) { string cmdInsert = "insert into " + sqlmakeRegistryTableName + " (path, name, value, sdate_i, suser_i, value_v1, value_v2, value_n1, value_c1, value_c2) " + "values (:path, 'SEQ', :value, sysdate, :suser_i, :value_v1, :value_v2, :value_n1, :value_c1, :value_c2)"; OracleCommand cmd = new OracleCommand(cmdInsert, db.GetMetaConnection()); cmd.Parameters.AddWithValue("path", "ERRORS."+version.ToString()); cmd.Parameters.AddWithValue("value", sequenceNo.ToString()); cmd.Parameters.AddWithValue("suser_i", Environment.UserName + "@" + Environment.MachineName); cmd.Parameters.AddWithValue("value_v1", scriptName); cmd.Parameters.AddWithValue("value_v2", sqlShortSummary); cmd.Parameters.AddWithValue("value_n1", lineNo); cmd.Parameters.AddWithValue("value_c1", errm.Trim()); cmd.Parameters.AddWithValue("value_c2", sqlText.Trim()); cmd.ExecuteNonQuery(); cmd.Dispose(); //db.Exec( // "insert into " + sqlmakeRegistryTableName + " (path, name, value, sdate_i, suser_i, value_v1, value_n1, value_c1)" + // String.Format("values ('ERRORS.{0}', 'ERROR', '{4}', sysdate, '{2}', '{3}', {5}, '{6}')", // version, errm.Substring(0, 9), Environment.UserName + "@" + Environment.MachineName, scriptName, sequenceNo, lineNo, errm.TrimEnd()), // "Write setup tables", "Add error"); //db.Exec("commit", "Write setup tables", "Commit"); }
public static void Go(string connectString, string outputScript, string sourceScriptsDir, bool recurseFlag) { Log.Verbose("install", "Install start"); OracleSql db = new OracleSql(); RegistryTable registryTable = new RegistryTable(); Settings.overrideSqlPlusVariableSubstitutionFlag(false); if (connectString != "") { // Open connections if (connectString != "") { db.OpenMetaConnection(connectString); db.OpenConnection(connectString); } Log.Verbose("install", "Check registry table"); // Check if registry files are already created registryTable.checkRegistryTables(db); string currDatamodelVersion = RegistryTable.getDatamodelVersion(db); if (currDatamodelVersion == "-1") { db.Close(); Log.Error("install", "Target schema is installed but does not contain version information", currDatamodelVersion); Log.Error("install", "Only manual upgrade is possible"); Log.ExitError("Installation failed"); } if (RegistryTable.compareVersion(currDatamodelVersion, "0") == 1) { db.Close(); Log.Error("install", "Target schema already contains version {0} of datamodel", currDatamodelVersion); Log.Error("install", "Use upgrade instead of install"); Log.ExitError("Installation failed"); } } else if (outputScript != "") db.SpoolOn(outputScript); else { Log.Error("install", "Either connect string or output script must be specified"); Log.ExitError("Install did not start"); } Log.Info("install", "Searching for sql scripts ..."); Log.Verbose("install", "Allowed file types {0}", Settings.getSqlFileList(true)); Log.Verbose("install", "Ignore directories {0}", Settings.getIgnoreDirList(true)); Log.Verbose("install", "Ignore files {0}", Settings.getIgnoreFileList(true)); ArrayList sqlCommandList = new ArrayList(); string[] fileList = FolderSearch.Search(sourceScriptsDir, recurseFlag, Settings.getSqlFileList(true), Settings.getIgnoreDirList(true), Settings.getIgnoreFileList(true)); Log.Info("install", "Loading sql commands from scripts ... "); //Load SQL commands from scripts foreach (string scriptname in fileList) { Log.Verbose("install", "Loading script {0}", scriptname); sqlCommandList.AddRange(SqlScript.Load(scriptname)); } Log.Verbose("install", "Sort loaded sql commands"); sqlCommandList.Sort(); //Extract datamodel version Log.Verbose("Install", "Looking for datamodel version..."); string datamodelVersion = "-1"; if (Settings.getDatamodelVersionLocation(true) == "FILE") { Log.Verbose("Install", "Extracting datamodel version from file {0}", Settings.getDatamodelVersionFilename(true)); datamodelVersion = VersionStringManipulation.extractVersionStringFromTextualFile(sourceScriptsDir, recurseFlag, Settings.getDatamodelVersionFilename(true), Settings.getDatamodelVersionSearchPattern(true), Settings.getDatamodelVersionIdDefinition(true)); } if (Settings.getDatamodelVersionLocation(true) == "DIRECTORY") { Log.Verbose("Install", "Extracting datamodel version from directory name {0}", sourceScriptsDir); datamodelVersion = VersionStringManipulation.extractVersionStringFromDirectoryName(sourceScriptsDir, Settings.getDatamodelVersionSearchPattern(true), Settings.getDatamodelVersionIdDefinition(true)); } if (datamodelVersion == "-1") Log.Warning("Install", " Target datamodel version not found. Setting version to -1."); //foreach (SqlObject s in sqlCommandList) //{ // Console.WriteLine("{6} [{0},{1}] action {2}, objectType {3}, objectName {4}, secondaryObjectName {5}", s.lineStart, s.lineEnd, s.action, s.objectType, s.objectName, s.secondaryObjectName, s.filename); //} Log.Info("install", "Executing SQL commands in predefined order..."); // execute in predefined order string installOrder = Settings.getInstallOrder(true); int sqlCount = 0; int cmdSequence = 0; int errCount = 0; foreach (string objectType in installOrder.Split(',')) { sqlCount = 0; Log.Verbose("install", "Looking for SQL commands where type is {0}", objectType); foreach (SqlObject s in sqlCommandList) { if (s.commandType != "SQLPlus" && ( ((s.action.Trim() == "CREATE" || s.action == "CREATE OR REPLACE") && s.objectType == objectType.Trim()) || ((s.action.Trim() == "GRANT" || s.action.Trim() == "INSERT") && s.action == objectType.Trim()) ) ) { if (sqlCount == 0) db.Prompt("=========== " + objectType + " ======================================"); db.Comment(String.Format("[Line {0} to {1}] {2}", s.lineStart, s.lineEnd, s.filename)); string installingWhat = ""; if (s.secondaryObjectName == "") installingWhat = String.Format("{0} {1} {2}", s.action.ToLower(), s.objectType.ToLower(), s.objectName.ToLower()); else installingWhat = String.Format("{0} {1} {2} on {3}", s.action.ToLower(), s.objectType.ToLower(), s.secondaryObjectName.ToLower(), s.objectName.ToLower()); db.Prompt(installingWhat + "..."); cmdSequence++; int sqlCode = db.Exec(s.sqlText, "install", ""); if (sqlCode != 0) { errCount++; registryTable.addError(db, datamodelVersion, cmdSequence, s.filename, s.lineStart, db.lastErrm, s.sqlText, installingWhat); } s.isInstalled = true; sqlCount++; } } Log.Verbose("install", "{0} found", sqlCount); } Log.Verbose("install", "Check for leftover commands"); // check if any of sqlObjects were left unatended // we can safely ignore: COMMIT bool lefotverFlag = false; foreach (SqlObject s in sqlCommandList) { if (s.commandType != "SQLPlus" && !s.isInstalled && s.action.Trim() != "COMMIT") { lefotverFlag = true; string installingWhat = ""; if (s.secondaryObjectName == "") installingWhat = String.Format("Action={0} ObjectType={1} ObjectName={2}...", s.action.ToLower(), s.objectType.ToLower(), s.objectName.ToLower()); else installingWhat = String.Format("Action={0} ObjectType={1} {2} on {3}...", s.action.ToLower(), s.objectType.ToLower(), s.secondaryObjectName.ToLower(), s.objectName.ToLower()); Log.Warning("install", "Leftover: [Line {0} to {1}] {2}", s.lineStart, s.lineEnd, s.filename); Log.Warning("install", installingWhat); } } // check for errors during install Log.Verbose("install", "Check for erros during install"); bool failedInstall = false; if (errCount > 0) { failedInstall = true; Log.Error("install", "{0} error(s) occured during install", errCount); } if (lefotverFlag) { failedInstall = true; Log.Error("install", "There are lefover SQL commands that did not get installed. See sqlmake log file for details"); } /* Log.Info("install", "Recompile invalid objects"); int invalidCount = db.RecompileInvalidObjects(); if ( invalidCount > 0) { failedInstall = true; Log.Error("install", "{0} invalid object(s) found after recompilation", invalidCount); Console.WriteLine("{0} invalid object(s) found after recompilation", invalidCount); } */ Log.Info("install", ""); Log.Verbose("install", "Set datamodel version in registry table"); if (datamodelVersion == "0") { failedInstall = true; registryTable.setDatamodelVersion(db, "-1"); Log.Error("install", "Unknown version of datamodel installed"); } else { registryTable.setDatamodelVersion(db, datamodelVersion); Log.Info("install", "Version {0} of datamodel installed", datamodelVersion); } db.Close(); // Done if (failedInstall) { Log.ExitError("Installation failed"); } else { Console.ForegroundColor = ConsoleColor.Green; Log.Info("install", "Installation successful"); Console.ResetColor(); } }
public static int getDependantTypesCount(string oracleTypeName, OracleSql db) { Int32 dependantTypesCount = 0; if (db.GetMetaConnection() != null) { string cmdQuery = "select count(*) from user_dependencies where referenced_name = :referenced_name and type = 'TYPE'"; OracleCommand cmd = new OracleCommand(cmdQuery, db.GetMetaConnection()); cmd.Parameters.AddWithValue("referenced_name", oracleTypeName); dependantTypesCount = Convert.ToInt32(cmd.ExecuteScalar()); cmd.Dispose(); } return dependantTypesCount; }