Initial commit

master
Stefan Hutter 4 years ago
commit 3afa4c82ef

@ -0,0 +1,11 @@
root = true
[*]
end_of_line = crlf
insert_final_newline = true
trim_trailing_whitespace = true
# 4 space indentation
[*.cs]
indent_style = space
indent_size = 4

6
.gitattributes vendored

@ -0,0 +1,6 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Declare files that will always have CRLF line endings on checkout.
# required for unit tests to pass on any platform
*.sql text eol=crlf

352
.gitignore vendored

@ -0,0 +1,352 @@
# Created by https://www.gitignore.io/api/csharp
# Edit at https://www.gitignore.io/?templates=csharp
### Csharp ###
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
.vs
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- Backup*.rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# End of https://www.gitignore.io/api/csharp

@ -0,0 +1,7 @@
rem cd %1
git init
git remote add origin http://192.168.111.85:30000/shu/OpenDBDiff.git
git add .
git commit -m "Initial commit"
git push -u origin master
pause

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

@ -0,0 +1,33 @@
using System;
namespace OpenDBDiff.Abstractions.Schema.Attributes
{
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public sealed class SchemaNodeAttribute : Attribute
{
public SchemaNodeAttribute(string name)
{
this.Name = name;
this.Image = "Folder";
}
public SchemaNodeAttribute(string name, string image)
{
this.Name = name;
this.Image = image;
}
public SchemaNodeAttribute(string name, string image, Boolean isFullName)
{
this.Name = name;
this.Image = image;
this.IsFullName = isFullName;
}
public string Name { get; private set; }
public string Image { get; private set; }
public Boolean IsFullName { get; private set; }
}
}

@ -0,0 +1,25 @@
namespace OpenDBDiff.Abstractions.Schema.Errors
{
public class MessageLog
{
public enum LogType
{
Information = 0,
Warning = 1,
Error = 2
}
public MessageLog(string description, string fullDescription, LogType type)
{
this.Description = description;
this.FullDescription = fullDescription;
this.Type = type;
}
public LogType Type { get; private set; }
public string FullDescription { get; private set; }
public string Description { get; private set; }
}
}

@ -0,0 +1,17 @@
using System;
namespace OpenDBDiff.Abstractions.Schema.Events
{
public class ProgressEventArgs : EventArgs
{
public string Message { get; set; }
public ProgressEventArgs(string message, int progress)
{
this.Progress = progress;
this.Message = message;
}
public int Progress { get; set; }
}
}

@ -0,0 +1,14 @@
namespace OpenDBDiff.Abstractions.Schema.Events
{
public class ProgressEventHandler
{
public delegate void ProgressHandler(ProgressEventArgs e);
public static event ProgressHandler OnProgress;
public static void RaiseOnChange(ProgressEventArgs e)
{
if (OnProgress != null) OnProgress(e);
}
}
}

@ -0,0 +1,43 @@
using System;
using System.Globalization;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
namespace OpenDBDiff.Abstractions.Schema.Misc
{
[Serializable]
public class SchemaException : Exception
{
private static void Write(string message)
{
try
{
StreamWriter writer = new StreamWriter(Path.Combine(Path.GetTempPath(), "OpenDBDiff.log"), true, Encoding.ASCII);
writer.WriteLine("ERROR: " + DateTime.Now.ToString("yyyy/MM/dd hh:mm", CultureInfo.InvariantCulture) + "-" + message);
writer.Close();
}
finally { }
}
public SchemaException() : base()
{
}
public SchemaException(string message)
: base(message)
{
Write(base.StackTrace);
}
public SchemaException(string message, Exception exception)
: base(message, exception)
{
Write(exception.StackTrace);
}
protected SchemaException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}

@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace OpenDBDiff.Abstractions.Schema.Model
{
public interface IDatabase : ISchemaBase
{
bool IsCaseSensitive { get; }
SqlAction ActionMessage { get; }
IOption Options { get; }
new SQLScriptList ToSqlDiff(ICollection<ISchemaBase> selectedSchemas);
ISchemaBase Find(string objectFullName);
}
}

@ -0,0 +1,22 @@
namespace OpenDBDiff.Abstractions.Schema.Model
{
public interface IOption
{
IOptionFilter Filters { get; }
IOptionsContainer<string> Defaults { get; }
IOptionsContainer<bool> Ignore { get; }
IOptionsContainer<bool> Script { get; }
IOptionComparison Comparison { get; }
string Serialize();
}
public interface IOptionsContainer<T>
{
System.Collections.Generic.IDictionary<string, T> GetOptions();
}
public interface IOptionComparison : IOptionsContainer<string>
{
bool ReloadComparisonOnUpdate { get; set; }
}
}

@ -0,0 +1,7 @@
namespace OpenDBDiff.Abstractions.Schema.Model
{
public interface IOptionFilter : IOptionsContainer<string>
{
bool IsItemIncluded(ISchemaBase item);
}
}

@ -0,0 +1,31 @@
using System;
namespace OpenDBDiff.Abstractions.Schema.Model
{
public interface ISchemaBase
{
ISchemaBase Clone(ISchemaBase parent);
int DependenciesCount { get; }
string FullName { get; }
int Id { get; set; }
Boolean HasState(ObjectStatus statusFind);
string Name { get; set; }
string Owner { get; set; }
ISchemaBase Parent { get; set; }
ObjectStatus Status { get; set; }
Boolean IsSystem { get; set; }
ObjectType ObjectType { get; set; }
Boolean GetWasInsertInDiffList(ScriptAction action);
void SetWasInsertInDiffList(ScriptAction action);
void ResetWasInsertInDiffList();
string ToSqlDrop();
string ToSqlAdd();
string ToSql();
SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas);
SQLScript Create();
SQLScript Drop();
int CompareFullNameTo(string name, string myName);
Boolean IsCodeType { get; }
IDatabase RootParent { get; }
}
}

@ -0,0 +1,16 @@
namespace OpenDBDiff.Abstractions.Schema.Model
{
public interface ISchemaList<T, P>
where T : ISchemaBase
where P : ISchemaBase
{
void Add(T item);
SchemaList<T, P> Clone(P parentObject);
bool Contains(string name);
T Find(int id);
T this[string name] { get; set; }
T this[int index] { get; set; }
P Parent { get; }
int Count { get; }
}
}

@ -0,0 +1,286 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace OpenDBDiff.Abstractions.Schema.Model
{
[DebuggerDisplay("Id: {Id} - Name: {Name} - Status: {status}")]
public abstract class SchemaBase : ISchemaBase
{
private ObjectStatus status;
private ISchemaBase parent;
private string nameCharacterOpen;
private string nameCharacterClose;
private Hashtable wasInsertInDiffList;
private IDatabase rootParent = null;
protected SchemaBase(string nameCharacterOpen, string nameCharacterClose, ObjectType objectType)
{
this.Guid = System.Guid.NewGuid().ToString();
this.ObjectType = objectType;
this.status = ObjectStatus.Original;
this.nameCharacterClose = nameCharacterClose;
this.nameCharacterOpen = nameCharacterOpen;
}
/*protected object Clone(object vObj, ISchemaBase parentObject)
{
if (vObj.GetType().IsValueType || vObj.GetType() == Type.GetType("System.String"))
return vObj;
else
{
object newObject = Activator.CreateInstance(vObj.GetType(), new object[] {parentObject });
foreach (PropertyInfo Item in newObject.GetType().GetProperties())
{
if (Item.GetType().GetInterface("ICloneable") != null)
{
ICloneable IClone = (ICloneable)Item.GetValue(vObj, null);
Item.SetValue(newObject, IClone.Clone(), null);
}
else
Item.SetValue(newObject, Clone(Item.GetValue(vObj, null),parentObject), null);
}
foreach (FieldInfo Item in newObject.GetType().GetFields())
{
if (Item.GetType().GetInterface("ICloneable") != null)
{
ICloneable IClone = (ICloneable)Item.GetValue(vObj);
Item.SetValue(newObject, IClone.Clone());
}
else
Item.SetValue(newObject, Clone(Item.GetValue(vObj),parentObject));
}
return newObject;
}
} */
/// <summary>
/// Instance's parent object
/// </summary>
public ISchemaBase Parent
{
get { return parent; }
set
{
rootParent = null;
parent = value;
}
}
public IDatabase RootParent
{
get
{
if (rootParent != null) return rootParent;
if (this.Parent != null)
{
if (this.Parent.Parent != null)
if (this.Parent.Parent.Parent != null)
rootParent = (IDatabase)this.Parent.Parent.Parent;
else
rootParent = (IDatabase)this.Parent.Parent;
else
rootParent = (IDatabase)this.Parent;
}
else if (this is IDatabase)
{
rootParent = (IDatabase)this;
}
return rootParent;
}
}
public int CompareFullNameTo(string name, string myName)
{
if (!RootParent.IsCaseSensitive)
return myName.ToUpper().CompareTo(name.ToUpper());
else
return myName.CompareTo(name);
}
/// <summary>
/// SQL Code for the database object
/// </summary>
public abstract string ToSql();
/// <summary>
/// SQL Code for drop the database object
/// </summary>
public abstract string ToSqlDrop();
/// <summary>
/// SQL Code for add the database object
/// </summary>
public abstract string ToSqlAdd();
/// <summary>
/// Deep clone the object
/// </summary>
/// <param name="parent">Parent of the object</param>
/// <returns></returns>
public virtual ISchemaBase Clone(ISchemaBase parent)
{
return null;
}
/// <summary>
/// Returns the list of SQL Scripts to execute to sync for the specified schemas
/// </summary>
/// <returns>
/// A list (<see cref="SQLScriptList"/>) of scripts to run to sync
/// </returns>
public virtual SQLScriptList ToSqlDiff(ICollection<ISchemaBase> schemas)
{
return null;
}
public virtual SQLScript Create()
{
throw new NotImplementedException();
}
public virtual SQLScript Drop()
{
throw new NotImplementedException();
}
/// <summary>
/// Returns if the obecet was already inserted in the list of scripts with differencies
/// </summary>
/// <param name="action">The action to check in the list</param>
/// <returns>True if is already inserted. False if it wasn't</returns>
public Boolean GetWasInsertInDiffList(ScriptAction action)
{
if (wasInsertInDiffList != null)
return (wasInsertInDiffList.ContainsKey(action));
else
return false;
}
/// <summary>
/// Sets the object as inserted in the list of differences script
/// </summary>
public void SetWasInsertInDiffList(ScriptAction action)
{
if (wasInsertInDiffList == null) wasInsertInDiffList = new Hashtable();
if (!wasInsertInDiffList.ContainsKey(action))
wasInsertInDiffList.Add(action, true);
}
public void ResetWasInsertInDiffList()
{
this.wasInsertInDiffList = null;
}
/// <summary>
/// Unique GUID identifying the object
/// </summary>
public string Guid { get; set; }
/// <summary>
/// Object type. <seealso cref="ObjectType"/>
/// </summary>
public ObjectType ObjectType { get; set; }
/// <summary>
/// ID del objeto.
/// </summary>
public int Id { get; set; }
/// <summary>
/// Nombre completo del objeto, incluyendo el owner.
/// </summary>
public virtual string FullName
{
get
{
if (String.IsNullOrEmpty(Owner))
return nameCharacterOpen + Name + nameCharacterClose;
else
return nameCharacterOpen + Owner + nameCharacterClose + "." + nameCharacterOpen + Name + nameCharacterClose;
}
}
/// <summary>
/// Username of the owner of the object
/// </summary>
public string Owner { get; set; }
/// <summary>
/// Nombre of the object
/// </summary>
public string Name { get; set; }
/// <summary>
/// Determine if the database object if a System object or not
/// </summary>
public Boolean IsSystem { get; set; }
/// <summary>
/// Returns the status of the object. By default is set to <see cref="ObjectStatus.Original"/>. When setting a value, it also affects to the <see cref="Parent"/> status.
/// </summary>
public virtual ObjectStatus Status
{
get { return status; }
set
{
if (status != ObjectStatus.Rebuild && status != ObjectStatus.RebuildDependencies)
status = value;
if (Parent == null) return;
// Si el estado de la tabla era el original, lo cambia, sino deja el actual estado.
// If the state of the table was the original, it changes it, but leaves the current state. (Google translated)
if (Parent.Status == ObjectStatus.Original
|| value == ObjectStatus.Rebuild
|| value == ObjectStatus.RebuildDependencies)
{
switch (value)
{
case ObjectStatus.RebuildDependencies:
case ObjectStatus.Rebuild:
Parent.Status = value;
break;
case ObjectStatus.Original:
break;
default:
Parent.Status = ObjectStatus.Alter;
break;
}
}
}
}
public Boolean HasState(ObjectStatus statusFind)
{
return ((this.Status & statusFind) == statusFind);
}
public virtual Boolean IsCodeType
{
get { return false; }
}
public virtual int DependenciesCount
{
get { return 0; }
}
public virtual bool HasDependencies
{
get { return DependenciesCount > 0; }
}
/// <summary>
/// Get if the SQL commands for the collection must build in one single statement
/// or one statmente for each item of the collection.
/// </summary>
public virtual Boolean MustBuildSqlInLine
{
get { return false; }
}
}
}

@ -0,0 +1,146 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OpenDBDiff.Abstractions.Schema.Model
{
public class SchemaList<T, P> : List<T>, ISchemaList<T, P>
where T : ISchemaBase
where P : ISchemaBase
{
private Dictionary<string, int> nameMap = new Dictionary<string, int>();
private SearchSchemaBase allObjects = null;
private bool IsCaseSensitive = false;
public SchemaList(P parent, SearchSchemaBase allObjects)
{
this.Parent = parent;
this.allObjects = allObjects;
this.Comparion = StringComparison.CurrentCultureIgnoreCase;
}
public SchemaList<T, P> Clone(P parentObject)
{
SchemaList<T, P> options = new SchemaList<T, P>(parentObject, allObjects);
this.ForEach(item =>
{
object cloned = item.Clone(parentObject);
//Not everything implements the clone methd, so make sure we got some actual cloned data before adding it back to the list
if (cloned != null)
options.Add((T)cloned);
});
return options;
}
protected StringComparison Comparion { get; private set; }
public SchemaList(P parent)
{
this.Parent = parent;
}
public new void Add(T item)
{
var db = this.Parent.RootParent;
if (!db.Options.Filters.IsItemIncluded(item))
return;
base.Add(item);
if (allObjects != null)
allObjects.Add(item);
string name = item.FullName;
IsCaseSensitive = item.RootParent.IsCaseSensitive;
if (!IsCaseSensitive)
name = name.ToUpper();
if (!nameMap.ContainsKey(name))
nameMap.Add(name, base.Count - 1);
}
/// <summary>
/// Devuelve el objecto Padre perteneciente a la coleccion.
/// </summary>
public P Parent { get; private set; }
/// <summary>
/// Devuelve el objeto correspondiente a un ID especifico.
/// </summary>
/// <param name="id">ID del objecto a buscar</param>
/// <returns>Si no encontro nada, devuelve null, de lo contrario, el objeto</returns>
public T Find(int id)
{
return Find(Item => Item.Id == id);
}
/// <summary>
/// Indica si el nombre del objecto existe en la coleccion de objectos del mismo tipo.
/// </summary>
/// <param name="table">
/// Nombre del objecto a buscar.
/// </param>
/// <returns></returns>
public Boolean Contains(string name)
{
if (IsCaseSensitive)
return nameMap.ContainsKey(name);
else
return nameMap.ContainsKey(name.ToUpper());
}
public virtual T this[string name]
{
get
{
try
{
if (IsCaseSensitive)
return this[nameMap[name]];
else
return this[nameMap[name.ToUpper()]];
}
catch
{
return default(T);
}
}
set
{
if (IsCaseSensitive)
base[nameMap[name]] = value;
else
base[nameMap[name.ToUpper()]] = value;
}
}
public virtual SQLScriptList ToSqlDiff()
{
return ToSqlDiff(new List<ISchemaBase>());
}
public virtual SQLScriptList ToSqlDiff(ICollection<ISchemaBase> schemas)
{
SQLScriptList listDiff = new SQLScriptList();
foreach (var item in this.Where(item => (schemas.Count() == 0 || schemas.FirstOrDefault(sch => sch.Id == item.Id || (sch.Parent != null && sch.Parent.Id == item.Id)) != default(ISchemaBase))))
{
item.ResetWasInsertInDiffList();
var childrenSchemas = schemas.Where(s => s.Parent != null && s.Parent.Id == item.Id).ToList();
listDiff.AddRange(item.ToSqlDiff(childrenSchemas).WarnMissingScript(item));
}
return listDiff;
}
public virtual string ToSql()
{
return string.Join
(
"\r\n",
this
.Where(item => !item.HasState(ObjectStatus.Drop))
.Select(item => item.ToSql())
);
}
}
}

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
namespace OpenDBDiff.Abstractions.Schema.Model
{
public class SearchSchemaBase
{
private Dictionary<String, ObjectType> objectTypes;
private Dictionary<String, String> objectParent;
private Dictionary<Int32, String> objectId;
public SearchSchemaBase()
{
objectTypes = new Dictionary<string, ObjectType>();
objectParent = new Dictionary<string, string>();
objectId = new Dictionary<Int32, string>();
}
public void Add(ISchemaBase item)
{
if (objectTypes.ContainsKey(item.FullName.ToUpper()))
objectTypes.Remove(item.FullName.ToUpper());
objectTypes.Add(item.FullName.ToUpper(), item.ObjectType);
if ((item.ObjectType == ObjectType.Constraint) || (item.ObjectType == ObjectType.Index) || (item.ObjectType == ObjectType.Trigger) || (item.ObjectType == ObjectType.CLRTrigger))
{
if (objectParent.ContainsKey(item.FullName.ToUpper()))
objectParent.Remove(item.FullName.ToUpper());
objectParent.Add(item.FullName.ToUpper(), item.Parent.FullName);
if (objectId.ContainsKey(item.Id))
objectId.Remove(item.Id);
objectId.Add(item.Id, item.FullName);
}
}
public Nullable<ObjectType> GetType(string FullName)
{
if (objectTypes.ContainsKey(FullName.ToUpper()))
return objectTypes[FullName.ToUpper()];
return null;
}
public string GetParentName(string FullName)
{
return objectParent[FullName.ToUpper()];
}
public string GetFullName(int Id)
{
return objectId[Id];
}
}
}

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{406558A0-1B98-4D0E-B8B6-2013700B065A}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OpenDBDiff.Abstractions.Schema</RootNamespace>
<AssemblyName>OpenDBDiff.Abstractions.Schema</AssemblyName>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\OpenDBDiff\Properties\AssemblyVersionInfo.cs">
<Link>Properties\AssemblyVersionInfo.cs</Link>
</Compile>
<Compile Include="Attributes\SchemaNodeAttribute.cs" />
<Compile Include="Errors\MessageLog.cs" />
<Compile Include="Events\ProgressEventArgs.cs" />
<Compile Include="Events\ProgressEventHandler.cs" />
<Compile Include="Model\IDatabase.cs" />
<Compile Include="Model\IOption.cs" />
<Compile Include="Model\IOptionFilter.cs" />
<Compile Include="Model\ISchemaList.cs" />
<Compile Include="Model\SchemaList.cs" />
<Compile Include="Misc\SchemaException.cs" />
<Compile Include="Model\ISchemaBase.cs" />
<Compile Include="Model\SchemaBase.cs" />
<Compile Include="Model\SearchSchemaBase.cs" />
<Compile Include="SqlAction.cs" />
<Compile Include="SQLScript.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SQLScriptList.cs" />
<Compile Include="StatusEnum.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\.editorconfig">
<Link>.editorconfig</Link>
</None>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

