<commit_before>﻿using MicroORM.Caching;
using MicroORM.Entity;
using MicroORM.Mapping;
using MicroORM.Materialization;
using MicroORM.Query;

namespace MicroORM.Storage
{
    internal class DbEntityPersister
    {
        private IDbProvider _dbProvider;

        internal DbEntityPersister(IDbProvider dbProvider)
        {
            _dbProvider = dbProvider;
        }

        /// <summary>
        /// This method is ONLY for POCOs 
        /// who inherit from Entity.Entity
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entity"></param>
        internal void PersistChanges<TEntity>(TEntity entity) where TEntity : Entity.Entity
        {
            EntityInfo entityInfo = ReferenceCacheManager.GetEntityInfo(entity);

            if (entity.Delete)
            {
                // Entity was already deleted
                // or is not yet loaded!!
                if (entityInfo.EntityState == EntityState.Deleted || entityInfo.EntityState == EntityState.None)
                    return;

                Delete(entity, entityInfo);
            }
            // Entity was already deleted
            // or is not yet loaded!!
            else if (entityInfo.EntityState == EntityState.Deleted || entityInfo.EntityState == EntityState.None)
            {
                Insert(entity, entityInfo);
            }
            else
            {
                // Any changes made to entity?!
                if (entityInfo.Checksum == CheckSumBuilder.CalculateEntityChecksum(entity))
                    return;

                Update(entity, entityInfo);
            }
        }

        private void Update<TEntity>(TEntity entity, EntityInfo entityInfo)
        {

        }

        internal void Delete<TEntity>(TEntity entity, EntityInfo entityInfo)
        {
            TableInfo tableInfo = TableInfo<TEntity>.GetTableInfo;
            string deleteStatement = tableInfo.CreateDeleteStatement(_dbProvider);
            QueryParameterCollection arguments = QueryParameterCollection.Create<TEntity>(tableInfo.GetPrimaryKeyValues(entity));

            _dbProvider.ExecuteCommand(new SqlQuery(deleteStatement, arguments));

            entityInfo.EntityState = EntityState.Deleted;
        }

        internal void Insert<TEntity>(TEntity entity, EntityInfo entityInfo)
        {
            TableInfo tableInfo = TableInfo<TEntity>.GetTableInfo;
            string insertStatement = tableInfo.CreateInsertStatement(_dbProvider);
            QueryParameterCollection arguments = QueryParameterCollection.Create<TEntity>(Utils.Utils.GetEntityArguments(entity, tableInfo));

            LastInsertId insertId = new LastInsertId(_dbProvider.ExecuteScalar<object>(new SqlQuery(insertStatement, arguments)));

            entityInfo.Checksum = CheckSumBuilder.CalculateEntityChecksum(entity);
            entityInfo.EntityState = EntityState.Inserted;
        }
    }
}<commit_msg>Included update method and method to prepare for update.<commit_after>﻿using System.Collections.Generic;
using MicroORM.Entity;
using MicroORM.Mapping;
using MicroORM.Query;
using MicroORM.Reflection;
using System;

namespace MicroORM.Storage
{
    internal class DbEntityPersister
    {
        private IDbProvider _dbProvider;

        internal DbEntityPersister(IDbProvider dbProvider)
        {
            _dbProvider = dbProvider;
        }

        /// <summary>
        /// This method is ONLY for POCOs 
        /// who inherit from Entity.Entity
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entity"></param>
        internal void PersistChanges<TEntity>(TEntity entity) where TEntity : Entity.Entity
        {
            if (entity.Delete)
            {
                // Entity was already deleted
                // or is not yet loaded!!
                if (entity.EntityInfo.EntityState == EntityState.Deleted || entity.EntityInfo.EntityState == EntityState.None)
                    return;

                Delete(entity);
                entity.EntityInfo.EntityState = EntityState.Deleted;
            }
            // Entity was already deleted
            // or is not yet loaded!!
            else if (entity.EntityInfo.EntityState == EntityState.Deleted || entity.EntityInfo.EntityState == EntityState.None)
            {
                Insert(entity);
                entity.EntityInfo.EntityState = EntityState.Inserted;
            }
            else
            {
                Tuple<bool, string, QueryParameterCollection> tuple = PrepareForUpdate<TEntity>(entity);
                if (tuple.Item1) return;

                Update<TEntity>(new SqlQuery(tuple.Item2, tuple.Item3));
                entity.EntityInfo.EntityState = EntityState.Updated;
            }
        }

        internal Tuple<bool, string, QueryParameterCollection> PrepareForUpdate<TEntity>(TEntity entity)
        {
            // Any changes made to entity?!
            Entity.Entity dbEntity = entity as Entity.Entity;
            KeyValuePair<string, object>[] valuesToUpdate = 
                EntityValueComparer.ComputeChangedValues<TEntity>(
                ParameterTypeDescriptor.ToKeyValuePairs(new object[] { entity }),
                dbEntity != null ? dbEntity.EntityInfo.EntityValueCollection : new EntityValueCollection());

            if (valuesToUpdate.Length == 0)
                return new Tuple<bool, string, QueryParameterCollection>(false, null, null);

            TableInfo tableInfo = TableInfo<TEntity>.GetTableInfo;
            string updateStatement = tableInfo.CreateUpdateStatement(_dbProvider, valuesToUpdate);
            QueryParameterCollection queryParameterCollection = QueryParameterCollection.Create<TEntity>(new object[] { valuesToUpdate });
            queryParameterCollection.AddRange(tableInfo.GetPrimaryKeyValues<TEntity>(entity));

            return new Tuple<bool, string, QueryParameterCollection>(true, updateStatement, queryParameterCollection);
        }

        internal void Update<TEntity>(IQuery query)
        {
            _dbProvider.ExecuteCommand(query);
        }

        internal void Delete<TEntity>(TEntity entity)
        {
            TableInfo tableInfo = TableInfo<TEntity>.GetTableInfo;
            string deleteStatement = tableInfo.CreateDeleteStatement(_dbProvider);
            QueryParameterCollection arguments = QueryParameterCollection.Create<TEntity>(tableInfo.GetPrimaryKeyValues(entity));

            _dbProvider.ExecuteCommand(new SqlQuery(deleteStatement, arguments));
        }

        internal void Insert<TEntity>(TEntity entity)
        {
            TableInfo tableInfo = TableInfo<TEntity>.GetTableInfo;
            string insertStatement = tableInfo.CreateInsertStatement(_dbProvider);
            QueryParameterCollection arguments = QueryParameterCollection.Create<TEntity>(Utils.Utils.GetEntityArguments(entity, tableInfo));

            LastInsertId insertId = new LastInsertId(_dbProvider.ExecuteScalar<object>(new SqlQuery(insertStatement, arguments)));
        }
    }
}
{'fraction_non_alphanumeric': 0.0848270995059986, 'fraction_numerical': 0.0005645730416372619, 'mean_word_length': 2.317415730337079, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2479199', 'n_tokens_mistral': 1725, 'n_tokens_neox': 1670, 'n_words': 356}