/// <summary> /// Obtains the lock. /// </summary> /// <returns><c>true</c> if the lock has been obtained, <c>false</c> otherwise.</returns> public override bool Obtain() { ICommandBuilder builder = _sqlStorageProviderUtility.GetCommandBuilder2(); DbConnection connection = builder.GetConnection(_connString); DbTransaction transaction = _sqlStorageProviderUtility.BeginTransaction(connection); QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.DeleteFrom("SearchIndexLock"); query = queryBuilder.Where(query, "Wiki", WhereOperator.Equals, "Wiki"); query = queryBuilder.AndWhere(query, "Name", WhereOperator.Equals, "Name"); List <Parameter> parameters = new List <Parameter>(2); parameters.Add(new Parameter(ParameterType.String, "Wiki", _wiki)); parameters.Add(new Parameter(ParameterType.String, "Name", _name)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = _sqlStorageProviderUtility.ExecuteNonQuery(command, false); if (rows != 0) { _sqlStorageProviderUtility.RollbackTransaction(transaction); return(false); // Deletion command failed (0 is the only accepted value) } query = queryBuilder.InsertInto("SearchIndexLock", new string[] { "wiki", "Name", "Value" }, new string[] { "Wiki", "Name", "Value" }); parameters = new List <Parameter>(3); parameters.Add(new Parameter(ParameterType.String, "Wiki", _wiki)); parameters.Add(new Parameter(ParameterType.String, "Name", _name)); parameters.Add(new Parameter(ParameterType.String, "Value", "locked")); command = builder.GetCommand(transaction, query, parameters); rows = _sqlStorageProviderUtility.ExecuteNonQuery(command, false); if (rows == 1) { _sqlStorageProviderUtility.CommitTransaction(transaction); } else { _sqlStorageProviderUtility.RollbackTransaction(transaction); } return(rows == 1); }
/// <summary> /// Deletes a file. /// </summary> /// <param name="name">The name of the file to be deleted.</param> public override void DeleteFile(string name) { ICommandBuilder builder = _sqlStorageProviderUtility.GetCommandBuilder2(); DbConnection connection = builder.GetConnection(_connString); DbTransaction transaction = _sqlStorageProviderUtility.BeginTransaction(connection); if (!FileExists(transaction, name)) { _sqlStorageProviderUtility.RollbackTransaction(transaction); return; } QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.DeleteFrom("SearchIndex"); query = queryBuilder.Where(query, "Wiki", WhereOperator.Equals, "Wiki"); query = queryBuilder.AndWhere(query, "Name", WhereOperator.Equals, "Name"); List <Parameter> parameters = new List <Parameter>(2); parameters.Add(new Parameter(ParameterType.String, "Wiki", _wiki)); parameters.Add(new Parameter(ParameterType.String, "Name", name)); DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = _sqlStorageProviderUtility.ExecuteNonQuery(command, false); if (rows != 1) { _sqlStorageProviderUtility.RollbackTransaction(transaction); } else { _sqlStorageProviderUtility.CommitTransaction(transaction); if (_cacheDirectory.FileExists(name + ".blob")) { _cacheDirectory.DeleteFile(name + ".blob"); } if (_cacheDirectory.FileExists(name)) { _cacheDirectory.DeleteFile(name); } } }
/// <summary> /// Closes the sql index output. /// </summary> public override void Close() { string fileName = _fileName; // make sure it's all written out _indexOutput.Flush(); long originalLength = _indexOutput.Length(); _indexOutput.Close(); Stream fileStream = new StreamInput(CacheDirectory.OpenInput(fileName)); try { // push the file stream up to the db. ICommandBuilder builder = _sqlStorageProviderUtility.GetCommandBuilder2(); DbConnection connection = builder.GetConnection(_connString); DbTransaction transaction = _sqlStorageProviderUtility.BeginTransaction(connection); QueryBuilder queryBuilder = new QueryBuilder(builder); //bool fileExists = FileExists(transaction, _wiki, _fileName); // To achieve decent performance, an UPDATE query is issued if the file exists, // otherwise an INSERT query is issued string query; List <Parameter> parameters; byte[] fileData = null; int size = Tools.ReadStream(fileStream, ref fileData, MaxFileSize); if (size < 0) { _sqlStorageProviderUtility.RollbackTransaction(transaction); throw new ArgumentException("Source Stream contains too much data", "sourceStream"); } //if(fileExists) { // query = queryBuilder.Update("SearchIndex", new string[] { "Size", "LastModified", "Data" }, new string[] { "Size", "LastModified", "Data" }); // query = queryBuilder.Where(query, "Wiki", WhereOperator.Equals, "Wiki"); // query = queryBuilder.AndWhere(query, "Name", WhereOperator.Equals, "Name"); // parameters = new List<Parameter>(5); // parameters.Add(new Parameter(ParameterType.String, "Wiki", _wiki)); // parameters.Add(new Parameter(ParameterType.Int64, "Size", (long)originalLength)); // parameters.Add(new Parameter(ParameterType.DateTime, "LastModified", DateTime.Now.ToUniversalTime())); // parameters.Add(new Parameter(ParameterType.ByteArray, "Data", fileData)); // parameters.Add(new Parameter(ParameterType.String, "Name", _fileName)); //} //else { query = queryBuilder.InsertInto("SearchIndex", new string[] { "Wiki", "Name", "Size", "LastModified", "Data" }, new string[] { "Wiki", "Name", "Size", "LastModified", "Data" }); parameters = new List <Parameter>(5); parameters.Add(new Parameter(ParameterType.String, "Wiki", _wiki)); parameters.Add(new Parameter(ParameterType.String, "Name", _fileName)); parameters.Add(new Parameter(ParameterType.Int64, "Size", (long)originalLength)); parameters.Add(new Parameter(ParameterType.DateTime, "LastModified", DateTime.Now.ToUniversalTime())); parameters.Add(new Parameter(ParameterType.ByteArray, "Data", fileData)); //} DbCommand command = builder.GetCommand(transaction, query, parameters); int rows = _sqlStorageProviderUtility.ExecuteNonQuery(command, false); if (rows == 1) { _sqlStorageProviderUtility.CommitTransaction(transaction); } else { _sqlStorageProviderUtility.RollbackTransaction(transaction); } } finally { fileStream.Dispose(); } // clean up _indexOutput = null; GC.SuppressFinalize(this); }
/// <summary> /// Initializes a new instance of the <see cref="SqlIndexInput"/> class. /// </summary> /// <param name="sqlServerDirectory">The Sql Server Directory object.</param> /// <param name="sqlStorageProviderUtility">The SQL storage provider utility.</param> /// <param name="connString">The connection string.</param> /// <param name="wiki">The wiki.</param> /// <param name="name">The name of the file.</param> public SqlIndexInput(SqlDirectory sqlServerDirectory, ISqlStorageProviderUtility sqlStorageProviderUtility, string connString, string wiki, string name) { _sqlServerDirectory = sqlServerDirectory; _sqlStorageProviderUtility = sqlStorageProviderUtility; bool fFileNeeded = false; if (!CacheDirectory.FileExists(name)) { fFileNeeded = true; } if (name.Contains("segments")) { fFileNeeded = true; } if (fFileNeeded) { StreamOutput fileStream = _sqlServerDirectory.CreateCachedOutputAsStream(name); ICommandBuilder builder = _sqlStorageProviderUtility.GetCommandBuilder2(); DbConnection connection = builder.GetConnection(connString); DbTransaction transaction = _sqlStorageProviderUtility.BeginTransaction(connection); if (!FileExists(transaction, wiki, name)) { _sqlStorageProviderUtility.RollbackTransaction(transaction); _sqlStorageProviderUtility.CloseDbConnection(connection); throw new FileNotFoundException(); } QueryBuilder queryBuilder = new QueryBuilder(builder); string query = queryBuilder.SelectFrom("SearchIndex", new string[] { "Size", "Data" }); query = queryBuilder.Where(query, "Wiki", WhereOperator.Equals, "Wiki"); query = queryBuilder.AndWhere(query, "Name", WhereOperator.Equals, "Name"); List <Parameter> parameters = new List <Parameter>(2); parameters.Add(new Parameter(ParameterType.String, "Wiki", wiki)); parameters.Add(new Parameter(ParameterType.String, "Name", name)); DbCommand command = builder.GetCommand(transaction, query, parameters); DbDataReader reader = _sqlStorageProviderUtility.ExecuteReader(command); if (reader != null) { bool done = false; if (reader.Read()) { int read = _sqlStorageProviderUtility.ReadBinaryColumn(reader, "Data", fileStream); done = (long)read == (long)reader["Size"]; } _sqlStorageProviderUtility.CloseReader(reader); if (!done) { _sqlStorageProviderUtility.RollbackTransaction(transaction); } _sqlStorageProviderUtility.CommitTransaction(transaction); } else { _sqlStorageProviderUtility.RollbackTransaction(transaction); } fileStream.Flush(); fileStream.Close(); // and open it as an input _indexInput = CacheDirectory.OpenInput(name); } else { _indexInput = CacheDirectory.OpenInput(name); } }