@ -0,0 +1,24 @@
using System;
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenDBDiff.Abstractions.Schema")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OpenDBDiff.Abstractions.Schema")]
[assembly: AssemblyCopyright("OpenDBDiff")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("713fb09f-31e8-40a9-a6d0-93e28dc5ef67")]
[assembly: CLSCompliant(true)]

@ -0,0 +1,72 @@
using System;
namespace OpenDBDiff.Abstractions.Schema
{
public class SQLScript : IComparable<SQLScript>
{
public SQLScript(int deepvalue, string sqlScript, int dependenciesCount, ScriptAction action)
{
SQL = sqlScript;
Dependencies = dependenciesCount;
Status = action;
Deep = deepvalue;
//childs = new SQLScriptList();
}
public SQLScript(string sqlScript, int dependenciesCount, ScriptAction action)
{
SQL = sqlScript;
Dependencies = dependenciesCount;
Status = action;
//childs = new SQLScriptList();
}
/*public SQLScriptList Childs
{
get { return childs; }
set { childs = value; }
}*/
public int Deep { get; set; }
public ScriptAction Status { get; set; }
public int Dependencies { get; set; }
public string SQL { get; set; }
public bool IsDropAction
{
get
{
return ((Status == ScriptAction.DropView) || (Status == ScriptAction.DropFunction) || (Status == ScriptAction.DropStoredProcedure));
}
}
public bool IsAddAction
{
get
{
return ((Status == ScriptAction.AddView) || (Status == ScriptAction.AddFunction) || (Status == ScriptAction.AddStoredProcedure));
}
}
public int CompareTo(SQLScript other)
{
if (this.Deep == other.Deep)
{
if (this.Status == other.Status)
{
if (this.Status == ScriptAction.DropTable || this.Status == ScriptAction.DropConstraint || this.Status == ScriptAction.DropTrigger)
return other.Dependencies.CompareTo(this.Dependencies);
else
return this.Dependencies.CompareTo(other.Dependencies);
}
else
return this.Status.CompareTo(other.Status);
}
else
return this.Deep.CompareTo(other.Deep);
}
}
}

@ -0,0 +1,135 @@
using OpenDBDiff.Abstractions.Schema.Model;
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenDBDiff.Abstractions.Schema
{
public class SQLScriptList
{
private List<SQLScript> list;
public void Sort()
{
if (list != null) list.Sort();
}
public void Add(SQLScript item, int deep)
{
if (list == null) list = new List<SQLScript>();
if (item != null)
{
item.Deep = deep;
list.Add(item);
}
}
public void Add(SQLScript item)
{
if (list == null) list = new List<SQLScript>();
if (item != null) list.Add(item);
}
public void Add(string SQL, int dependencies, ScriptAction type)
{
if (list == null) list = new List<SQLScript>();
list.Add(new SQLScript(SQL, dependencies, type));
}
public void AddRange(SQLScriptList items)
{
for (int j = 0; j < items.Count; j++)
{
if (list == null) list = new List<SQLScript>();
list.Add(items[j]);
}
}
public int Count
{
get { return (list == null) ? 0 : list.Count; }
}
public SQLScript this[int index]
{
get { return list[index]; }
}
/*private string ToSqlDown(SQLScript item)
{
string sql = "";
for (int i = 0; i < item.Childs.Count; i++)
{
for (int k = 0; k < item.Childs[i].Childs.Count; k++)
{
for (int h = 0; h < item.Childs[i].Childs[k].Childs.Count; h++)
{
for (int l = 0; l < item.Childs[i].Childs[k].Childs[h].Childs.Count; l++)
{
for (int m = 0; m < item.Childs[i].Childs[k].Childs[h].Childs[l].Childs.Count; m++)
{
sql += item.Childs[i].Childs[k].Childs[h].Childs[l].Childs[m].SQL;
}
sql += item.Childs[i].Childs[k].Childs[h].Childs[l].SQL;
}
sql += item.Childs[i].Childs[k].Childs[h].SQL;
}
sql += item.Childs[i].Childs[k].SQL;
}
sql += item.Childs[i].SQL;
}
sql += item.SQL;
return sql;
}*/
public string ToSQL()
{
StringBuilder sql = new StringBuilder();
this.Sort(); /*Ordena la lista antes de generar el script*/
if (list != null)
{
for (int j = 0; j < list.Count; j++)
{
//if ((list[j].IsDropAction) || (!list[j].IsAddAction))
sql.Append(list[j].SQL); //ToSqlDown(list[j]);
}
/*for (int j = list.Count-1; j >= 0; j--)
{
if (list[j].IsAddAction)
sql.Append(list[j].SQL);
}*/
}
return sql.ToString();
}
public SQLScriptList FindAlter()
{
SQLScriptList alter = new SQLScriptList();
list.ForEach(item => { if ((item.Status == ScriptAction.AlterView) || (item.Status == ScriptAction.AlterFunction) || (item.Status == ScriptAction.AlterProcedure)) alter.Add(item); });
return alter;
}
}
public static class SQLScriptListExtensionMethod
{
public static SQLScriptList WarnMissingScript(this SQLScriptList scriptList, ISchemaBase scriptSource)
{
if (scriptList == null || scriptSource == null || scriptSource.Status == ObjectStatus.Original)
{
return scriptList;
}
for (int i = 0; i < scriptList.Count; ++i)
{
if (!String.IsNullOrEmpty(scriptList[i].SQL))
{
return scriptList;
}
}
scriptList.Add(String.Format("\r\n--\r\n-- DIFF-ERROR 0x{0:x8}.{1:d3}: Missing {2} script for {3} '{4}'\r\n--\r\n\r\n", (int)scriptSource.Status, (int)scriptSource.ObjectType, scriptSource.Status, scriptSource.ObjectType, scriptSource.Name), 0, ScriptAction.None);
return scriptList;
}
}
}

@ -0,0 +1,90 @@
using OpenDBDiff.Abstractions.Schema.Model;
using System.Collections.Generic;
namespace OpenDBDiff.Abstractions.Schema
{
public class SqlAction
{
public SqlAction(ISchemaBase item)
{
if ((item.ObjectType == ObjectType.Column) || (item.ObjectType == ObjectType.Index) || (item.ObjectType == ObjectType.Constraint))
this.Name = item.Name;
else
this.Name = item.FullName;
this.Action = item.Status;
this.Type = item.ObjectType;
Childs = new List<SqlAction>();
}
public void Add(ISchemaBase item)
{
Childs.Add(new SqlAction(item));
}
public SqlAction this[string name]
{
get
{
for (int j = 0; j < Childs.Count; j++)
{
if (Childs[j].Name.Equals(name))
return Childs[j];
}
return null;
}
}
public string Name { get; private set; }
public ObjectType Type { get; set; }
public ObjectStatus Action { get; set; }
public List<SqlAction> Childs { get; private set; }
private string GetTypeName()
{
if (Type == ObjectType.Table) return "TABLE";
if (Type == ObjectType.Column) return "COLUMN";
if (Type == ObjectType.Constraint) return "CONSTRAINT";
if (Type == ObjectType.Index) return "INDEX";
if (Type == ObjectType.View) return "VIEW";
if (Type == ObjectType.StoredProcedure) return "STORED PROCEDURE";
if (Type == ObjectType.Synonym) return "SYNONYM";
if (Type == ObjectType.Function) return "FUNCTION";
if (Type == ObjectType.Assembly) return "ASSEMBLY";
if (Type == ObjectType.Trigger) return "TRIGGER";
return "";
}
private bool IsRoot
{
get
{
return ((this.Type != ObjectType.Function) && (this.Type != ObjectType.StoredProcedure) && (this.Type != ObjectType.View) && (this.Type != ObjectType.Table) && (this.Type != ObjectType.Database));
}
}
public string Message
{
get
{
string message = "";
if (Action == ObjectStatus.Drop)
message = "DROP " + GetTypeName() + " " + Name + "\r\n";
if (Action == ObjectStatus.Create)
message = "ADD " + GetTypeName() + " " + Name + "\r\n";
if ((Action == ObjectStatus.Alter) || (Action == ObjectStatus.Rebuild) || (Action == ObjectStatus.RebuildDependencies))
message = "MODIFY " + GetTypeName() + " " + Name + "\r\n";
Childs.ForEach(item =>
{
if (item.IsRoot)
message += " ";
message += item.Message;
});
return message;
}
}
}
}

@ -0,0 +1,231 @@
using System;
using System.ComponentModel;
namespace OpenDBDiff.Abstractions.Schema
{
/// <summary>
/// Original = The object has no modifications.
/// Create = The object must be created.
/// Drop = The object must be deleted.
/// Alter = The object has modifications.
/// AlterRebuild = The object has modifications, but a DROP and ADD must be done too.
/// AlterProperties = The object has modifications in its properties, but not in its structure.
/// </summary>
[Flags]
public enum ObjectStatus
{
/// <summary>
/// The object is unaltered
/// </summary>
Original = 0,
/// <summary>
/// The object was altered
/// </summary>
Alter = 2,
AlterBody = 4,
/// <summary>
/// The object was altered but requires a rebuild
/// </summary>
Rebuild = 8,
/// <summary>
/// The object has properties altered, but not in it's structure
/// </summary>
RebuildDependencies = 16,
Update = 32,
Create = 64,
/// <summary>
/// The object should be dropped
/// </summary>
Drop = 128,
Disabled = 256,
/// <summary>
/// The owner of the object changed
/// </summary>
ChangeOwner = 512,
DropOlder = 1024,
Bind = 2048,
/// <summary>
/// The permission set of the object changed
/// </summary>
PermissionSet = 4096,
AlterWhitespace = 8192
}
public enum ScriptAction
{
None = 0,
UseDatabase = 1,
AddFileGroup = 2,
AddFile = 3,
AlterFile = 4,
AlterFileGroup = 5,
UnbindRuleColumn = 6,
UnbindRuleType = 7,
DropRule = 8,
AddRule = 9,
DropFullTextIndex = 10,
DropConstraintFK = 11,
DropConstraint = 12,
DropConstraintPK = 13,
DropSynonyms = 14,
DropStoredProcedure = 15,
DropTrigger = 16,
DropView = 17,
DropFunction = 17,
DropIndex = 18,
DropTable = 20,
AlterColumnFormula = 21,
AlterColumn = 22,
AddRole = 23,
AddUser = 24,
AddSchema = 25,
AddDefault = 26,
AddAssembly = 27,
AddAssemblyFile = 28,
AddUserDataType = 29,
AddTableType = 30,
AlterPartitionFunction = 31,
AddPartitionFunction = 32,
AddPartitionScheme = 33,
AddFullText = 34,
AddXMLSchema = 35,
AlterAssembly = 36,
UpdateTable = 37,
AlterTable = 38,
AlterIndex = 39,
AlterFullTextIndex = 40,
AddTable = 41,
RebuildTable = 42,
AlterColumnRestore = 43,
AlterColumnFormulaRestore = 44,
AlterFunction = 45,
AlterView = 46,
AlterProcedure = 47,
AddIndex = 48,
AddFunction = 49,
AddView = 49, /*AddFunction and AddView must have the same number!!!*/
AddTrigger = 50,
AddConstraint = 51,
AddConstraintPK = 52,
AddConstraintFK = 53,
AlterConstraint = 54,
AddFullTextIndex = 55,
EnabledTrigger = 56,
AddSynonyms = 57,
AddStoredProcedure = 58,
DropOptions = 59,
AddOptions = 60,
AlterTableChangeTracking = 61,
DropFullText = 62,
DropTableType = 63,
DropUserDataType = 64,
DropXMLSchema = 65,
DropAssemblyUserDataType = 66,
DropAssemblyFile = 67,
DropAssembly = 68,
DropDefault = 69,
DropPartitionScheme = 70,
DropPartitionFunction = 71,
DropSchema = 72,
DropUser = 73,
DropRole = 74,
DropFile = 75,
DropFileGroup = 76,
AddExtendedProperty = 77,
DropExtendedProperty = 78
}
public enum ObjectType
{
None = 0,
Table = 1,
Column = 2,
Trigger = 3,
Constraint = 4,
[Description("Constraint Column")]
ConstraintColumn = 5,
Index = 6,
[Description("Index Column")]
IndexColumn = 7,
[Description("User Data Type")]
UserDataType = 8,
[Description("XML Schema")]
XMLSchema = 9,
View = 10,
Function = 11,
[Description("Stored Procedure")]
StoredProcedure = 12,
[Description("Table Option")]
TableOption = 13,
Database = 14,
Schema = 15,
[Description("File Group")]
FileGroup = 16,
File = 17,
Default = 18,
Rule = 19,
Synonym = 20,
Assembly = 21,
User = 22,
Role = 23,
[Description("Full Text")]
FullText = 24,
[Description("Assembly File")]
AssemblyFile = 25,
[Description("CLR Stored Procedure")]
CLRStoredProcedure = 26,
[Description("CLR Trigger")]
CLRTrigger = 27,
[Description("CLR Function")]
CLRFunction = 28,
[Description("Extended Property")]
ExtendedProperty = 30,
Partition = 31,
[Description("Partition Function")]
PartitionFunction = 32,
[Description("Partition Scheme")]
PartitionScheme = 33,
[Description("Table Type")]
TableType = 34,
[Description("Full Text Index")]
FullTextIndex = 35
}
}

@ -0,0 +1,9 @@
using OpenDBDiff.Abstractions.Schema.Model;
namespace OpenDBDiff.Abstractions.Ui
{
public interface IDatabaseComparer
{
IDatabase Compare(IDatabase origin, IDatabase destination);
}
}

@ -0,0 +1,24 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace OpenDBDiff.Abstractions.Ui
{
public interface IFront : ICloneable
{
Point Location { get; set; }
string Name { get; set; }
Size Size { get; set; }
int TabIndex { get; set; }
bool Visible { get; set; }
DockStyle Dock { get; set; }
Boolean TestConnection();
string ConnectionString { get; set; }
string ErrorConnection { get; }
string DatabaseName { get; }
string Text { get; set; }
AnchorStyles Anchor { get; set; }
Control Control { get; }
void SetSettingsFrom(IFront other);
}
}

@ -0,0 +1,13 @@
using OpenDBDiff.Abstractions.Schema.Model;
namespace OpenDBDiff.Abstractions.Ui
{
public interface IGenerator
{
event Schema.Events.ProgressEventHandler.ProgressHandler OnProgress;
int GetMaxValue();
IDatabase Process();
}
}

@ -0,0 +1,24 @@
using OpenDBDiff.Abstractions.Schema.Model;
namespace OpenDBDiff.Abstractions.Ui
{
public interface IProjectHandler
{
IFront CreateSourceSelector();
IFront CreateDestinationSelector();
string GetSourceConnectionString();
string GetDestinationConnectionString();
string GetSourceServerName();
string GetSourceDatabaseName();
string GetDestinationServerName();
OptionControl CreateOptionControl();
string GetDestinationDatabaseName();
IGenerator SetSourceGenerator(string connectionString, IOption options);
IGenerator SetDestinationGenerator(string connectionString, IOption options);
IDatabaseComparer GetDatabaseComparer();
IOption GetDefaultProjectOptions();
string GetScriptLanguage();
void Unload();
}
}

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E82CFC94-DE8C-4EDD-AA0C-F78ABAE03768}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OpenDBDiff.Abstractions.Ui</RootNamespace>
<AssemblyName>OpenDBDiff.Abstractions.Ui</AssemblyName>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\OpenDBDiff\Properties\AssemblyVersionInfo.cs">
<Link>Properties\AssemblyVersionInfo.cs</Link>
</Compile>
<Compile Include="IDatabaseComparer.cs" />
<Compile Include="IFront.cs" />
<Compile Include="IGenerator.cs" />
<Compile Include="IProjectHandler.cs" />
<Compile Include="OptionControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\.editorconfig">
<Link>.editorconfig</Link>
</None>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenDBDiff.Abstractions.Schema\OpenDBDiff.Abstractions.Schema.csproj">
<Project>{406558a0-1b98-4d0e-b8b6-2013700b065a}</Project>
<Name>OpenDBDiff.Abstractions.Schema</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

@ -0,0 +1,25 @@
using OpenDBDiff.Abstractions.Schema.Model;
using System;
namespace OpenDBDiff.Abstractions.Ui
{
public class OptionControl : System.Windows.Forms.UserControl
{
public event OptionEventHandler OptionSaved;
public delegate void OptionEventHandler(IOption option);
public new virtual void Load(IOption option)
{
throw new NotImplementedException("Load option not implemented");
}
public virtual void Save()
{
throw new NotImplementedException("Save not implemented");
}
protected virtual void FireOptionChanged(IOption option)
{
OptionSaved?.Invoke(option);
}
}
}

@ -0,0 +1,23 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenDBDiff.Abstractions.Ui")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OpenDBDiff.Abstractions.Ui")]
[assembly: AssemblyCopyright("OpenDBDiff")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("cd2b11ca-bbad-48a4-98e2-eeac17dde7ad")]
[assembly: System.CLSCompliant(true)]

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="OpenDBDiff.NewIssueUri" value="https://github.com/OpenDBDiff/OpenDBDiff/issues/new" />
</appSettings>
</configuration>

