using System; using System.Globalization; namespace SyncEngine.Access { /// Translates Access DefaultValue expressions to T-SQL DEFAULT literals. public static class AccessDefaultTranslator { public static bool IsNullDefault(string accessDefault) { if (string.IsNullOrWhiteSpace(accessDefault)) { return false; } var expr = accessDefault.Trim(); if (expr.StartsWith("=", StringComparison.Ordinal)) { expr = expr.Substring(1).Trim(); } return string.Equals(expr, "Null", StringComparison.OrdinalIgnoreCase); } public static bool TryTranslate(string accessDefault, out string sqlExpression) { sqlExpression = null; if (string.IsNullOrWhiteSpace(accessDefault)) { return false; } if (IsNullDefault(accessDefault)) { return false; } var expr = accessDefault.Trim(); if (expr.StartsWith("=", StringComparison.Ordinal)) { expr = expr.Substring(1).Trim(); } if (string.Equals(expr, "Now()", StringComparison.OrdinalIgnoreCase) || string.Equals(expr, "Date()", StringComparison.OrdinalIgnoreCase) || string.Equals(expr, "Time()", StringComparison.OrdinalIgnoreCase)) { sqlExpression = "GETDATE()"; return true; } if (TryTranslateAccessDateLiteral(expr, out sqlExpression)) { return true; } if (string.Equals(expr, "False", StringComparison.OrdinalIgnoreCase) || string.Equals(expr, "No", StringComparison.OrdinalIgnoreCase)) { sqlExpression = "0"; return true; } if (string.Equals(expr, "True", StringComparison.OrdinalIgnoreCase) || string.Equals(expr, "Yes", StringComparison.OrdinalIgnoreCase)) { sqlExpression = "1"; return true; } if (expr == "\"\"" || expr == "''") { sqlExpression = "N''"; return true; } if (IsQuotedString(expr, '"', out var doubleQuoted)) { sqlExpression = "N'" + doubleQuoted.Replace("'", "''") + "'"; return true; } if (IsQuotedString(expr, '\'', out var singleQuoted)) { sqlExpression = "N'" + singleQuoted.Replace("'", "''") + "'"; return true; } if (decimal.TryParse(expr, NumberStyles.Number, CultureInfo.InvariantCulture, out _)) { sqlExpression = expr; return true; } return false; } private static bool TryTranslateAccessDateLiteral(string expr, out string sqlExpression) { sqlExpression = null; if (expr.Length < 3 || expr[0] != '#' || expr[expr.Length - 1] != '#') { return false; } var dateText = expr.Substring(1, expr.Length - 2); if (!DateTime.TryParse(dateText, CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsed) && !DateTime.TryParse(dateText, CultureInfo.CurrentCulture, DateTimeStyles.None, out parsed)) { return false; } sqlExpression = "'" + parsed.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture) + "'"; return true; } private static bool IsQuotedString(string expr, char quote, out string inner) { inner = null; if (expr.Length < 2 || expr[0] != quote || expr[expr.Length - 1] != quote) { return false; } inner = expr.Substring(1, expr.Length - 2); return true; } public static string BuildDefaultConstraintName(string tableName, string columnName) { var name = "DF_" + SqlServer.SqlIdentifierHelper.SanitizeConstraintName(tableName) + "_" + SqlServer.SqlIdentifierHelper.SanitizeConstraintName(columnName); return name.Length <= 128 ? name : name.Substring(0, 128); } } }