All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
0.4.0 - 2026-04-13
- Replace
sqlct.config.jsonwithsqlct.config.yamlas the project configuration file; config files are now written in YAML with a header comment block containing a tool introduction, installation instructions, usage instructions, and a link to the GitHub repository.
sqlct.config.jsonis no longer supported; existing users should rename the file tosqlct.config.yamland runsqlct configto rewrite it in the new format.
0.3.0 - 2026-04-12
- Script schema-level permissions after schema creation and before schema extended properties.
- Match legacy non-canonical schema-less object filenames to the scripted object name when the canonical name requires percent escaping.
- Allow bare
--objectselectors with dotted schema-less names (for example assemblies) to resolve correctly during targetedstatus,diff, andpull. - Treat equivalent queue option formatting, explicit default
ON [PRIMARY], and disabled default activation as compatible during comparison. - Treat equivalent role-membership statements written as
EXEC sp_addrolemember ...orALTER ROLE ... ADD MEMBER ...as compatible during comparison. - Treat legacy Service Broker message-type validation synonyms and equivalent contract/service body formatting and item ordering as compatible during comparison.
- Treat equivalent
TableDatascripts as compatible during comparison when the normalizedINSERTstatements differ only by row ordering within the same contiguous data block. - Treat equivalent
TableDatascripts as compatible during comparison when single-rowINSERTcolumn lists and corresponding value tuples are reordered consistently. - Treat equivalent
Tablescripts as compatible during comparison when post-create statement packages differ only by ordering after the baseCREATE TABLEblock. - Treat equivalent legacy
Tablestatement formatting as compatible during comparison when normalized table definitions, post-create table statements, and persisted option values are otherwise identical. - Treat equivalent legacy
UserDefinedTypeCREATE TYPEformatting as compatible during comparison when the normalized type definition is otherwise identical. - Treat omitted
TEXTIMAGE_ONonTablescripts as compatible during comparison only when DB metadata shows the table LOB data space matches the current default data space. - Treat equivalent extended-property blocks as compatible during comparison when the normalized
sp_addextendedpropertystatements differ only by ordering, argument spacing, or named-vs-positional argument forms within the same contiguous block. - Treat equivalent extended-property blocks as compatible during comparison when the normalized
sp_addextendedpropertystatements differ only by ordering, argument spacing, named-vs-positional forms, or top-levelN'...'string literal prefixes. - Treat leading SSMS-generated banner comments on programmable objects as compatible during comparison.
- Treat redundant empty or otherwise no-op
GObatches as compatible during comparison. - Treat an omitted terminal
GOafter the final batch as compatible during comparison with an explicit finalGO. - Keep
diffoutput readable by rendering compatibleTableandUserDefinedTypechanges from readable script text instead of opaque comparison-normalized text. - Keep normal
diffoutput readable for non-table objects such as users and roles by rendering permission changes from readable script text instead of lowercase comparison-normalized tokens. - Keep readable
diffoutput forTableand table-valuedUserDefinedTypebodies at per-entry granularity instead of collapsing the entire body into one changed line. - Align readable
Tableand table-valuedUserDefinedTypediffs by individual body entries so a single changed column or inline constraint does not mark the entire body as changed. - Exclude SSMS database-diagram support stored procedures from discovery and scripting even when SQL Server does not mark them as system-shipped.
- Exclude SSMS database-diagram support table and function objects from discovery and scripting even when SQL Server does not mark them as system-shipped.
- Script
TYPE::permissions for scalar and table-valuedUserDefinedTypeobjects. - Script database-level permissions granted directly to
RoleandUserprincipals, and emitCREATE USER ... WITHOUT LOGINwhen no server-login metadata is available. - Treat equivalent contiguous permission statement ordering as compatible during comparison.
- Treat legacy standalone table-level inline
PRIMARY KEYandUNIQUEconstraints as compatible during comparison with canonical post-create key-constraint statements. - Treat legacy CLR table-valued function return-column collation clauses as compatible during comparison when SQL Server ignores them in the effective return shape.
- Treat legacy explicit
NULLtokens on CLR table-valued function return columns as compatible during comparison and preserve them during compatibility reconciliation when the rest of the definition matches. - Treat equivalent legacy
Assemblyscripts as compatible during comparison when they differ only by banner comments, wrapped or case-varied hex payload formatting,PERMISSION_SETspacing, or quoted versus bracketedADD FILEnames. - Rewrite programmable-object declaration lines to the current metadata name when SQL Server stores stale module text after an object rename.
- Fix table-trigger scripting after the declaration rewrite change by resolving trigger schema without referencing a non-existent
sys.triggers.schema_idcolumn. - Trailing semicolon differences on
INSERTstatement lines in data scripts are now suppressed during comparison normalization; scripts emitted with and without statement terminators compare as compatible (#47). - Legacy
TableDatascripts now compare as compatible when they differ from canonical output only bySET IDENTITY_INSERTsemicolons or top-levelN'...'string literal prefixes, including inside multi-lineINSERT ... VALUES (...)statements. - Empty separator lines are now ignored during
statusanddiff, and whitespace-only separator lines compare as compatible after normalization. - Preserve reference banner-comment formatting and module-declaration identifier quoting during programmable-object compatibility reconciliation.
- Preserve compatible computed-column arithmetic grouping parentheses during table compatibility reconciliation.
sqlct initnow scans the target project directory for existingData/*.sqlfiles, extracts table names from the file names, and proposes atrackedTableslist: in interactive mode the user is prompted to confirm before the tables are written to config; in non-interactive mode (with--project-dir) the tables are added automatically.- Discover and script SQL CLR scalar functions as
Functionobjects. - Discover and script SQL CLR table-valued functions as
Functionobjects. - Discover and script SQL CLR stored procedures as
StoredProcedureobjects. - Discover and script SQL CLR aggregates as
Aggregateobjects inFunctions/. - Discover and script built-in
dboas aSchemaobject when it has explicit schema permissions or schema-level extended properties, without emittingCREATE SCHEMA. sqlct initnow prompts interactively for connection details (server, database, auth, credentials, trust-server-certificate) when run without flags in a new project directory (#36).- Connection flags (
--server,--database,--auth,--user,--password,--trust-server-certificate) for non-interactive/scriptedinituse (#36). --skip-connection-testflag forsqlct initto bypass the connection test step (#36).- After
sqlct init, a connection test is attempted before creating any files, reporting success or failure with troubleshooting tips; in interactive mode, a failed test prompts the user to proceed or abort (#36). - Next-steps suggestions are printed after
sqlct initto guide users towardpull,status, anddiff(#36). - Add
--object <selector>tosqlct pullfor exact-match filtering using the same selector forms asdiff --object(#35). - Add
--filter <pattern>tosqlct pullfor regex-based filtering; multiple patterns may be provided and matching is case-insensitive (#35). - Add
--normalized-difftosqlct diffto render comparison-normalized diff text for debugging while preserving readable diff output by default. - Add
--filter <pattern>tosqlct difffor regex-based filtering; without--objectfilters the output to matching objects, with--objectadditionally constrains the single-object result (#35). - SQL Authentication support: set
database.authto"sql"and supplydatabase.user(and optionallydatabase.password) insqlct.config.jsonto connect using SQL Server Authentication (#30). - Support active object type
Assembly, with deterministic scripting toAssemblies/*.sqlfor user-defined SQL Server assemblies. - Support additional active object types:
TableType,XmlSchemaCollection,MessageType,Contract,Queue,Service,Route,EventNotification,ServiceBinding,FullTextCatalog,FullTextStoplist, andSearchPropertyList. - Script standalone user-created table statistics as deterministic post-create table statements, including filtered, effective sampling, persisted-sample, incremental, and auto-drop metadata when available.
- Script persisted key and index storage options such as fill factor, pad index, duplicate-key handling, and row/page locking when those options differ from defaults.
- Add
--object <pattern>tosqlct data trackandsqlct data untrackas a flag alias for the positional pattern argument. - Add
--filter <regex>tosqlct data trackandsqlct data untrackfor regex-based table matching; matched case-insensitively against the fullschema.tabledisplay name. Exactly one of the positional pattern,--object, or--filtermust be provided; combining any two returns exit code 2. sqlct diffnow uses a chunked diff format: only changed segments and configurable surrounding context lines are shown instead of the full file. Use--context <N>to control the number of context lines (default: 3) (#39).
- In
diff --objectmode, database discovery and scripting are now limited to the selector-matching candidate set instead of scanning the full active object set, improving performance for targeted diffs (#28). - In
pull --objectmode, database discovery and scripting are now limited to the selector-matching candidate object set instead of scanning the full active object set (#38). - In
diff --filtermode (without--object), database scripting is now limited to objects whose display name matches at least one pattern, avoiding unnecessary reads (#38). - In
pull --filtermode, database scripting is now limited to objects whose display name matches at least one pattern, avoiding unnecessary reads (#38). - Collapse table-valued types into
UserDefinedType, writing all UDT scripts toTypes/User-defined Data Types/;TableType:selectors andTypes/Table Types/are no longer supported. - Extend scripting for the newly supported securables to emit permissions and extended properties where SQL Server exposes them, with platform-limited cases documented in specs and package docs.
- Close additional
SqlDataReaderscopes in object-type scripting paths to avoidThere is already an open DataReader associated with this Connectionfailures duringstatus,diff, andpull.
0.2.1 - 2026-04-07
- Support for .NET 8 alongside .NET 10 (multi-targeted); CI validates both frameworks (#16).
- Ensure
SqlDataReaderinstances are closed after use inSqlServerScripterto prevent "There is already an open DataReader" errors (#25).
0.2.0 - 2026-04-07
- Support for additional active object types:
Sequence,Schema,Role,User,Synonym,UserDefinedType,PartitionFunction,PartitionScheme(#4). - Add
sqlct data track,sqlct data untrack, andsqlct data listcommands for managing explicit tracked tables used for data scripting (#15). - Add tracked-table
TableDatascripting tostatus,diff, andpull, includingData/Schema.Table_Data.sqloutput and thedata:schema.namediff selector (#15). - Parallelism option (
options.parallelism) for database introspection; defaults to processor count when set to0(#9). - Add a progress bar for long-running commands (#3).
- Add --version / -v to print the installed sqlct semantic version (#2).
- Change
statusandpulloutput to report schema and data summaries separately when tracked-table data scripting is configured (#15).
- Remove unused
options.orderByDependenciesconfig option; legacy configs containing this field continue to load without error but the field is stripped on save.
- Parameter-level MS_Description extended properties are not scripted for procedures and functions (#5).
sqlct configshould fail with a clear error if executed in a non-initialized project directory (#1).
0.1.0 - 2026-03-22
sqlct initcommand — scaffolds a new schema-folder project withsqlct.config.jsonand folder structure.sqlct configcommand — validates and displays the current project configuration.sqlct statuscommand — compares the live database against the local schema folder and reports added, changed, and deleted objects.sqlct diffcommand — shows unified diffs for individual objects or all changed objects.sqlct pullcommand — reconciles the local schema folder from the live database (create, update, delete files).- Support for active object types:
Table,View,StoredProcedure,Function. - Human-readable and JSON output modes for
status,diff, andpull. - Deterministic script ordering (dependency-aware where applicable).
- Extended property scripting support for database objects.
- Exit codes aligned with spec:
0(no diffs),1(diffs present),2/3/4(failure categories). - NuGet CI publish workflow triggered on version tag push.