@ -0,0 +1,16 @@
using CommandLine;
namespace OpenDBDiff.CLI
{
public class CommandlineOptions
{
[Option('b', "before", Required = true, HelpText = "Connection string of database before changes are applied.")]
public string Before { get; set; }
[Option('a', "after", Required = true, HelpText = "Connection string of database after changes are applied.")]
public string After { get; set; }
[Option('o', "outputfile", Required = false, HelpText = "Output file of action script. If omitted, script is written to the console.")]
public string OutputFile { get; set; }
}
}

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E794AA28-EE68-44BD-827B-1BFD9C106B65}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OpenDBDiff.CLI</RootNamespace>
<AssemblyName>OpenDBDiff.CLI</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<ItemGroup>
<Reference Include="CommandLine, Version=2.8.0.0, Culture=neutral, PublicKeyToken=5a870481e358d379, processorArchitecture=MSIL">
<HintPath>..\packages\CommandLineParser.2.8.0\lib\net45\CommandLine.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\OpenDBDiff\Properties\AssemblyVersionInfo.cs">
<Link>Properties\AssemblyVersionInfo.cs</Link>
</Compile>
<Compile Include="CommandlineOptions.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenDBDiff.Abstractions.Schema\OpenDBDiff.Abstractions.Schema.csproj">
<Project>{406558a0-1b98-4d0e-b8b6-2013700b065a}</Project>
<Name>OpenDBDiff.Abstractions.Schema</Name>
</ProjectReference>
<ProjectReference Include="..\OpenDBDiff.SqlServer.Schema\OpenDBDiff.SqlServer.Schema.csproj">
<Project>{32ac9af6-db93-4354-b69f-6dbc65c70867}</Project>
<Name>OpenDBDiff.SqlServer.Schema</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="..\.editorconfig">
<Link>.editorconfig</Link>
</None>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

@ -0,0 +1,120 @@
using CommandLine;
using OpenDBDiff.Abstractions.Schema.Model;
using OpenDBDiff.SqlServer.Schema.Generates;
using OpenDBDiff.SqlServer.Schema.Model;
using OpenDBDiff.SqlServer.Schema.Options;
using System;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
namespace OpenDBDiff.CLI
{
public class Program
{
private static SqlOption SqlFilter = new SqlOption();
protected Program()
{
}
private static int Main(string[] args)
{
bool completedSuccessfully = false;
Parser.Default.ParseArguments<CommandlineOptions>(args)
.WithParsed(options =>
{
try
{
completedSuccessfully = Work(options);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
});
if (Debugger.IsAttached)
{
Console.WriteLine("Press any key to continue...");
Console.ReadKey(false);
}
return completedSuccessfully ? 0 : 1;
}
private static Boolean TestConnection(string connectionString1)
{
using (SqlConnection connection = new SqlConnection())
{
connection.ConnectionString = connectionString1;
connection.Open();
connection.Close();
return true;
}
}
private static bool Work(CommandlineOptions options)
{
try
{
Database origin;
Database destination;
if (TestConnection(options.Before)
&& TestConnection(options.After))
{
Generate sql = new Generate();
sql.ConnectionString = options.Before;
Console.WriteLine("Reading first database...");
sql.Options = SqlFilter;
origin = sql.Process();
sql.ConnectionString = options.After;
Console.WriteLine("Reading second database...");
destination = sql.Process();
Console.WriteLine("Comparing databases schemas...");
origin = Generate.Compare(origin, destination);
// temporary work-around: run twice just like GUI
origin.ToSqlDiff(new System.Collections.Generic.List<ISchemaBase>());
Console.WriteLine("Generating SQL file...");
var script = origin.ToSqlDiff(new System.Collections.Generic.List<ISchemaBase>()).ToSQL();
if (!string.IsNullOrWhiteSpace(options.OutputFile))
{
Console.WriteLine("Writing action script to {0}", options.OutputFile);
SaveFile(options.OutputFile, script);
}
else
{
Console.WriteLine();
Console.WriteLine(script);
Console.WriteLine();
}
return true;
}
}
catch (Exception ex)
{
string newIssueUri = System.Configuration.ConfigurationManager.AppSettings["OpenDBDiff.NewIssueUri"];
if (string.IsNullOrEmpty(newIssueUri))
newIssueUri = "https://github.com/OpenDBDiff/OpenDBDiff/issues/new";
Console.WriteLine($"{ex.Message}\r\n{ex.StackTrace}\r\n\r\nPlease report this issue at {newIssueUri}.");
Console.WriteLine();
}
return false;
}
private static void SaveFile(string filenmame, string sql)
{
if (!String.IsNullOrEmpty(filenmame))
{
StreamWriter writer = new StreamWriter(filenmame, false);
writer.Write(sql);
writer.Close();
}
}
}
}

@ -0,0 +1,22 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenDBDiff Console")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OpenDBDiff Console")]
[assembly: AssemblyCopyright("OpenDBDiff")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("30c9b799-3cd9-4c83-9141-dc7782005ec1")]

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommandLineParser" version="2.8.0" targetFramework="net452" />
</packages>

@ -0,0 +1,9 @@
using OpenDBDiff.Schema.Model;
namespace OpenDBDiff.Front
{
public interface IDatabaseComparer
{
IDatabase Compare(IDatabase origin, IDatabase destination);
}
}

@ -0,0 +1,23 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace OpenDBDiff.Front
{
public interface IFront
{
Point Location { get; set; }
string Name { get; set; }
Size Size { get; set; }
int TabIndex { get; set; }
bool Visible { get; set; }
DockStyle Dock { get; set; }
Boolean TestConnection();
string ConnectionString { get; set; }
string ErrorConnection { get; }
string DatabaseName { get; }
string Text { get; set; }
AnchorStyles Anchor { get; set; }
Control Control { get; }
}
}

@ -0,0 +1,13 @@
using OpenDBDiff.Schema.Model;
namespace OpenDBDiff.Front
{
public interface IGenerator
{
event Schema.Events.ProgressEventHandler.ProgressHandler OnProgress;
int GetMaxValue();
IDatabase Process();
}
}

@ -0,0 +1,26 @@
using System;
using System.Windows.Forms;
using OpenDBDiff.Schema.Model;
namespace OpenDBDiff.Front
{
public interface IProjectHandler
{
IFront CreateSourceSelector();
IFront CreateDestinationSelector();
string GetSourceConnectionString();
string GetDestinationConnectionString();
string GetSourceServerName();
string GetSourceDatabaseName();
string GetDestinationServerName();
OptionControl CreateOptionControl();
string GetDestinationDatabaseName();
IGenerator SetSourceGenerator(string connectionString, IOption options);
IGenerator SetDestinationGenerator(string connectionString, IOption options);
IDatabaseComparer GetDatabaseComparer();
IOption GetDefaultProjectOptions();
string GetScriptLanguage();
void Unload();
}
}

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E82CFC94-DE8C-4EDD-AA0C-F78ABAE03768}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OpenDBDiff.Front</RootNamespace>
<AssemblyName>OpenDBDiff.Front</AssemblyName>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>OpenDBDiff.Front.snk</AssemblyOriginatorKeyFile>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\OpenDBDiff\Properties\AssemblyVersionInfo.cs">
<Link>Properties\AssemblyVersionInfo.cs</Link>
</Compile>
<Compile Include="IDatabaseComparer.cs" />
<Compile Include="IFront.cs" />
<Compile Include="IGenerator.cs" />
<Compile Include="IProjectHandler.cs" />
<Compile Include="OptionControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\.editorconfig">
<Link>.editorconfig</Link>
</None>
<None Include="OpenDBDiff.Front.snk" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenDBDiff.Schema\OpenDBDiff.Schema.csproj">
<Project>{406558a0-1b98-4d0e-b8b6-2013700b065a}</Project>
<Name>DBDiff.Schema</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenDBDiff.Schema.Model;
namespace OpenDBDiff.Front
{
public class OptionControl : System.Windows.Forms.UserControl
{
public event OptionEventHandler OptionSaved;
public delegate void OptionEventHandler(IOption option);
public new virtual void Load(IOption option)
{
throw new NotImplementedException("Load option not implemented");
}
public virtual void Save()
{
throw new NotImplementedException("Save not implemented");
}
protected virtual void FireOptionChanged(IOption option)
{
OptionSaved?.Invoke(option);
}
}
}

@ -0,0 +1,23 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenDBDiff.Front")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OpenDBDiff.Front")]
[assembly: AssemblyCopyright("OpenDBDiff")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("cd2b11ca-bbad-48a4-98e2-eeac17dde7ad")]
[assembly: System.CLSCompliant(true)]

@ -0,0 +1,58 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareAssemblies : CompareBase<Assembly>
{
protected override void DoUpdate<Root>(SchemaList<Assembly, Root> originFields, Assembly node)
{
if (!node.Compare(originFields[node.FullName]))
{
Assembly newNode = (Assembly)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Alter;
if (node.Text.Equals(originFields[node.FullName].Text))
{
if (!node.PermissionSet.Equals(originFields[node.FullName].PermissionSet))
newNode.Status += (int)ObjectStatus.PermissionSet;
if (!node.Owner.Equals(originFields[node.FullName].Owner))
newNode.Status += (int)ObjectStatus.ChangeOwner;
}
else
newNode.Status = ObjectStatus.Rebuild;
originFields[node.FullName].Files.ForEach(item =>
{
if (!newNode.Files.Contains(item.FullName))
newNode.Files.Add(new AssemblyFile(newNode, item, ObjectStatus.Drop));
else
item.Status = ObjectStatus.Alter;
});
newNode.Files.ForEach(item =>
{
if (!originFields[node.FullName].Files.Contains(item.FullName))
{
item.Status = ObjectStatus.Create;
}
});
CompareExtendedProperties(originFields[node.FullName], newNode);
originFields[node.FullName] = newNode;
}
}
protected override void DoNew<Root>(SchemaList<Assembly, Root> originFields, Assembly node)
{
bool pass = true;
Assembly newNode = (Assembly)node.Clone(originFields.Parent);
if ((((Database)newNode.RootParent).Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2005)
&& (((Database)node.RootParent).Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008))
pass = node.FullName.Equals("Microsoft.SqlServer.Types");
if (pass)
{
newNode.Status = ObjectStatus.Create;
originFields.Add(newNode);
}
}
}
}

@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Generates;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal abstract class CompareBase<T> where T : ISchemaBase
{
protected virtual void DoUpdate<Root>(SchemaList<T, Root> originFields, T node) where Root : ISchemaBase
{
}
protected virtual void DoNew<Root>(SchemaList<T, Root> originFields, T node) where Root : ISchemaBase
{
T newNode = node;//.Clone(originFields.Parent);
newNode.Parent = originFields.Parent;
newNode.Status = ObjectStatus.Create;
originFields.Add(newNode);
}
protected void DoDelete(T node)
{
node.Status = ObjectStatus.Drop;
}
public void GenerateDifferences<Root>(SchemaList<T, Root> originFields, SchemaList<T, Root> destinationFields) where Root : ISchemaBase
{
bool has = true;
int destinationIndex = 0;
int originIndex = 0;
int destinationCount = destinationFields.Count;
int originCount = originFields.Count;
T node;
while (has)
{
has = false;
if (destinationCount > destinationIndex)
{
node = destinationFields[destinationIndex];
Generate.RaiseOnCompareProgress("Comparing Destination {0}: [{1}]", node.ObjectType, node.Name);
if (!originFields.Contains(node.FullName))
{
Generate.RaiseOnCompareProgress("Adding {0}: [{1}]", node.ObjectType, node.Name);
DoNew<Root>(originFields, node);
}
else
{
Generate.RaiseOnCompareProgress("Updating {0}: [{1}]", node.ObjectType, node.Name);
DoUpdate<Root>(originFields, node);
}
destinationIndex++;
has = true;
}
if (originCount > originIndex)
{
node = originFields[originIndex];
Generate.RaiseOnCompareProgress("Comparing Source {0}: [{1}]", node.ObjectType, node.Name);
if (!destinationFields.Contains(node.FullName))
{
Generate.RaiseOnCompareProgress("Deleting {0}: [{1}]", node.ObjectType, node.Name);
DoDelete(node);
}
originIndex++;
has = true;
}
}
}
protected static void CompareExtendedProperties(ISQLServerSchemaBase origin, ISQLServerSchemaBase destination)
{
List<ExtendedProperty> dropList = (from node in origin.ExtendedProperties
where !destination.ExtendedProperties.Exists(item => item.Name.Equals(node.Name, StringComparison.CurrentCultureIgnoreCase))
select node).ToList<ExtendedProperty>();
List<ExtendedProperty> addList = (from node in destination.ExtendedProperties
where !origin.ExtendedProperties.Exists(item => item.Name.Equals(node.Name, StringComparison.CurrentCultureIgnoreCase))
select node).ToList<ExtendedProperty>();
dropList.ForEach(item => { item.Status = ObjectStatus.Drop; });
addList.ForEach(item => { item.Status = ObjectStatus.Create; });
origin.ExtendedProperties.AddRange(addList);
}
}
}

