public static void EnsureLibraryRegistered(Program program, Schema.LibraryReference libraryReference, bool withReconciliation) { Schema.LoadedLibrary loadedLibrary = program.CatalogDeviceSession.ResolveLoadedLibrary(libraryReference.Name, false); if (loadedLibrary == null) { Schema.LoadedLibrary currentLibrary = program.ServerProcess.ServerSession.CurrentLibrary; try { Schema.Library library = program.Catalog.Libraries[libraryReference.Name]; if (!VersionNumber.Compatible(libraryReference.Version, library.Version)) { throw new Schema.SchemaException(Schema.SchemaException.Codes.LibraryVersionMismatch, libraryReference.Name, libraryReference.Version.ToString(), library.Version.ToString()); } RegisterLibrary(program, library.Name, withReconciliation); } finally { program.ServerProcess.ServerSession.CurrentLibrary = currentLibrary; } } else { Schema.Library library = program.Catalog.Libraries[libraryReference.Name]; if (!VersionNumber.Compatible(libraryReference.Version, library.Version)) { throw new Schema.SchemaException(Schema.SchemaException.Codes.LibraryVersionMismatch, libraryReference.Name, libraryReference.Version.ToString(), library.Version.ToString()); } } }
private static void LoadLibrary(Program program, string libraryName, bool isKnown) { lock (program.Catalog.Libraries) { try { Schema.Library library = program.Catalog.Libraries[libraryName]; VersionNumber currentVersion = ((ServerCatalogDeviceSession)program.CatalogDeviceSession).GetCurrentLibraryVersion(libraryName); if (program.Catalog.LoadedLibraries.Contains(library.Name)) { throw new Schema.SchemaException(Schema.SchemaException.Codes.LibraryAlreadyLoaded, libraryName); } bool isLoaded = false; bool areAssembliesRegistered = false; Schema.LoadedLibrary loadedLibrary = null; try { loadedLibrary = new Schema.LoadedLibrary(libraryName); loadedLibrary.Owner = program.CatalogDeviceSession.ResolveUser(((ServerCatalogDeviceSession)program.CatalogDeviceSession).GetLibraryOwner(libraryName)); // Ensure that each required library is loaded foreach (Schema.LibraryReference reference in library.Libraries) { Schema.Library requiredLibrary = program.Catalog.Libraries[reference.Name]; if (!VersionNumber.Compatible(reference.Version, requiredLibrary.Version)) { throw new Schema.SchemaException(Schema.SchemaException.Codes.LibraryVersionMismatch, reference.Name, reference.Version.ToString(), requiredLibrary.Version.ToString()); } if (!program.Catalog.LoadedLibraries.Contains(reference.Name)) { if (!requiredLibrary.IsSuspect) { LoadLibrary(program, reference.Name, isKnown); } else { throw new Schema.SchemaException(Schema.SchemaException.Codes.RequiredLibraryNotLoaded, libraryName, reference.Name); } } loadedLibrary.RequiredLibraries.Add(program.CatalogDeviceSession.ResolveLoadedLibrary(reference.Name)); program.Catalog.OperatorResolutionCache.Clear(loadedLibrary.GetNameResolutionPath(program.ServerProcess.ServerSession.Server.SystemLibrary)); loadedLibrary.ClearNameResolutionPath(); } program.ServerProcess.ServerSession.Server.DoLibraryLoading(library.Name); try { // RegisterAssemblies RegisterLibraryFiles(program, library, loadedLibrary); areAssembliesRegistered = true; program.CatalogDeviceSession.InsertLoadedLibrary(loadedLibrary); loadedLibrary.AttachLibrary(); try { ((ServerCatalogDeviceSession)program.CatalogDeviceSession).SetLibraryOwner(loadedLibrary.Name, loadedLibrary.Owner.ID); } catch (Exception registerException) { loadedLibrary.DetachLibrary(); throw registerException; } isLoaded = true; // If we reach this point, a subsequent exception must unload the library if (library.IsSuspect) { library.IsSuspect = false; library.SaveInfoToFile(Path.Combine(library.GetInstanceLibraryDirectory(((Server.Server)program.ServerProcess.ServerSession.Server).InstanceDirectory), Schema.LibraryUtility.GetInfoFileName(library.Name))); } } finally { program.ServerProcess.ServerSession.Server.DoLibraryLoaded(library.Name); } } catch (Exception exception) { program.ServerProcess.ServerSession.Server.LogError(exception); library.IsSuspect = true; library.SuspectReason = ExceptionUtility.DetailedDescription(exception); library.SaveInfoToFile(Path.Combine(library.GetInstanceLibraryDirectory(((Server.Server)program.ServerProcess.ServerSession.Server).InstanceDirectory), Schema.LibraryUtility.GetInfoFileName(library.Name))); if (isLoaded) { UnregisterLibrary(program, libraryName, false); } else if (areAssembliesRegistered) { UnregisterLibraryAssemblies(program, loadedLibrary); } throw; } ((ServerCatalogDeviceSession)program.CatalogDeviceSession).SetCurrentLibraryVersion(library.Name, currentVersion); // Once a library has loaded, record the version number program.Catalog.Libraries.DoLibraryLoaded(program, library.Name); } catch { if (program.ServerProcess.ServerSession.Server.State == ServerState.Started) { throw; } } } }