@ -0,0 +1,18 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareCLRFunction : CompareBase<CLRFunction>
{
protected override void DoUpdate<Root>(SchemaList<CLRFunction, Root> originFields, CLRFunction node)
{
if (!node.Compare(originFields[node.FullName]))
{
CLRFunction newNode = node; //.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Alter;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,18 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareCLRStoredProcedure : CompareBase<CLRStoredProcedure>
{
protected override void DoUpdate<Root>(SchemaList<CLRStoredProcedure, Root> originFields, CLRStoredProcedure node)
{
if (!node.Compare(originFields[node.FullName]))
{
CLRStoredProcedure newNode = node; //.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Alter;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,19 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareCLRTriggers : CompareBase<CLRTrigger>
{
protected override void DoUpdate<Root>(SchemaList<CLRTrigger, Root> originFields, CLRTrigger node)
{
if (!node.Compare(originFields[node.FullName]))
{
CLRTrigger newNode = node;
newNode.Status = ObjectStatus.Alter;
CompareExtendedProperties(newNode, originFields[node.FullName]);
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,91 @@
using System;
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
public class CompareColumns
{
public void GenerateDifferences<T>(Columns<T> originFields, Columns<T> destinationFields) where T : ISchemaBase
{
int restPosition = 0;
int sumPosition = 0;
foreach (Column node in originFields)
{
if (!destinationFields.Contains(node.FullName))
{
node.Status = ObjectStatus.Drop;
restPosition++;
}
else
originFields[node.FullName].Position -= restPosition;
}
foreach (Column node in destinationFields)
{
if (!originFields.Contains(node.FullName))
{
Column newNode = node.Clone(originFields.Parent);
if ((newNode.Position == 1) || ((newNode.DefaultConstraint == null) && (!newNode.IsNullable) && (!newNode.IsComputed) && (!newNode.IsIdentity) && (!newNode.IsIdentityForReplication)))
{
newNode.Status = ObjectStatus.Create;
newNode.Parent.Status = ObjectStatus.Rebuild;
}
else
newNode.Status = ObjectStatus.Create;
sumPosition++;
originFields.Add(newNode);
}
else
{
Column originField = originFields[node.FullName];
/*ColumnConstraint oldDefault = null;
if (originField.DefaultConstraint != null)
oldDefault = originField.DefaultConstraint.Clone(originField);*/
Boolean IsColumnEqual = Column.Compare(originField, node);
if ((!IsColumnEqual) || (originField.Position != node.Position))
{
if (Column.CompareIdentity(originField, node))
{
if (node.HasToRebuildOnlyConstraint)
{
node.Status = ObjectStatus.Alter;
if ((originField.IsNullable) && (!node.IsNullable))
node.Status += (int)ObjectStatus.Update;
}
else
{
if (node.HasToRebuild(originField.Position + sumPosition, originField.Type, originField.IsFileStream))
node.Status = ObjectStatus.Rebuild;
else
{
if (!IsColumnEqual)
{
node.Status = ObjectStatus.Alter;
if ((originField.IsNullable) && (!node.IsNullable))
node.Status += (int)ObjectStatus.Update;
}
}
}
if (node.Status != ObjectStatus.Rebuild)
{
if (!Column.CompareRule(originField, node))
{
node.Status += (int)ObjectStatus.Bind;
}
}
}
else
{
node.Status = ObjectStatus.Rebuild;
}
originFields[node.FullName] = node.Clone(originFields.Parent);
}
originFields[node.FullName].DefaultConstraint = CompareColumnsConstraints.GenerateDifferences(originField, node);
}
}
}
}
}

@ -0,0 +1,72 @@
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareColumnsConstraints : CompareBase<ColumnConstraint>
{
public static ColumnConstraint GenerateDifferences(Column originFields, Column destinationFields)
{
if ((originFields.DefaultConstraint == null) && (destinationFields.DefaultConstraint != null))
{
originFields.DefaultConstraint = destinationFields.DefaultConstraint.Clone(originFields);
originFields.DefaultConstraint.Status = ObjectStatus.Create;
originFields.DefaultConstraint.Parent.Status = ObjectStatus.Original;
originFields.DefaultConstraint.Parent.Parent.Status = ObjectStatus.Alter;
}
else
{
if ((originFields.DefaultConstraint != null) && (destinationFields.DefaultConstraint != null))
{
if (!ColumnConstraint.Compare(originFields.DefaultConstraint, destinationFields.DefaultConstraint))
{
originFields.DefaultConstraint = destinationFields.DefaultConstraint.Clone(originFields);
//Indico que hay un ALTER TABLE, pero sobre la columna, no seteo ningun estado.
originFields.DefaultConstraint.Status = ObjectStatus.Alter;
originFields.DefaultConstraint.Parent.Status = ObjectStatus.Original;
originFields.DefaultConstraint.Parent.Parent.Status = ObjectStatus.Alter;
}
}
else
if ((originFields.DefaultConstraint != null) && (destinationFields.DefaultConstraint == null))
{
originFields.DefaultConstraint.Status = ObjectStatus.Drop;
originFields.DefaultConstraint.Parent.Status = ObjectStatus.Original;
originFields.DefaultConstraint.Parent.Parent.Status = ObjectStatus.Alter;
}
}
/*foreach (ColumnConstraint node in destinationFields)
{
if (!originFields.Exists(node.FullName))
{
node.Status = ObjectStatusType.CreateStatus;
originFields.Parent.Status = ObjectStatusType.OriginalStatus;
originFields.Parent.Parent.Status = ObjectStatusType.AlterStatus;
originFields.Add(node);
}
else
{
if (!ColumnConstraint.Compare(originFields[node.FullName], node))
{
ColumnConstraint newNode = node.Clone(originFields.Parent);
//Indico que hay un ALTER TABLE, pero sobre la columna, no seteo ningun estado.
newNode.Status = ObjectStatusType.AlterStatus;
newNode.Parent.Status = ObjectStatusType.OriginalStatus;
newNode.Parent.Parent.Status = ObjectStatusType.AlterStatus;
originFields[node.FullName] = newNode;
}
}
}
MarkDrop(originFields, destinationFields, node =>
{
node.Status = ObjectStatusType.DropStatus;
originFields.Parent.Status = ObjectStatusType.OriginalStatus;
originFields.Parent.Parent.Status = ObjectStatusType.AlterStatus;
}
);
*/
return originFields.DefaultConstraint;
}
}
}

@ -0,0 +1,40 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareConstraints : CompareBase<Constraint>
{
protected override void DoUpdate<Root>(SchemaList<Constraint, Root> originFields, Constraint node)
{
Constraint origin = originFields[node.FullName];
if (!Constraint.Compare(origin, node))
{
Constraint newNode = (Constraint)node.Clone(originFields.Parent);
if (node.IsDisabled == origin.IsDisabled)
{
newNode.Status = ObjectStatus.Alter;
}
else
newNode.Status = ObjectStatus.Alter + (int)ObjectStatus.Disabled;
originFields[node.FullName] = newNode;
}
else
{
if (node.IsDisabled != origin.IsDisabled)
{
Constraint newNode = (Constraint)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Disabled;
originFields[node.FullName] = newNode;
}
}
}
protected override void DoNew<Root>(SchemaList<Constraint, Root> originFields, Constraint node)
{
Constraint newNode = (Constraint)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Create;
originFields.Add(newNode);
}
}
}

@ -0,0 +1,28 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareDDLTriggers : CompareBase<Trigger>
{
protected override void DoUpdate<Root>(SchemaList<Trigger, Root> originFields, Trigger node)
{
if (!node.Compare(originFields[node.FullName]))
{
Trigger newNode = (Trigger)node.Clone(originFields.Parent);
if (!newNode.Text.Equals(originFields[node.FullName].Text))
newNode.Status = ObjectStatus.Alter;
if (node.IsDisabled != originFields[node.FullName].IsDisabled)
newNode.Status = newNode.Status + (int)ObjectStatus.Disabled;
originFields[node.FullName] = newNode;
}
}
protected override void DoNew<Root>(SchemaList<Trigger, Root> originFields, Trigger node)
{
Trigger newNode = (Trigger)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Create;
originFields.Add(newNode);
}
}
}

@ -0,0 +1,54 @@
using OpenDBDiff.Schema.Misc;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
using System;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal static class CompareDatabase
{
/// <summary>
/// Generates the differences to migrate a schema from origin to destination
/// </summary>
/// <param name="origin">The Origin schema is the schema before our generated actions are applied.</param>
/// <param name="destination">The Destination schema is the schema after our actions are applied.</param>
/// <returns></returns>
/// <exception cref="SchemaException"></exception>
public static Database GenerateDifferences(Database origin, Database destination)
{
try
{
Database data = origin;
(new CompareTables()).GenerateDifferences<Database>(origin.Tables, destination.Tables);
(new CompareAssemblies()).GenerateDifferences<Database>(origin.Assemblies, destination.Assemblies);
(new CompareUserDataTypes()).GenerateDifferences<Database>(origin.UserTypes, destination.UserTypes);
(new CompareXMLSchemas()).GenerateDifferences<Database>(origin.XmlSchemas, destination.XmlSchemas);
(new CompareSchemas()).GenerateDifferences<Database>(origin.Schemas, destination.Schemas);
(new CompareFileGroups()).GenerateDifferences<Database>(origin.FileGroups, destination.FileGroups);
(new CompareRules()).GenerateDifferences<Database>(origin.Rules, destination.Rules);
(new CompareDDLTriggers()).GenerateDifferences<Database>(origin.DDLTriggers, destination.DDLTriggers);
(new CompareSynonyms()).GenerateDifferences<Database>(origin.Synonyms, destination.Synonyms);
(new CompareUsers()).GenerateDifferences<Database>(origin.Users, destination.Users);
(new CompareStoredProcedures()).GenerateDifferences<Database>(origin.Procedures, destination.Procedures);
(new CompareCLRStoredProcedure()).GenerateDifferences<Database>(origin.CLRProcedures, destination.CLRProcedures);
(new CompareCLRFunction()).GenerateDifferences<Database>(origin.CLRFunctions, destination.CLRFunctions);
(new CompareViews()).GenerateDifferences<Database>(origin.Views, destination.Views);
(new CompareFunctions()).GenerateDifferences<Database>(origin.Functions, destination.Functions);
(new CompareRoles()).GenerateDifferences<Database>(origin.Roles, destination.Roles);
(new ComparePartitionFunction()).GenerateDifferences<Database>(origin.PartitionFunctions, destination.PartitionFunctions);
(new ComparePartitionSchemes()).GenerateDifferences<Database>(origin.PartitionSchemes, destination.PartitionSchemes);
(new CompareTableType()).GenerateDifferences<Database>(origin.TablesTypes, destination.TablesTypes);
(new CompareFullText()).GenerateDifferences<Database>(origin.FullText, destination.FullText);
data.SourceInfo = destination.Info;
return data;
}
catch (SchemaException)
{
throw;
}
catch (Exception ex)
{
throw new SchemaException(ex.Message, ex);
}
}
}
}

@ -0,0 +1,44 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareFileGroups : CompareBase<FileGroup>
{
protected override void DoNew<Root>(SchemaList<FileGroup, Root> originFields, FileGroup node)
{
FileGroup newNode = (FileGroup)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Create;
/*If the Logical File Name exists in another filegroup,
* we must change the new Logical File Name.
*/
originFields.ForEach(file =>
{
if (file.Status != ObjectStatus.Drop)
{
file.Files.ForEach(group =>
{
newNode.Files.ForEach(ngroup =>
{
if (group.CompareFullNameTo(group.FullName, ngroup.FullName) == 0)
{
newNode.Files[ngroup.FullName].Name = group.Name + "_2";
}
});
});
}
});
originFields.Add(newNode);
}
protected override void DoUpdate<Root>(SchemaList<FileGroup, Root> originFields, FileGroup node)
{
if (!FileGroup.Compare(node, originFields[node.FullName]))
{
FileGroup newNode = (FileGroup)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Alter;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,23 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareFullText : CompareBase<FullText>
{
protected override void DoUpdate<Root>(SchemaList<FullText, Root> originFields, FullText node)
{
if (!node.Compare(originFields[node.FullName]))
{
FullText newNode = node; //.Clone(originFields.Parent);
if (node.IsDefault != originFields[node.FullName].IsDefault)
newNode.Status += (int)ObjectStatus.Disabled;
if (!node.Owner.Equals(originFields[node.FullName].Owner))
newNode.Status += (int)ObjectStatus.ChangeOwner;
if (node.IsAccentSensity != originFields[node.FullName].IsAccentSensity)
newNode.Status += (int)ObjectStatus.Alter;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,28 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareFullTextIndex : CompareBase<FullTextIndex>
{
protected override void DoNew<Root>(SchemaList<FullTextIndex, Root> originFields, FullTextIndex node)
{
FullTextIndex newNode = (FullTextIndex)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Create;
originFields.Add(newNode);
}
protected override void DoUpdate<Root>(SchemaList<FullTextIndex, Root> originFields, FullTextIndex node)
{
if (!node.Compare(originFields[node.FullName]))
{
FullTextIndex newNode = (FullTextIndex)node.Clone(originFields.Parent);
if (node.IsDisabled != originFields[node.FullName].IsDisabled)
newNode.Status += (int)ObjectStatus.Disabled;
else
newNode.Status += (int)ObjectStatus.Alter;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,44 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareFunctions : CompareBase<Function>
{
protected override void DoNew<Root>(SchemaList<Function, Root> originFields, Function node)
{
Function newNode = (Function)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Create;
originFields.Add(newNode);
newNode.DependenciesIn.ForEach(dep =>
{
ISchemaBase item = ((Database)((ISchemaBase)originFields.Parent)).Find(dep);
if (item != null)
{
if (item.IsCodeType)
((ICode)item).DependenciesOut.Add(newNode.FullName);
}
}
);
}
protected override void DoUpdate<Root>(SchemaList<Function, Root> originFields, Function node)
{
if (!node.Compare(originFields[node.FullName]))
{
Function newNode = (Function)node.Clone(originFields.Parent);
newNode.DependenciesIn.AddRange(originFields[node.FullName].DependenciesIn);
newNode.DependenciesOut.AddRange(originFields[node.FullName].DependenciesOut);
newNode.Status = ObjectStatus.Alter;
if (newNode.IsSchemaBinding)
newNode.Status += (int)ObjectStatus.RebuildDependencies;
if (newNode.HasToRebuild)
newNode.Status += (int)ObjectStatus.Rebuild;
else
newNode.Status += (int)ObjectStatus.AlterBody;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,30 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareIndexes : CompareBase<Index>
{
protected override void DoNew<Root>(SchemaList<Index, Root> originFields, Index node)
{
Index newNode = (Index)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Create;
originFields.Add(newNode);
}
protected override void DoUpdate<Root>(SchemaList<Index, Root> originFields, Index node)
{
if (!Index.Compare(node, originFields[node.FullName]))
{
Index newNode = (Index)node.Clone(originFields.Parent);
if (!Index.CompareExceptIsDisabled(node, originFields[node.FullName]))
{
newNode.Status = ObjectStatus.Alter;
}
else
newNode.Status = ObjectStatus.Disabled;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,31 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class ComparePartitionFunction : CompareBase<PartitionFunction>
{
protected override void DoUpdate<Root>(SchemaList<PartitionFunction, Root> originFields, PartitionFunction node)
{
if (!PartitionFunction.Compare(node, originFields[node.FullName]))
{
PartitionFunction newNode = node; //.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Rebuild;
originFields[node.FullName] = newNode;
}
else
{
if (!PartitionFunction.CompareValues(node, originFields[node.FullName]))
{
PartitionFunction newNode = node.Clone(originFields.Parent);
if (newNode.Values.Count == originFields[node.FullName].Values.Count)
newNode.Status = ObjectStatus.Rebuild;
else
newNode.Status = ObjectStatus.Alter;
newNode.Old = originFields[node.FullName].Clone(originFields.Parent);
originFields[node.FullName] = newNode;
}
}
}
}
}

@ -0,0 +1,18 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class ComparePartitionSchemes : CompareBase<PartitionScheme>
{
protected override void DoUpdate<Root>(SchemaList<PartitionScheme, Root> originFields, PartitionScheme node)
{
if (!PartitionScheme.Compare(node, originFields[node.FullName]))
{
PartitionScheme newNode = node; //.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Rebuild;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,18 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareRoles : CompareBase<Role>
{
protected override void DoUpdate<Root>(SchemaList<Role, Root> originFields, Role node)
{
if (!node.Compare(originFields[node.FullName]))
{
Role newNode = node;
newNode.Status = ObjectStatus.Alter;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,25 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareRules : CompareBase<Rule>
{
protected override void DoUpdate<Root>(SchemaList<Rule, Root> originFields, Rule node)
{
if (!node.Compare(originFields[node.FullName]))
{
Rule newNode = node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Alter;
originFields[node.FullName] = newNode;
}
}
protected override void DoNew<Root>(SchemaList<Rule, Root> originFields, Rule node)
{
Rule newNode = node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Create;
originFields.Add(newNode);
}
}
}

@ -0,0 +1,7 @@
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareSchemas : CompareBase<Model.Schema>
{
}
}

@ -0,0 +1,27 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareStoredProcedures : CompareBase<StoredProcedure>
{
protected override void DoUpdate<Root>(SchemaList<StoredProcedure, Root> originFields, StoredProcedure node)
{
if (!node.Compare(originFields[node.FullName]))
{
StoredProcedure newNode = node; //.Clone(originFields.Parent);
if (node.CompareExceptWhitespace(originFields[node.FullName]))
{
newNode.Status = ObjectStatus.AlterWhitespace;
}
else
{
newNode.Status = ObjectStatus.Alter;
}
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,18 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareSynonyms : CompareBase<Synonym>
{
protected override void DoUpdate<Root>(SchemaList<Synonym, Root> originFields, Synonym node)
{
if (!Synonym.Compare(node, originFields[node.FullName]))
{
Synonym newNode = node; //.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Alter;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,44 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareTableType : CompareBase<TableType>
{
protected override void DoUpdate<Root>(SchemaList<TableType, Root> originFields, TableType node)
{
if (node.Status != ObjectStatus.Drop)
{
TableType tablaOriginal = originFields[node.FullName];
(new CompareColumns()).GenerateDifferences<TableType>(tablaOriginal.Columns, node.Columns);
(new CompareConstraints()).GenerateDifferences<TableType>(tablaOriginal.Constraints, node.Constraints);
(new CompareIndexes()).GenerateDifferences<TableType>(tablaOriginal.Indexes, node.Indexes);
}
}
/*public static void GenerateDifferences(SchemaList<TableType, Database> originTables, SchemaList<TableType, Database> destinationTables)
{
MarkDrop(originTables, destinationTables);
foreach (TableType node in destinationTables)
{
if (!originTables.Exists(node.FullName))
{
node.Status = ObjectStatusType.CreateStatus;
node.Parent = originTables.Parent;
originTables.Add(node);
}
else
{
if (node.Status != ObjectStatusType.DropStatus)
{
TableType tablaOriginal = originTables[node.FullName];
CompareColumns.GenerateDifferences<TableType>(tablaOriginal.Columns, node.Columns);
CompareConstraints.GenerateDifferences<TableType>(tablaOriginal.Constraints, node.Constraints);
CompareIndexes.GenerateDifferences(tablaOriginal.Indexes, node.Indexes);
}
}
}
}*/
}
}

@ -0,0 +1,92 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareTables : CompareBase<Table>
{
protected override void DoUpdate<Root>(SchemaList<Table, Root> originFields, Table node)
{
if (node.Status != ObjectStatus.Drop)
{
Table tablaOriginal = originFields[node.FullName];
tablaOriginal.OriginalTable = (Table)originFields[node.FullName].Clone((Database)tablaOriginal.Parent);
(new CompareColumns()).GenerateDifferences<Table>(tablaOriginal.Columns, node.Columns);
(new CompareConstraints()).GenerateDifferences<Table>(tablaOriginal.Constraints, node.Constraints);
(new CompareIndexes()).GenerateDifferences<Table>(tablaOriginal.Indexes, node.Indexes);
(new CompareTablesOptions()).GenerateDifferences<Table>(tablaOriginal.Options, node.Options);
(new CompareTriggers()).GenerateDifferences<Table>(tablaOriginal.Triggers, node.Triggers);
(new CompareCLRTriggers()).GenerateDifferences<Table>(tablaOriginal.CLRTriggers, node.CLRTriggers);
(new CompareFullTextIndex()).GenerateDifferences<Table>(tablaOriginal.FullTextIndex, node.FullTextIndex);
if (!Table.CompareFileGroup(tablaOriginal, node))
{
tablaOriginal.FileGroup = node.FileGroup;
/*Esto solo aplica a las tablas heap, el resto hace el campo en el filegroup del indice clustered*/
if (!tablaOriginal.HasClusteredIndex)
tablaOriginal.Status = ObjectStatus.Rebuild;
}
if (!Table.CompareFileGroupText(tablaOriginal, node))
{
tablaOriginal.FileGroupText = node.FileGroupText;
tablaOriginal.Status = ObjectStatus.Rebuild;
}
if (node.HasChangeTracking != tablaOriginal.HasChangeTracking)
{
tablaOriginal.HasChangeTracking = node.HasChangeTracking;
tablaOriginal.HasChangeTrackingTrackColumn = node.HasChangeTrackingTrackColumn;
tablaOriginal.Status += (int)ObjectStatus.Disabled;
}
}
}
/// <summary>
/// Compara las colecciones de tablas de dos bases diferentes y marca el estado de los objetos
/// dependiendo si existen o si deben borrarse.
/// </summary>
/// <param name="originTables"></param>
/// Tablas originales, donde se guardaran los estados de las tablas.
/// <param name="destinationTables">
/// Tablas comparativas, que se usa para comparar con la base original.
/// </param>
/*public static void GenerateDifferences(SchemaList<Table, Database> originTables, SchemaList<Table, Database> destinationTables)
{
MarkDrop(originTables, destinationTables);
foreach (Table node in destinationTables)
{
if (!originTables.Exists(node.FullName))
{
node.Status = ObjectStatusType.CreateStatus;
node.Parent = originTables.Parent;
originTables.Add(node);
}
else
{
if (node.Status != ObjectStatusType.DropStatus)
{
Table tablaOriginal = originTables[node.FullName];
tablaOriginal.OriginalTable = (Table)originTables[node.FullName].Clone((Database)tablaOriginal.Parent);
CompareColumns.GenerateDifferences<Table>(tablaOriginal.Columns, node.Columns);
CompareConstraints.GenerateDifferences<Table>(tablaOriginal.Constraints, node.Constraints);
CompareIndexes.GenerateDifferences(tablaOriginal.Indexes, node.Indexes);
CompareTablesOptions.GenerateDifferences(tablaOriginal.Options, node.Options);
(new CompareTriggers()).GenerateDifferences<Table>(tablaOriginal.Triggers, node.Triggers);
(new CompareCLRTriggers()).GenerateDifferences<Table>(tablaOriginal.CLRTriggers, node.CLRTriggers);
if (!Table.CompareFileGroup(tablaOriginal, node))
{
tablaOriginal.FileGroup = node.FileGroup;
//Esto solo aplica a las tablas heap, el resto hace el campo en el filegroup del indice clustered
if (!tablaOriginal.HasClusteredIndex)
tablaOriginal.Status = ObjectStatusType.RebuildStatus;
}
if (!Table.CompareFileGroupText(tablaOriginal, node))
{
tablaOriginal.FileGroupText = node.FileGroupText;
tablaOriginal.Status = ObjectStatusType.RebuildStatus;
}
}
}
}
}*/
}
}

@ -0,0 +1,25 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareTablesOptions : CompareBase<TableOption>
{
protected override void DoNew<Root>(SchemaList<TableOption, Root> originFields, TableOption node)
{
TableOption newNode = (TableOption)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Create;
originFields.Add(newNode);
}
protected override void DoUpdate<Root>(SchemaList<TableOption, Root> originFields, TableOption node)
{
if (!TableOption.Compare(node, originFields[node.FullName]))
{
TableOption newNode = (TableOption)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Alter;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,28 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareTriggers : CompareBase<Trigger>
{
protected override void DoNew<Root>(SchemaList<Trigger, Root> originFields, Trigger node)
{
Trigger newNode = (Trigger)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Create;
originFields.Add(newNode);
}
protected override void DoUpdate<Root>(SchemaList<Trigger, Root> originFields, Trigger node)
{
if (!node.Compare(originFields[node.FullName]))
{
Trigger newNode = (Trigger)node.Clone(originFields.Parent);
if (!newNode.Text.Equals(originFields[node.FullName].Text))
newNode.Status = ObjectStatus.Alter;
if (node.IsDisabled != originFields[node.FullName].IsDisabled)
newNode.Status = newNode.Status + (int)ObjectStatus.Disabled;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,51 @@
using System;
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareUserDataTypes : CompareBase<UserDataType>
{
protected override void DoNew<Root>(SchemaList<UserDataType, Root> originFields, UserDataType node)
{
UserDataType newNode = (UserDataType)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Create;
Boolean HasAssembly = originFields.Exists(item => item.AssemblyFullName.Equals(node.AssemblyFullName) && item.IsAssembly);
if (HasAssembly)
newNode.Status += (int)ObjectStatus.DropOlder;
originFields.Add(newNode);
}
protected override void DoUpdate<Root>(SchemaList<UserDataType, Root> originFields, UserDataType node)
{
if (!node.Compare(originFields[node.FullName]))
{
UserDataType newNode = (UserDataType)node.Clone(originFields.Parent);
newNode.Dependencies.AddRange(originFields[node.FullName].Dependencies);
if (!UserDataType.CompareDefault(node, originFields[node.FullName]))
{
if (!String.IsNullOrEmpty(node.Default.Name))
newNode.Default.Status = ObjectStatus.Create;
else
newNode.Default.Status = ObjectStatus.Drop;
newNode.Status = ObjectStatus.Alter;
}
else
{
if (!UserDataType.CompareRule(node, originFields[node.FullName]))
{
if (!String.IsNullOrEmpty(node.Rule.Name))
newNode.Rule.Status = ObjectStatus.Create;
else
newNode.Rule.Status = ObjectStatus.Drop;
newNode.Status = ObjectStatus.Alter;
}
else
newNode.Status = ObjectStatus.Rebuild;
}
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,8 @@
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareUsers : CompareBase<User>
{
}
}

@ -0,0 +1,52 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareViews : CompareBase<View>
{
protected override void DoUpdate<Root>(SchemaList<View, Root> originFields, View node)
{
View original = originFields[node.FullName];
if (!node.Compare(original))
{
View newNode = (View)node.Clone(originFields.Parent);
newNode.DependenciesOut.AddRange(original.DependenciesOut);
newNode.DependenciesIn.AddRange(original.DependenciesIn);
newNode.Status = ObjectStatus.Alter;
newNode.Indexes = original.Indexes;
newNode.Triggers = original.Triggers;
if (newNode.IsSchemaBinding)
newNode.Status += (int)ObjectStatus.RebuildDependencies;
if (newNode.HasToRebuild)
newNode.Status += (int)ObjectStatus.Rebuild;
else
newNode.Status += (int)ObjectStatus.AlterBody;
originFields[node.FullName] = newNode;
original = newNode;
}
(new CompareIndexes()).GenerateDifferences<View>(original.Indexes, node.Indexes);
(new CompareTriggers()).GenerateDifferences<View>(original.Triggers, node.Triggers);
}
protected override void DoNew<Root>(SchemaList<View, Root> originFields, View node)
{
View newNode = (View)node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Create;
originFields.Add(newNode);
newNode.DependenciesIn.ForEach(dep =>
{
ISchemaBase item = ((Database)((ISchemaBase)originFields.Parent)).Find(dep);
if (item != null)
{
if (item.IsCodeType)
((ICode)item).DependenciesOut.Add(newNode.FullName);
}
}
);
}
}
}

@ -0,0 +1,18 @@
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
{
internal class CompareXMLSchemas : CompareBase<XMLSchema>
{
protected override void DoUpdate<Root>(SchemaList<XMLSchema, Root> originFields, XMLSchema node)
{
if (!node.Compare(originFields[node.FullName]))
{
XMLSchema newNode = node.Clone(originFields.Parent);
newNode.Status = ObjectStatus.Alter;
originFields[node.FullName] = newNode;
}
}
}
}

@ -0,0 +1,191 @@
using OpenDBDiff.Schema.Errors;
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.Misc;
using OpenDBDiff.Schema.SQLServer.Generates.Compare;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Options;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class Generate
{
private readonly List<MessageLog> messages;
private ProgressEventArgs currentlyReading;
public Generate()
{
messages = new List<MessageLog>();
OnReading += Generate_OnReading;
}
public static int MaxValue
{
get { return Constants.READING_MAX; }
}
public string ConnectionString { get; set; }
private string Name
{
get
{
string name;
using (var conn = new SqlConnection(ConnectionString))
{
name = conn.Database;
}
return name;
}
}
public SqlOption Options { get; set; }
private event ProgressEventHandler.ProgressHandler OnReading;
public event ProgressEventHandler.ProgressHandler OnProgress;
private void Generate_OnReading(ProgressEventArgs e)
{
if (OnProgress != null) OnProgress(e);
}
public void RaiseOnReading(ProgressEventArgs e)
{
this.currentlyReading = e;
if (OnReading != null) OnReading(e);
}
public void RaiseOnReadingOne(object name)
{
if (name != null && this.OnReading != null && this.currentlyReading != null)
{
var eOne = new ProgressEventArgs(this.currentlyReading.Message, this.currentlyReading.Progress);
eOne.Message = eOne.Message.Replace("...", String.Format(": [{0}]", name));
this.OnReading(eOne);
}
}
/// <summary>
/// Genera el schema de la base de datos seleccionada y devuelve un objeto Database.
/// </summary>
public Database Process()
{
string error = "";
var databaseSchema = new Database();
//tables.OnTableProgress += new Progress.ProgressHandler(tables_OnTableProgress);
databaseSchema.Options = Options;
databaseSchema.Name = Name;
databaseSchema.Info = (new GenerateDatabase(ConnectionString, Options)).Get(databaseSchema);
/*Thread t1 = new Thread(delegate()
{
try
{*/
(new GenerateRules(this)).Fill(databaseSchema, ConnectionString);
(new GenerateTables(this)).Fill(databaseSchema, ConnectionString, messages);
(new GenerateViews(this)).Fill(databaseSchema, ConnectionString, messages);
if (Options.Ignore.FilterIndex)
{
(new GenerateIndex(this)).Fill(databaseSchema, ConnectionString);
(new GenerateFullTextIndex(this)).Fill(databaseSchema, ConnectionString);
}
(new GenerateUserDataTypes(this)).Fill(databaseSchema, ConnectionString, messages);
(new GenerateXMLSchemas(this)).Fill(databaseSchema, ConnectionString);
(new GenerateSchemas(this)).Fill(databaseSchema, ConnectionString);
/*}
catch (Exception ex)
{
error = ex.StackTrace;
}
});
Thread t2 = new Thread(delegate()
{
try
{*/
//not supported in azure yet
if (databaseSchema.Info.Version != DatabaseInfo.SQLServerVersion.SQLServerAzure10)
{
(new GeneratePartitionFunctions(this)).Fill(databaseSchema, ConnectionString);
(new GeneratePartitionScheme(this)).Fill(databaseSchema, ConnectionString);
(new GenerateFileGroups(this)).Fill(databaseSchema, ConnectionString);
}
(new GenerateDDLTriggers(this)).Fill(databaseSchema, ConnectionString);
(new GenerateSynonyms(this)).Fill(databaseSchema, ConnectionString);
//not supported in azure yet
if (databaseSchema.Info.Version != DatabaseInfo.SQLServerVersion.SQLServerAzure10)
{
(new GenerateAssemblies(this)).Fill(databaseSchema, ConnectionString);
(new GenerateFullText(this)).Fill(databaseSchema, ConnectionString);
}
/*}
catch (Exception ex)
{
error = ex.StackTrace;
}
});
Thread t3 = new Thread(delegate()
{
try
{*/
(new GenerateStoredProcedures(this)).Fill(databaseSchema, ConnectionString);
(new GenerateFunctions(this)).Fill(databaseSchema, ConnectionString);
(new GenerateTriggers(this)).Fill(databaseSchema, ConnectionString, messages);
(new GenerateTextObjects(this)).Fill(databaseSchema, ConnectionString);
(new GenerateUsers(this)).Fill(databaseSchema, ConnectionString);
/*}
catch (Exception ex)
{
error = ex.StackTrace;
}
});
t1.Start();
t2.Start();
t3.Start();
t1.Join();
t2.Join();
t3.Join();*/
if (String.IsNullOrEmpty(error))
{
/*Las propiedades extendidas deben ir despues de haber capturado el resto de los objetos de la base*/
(new GenerateExtendedProperties(this)).Fill(databaseSchema, ConnectionString, messages);
databaseSchema.BuildDependency();
return databaseSchema;
}
else
throw new SchemaException(error);
}
private void tables_OnTableProgress(object sender, ProgressEventArgs e)
{
ProgressEventHandler.RaiseOnChange(e);
}
// TODO: Static because Compare method is static; static events are not my favorite
public static event ProgressEventHandler.ProgressHandler OnCompareProgress;
internal static void RaiseOnCompareProgress(string formatString, params object[] formatParams)
{
OnCompareProgress?.Invoke(new ProgressEventArgs(String.Format(formatString, formatParams), -1));
}
/// <summary>
/// Generates the differences to migrate a schema from origin to destination
/// </summary>
/// <param name="origin">The Origin schema is the schema before our generated actions are applied.</param>
/// <param name="destination">The Destination schema is the schema after our actions are applied.</param>
/// <returns></returns>
public static Database Compare(Database origin, Database destination)
{
Database merge = CompareDatabase.GenerateDifferences(origin, destination);
return merge;
}
}
}

@ -0,0 +1,103 @@
using System;
using System.Data.SqlClient;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateAssemblies
{
private Generate root;
public GenerateAssemblies(Generate root)
{
this.root = root;
}
private static string GetSQLFiles()
{
return SQLQueries.SQLQueryFactory.Get("GetAssemblyFiles");
}
private static string GetSQL()
{
return SQLQueries.SQLQueryFactory.Get("GetAssemblies");
}
private static string ToHex(byte[] stream)
{
return ByteToHexEncoder.ByteArrayToHex(stream);
}
private static void FillFiles(Database database, string connectionString)
{
if (database.Options.Ignore.FilterAssemblies)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQLFiles(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
if (((int)reader["FileId"]) != 1)
{
Assembly assem = database.Assemblies[reader["Name"].ToString()];
AssemblyFile file = new AssemblyFile(assem, reader["FileName"].ToString(), ToHex((byte[])reader["FileContent"]));
assem.Files.Add(file);
}
}
}
}
}
}
}
public void Fill(Database database, string connectionString)
{
int lastViewId = 0;
if (database.Options.Ignore.FilterAssemblies)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
Assembly item = null;
while (reader.Read())
{
if (lastViewId != (int)reader["assembly_id"])
{
item = new Assembly(database)
{
Id = (int)reader["assembly_id"],
Name = reader["Name"].ToString(),
Owner = reader["Owner"].ToString(),
CLRName = reader["clr_name"].ToString(),
PermissionSet = reader["permission_set_desc"].ToString(),
Text = ToHex((byte[])reader["content"]),
Visible = (bool)reader["is_visible"]
};
lastViewId = item.Id;
database.Assemblies.Add(item);
}
if (!String.IsNullOrEmpty(reader["Dependency"].ToString()))
item.DependenciesOut.Add(reader["Dependency"].ToString());
if (!String.IsNullOrEmpty(reader["ObjectDependency"].ToString()))
item.DependenciesOut.Add(reader["ObjectDependency"].ToString());
if (!String.IsNullOrEmpty(reader["UDTName"].ToString()))
item.DependenciesOut.Add(reader["UDTName"].ToString());
}
}
}
FillFiles(database, connectionString);
}
}
}
}
}

@ -0,0 +1,303 @@
using System;
using System.Data.SqlClient;
using System.Text;
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateConstraint
{
private Generate root;
public GenerateConstraint(Generate root)
{
this.root = root;
}
#region Check Functions...
public void FillCheck(Database database, string connectionString)
{
int parentId = 0;
ISchemaBase table = null;
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(ConstraintSQLCommand.GetCheck(database.Info.Version), conn))
{
root.RaiseOnReading(new ProgressEventArgs("Reading constraint...", Constants.READING_CONSTRAINTS));
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
Constraint item = null;
while (reader.Read())
{
root.RaiseOnReadingOne(reader["Name"]);
if (parentId != (int)reader["parent_object_id"])
{
parentId = (int)reader["parent_object_id"];
if (reader["ObjectType"].ToString().Trim().Equals("U"))
table = database.Tables.Find(parentId);
else
table = database.TablesTypes.Find(parentId);
}
if (table != null)
{
item = new Constraint(table);
item.Id = (int)reader["id"];
item.Name = reader["Name"].ToString();
item.Type = Constraint.ConstraintType.Check;
item.Definition = reader["Definition"].ToString();
item.WithNoCheck = (bool)reader["WithCheck"];
item.IsDisabled = (bool)reader["is_disabled"];
item.Owner = reader["Owner"].ToString();
if (database.Options.Ignore.FilterNotForReplication)
item.NotForReplication = (bool)reader["is_not_for_replication"];
if (reader["ObjectType"].ToString().Trim().Equals("U"))
((Table)table).Constraints.Add(item);
else
((TableType)table).Constraints.Add(item);
}
}
}
}
}
}
#endregion
#region ForeignKey Functions...
private static string GetSQLForeignKey()
{
return SQLQueries.SQLQueryFactory.Get("GetForeignKeys");
}
private static void FillForeignKey(Database database, string connectionString)
{
int lastid = 0;
int parentId = 0;
Table table = null;
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQLForeignKey(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
Constraint con = null;
while (reader.Read())
{
if (parentId != (int)reader["parent_object_id"])
{
parentId = (int)reader["parent_object_id"];
table = database.Tables.Find(parentId);
}
if (table != null)
{
if (lastid != (int)reader["object_id"])
{
con = new Constraint(table);
con.Id = (int)reader["object_id"];
con.Name = reader["Name"].ToString();
con.Type = Constraint.ConstraintType.ForeignKey;
con.WithNoCheck = (bool)reader["is_not_trusted"];
con.RelationalTableFullName = "[" + reader["ReferenceOwner"].ToString() + "].[" + reader["TableRelationalName"].ToString() + "]";
con.RelationalTableId = (int)reader["TableRelationalId"];
con.Owner = reader["Owner"].ToString();
con.IsDisabled = (bool)reader["is_disabled"];
con.OnDeleteCascade = (byte)reader["delete_referential_action"];
con.OnUpdateCascade = (byte)reader["update_referential_action"];
if (database.Options.Ignore.FilterNotForReplication)
con.NotForReplication = (bool)reader["is_not_for_replication"];
lastid = (int)reader["object_id"];
table.Constraints.Add(con);
}
ConstraintColumn ccon = new ConstraintColumn(con);
ccon.Name = reader["ColumnName"].ToString();
ccon.ColumnRelationalName = reader["ColumnRelationalName"].ToString();
ccon.ColumnRelationalId = (int)reader["ColumnRelationalId"];
ccon.Id = (int)reader["ColumnId"];
ccon.KeyOrder = con.Columns.Count;
ccon.ColumnRelationalDataTypeId = (int)reader["user_type_id"];
//table.DependenciesCount++;
con.Columns.Add(ccon);
}
}
}
}
}
}
#endregion
#region UniqueKey Functions...
private static void FillUniqueKey(Database database, string connectionString)
{
int lastId = 0;
int parentId = 0;
bool change = false;
ISchemaBase table = null;
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(ConstraintSQLCommand.GetUniqueKey(database.Info.Version, database.Info.Edition), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
Constraint con = null;
while (reader.Read())
{
if (parentId != (int)reader["ID"])
{
parentId = (int)reader["ID"];
if (reader["ObjectType"].ToString().Trim().Equals("U"))
table = database.Tables.Find(parentId);
else
table = database.TablesTypes.Find(parentId);
change = true;
}
else
change = false;
if (table != null)
{
if ((lastId != (int)reader["Index_id"]) || (change))
{
con = new Constraint(table);
con.Name = reader["Name"].ToString();
con.Owner = (string)reader["Owner"];
con.Id = (int)reader["Index_id"];
con.Type = Constraint.ConstraintType.Unique;
con.Index.Id = (int)reader["Index_id"];
con.Index.AllowPageLocks = (bool)reader["allow_page_locks"];
con.Index.AllowRowLocks = (bool)reader["allow_row_locks"];
con.Index.FillFactor = (byte)reader["fill_factor"];
con.Index.IgnoreDupKey = (bool)reader["ignore_dup_key"];
con.Index.IsAutoStatistics = (bool)reader["ignore_dup_key"];
con.Index.IsDisabled = (bool)reader["is_disabled"];
con.Index.IsPadded = (bool)reader["is_padded"];
con.Index.IsPrimaryKey = false;
con.Index.IsUniqueKey = true;
con.Index.Type = (Index.IndexTypeEnum)(byte)reader["type"];
con.Index.Name = con.Name;
if (database.Options.Ignore.FilterTableFileGroup)
con.Index.FileGroup = reader["FileGroup"].ToString();
lastId = (int)reader["Index_id"];
if (reader["ObjectType"].ToString().Trim().Equals("U"))
((Table)table).Constraints.Add(con);
else
((TableType)table).Constraints.Add(con);
}
ConstraintColumn ccon = new ConstraintColumn(con);
ccon.Name = reader["ColumnName"].ToString();
ccon.IsIncluded = (bool)reader["is_included_column"];
ccon.Order = (bool)reader["is_descending_key"];
ccon.Id = (int)reader["column_id"];
ccon.DataTypeId = (int)reader["user_type_id"];
con.Columns.Add(ccon);
}
}
}
}
}
}
#endregion
#region PrimaryKey Functions...
private static void FillPrimaryKey(Database database, string connectionString)
{
int lastId = 0;
int parentId = 0;
bool change = false;
ISchemaBase table = null;
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(ConstraintSQLCommand.GetPrimaryKey(database.Info.Version, null), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
Constraint con = null;
while (reader.Read())
{
if (parentId != (int)reader["ID"])
{
parentId = (int)reader["ID"];
if (reader["ObjectType"].ToString().Trim().Equals("U"))
table = database.Tables.Find(parentId);
else
table = database.TablesTypes.Find(parentId);
change = true;
}
else
change = false;
if (table != null)
{
if ((lastId != (int)reader["Index_id"]) || (change))
{
con = new Constraint(table);
con.Id = (int)reader["Index_id"];
con.Name = (string)reader["Name"];
con.Owner = (string)reader["Owner"];
con.Type = Constraint.ConstraintType.PrimaryKey;
con.Index.Id = (int)reader["Index_id"];
con.Index.AllowPageLocks = (bool)reader["allow_page_locks"];
con.Index.AllowRowLocks = (bool)reader["allow_row_locks"];
con.Index.FillFactor = (byte)reader["fill_factor"];
con.Index.IgnoreDupKey = (bool)reader["ignore_dup_key"];
con.Index.IsAutoStatistics = (bool)reader["ignore_dup_key"];
con.Index.IsDisabled = (bool)reader["is_disabled"];
con.Index.IsPadded = (bool)reader["is_padded"];
con.Index.IsPrimaryKey = true;
con.Index.IsUniqueKey = false;
con.Index.Type = (Index.IndexTypeEnum)(byte)reader["type"];
con.Index.Name = con.Name;
if (database.Options.Ignore.FilterTableFileGroup)
con.Index.FileGroup = reader["FileGroup"].ToString();
lastId = (int)reader["Index_id"];
if (reader["ObjectType"].ToString().Trim().Equals("U"))
((Table)table).Constraints.Add(con);
else
((TableType)table).Constraints.Add(con);
}
ConstraintColumn ccon = new ConstraintColumn(con);
ccon.Name = (string)reader["ColumnName"];
ccon.IsIncluded = (bool)reader["is_included_column"];
ccon.Order = (bool)reader["is_descending_key"];
ccon.KeyOrder = (byte)reader["key_ordinal"];
ccon.Id = (int)reader["column_id"];
ccon.DataTypeId = (int)reader["user_type_id"];
con.Columns.Add(ccon);
}
}
}
}
}
}
#endregion
public void Fill(Database database, string connectionString)
{
if (database.Options.Ignore.FilterConstraintPK)
FillPrimaryKey(database, connectionString);
if (database.Options.Ignore.FilterConstraintFK)
FillForeignKey(database, connectionString);
if (database.Options.Ignore.FilterConstraintUK)
FillUniqueKey(database, connectionString);
if (database.Options.Ignore.FilterConstraintCheck)
FillCheck(database, connectionString);
}
}
}

@ -0,0 +1,50 @@
using System.Data.SqlClient;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateDDLTriggers
{
private Generate root;
public GenerateDDLTriggers(Generate root)
{
this.root = root;
}
private static string GetSQL()
{
return SQLQueries.SQLQueryFactory.Get("GetDDLTriggers");
}
public void Fill(Database database, string connectionString)
{
if (database.Options.Ignore.FilterDDLTriggers)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
{
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Trigger trigger = new Trigger(database);
trigger.Text = reader["Text"].ToString();
trigger.Name = reader["Name"].ToString();
trigger.InsteadOf = (bool)reader["is_instead_of_trigger"];
trigger.IsDisabled = (bool)reader["is_disabled"];
trigger.IsDDLTrigger = true;
trigger.NotForReplication = (bool)reader["is_not_for_replication"];
trigger.Owner = "";
database.DDLTriggers.Add(trigger);
}
}
}
}
}
}
}
}

@ -0,0 +1,97 @@
using System;
using System.Data.SqlClient;
using System.Globalization;
using OpenDBDiff.Schema.Misc;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Options;
#if DEBUG
using System.Runtime.InteropServices;
#endif
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateDatabase
{
private string connectioString;
private SqlOption objectFilter;
public bool UseDefaultVersionOnVersionParseError { get; private set; }
/// <summary>
/// Constructor de la clase.
/// </summary>
/// <param name="connectioString">Connection string de la base</param>
public GenerateDatabase(string connectioString, SqlOption filter)
{
this.connectioString = connectioString;
this.objectFilter = filter;
}
public DatabaseInfo Get(Database database)
{
DatabaseInfo item = new DatabaseInfo();
using (SqlConnection conn = new SqlConnection(connectioString))
{
using (SqlCommand command = new SqlCommand(DatabaseSQLCommand.GetVersion(database), conn))
{
conn.Open();
item.Server = conn.DataSource;
item.Database = conn.Database;
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
string versionValue = reader["Version"] as string;
try
{
// used to use the decimal as well when Azure was 10.25
var version = new Version(versionValue);
item.VersionNumber = float.Parse(String.Format("{0}.{1}", version.Major, version.Minor), CultureInfo.InvariantCulture);
if (reader.FieldCount > 1 && !reader.IsDBNull(1))
{
int edition;
if (int.TryParse(reader[1].ToString(), out edition)
&& Enum.IsDefined(typeof(DatabaseInfo.SQLServerEdition), edition))
{
item.SetEdition((DatabaseInfo.SQLServerEdition)edition);
}
}
}
catch (Exception notAGoodIdeaToCatchAllErrors)
{
var exception = new SchemaException(
String.Format("Error parsing ProductVersion. ({0})", versionValue ?? "[null]")
, notAGoodIdeaToCatchAllErrors);
if (!UseDefaultVersionOnVersionParseError)
{
throw exception;
}
}
}
}
}
using (SqlCommand command = new SqlCommand(DatabaseSQLCommand.Get(item.Version, item.Edition, database), conn))
{
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
item.Collation = reader["Collation"].ToString();
item.HasFullTextEnabled = ((int)reader["IsFulltextEnabled"]) == 1;
}
}
}
}
return item;
}
}
}

@ -0,0 +1,46 @@
using System.Data.SqlClient;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateDefaults
{
private Generate root;
public GenerateDefaults(Generate root)
{
this.root = root;
}
private static string GetSQL()
{
return SQLQueries.SQLQueryFactory.Get("GetDefaults");
}
public void Fill(Database database, string connectionString)
{
if (database.Options.Ignore.FilterRules)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
{
conn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Default item = new Default(database);
item.Id = (int)reader["object_id"];
item.Name = reader["Name"].ToString();
item.Owner = reader["Owner"].ToString();
item.Value = reader["Definition"].ToString();
database.Defaults.Add(item);
}
}
}
}
}
}
}
}

@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using OpenDBDiff.Schema.Errors;
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateExtendedProperties
{
private Generate root;
public GenerateExtendedProperties(Generate root)
{
this.root = root;
}
private static string GetSQL()
{
return SQLQueries.SQLQueryFactory.Get("GetExtendedProperties");
}
private static string GetTypeDescription(string type)
{
if (type.Equals("PC")) return "PROCEDURE";
if (type.Equals("P")) return "PROCEDURE";
if (type.Equals("V")) return "VIEW";
if (type.Equals("U")) return "TABLE";
if (type.Equals("TR")) return "TRIGGER";
if (type.Equals("TA")) return "TRIGGER";
if (type.Equals("FS")) return "FUNCTION";
if (type.Equals("FN")) return "FUNCTION";
if (type.Equals("IF")) return "FUNCTION";
if (type.Equals("TF")) return "FUNCTION";
return "";
}
public void Fill(Database database, string connectionString, List<MessageLog> messages)
{
ISQLServerSchemaBase parent;
try
{
if (database.Options.Ignore.FilterExtendedProperties)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
ExtendedProperty item = new ExtendedProperty(null);
if (((byte)reader["Class"]) == 5)
{
item.Level0type = "ASSEMBLY";
item.Level0name = reader["AssemblyName"].ToString();
}
if (((byte)reader["Class"]) == 1)
{
string ObjectType = GetTypeDescription(reader["type"].ToString().Trim());
item.Level0type = "SCHEMA";
item.Level0name = reader["Owner"].ToString();
if (!ObjectType.Equals("TRIGGER"))
{
item.Level1name = reader["ObjectName"].ToString();
item.Level1type = ObjectType;
}
else
{
item.Level1type = "TABLE";
item.Level1name = reader["ParentName"].ToString();
item.Level2name = reader["ObjectName"].ToString();
item.Level2type = ObjectType;
}
}
if (((byte)reader["Class"]) == 6)
{
item.Level0type = "SCHEMA";
item.Level0name = reader["OwnerType"].ToString();
item.Level1name = reader["TypeName"].ToString();
item.Level1type = "TYPE";
}
if (((byte)reader["Class"]) == 7)
{
item.Level0type = "SCHEMA";
item.Level0name = reader["Owner"].ToString();
item.Level1type = "TABLE";
item.Level1name = reader["ObjectName"].ToString();
item.Level2type = reader["class_desc"].ToString();
item.Level2name = reader["IndexName"].ToString();
}
item.Value = reader["Value"].ToString();
item.Name = reader["Name"].ToString();
parent = ((ISQLServerSchemaBase)database.Find(item.FullName));
if (parent != null)
{
item.Parent = (ISchemaBase)parent;
parent.ExtendedProperties.Add(item);
}
else
messages.Add(new MessageLog(item.FullName + " not found in extended properties.", "", MessageLog.LogType.Error));
}
}
}
}
}
}
catch (Exception ex)
{
messages.Add(new MessageLog(ex.Message, ex.StackTrace, MessageLog.LogType.Error));
}
}
}
}

@ -0,0 +1,92 @@
using System.Data.SqlClient;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateFileGroups
{
private Generate root;
public GenerateFileGroups(Generate root)
{
this.root = root;
}
private static string GetSQLFile(FileGroup filegroup)
{
string query = SQLQueries.SQLQueryFactory.Get("GetDatabaseFile");
return query.Replace("{ID}", filegroup.Id.ToString());
}
private static string GetSQL()
{
return SQLQueries.SQLQueryFactory.Get("GetFileGroups");
}
private static void FillFiles(FileGroup filegroup, string connectionString)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQLFile(filegroup), conn))
{
conn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
FileGroupFile item = new FileGroupFile(filegroup);
item.Id = (int)reader["file_id"];
item.Name = reader["name"].ToString();
item.Owner = "";
item.Growth = (int)reader["growth"];
item.IsPercentGrowth = (bool)reader["is_percent_growth"];
item.IsSparse = (bool)reader["is_sparse"];
item.MaxSize = (int)reader["max_size"];
item.PhysicalName = reader["physical_name"].ToString();
item.Size = (int)reader["size"];
item.Type = (byte)reader["type"];
filegroup.Files.Add(item);
}
}
}
}
}
public void Fill(Database database, string connectionString)
{
try
{
if (database.Options.Ignore.FilterTableFileGroup)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
{
conn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
FileGroup item = new FileGroup(database);
item.Id = (int)reader["ID"];
item.Name = reader["name"].ToString();
item.Owner = "";
item.IsDefaultFileGroup = (bool)reader["is_default"];
item.IsReadOnly = (bool)reader["is_read_only"];
item.IsFileStream = reader["type"].Equals("FD");
FillFiles(item, connectionString);
database.FileGroups.Add(item);
}
}
}
}
}
}
catch
{
throw;
}
}
}
}

@ -0,0 +1,51 @@
using System.Data.SqlClient;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateFullText
{
private Generate root;
public GenerateFullText(Generate root)
{
this.root = root;
}
private static string GetSQL()
{
return SQLQueries.SQLQueryFactory.Get("GetFullTextCatalogs");
}
public void Fill(Database database, string connectionString)
{
if (database.Options.Ignore.FilterFullText)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
{
conn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
FullText item = new FullText(database);
item.Id = (int)reader["fulltext_catalog_id"];
item.Name = reader["Name"].ToString();
item.Owner = reader["Owner"].ToString();
item.IsAccentSensity = (bool)reader["is_accent_sensitivity_on"];
item.IsDefault = (bool)reader["is_default"];
if (!reader.IsDBNull(reader.GetOrdinal("path")))
item.Path = reader["path"].ToString().Substring(0, reader["path"].ToString().Length - item.Name.Length);
if (!reader.IsDBNull(reader.GetOrdinal("FileGroupName")))
item.FileGroupName = reader["FileGroupName"].ToString();
database.FullText.Add(item);
}
}
}
}
}
}
}
}

@ -0,0 +1,70 @@
using System.Data.SqlClient;
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateFullTextIndex
{
private Generate root;
public GenerateFullTextIndex(Generate root)
{
this.root = root;
}
public void Fill(Database database, string connectionString)
{
//not supported in azure yet
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServerAzure10) return;
int parentId = 0;
bool change = false;
Table parent = null;
root.RaiseOnReading(new ProgressEventArgs("Reading FullText Index...", Constants.READING_INDEXES));
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(FullTextIndexSQLCommand.Get(database.Info.Version), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
FullTextIndex item = null;
while (reader.Read())
{
root.RaiseOnReadingOne(reader["Name"]);
if (parentId != (int)reader["object_id"])
{
parentId = (int)reader["object_id"];
parent = database.Tables.Find(parentId);
change = true;
}
else
change = false;
if (change)
{
item = new FullTextIndex(parent);
item.Name = reader["Name"].ToString();
item.Owner = parent.Owner;
item.FullText = reader["FullTextCatalogName"].ToString();
item.Index = reader["IndexName"].ToString();
item.IsDisabled = !(bool)reader["is_enabled"];
item.ChangeTrackingState = reader["ChangeTracking"].ToString();
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
item.FileGroup = reader["FileGroupName"].ToString();
((Table)parent).FullTextIndex.Add(item);
}
FullTextIndexColumn ccon = new FullTextIndexColumn();
ccon.ColumnName = reader["ColumnName"].ToString();
ccon.Language = reader["LanguageName"].ToString();
item.Columns.Add(ccon);
}
}
}
}
}
}
}

@ -0,0 +1,138 @@
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
using System;
using System.Data.SqlClient;
using System.Linq;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateFunctions
{
private Generate root;
public GenerateFunctions(Generate root)
{
this.root = root;
}
private static string GetSQLParameters()
{
return SQLQueries.SQLQueryFactory.Get("GetParameters");
}
private static void FillParameters(Database database, string connectionString)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQLParameters(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
var objectName = reader["ObjectName"].ToString();
if (database.CLRFunctions.Contains(objectName))
{
Parameter param = new Parameter();
param.Name = reader["Name"].ToString();
param.Type = reader["TypeName"].ToString();
param.Size = (short)reader["max_length"];
param.Scale = (byte)reader["scale"];
param.Precision = (byte)reader["precision"];
param.Output = (bool)reader["is_output"];
if (param.Type.Equals("nchar") || param.Type.Equals("nvarchar"))
{
if (param.Size != -1)
param.Size = param.Size / 2;
}
database.CLRFunctions[objectName].Parameters.Add(param);
}
}
}
}
}
}
public void Fill(Database database, string connectionString)
{
int lastViewId = 0;
if ((database.Options.Ignore.FilterFunction) || (database.Options.Ignore.FilterCLRFunction))
{
root.RaiseOnReading(new ProgressEventArgs("Reading functions...", Constants.READING_FUNCTIONS));
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(FunctionSQLCommand.Get(database.Info.Version, database.Info.Edition), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
Function itemF = null;
CLRFunction itemC = null;
while (reader.Read())
{
root.RaiseOnReadingOne(reader["name"]);
if ((!reader["type"].ToString().Trim().Equals("FS")) && (database.Options.Ignore.FilterFunction))
{
if (lastViewId != (int)reader["object_id"])
{
itemF = new Function(database);
itemF.Id = (int)reader["object_id"];
itemF.Name = reader["name"].ToString();
itemF.Owner = reader["owner"].ToString();
itemF.IsSchemaBinding = reader["IsSchemaBound"].ToString().Equals("1");
database.Functions.Add(itemF);
lastViewId = itemF.Id;
}
if (itemF.IsSchemaBinding)
{
if (!reader.IsDBNull(reader.GetOrdinal("referenced_major_id")))
database.Dependencies.Add(database, (int)reader["referenced_major_id"], itemF);
if (!String.IsNullOrEmpty(reader["TableName"].ToString()))
itemF.DependenciesIn.Add(reader["TableName"].ToString());
if (!String.IsNullOrEmpty(reader["DependOut"].ToString()))
itemF.DependenciesOut.Add(reader["DependOut"].ToString());
}
}
if ((reader["type"].ToString().Trim().Equals("FS")) && (database.Options.Ignore.FilterCLRFunction))
{
itemC = new CLRFunction(database);
if (lastViewId != (int)reader["object_id"])
{
itemC.Id = (int)reader["object_id"];
itemC.Name = reader["name"].ToString();
itemC.Owner = reader["owner"].ToString();
itemC.IsAssembly = true;
itemC.AssemblyId = (int)reader["assembly_id"];
itemC.AssemblyName = reader["assembly_name"].ToString();
itemC.AssemblyClass = reader["assembly_class"].ToString();
itemC.AssemblyExecuteAs = reader["ExecuteAs"].ToString();
itemC.AssemblyMethod = reader["assembly_method"].ToString();
itemC.ReturnType.Type = reader["ReturnType"].ToString();
itemC.ReturnType.Size = (short)reader["max_length"];
itemC.ReturnType.Scale = (byte)reader["Scale"];
itemC.ReturnType.Precision = (byte)reader["precision"];
if (itemC.ReturnType.Type.Equals("nchar") || itemC.ReturnType.Type.Equals("nvarchar"))
{
if (itemC.ReturnType.Size != -1)
itemC.ReturnType.Size = itemC.ReturnType.Size / 2;
}
database.CLRFunctions.Add(itemC);
lastViewId = itemC.Id;
}
}
}
}
}
}
}
if (database.CLRFunctions.Any())
FillParameters(database, connectionString);
}
}
}

@ -0,0 +1,105 @@
using System.Data.SqlClient;
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateIndex
{
private Generate root;
public GenerateIndex(Generate root)
{
this.root = root;
}
public void Fill(Database database, string connectionString)
{
int indexid = 0;
int parentId = 0;
bool change = false;
string type;
ISchemaBase parent = null;
root.RaiseOnReading(new ProgressEventArgs("Reading Index...", Constants.READING_INDEXES));
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(IndexSQLCommand.Get(database.Info.Version, database.Info.Edition), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
Index item = null;
while (reader.Read())
{
root.RaiseOnReadingOne(reader["Name"]);
type = reader["ObjectType"].ToString().Trim();
if (parentId != (int)reader["object_id"])
{
parentId = (int)reader["object_id"];
if (type.Equals("V"))
parent = database.Views.Find(parentId);
else
parent = database.Tables.Find(parentId);
change = true;
}
else
change = false;
if (parent != null)
{
if (indexid != (int)reader["index_id"] || change)
{
item = new Index(parent);
item.Name = reader["Name"].ToString();
item.Owner = parent.Owner;
item.Type = (Index.IndexTypeEnum)(byte)reader["type"];
item.Id = (int)reader["index_id"];
item.IgnoreDupKey = (bool)reader["ignore_dup_key"];
item.IsAutoStatistics = (bool)reader["NoAutomaticRecomputation"];
item.IsDisabled = (bool)reader["is_disabled"];
item.IsPrimaryKey = (bool)reader["is_primary_key"];
item.IsUniqueKey = (bool)reader["is_unique"];
if (database.Options.Ignore.FilterIndexRowLock)
{
item.AllowPageLocks = (bool)reader["allow_page_locks"];
item.AllowRowLocks = (bool)reader["allow_row_locks"];
}
if (database.Options.Ignore.FilterIndexFillFactor)
{
item.FillFactor = (byte)reader["fill_factor"];
item.IsPadded = (bool)reader["is_padded"];
}
if ((database.Options.Ignore.FilterTableFileGroup) && (item.Type != Index.IndexTypeEnum.XML))
item.FileGroup = reader["FileGroup"].ToString();
if ((database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008) && (database.Options.Ignore.FilterIndexFilter))
{
item.FilterDefintion = reader["FilterDefinition"].ToString();
}
indexid = (int)reader["index_id"];
if (type.Equals("V"))
((View)parent).Indexes.Add(item);
else
((Table)parent).Indexes.Add(item);
}
IndexColumn ccon = new IndexColumn(item.Parent);
ccon.Name = reader["ColumnName"].ToString();
ccon.IsIncluded = (bool)reader["is_included_column"];
ccon.Order = (bool)reader["is_descending_key"];
ccon.Id = (int)reader["column_id"];
ccon.KeyOrder = (byte)reader["key_ordinal"];
ccon.DataTypeId = (int)reader["user_type_id"];
if ((!ccon.IsIncluded) || (ccon.IsIncluded && database.Options.Ignore.FilterIndexIncludeColumns))
item.Columns.Add(ccon);
}
}
}
}
}
}
}
}

@ -0,0 +1,84 @@
using System;
using System.Data.SqlClient;
using System.Text;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GeneratePartitionFunctions
{
private Generate root;
public GeneratePartitionFunctions(Generate root)
{
this.root = root;
}
private static string GetSQL()
{
return SQLQueries.SQLQueryFactory.Get("GetPartitionFunctions");
}
private static string ToHex(byte[] stream)
{
StringBuilder sHex = new StringBuilder(2 * stream.Length);
for (int i = 0; i < stream.Length; i++)
sHex.AppendFormat("{0:X2} ", stream[i]);
return "0x" + sHex.ToString().Replace(" ", String.Empty);
}
public void Fill(Database database, string connectioString)
{
int lastObjectId = 0;
PartitionFunction item = null;
if (database.Options.Ignore.FilterPartitionFunction)
{
using (SqlConnection conn = new SqlConnection(connectioString))
{
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
if (lastObjectId != (int)reader["function_id"])
{
lastObjectId = (int)reader["function_id"];
item = new PartitionFunction(database);
item.Id = (int)reader["function_id"];
item.Name = reader["name"].ToString();
item.IsBoundaryRight = (bool)reader["IsRight"];
item.Precision = (byte)reader["precision"];
item.Scale = (byte)reader["scale"];
item.Size = (short)reader["max_length"];
item.Type = reader["TypeName"].ToString();
database.PartitionFunctions.Add(item);
}
switch (item.Type) {
case "binary":
case "varbinary":
item.Values.Add(ToHex((byte[])reader["value"]));
break;
case "date":
item.Values.Add(String.Format("'{0:yyyy/MM/dd}'", (DateTime)reader["value"]));
break;
case "smalldatetime":
case "datetime":
item.Values.Add(String.Format("'{0:yyyy/MM/dd HH:mm:ss.fff}'", (DateTime)reader["value"]));
break;
default:
item.Values.Add(reader["value"].ToString());
break;
}
}
}
}
}
}
}
}
}

@ -0,0 +1,53 @@
using System.Data.SqlClient;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GeneratePartitionScheme
{
private Generate root;
public GeneratePartitionScheme(Generate root)
{
this.root = root;
}
private static string GetSQL()
{
return SQLQueries.SQLQueryFactory.Get("GetPartitionSchemes");
}
public void Fill(Database database, string connectioString)
{
int lastObjectId = 0;
PartitionScheme item = null;
if (database.Options.Ignore.FilterPartitionScheme)
{
using (SqlConnection conn = new SqlConnection(connectioString))
{
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
if (lastObjectId != (int)reader["ID"])
{
lastObjectId = (int)reader["ID"];
item = new PartitionScheme(database);
item.Id = (int)reader["ID"];
item.Name = reader["name"].ToString();
item.PartitionFunction = reader["FunctionName"].ToString();
database.PartitionSchemes.Add(item);
}
item.FileGroups.Add(reader["FileGroupName"].ToString());
}
}
}
}
}
}
}
}

@ -0,0 +1,46 @@
using System.Data.SqlClient;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateRules
{
private Generate root;
public GenerateRules(Generate root)
{
this.root = root;
}
private static string GetSQL()
{
return SQLQueries.SQLQueryFactory.Get("GetRules");
}
public void Fill(Database database, string connectionString)
{
if (database.Options.Ignore.FilterRules)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
{
conn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Rule item = new Rule(database);
item.Id = (int)reader["object_id"];
item.Name = reader["Name"].ToString();
item.Owner = reader["Owner"].ToString();
item.Text = reader["Definition"].ToString();
database.Rules.Add(item);
}
}
}
}
}
}
}
}

@ -0,0 +1,46 @@
using System.Data.SqlClient;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateSchemas
{
private Generate root;
public GenerateSchemas(Generate root)
{
this.root = root;
}
private static string GetSQL()
{
return SQLQueries.SQLQueryFactory.Get("GetSchemas");
}
public void Fill(Database database, string connectioString)
{
if (database.Options.Ignore.FilterSchema)
{
using (SqlConnection conn = new SqlConnection(connectioString))
{
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Model.Schema item = new Model.Schema(database);
item.Id = (int)reader["schema_id"];
item.Name = reader["name"].ToString();
item.Owner = reader["owner"].ToString();
database.Schemas.Add(item);
}
}
}
}
}
}
}
}

@ -0,0 +1,145 @@
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
using System.Data.SqlClient;
using System.Linq;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateStoredProcedures
{
private static int NameIndex = -1;
private static int object_idIndex = -1;
private static int ownerIndex = -1;
private static int typeIndex = -1;
private Generate root;
public GenerateStoredProcedures(Generate root)
{
this.root = root;
}
private static void InitIndex(SqlDataReader reader)
{
if (NameIndex == -1)
{
object_idIndex = reader.GetOrdinal("object_id");
NameIndex = reader.GetOrdinal("Name");
ownerIndex = reader.GetOrdinal("owner");
typeIndex = reader.GetOrdinal("type");
}
}
private static string GetSQLParameters()
{
return SQLQueries.SQLQueryFactory.Get("GetParameters");
}
private static string GetSQL(DatabaseInfo.SQLServerVersion version)
{
if (version == DatabaseInfo.SQLServerVersion.SQLServerAzure10)
{
return SQLQueries.SQLQueryFactory.Get("GetProcedures", DatabaseInfo.SQLServerVersion.SQLServerAzure10);
}
else
{
return SQLQueries.SQLQueryFactory.Get("GetProcedures");
}
}
private static void FillParameters(Database database, string connectionString)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQLParameters(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
var objectName = reader["ObjectName"].ToString();
if (database.CLRProcedures.Contains(objectName))
{
Parameter param = new Parameter();
param.Name = reader["Name"].ToString();
param.Type = reader["TypeName"].ToString();
param.Size = (short)reader["max_length"];
param.Scale = (byte)reader["scale"];
param.Precision = (byte)reader["precision"];
param.Output = (bool)reader["is_output"];
if (param.Type.Equals("nchar") || param.Type.Equals("nvarchar"))
{
if (param.Size != -1)
param.Size = param.Size / 2;
}
database.CLRProcedures[objectName].Parameters.Add(param);
}
}
}
}
}
}
public void Fill(Database database, string connectionString)
{
if ((database.Options.Ignore.FilterStoredProcedure) || (database.Options.Ignore.FilterCLRStoredProcedure))
{
root.RaiseOnReading(new ProgressEventArgs("Reading stored procedures...", Constants.READING_PROCEDURES));
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQL(database.Info.Version), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
InitIndex(reader);
root.RaiseOnReadingOne(reader[NameIndex]);
var objectType = reader[typeIndex].ToString().Trim();
switch (objectType)
{
case "P":
if (database.Options.Ignore.FilterStoredProcedure)
{
StoredProcedure item = new StoredProcedure(database);
item.Id = (int)reader[object_idIndex];
item.Name = (string)reader[NameIndex];
item.Owner = (string)reader[ownerIndex];
database.Procedures.Add(item);
}
break;
case "PC":
if (database.Options.Ignore.FilterCLRStoredProcedure)
{
CLRStoredProcedure item = new CLRStoredProcedure(database);
item.Id = (int)reader[object_idIndex];
item.Name = reader[NameIndex].ToString();
item.Owner = reader[ownerIndex].ToString();
item.IsAssembly = true;
item.AssemblyId = (int)reader["assembly_id"];
item.AssemblyName = reader["assembly_name"].ToString();
item.AssemblyClass = reader["assembly_class"].ToString();
item.AssemblyExecuteAs = reader["ExecuteAs"].ToString();
item.AssemblyMethod = reader["assembly_method"].ToString();
database.CLRProcedures.Add(item);
}
break;
}
}
}
}
}
if (database.CLRProcedures.Any())
FillParameters(database, connectionString);
}
}
}
}

@ -0,0 +1,47 @@
using System.Data.SqlClient;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateSynonyms
{
private Generate root;
public GenerateSynonyms(Generate root)
{
this.root = root;
}
private static string GetSQL()
{
return SQLQueries.SQLQueryFactory.Get("GetSynonyms");
}
public void Fill(Database database, string connectionString)
{
if (database.Options.Ignore.FilterSynonyms)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Synonym item = new Synonym(database);
item.Id = (int)reader["object_id"];
item.Name = reader["Name"].ToString();
item.Owner = reader["Owner"].ToString();
item.Value = reader["base_object_name"].ToString();
database.Synonyms.Add(item);
}
}
}
}
}
}
}
}

@ -0,0 +1,313 @@
using OpenDBDiff.Schema.Errors;
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using Constraint = OpenDBDiff.Schema.SQLServer.Generates.Model.Constraint;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateTables
{
private int colIDIndex = -1;
private int colNameIndex = -1;
private int colFormulaIndex = -1;
private int colIsPersistedIndex = -1;
private int colIsComputedIndex = -1;
private int colNullableIndex = -1;
private int colXmlSchemaIndex = -1;
private int colIs_xml_documentIndex = -1;
private int colPrecisionIndex = -1;
private int colScaleIndex = -1;
private int colDataUserTypeIdIndex = -1;
private int colIsUserDefinedTypeIndex = -1;
private int colSizeIndex = -1;
private int colHasIndexIndex = -1;
private int colHasComputedFormulaIndex = -1;
private int colIsRowGuidIndex = -1;
private int colTypeIndex = -1;
private int colOwnerType = -1;
private int colis_sparseIndex = -1;
private int colIs_FileStream = -1;
private int colDefaultIdIndex = -1;
private int colDefaultNameIndex = -1;
private int colDefaultDefinitionIndex = -1;
private int colrule_object_idIndex = -1;
private int colIsIdentityReplIndex = -1;
private int colCollationIndex = -1;
private int colIsIdentityIndex = -1;
private int colIdentSeedIndex = -1;
private int colIdentIncrementIndex = -1;
private int TableIdIndex = -1;
private int TableNameIndex = -1;
private int TableOwnerIndex = -1;
private int TableHasChangeTracking = -1;
private int TableHasChangeTrackingTrackColumn = -1;
private int TableLockEscalation = -1;
private int Text_In_Row_limitIndex = -1;
private int HasClusteredIndexIndex = -1;
private int large_value_types_out_of_rowIndex = -1;
private int HasVarDecimalIndex = -1;
private int FileGroupIndex = -1;
private int FileGroupTextIndex = -1;
private int FileGroupStreamIndex = -1;
private Generate root;
public GenerateTables(Generate root)
{
this.root = root;
}
private void InitTableIndex(Database database, IDataRecord reader)
{
if (reader == null) throw new ArgumentNullException("reader");
if (TableIdIndex == -1)
{
TableIdIndex = reader.GetOrdinal("TableId");
TableNameIndex = reader.GetOrdinal("TableName");
TableOwnerIndex = reader.GetOrdinal("TableOwner");
Text_In_Row_limitIndex = reader.GetOrdinal("Text_In_Row_limit");
HasClusteredIndexIndex = reader.GetOrdinal("HasClusteredIndex");
large_value_types_out_of_rowIndex = reader.GetOrdinal("large_value_types_out_of_row");
HasVarDecimalIndex = reader.GetOrdinal("HasVarDecimal");
FileGroupIndex = reader.GetOrdinal("FileGroup");
FileGroupTextIndex = reader.GetOrdinal("FileGroupText");
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
{
FileGroupStreamIndex = reader.GetOrdinal("FileGroupStream");
TableHasChangeTracking = reader.GetOrdinal("HasChangeTracking");
TableHasChangeTrackingTrackColumn = reader.GetOrdinal("HasChangeTrackingTrackColumn");
TableLockEscalation = reader.GetOrdinal("lock_escalation_desc");
}
}
}
private void InitColIndex(Database database, IDataRecord reader)
{
if (reader == null) throw new ArgumentNullException("reader");
if (colNameIndex == -1)
{
colIDIndex = reader.GetOrdinal("ID");
colNameIndex = reader.GetOrdinal("Name");
colFormulaIndex = reader.GetOrdinal("Formula");
colIsPersistedIndex = reader.GetOrdinal("FormulaPersisted");
colIsComputedIndex = reader.GetOrdinal("IsComputed");
colNullableIndex = reader.GetOrdinal("IsNullable");
colOwnerType = reader.GetOrdinal("OwnerType");
colXmlSchemaIndex = reader.GetOrdinal("XmlSchema");
colIs_xml_documentIndex = reader.GetOrdinal("Is_xml_document");
colPrecisionIndex = reader.GetOrdinal("Precision");
colScaleIndex = reader.GetOrdinal("Scale");
colDataUserTypeIdIndex = reader.GetOrdinal("user_type_id");
colIsUserDefinedTypeIndex = reader.GetOrdinal("is_user_defined");
colSizeIndex = reader.GetOrdinal("Size");
colHasIndexIndex = reader.GetOrdinal("HasIndex");
colHasComputedFormulaIndex = reader.GetOrdinal("HasComputedFormula");
colIsRowGuidIndex = reader.GetOrdinal("IsRowGuid");
colTypeIndex = reader.GetOrdinal("Type");
colDefaultIdIndex = reader.GetOrdinal("DefaultId");
colDefaultNameIndex = reader.GetOrdinal("DefaultName");
colDefaultDefinitionIndex = reader.GetOrdinal("DefaultDefinition");
colrule_object_idIndex = reader.GetOrdinal("rule_object_id");
colIsIdentityReplIndex = reader.GetOrdinal("IsIdentityRepl");
colCollationIndex = reader.GetOrdinal("Collation");
colIsIdentityIndex = reader.GetOrdinal("IsIdentity");
colIdentSeedIndex = reader.GetOrdinal("IdentSeed");
colIdentIncrementIndex = reader.GetOrdinal("IdentIncrement");
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
{
colis_sparseIndex = reader.GetOrdinal("is_sparse");
colIs_FileStream = reader.GetOrdinal("is_filestream");
}
}
}
private void FillColumn<T>(ITable<T> table, SqlDataReader reader) where T : ISchemaBase
{
Database database = (Database)table.Parent;
InitColIndex(database, reader);
Column col = new Column((ISchemaBase)table);
col.Id = (int)reader[colIDIndex];
if (database.Options.Ignore.FilterColumnOrder)
col.Position = table.Columns.Count + 1;
if (database.Options.Ignore.FilterColumnCollation)
col.Collation = (string)reader[colCollationIndex];
if (database.Options.Ignore.FilterColumnIdentity)
{
col.IsIdentity = (bool)reader[colIsIdentityIndex];
if ((col.IsIdentity) || (col.IsIdentityForReplication))
{
if (!reader.IsDBNull(colIdentSeedIndex))
col.IdentitySeed = (long)(decimal)reader[colIdentSeedIndex];
else
col.IdentitySeed = 1;
if (!reader.IsDBNull(colIdentIncrementIndex))
col.IdentityIncrement = (int)(decimal)reader[colIdentIncrementIndex];
else
col.IdentityIncrement = 1;
}
if (database.Options.Ignore.FilterNotForReplication)
col.IsIdentityForReplication = ((int)reader[colIsIdentityReplIndex] == 1);
}
col.Name = (string)reader[colNameIndex];
col.Owner = table.Owner;
col.ComputedFormula = (string)reader[colFormulaIndex];
col.IsPersisted = (bool)reader[colIsPersistedIndex];
col.IsComputed = (bool)reader[colIsComputedIndex];
col.IsNullable = (bool)reader[colNullableIndex];
col.XmlSchema = reader[colXmlSchemaIndex].ToString();
col.IsXmlDocument = (bool)reader[colIs_xml_documentIndex];
col.Precision = (byte)reader[colPrecisionIndex];
col.Scale = (byte)reader[colScaleIndex];
col.DataUserTypeId = (int)reader[colDataUserTypeIdIndex];
col.IsUserDefinedType = (bool)reader[colIsUserDefinedTypeIndex];
if (!String.IsNullOrEmpty(reader[colSizeIndex].ToString()))
col.Size = (short)reader[colSizeIndex];
col.HasIndexDependencies = ((int)reader[colHasIndexIndex] == 1);
col.HasComputedDependencies = ((int)reader[colHasComputedFormulaIndex] == 1);
col.IsRowGuid = (bool)reader[colIsRowGuidIndex];
if (col.IsUserDefinedType)
col.Type = "[" + (string)reader[colOwnerType] + "].[" + (string)reader[colTypeIndex] + "]";
else
col.Type = (string)reader[colTypeIndex];
if (((Database)table.Parent).Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
{
col.IsSparse = (bool)reader[colis_sparseIndex];
col.IsFileStream = (bool)reader[colIs_FileStream];
}
if ((int)reader[colDefaultIdIndex] != 0)
{
col.DefaultConstraint = new ColumnConstraint(col)
{
Id = (int)reader[colDefaultIdIndex],
Owner = table.Owner,
Name = (string)reader[colDefaultNameIndex],
Type = Constraint.ConstraintType.Default,
Definition = (string)reader[colDefaultDefinitionIndex]
};
}
if ((int)reader[colrule_object_idIndex] != 0)
col.Rule = ((Database)table.Parent).Rules.Find((int)reader[colrule_object_idIndex]);
table.Columns.Add(col);
}
public void Fill(Database database, string connectionString, List<MessageLog> messages)
{
try
{
root.RaiseOnReading(new ProgressEventArgs("Reading tables...", Constants.READING_TABLES));
FillTables(database, connectionString);
if (database.Tables.Any() || database.TablesTypes.Any())
{
if (database.Options.Ignore.FilterConstraint)
(new GenerateConstraint(root)).Fill(database, connectionString);
}
}
catch (Exception ex)
{
messages.Add(new MessageLog(ex.Message, ex.StackTrace, MessageLog.LogType.Error));
}
}
private void FillTables(Database database, string connectionString)
{
int textInRow;
Boolean largeValues;
Boolean varDecimal;
int lastObjectId = 0;
bool isTable = true;
ISchemaBase item = null;
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(TableSQLCommand.GetTableDetail(database.Info.Version, database.Info.Edition), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
InitTableIndex(database, reader);
root.RaiseOnReadingOne(reader[TableNameIndex]);
if (lastObjectId != (int)reader[TableIdIndex])
{
lastObjectId = (int)reader[TableIdIndex];
isTable = reader["ObjectType"].ToString().Trim().Equals("U");
if (isTable)
{
item = new Table(database);
item.Id = (int)reader[TableIdIndex];
item.Name = (string)reader[TableNameIndex];
item.Owner = (string)reader[TableOwnerIndex];
((Table)item).HasClusteredIndex = (int)reader[HasClusteredIndexIndex] == 1;
textInRow = (int)reader[Text_In_Row_limitIndex];
largeValues = (Boolean)reader[large_value_types_out_of_rowIndex];
varDecimal = ((int)reader[HasVarDecimalIndex]) == 1;
if (database.Options.Ignore.FilterTableFileGroup)
{
((Table)item).FileGroup = (string)reader[FileGroupIndex];
((Table)item).FileGroupText = (string)reader[FileGroupTextIndex];
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
{
if (database.Options.Ignore.FilterTableChangeTracking)
{
((Table)item).FileGroupStream = (string)reader[FileGroupStreamIndex];
((Table)item).HasChangeTracking = ((int)reader[TableHasChangeTracking]) == 1;
((Table)item).HasChangeTrackingTrackColumn = ((int)reader[TableHasChangeTrackingTrackColumn]) == 1;
}
}
}
if (database.Options.Ignore.FilterTableOption)
{
if (textInRow > 0) ((Table)item).Options.Add(new TableOption("TextInRow", textInRow.ToString(CultureInfo.InvariantCulture), item));
if (largeValues) ((Table)item).Options.Add(new TableOption("LargeValues", "1", item));
if (varDecimal) ((Table)item).Options.Add(new TableOption("VarDecimal", "1", item));
}
if ((database.Options.Ignore.FilterTableLockEscalation) && (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008))
((Table)item).Options.Add(new TableOption("LockEscalation", (string)reader[TableLockEscalation], item));
else
((Table)item).Options.Add(new TableOption("LockEscalation", "TABLE", item));
database.Tables.Add((Table)item);
}
else
{
item = new TableType(database)
{
Id = (int)reader[TableIdIndex],
Name = (string)reader[TableNameIndex],
Owner = (string)reader[TableOwnerIndex]
};
database.TablesTypes.Add((TableType)item);
}
}
if (isTable)
{
if (database.Options.Ignore.FilterTable)
FillColumn((ITable<Table>)item, reader);
}
else
{
if (database.Options.Ignore.FilterUserDataType)
FillColumn((ITable<TableType>)item, reader);
}
}
}
}
}
//tables.ToSQL();
}
}
}

@ -0,0 +1,120 @@
using System;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Options;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateTextObjects
{
private Generate root;
public GenerateTextObjects(Generate root)
{
this.root = root;
}
private static string GetSQL(SqlOption options)
{
var filterQuery = SQLQueries.SQLQueryFactory.Get("GetTextObjectsQuery");
string filter = "";
if (options.Ignore.FilterStoredProcedure)
filter += "O.type = 'P' OR ";
if (options.Ignore.FilterView)
filter += "O.type = 'V' OR ";
if (options.Ignore.FilterTrigger)
filter += "O.type = 'TR' OR ";
if (options.Ignore.FilterFunction)
filter += "O.type IN ('IF','FN','TF') OR ";
filter = filter.Substring(0, filter.Length - 4);
return filterQuery.Replace("{FILTER}", filter);
}
public void Fill(Database database, string connectionString)
{
ICode code = null;
try
{
if ((database.Options.Ignore.FilterStoredProcedure) || (database.Options.Ignore.FilterView) || (database.Options.Ignore.FilterFunction) || (database.Options.Ignore.FilterTrigger))
{
root.RaiseOnReading(new ProgressEventArgs("Reading Text Objects...", Constants.READING_TEXTOBJECTS));
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQL(database.Options), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
code = null;
root.RaiseOnReadingOne(reader["name"]);
string type = reader["Type"].ToString().Trim();
string name = reader["name"].ToString();
string definition = reader["Text"].ToString();
int id = (int)reader["object_id"];
if (type.Equals("V"))
code = (ICode)database.Views.Find(id);
if (type.Equals("TR"))
code = (ICode)database.Find(id);
if (type.Equals("P"))
{
var procedure = database.Procedures.Find(id);
if (procedure != null)
((ICode)procedure).Text = GetObjectDefinition(type, name, definition);
}
if (type.Equals("IF") || type.Equals("FN") || type.Equals("TF"))
code = (ICode)database.Functions.Find(id);
if (code != null)
code.Text = reader["Text"].ToString();
}
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
private string GetObjectDefinition(string type, string name, string definition)
{
string rv = definition;
string sqlDelimiters = @"(\r|\n|\s)+?";
RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Multiline;
Regex re = new Regex(@"CREATE" + sqlDelimiters + @"PROC(EDURE)?" + sqlDelimiters + @"(\w+\.|\[\w+\]\.)?\[?(?<spname>\w+)\]?" + sqlDelimiters, options);
switch (type)
{
case "P":
Match match = re.Match(definition);
if (match != null && match.Success)
{
// Try to replace the name saved in the definition when the object was created by the one used for the object in sys.object
string oldName = match.Groups["spname"].Value;
//if (String.IsNullOrEmpty(oldName)) System.Diagnostics.Debugger.Break();
if (String.Compare(oldName, name) != 0)
{
rv = rv.Replace(oldName, name);
}
}
break;
default:
//TODO : Add the logic used for other objects than procedures
break;
}
return rv;
}
}
}

@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using OpenDBDiff.Schema.Errors;
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Options;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateTriggers
{
private Generate root;
public GenerateTriggers(Generate root)
{
this.root = root;
}
private static string GetSQL(DatabaseInfo.SQLServerVersion version, SqlOption options)
{
if (version == DatabaseInfo.SQLServerVersion.SQLServerAzure10)
{
return SQLQueries.SQLQueryFactory.Get("GetTriggers", version);
}
else
{
return SQLQueries.SQLQueryFactory.Get("GetTriggers");
}
}
public void Fill(Database database, string connectionString, List<MessageLog> messages)
{
int parentId = 0;
ISchemaBase parent = null;
string type;
try
{
if (database.Options.Ignore.FilterTrigger)
{
root.RaiseOnReading(new ProgressEventArgs("Reading Triggers...", Constants.READING_TRIGGERS));
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQL(database.Info.Version, database.Options), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
root.RaiseOnReadingOne(reader["Name"]);
type = reader["ObjectType"].ToString().Trim();
if (parentId != (int)reader["parent_id"])
{
parentId = (int)reader["parent_id"];
if (type.Equals("V"))
parent = database.Views.Find(parentId);
else
parent = database.Tables.Find(parentId);
}
if (reader["type"].Equals("TR"))
{
Trigger item = new Trigger(parent);
item.Id = (int)reader["object_id"];
item.Name = reader["Name"].ToString();
item.InsteadOf = (bool)reader["is_instead_of_trigger"];
item.IsDisabled = (bool)reader["is_disabled"];
item.IsDDLTrigger = false;
item.Owner = reader["Owner"].ToString();
if (database.Options.Ignore.FilterNotForReplication)
item.NotForReplication = (bool)reader["is_not_for_replication"];
if (type.Equals("V"))
((View)parent).Triggers.Add(item);
else
((Table)parent).Triggers.Add(item);
}
else
{
CLRTrigger item = new CLRTrigger(parent);
item.Id = (int)reader["object_id"];
item.Name = reader["Name"].ToString();
item.IsDelete = (bool)reader["IsDelete"];
item.IsUpdate = (bool)reader["IsUpdate"];
item.IsInsert = (bool)reader["IsInsert"];
item.Owner = reader["Owner"].ToString();
item.IsAssembly = true;
item.AssemblyId = (int)reader["assembly_id"];
item.AssemblyName = reader["assembly_name"].ToString();
item.AssemblyClass = reader["assembly_class"].ToString();
item.AssemblyExecuteAs = reader["ExecuteAs"].ToString();
item.AssemblyMethod = reader["assembly_method"].ToString();
if (type.Equals("V"))
((View)parent).CLRTriggers.Add(item);
else
((Table)parent).CLRTriggers.Add(item);
/*if (!database.Options.Ignore.FilterIgnoreNotForReplication)
trigger.NotForReplication = (bool)reader["is_not_for_replication"];*/
}
}
}
}
}
}
}
catch (Exception ex)
{
messages.Add(new MessageLog(ex.Message, ex.StackTrace, MessageLog.LogType.Error));
}
}
}
}

@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using OpenDBDiff.Schema.Errors;
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateUserDataTypes
{
private readonly Generate root;
public GenerateUserDataTypes(Generate root)
{
this.root = root;
}
private static string GetSQLColumnsDependencies()
{
return SQLQueries.SQLQueryFactory.Get("GetSQLColumnsDependencies");
}
private static void FillColumnsDependencies(SchemaList<UserDataType, Database> types, string connectionString)
{
if (types == null) throw new ArgumentNullException("types");
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQLColumnsDependencies(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
types[reader["TypeName"].ToString()].Dependencies.Add(new ObjectDependency(reader["TableName"].ToString(), reader["ColumnName"].ToString(), ConvertType.GetObjectType(reader["Type"].ToString())));
}
}
}
}
}
public void Fill(Database database, string connectionString, List<MessageLog> messages)
{
//not supported in azure yet http://msdn.microsoft.com/en-us/library/ee336233.aspx
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServerAzure10) return;
try
{
if (database.Options.Ignore.FilterUserDataType)
{
root.RaiseOnReading(new ProgressEventArgs("Reading UDT...", Constants.READING_UDT));
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(UserDataTypeCommand.Get(database.Info.Version, database.Info.Edition), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
root.RaiseOnReadingOne(reader["Name"]);
UserDataType item = new UserDataType(database);
item.Id = (int)reader["tid"];
item.AllowNull = (bool)reader["is_nullable"];
item.Size = (short)reader["max_length"];
item.Name = reader["Name"].ToString();
item.Owner = reader["owner"].ToString();
item.Precision = int.Parse(reader["precision"].ToString());
item.Scale = int.Parse(reader["scale"].ToString());
if (!String.IsNullOrEmpty(reader["defaultname"].ToString()))
{
item.Default.Name = reader["defaultname"].ToString();
item.Default.Owner = reader["defaultowner"].ToString();
}
if (!String.IsNullOrEmpty(reader["rulename"].ToString()))
{
item.Rule.Name = reader["rulename"].ToString();
item.Rule.Owner = reader["ruleowner"].ToString();
}
item.Type = reader["basetypename"].ToString();
item.IsAssembly = (bool)reader["is_assembly_type"];
item.AssemblyId = (int)reader["assembly_id"];
item.AssemblyName = reader["assembly_name"].ToString();
item.AssemblyClass = reader["assembly_class"].ToString();
database.UserTypes.Add(item);
}
}
}
}
if (database.Options.Ignore.FilterTable)
FillColumnsDependencies(database.UserTypes, connectionString);
}
}
catch (Exception ex)
{
messages.Add(new MessageLog(ex.Message, ex.StackTrace, MessageLog.LogType.Error));
}
}
}
}

@ -0,0 +1,63 @@
using System;
using System.Data.SqlClient;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateUsers
{
private Generate root;
public GenerateUsers(Generate root)
{
this.root = root;
}
public void Fill(Database database, string connectioString)
{
string type;
if ((database.Options.Ignore.FilterUsers) || (database.Options.Ignore.FilterRoles))
{
using (SqlConnection conn = new SqlConnection(connectioString))
{
using (SqlCommand command = new SqlCommand(UserSQLCommand.Get(database.Info.Version, database.Info.Edition), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
type = reader["type"].ToString();
if (database.Options.Ignore.FilterUsers && (type.Equals("S") || type.Equals("U")))
{
User item = new User(database);
item.Id = (int)reader["principal_id"];
item.Name = reader["name"].ToString();
item.Login = reader["Login"].ToString();
item.Owner = reader["default_schema_name"].ToString();
database.Users.Add(item);
}
if (database.Options.Ignore.FilterRoles && (type.Equals("A") || type.Equals("R")))
{
Role item = new Role(database);
item.Id = (int)reader["principal_id"];
item.Name = reader["name"].ToString();
item.Owner = reader["default_schema_name"].ToString();
item.Password = "";
item.IsSystem = (Boolean)reader["is_fixed_role"];
if (type.Equals("A"))
item.Type = Role.RoleTypeEnum.ApplicationRole;
else
item.Type = Role.RoleTypeEnum.DatabaseRole;
database.Roles.Add(item);
}
}
}
}
}
}
}
}
}

@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using OpenDBDiff.Schema.Errors;
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateViews
{
private Generate root;
public GenerateViews(Generate root)
{
this.root = root;
}
public void Fill(Database database, string connectionString, List<MessageLog> messages)
{
try
{
root.RaiseOnReading(new ProgressEventArgs("Reading views...", Constants.READING_VIEWS));
if (database.Options.Ignore.FilterView)
{
FillView(database, connectionString);
}
}
catch (Exception ex)
{
messages.Add(new MessageLog(ex.Message, ex.StackTrace, MessageLog.LogType.Error));
}
}
private void FillView(Database database, string connectionString)
{
int lastViewId = 0;
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(ViewSQLCommand.GetView(database.Info.Version, database.Info.Edition), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
View item = null;
while (reader.Read())
{
root.RaiseOnReadingOne(reader["name"]);
if (lastViewId != (int)reader["object_id"])
{
item = new View(database);
item.Id = (int)reader["object_id"];
item.Name = reader["name"].ToString();
item.Owner = reader["owner"].ToString();
item.IsSchemaBinding = reader["IsSchemaBound"].ToString().Equals("1");
database.Views.Add(item);
lastViewId = item.Id;
}
if (item.IsSchemaBinding)
{
if (!reader.IsDBNull(reader.GetOrdinal("referenced_major_id")))
database.Dependencies.Add(database, (int)reader["referenced_major_id"], item);
if (!String.IsNullOrEmpty(reader["TableName"].ToString()))
item.DependenciesIn.Add(reader["TableName"].ToString());
if (!String.IsNullOrEmpty(reader["DependOut"].ToString()))
item.DependenciesOut.Add(reader["DependOut"].ToString());
}
}
}
}
}
}
}
}

@ -0,0 +1,85 @@
using System.Data.SqlClient;
using System.Text;
using OpenDBDiff.Schema.Events;
using OpenDBDiff.Schema.Model;
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
using OpenDBDiff.Schema.SQLServer.Generates.Model;
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
{
public class GenerateXMLSchemas
{
private Generate root;
public GenerateXMLSchemas(Generate root)
{
this.root = root;
}
private static string GetSQLColumnsDependencies()
{
return SQLQueries.SQLQueryFactory.Get("GetXMLSchemaCollections");
}
private static string GetSQLXMLSchema()
{
return SQLQueries.SQLQueryFactory.Get("GetSQLXMLSchema");
}
private static void FillColumnsDependencies(SchemaList<XMLSchema, Database> items, string connectionString)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQLColumnsDependencies(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
items[reader["XMLName"].ToString()].Dependencies.Add(new ObjectDependency(reader["TableName"].ToString(), reader["ColumnName"].ToString(), ConvertType.GetObjectType(reader["Type"].ToString())));
}
}
}
}
}
public void Fill(Database database, string connectionString)
{
//TODO XML_SCHEMA_NAMESPACE function not supported in Azure, is there a workaround?
//not supported in azure yet
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServerAzure10) return;
if (database.Options.Ignore.FilterXMLSchema)
{
root.RaiseOnReading(new ProgressEventArgs("Reading XML Schema...", Constants.READING_XMLSCHEMAS));
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(GetSQLXMLSchema(), conn))
{
conn.Open();
command.CommandTimeout = 0;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
root.RaiseOnReadingOne(reader["name"]);
XMLSchema item = new XMLSchema(database);
item.Id = (int)reader["ID"];
item.Name = reader["name"].ToString();
item.Owner = reader["owner"].ToString();
item.Text = reader["Text"].ToString();
database.XmlSchemas.Add(item);
}
}
}
}
if (database.Options.Ignore.FilterTable)
FillColumnsDependencies(database.XmlSchemas, connectionString);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save