Extending functionality of existing classes without breaking consumer code

Here is a set of classes that are used to build where clause for SQL Server and Oracle for different field types e.g. text, numeric and date.

public interface IConditionBuilder {     bool CanHandle(FilterAction filterAction);      string BuildCondition(SearchCondition filterCondition); }  public abstract class ConditionBuilder<TContext> : IConditionBuilder where TContext : FieldSearchContext {     public abstract string OperatorSymbol { get; }      public string BuildCondition(SearchCondition searchCondition)     {         var conditionBuilder = new StringBuilder();          var context = searchCondition.GetContext<TContext>();          conditionBuilder.Append(context.FieldId);         conditionBuilder.Append(OperatorSymbol);         conditionBuilder.Append(GetValue(context));          return conditionBuilder.ToString();     }      public abstract bool CanHandle(FilterAction filterAction);      public abstract object GetValue(TContext context);  }  public class TextLikeConditionBuilder : ConditionBuilder<TextContext> {     public override string OperatorSymbol => " LIKE ";      public override bool CanHandle(FilterAction action) => action == FilterAction.TextLike;      public override object GetValue(TextContext context)     {         if (context.Text == null)         {             return null;         }          return string.Concat("%", context.Text, "%");     } }  public class TextEqualsConditionBuilder : ConditionBuilder<TextContext> {     public override string OperatorSymbol => " = ";      public override bool CanHandle(FilterAction action) => action == FilterAction.TextEqual;      public override object GetValue(TextContext context)     {         if (context.Text == null)         {             return null;         }          return "'" + context.Text + "'";     } }  public class NumericLessThanConditionBuilder : ConditionBuilder<NumericContext> {     public override string OperatorSymbol => " < ";      public override bool CanHandle(FilterAction action) => action == FilterAction.NumericLessThan;      public override object GetValue(NumericContext context)     {         return context.Number;     } }  public class DateGreaterThanAndLessThanEqualConditionBuilder : IConditionBuilder {     public const string GREATER_THAN = " > ";      public const string LESS_THAN_EQUAL = " <= ";      public string BuildCondition(SearchCondition filterCondition)     {         var conditionBuilder = new StringBuilder();          var context = filterCondition.GetContext<DateContext>();          conditionBuilder.Append(context.FieldId);         conditionBuilder.Append(GREATER_THAN);         conditionBuilder.Append("'" + context.FromDate + "'");         conditionBuilder.Append(LESS_THAN_EQUAL);         conditionBuilder.Append("'" + context.EndDate + "'");         return conditionBuilder.ToString();     }      public bool CanHandle(FilterAction action) => action == FilterAction.DateGreaterThanLessThan;  } 

I want to extend the functionality so that context.FieldId is sanitized before it is used to build the condition statement for e.g. these classes will build a statement like Name = 'Aashish', I want the classes to build statement as [Name] = 'Aashish'. These classes are consumed by other developers so I don’t want to break the functionality for consumers as a result of the changes I will make, basically adhere to Open-Closed principle. So, here is how I implemented these changes. Notice how I added a virtual function SanitizeFieldId in ConditionBuilder and DateGreaterThanAndLessThanEqualConditionBuilder.

public abstract class ConditionBuilder<TContext> : IConditionBuilder where TContext : FieldSearchContext {     public abstract string OperatorSymbol { get; }      public string BuildCondition(SearchCondition searchCondition)     {         var conditionBuilder = new StringBuilder();          var context = searchCondition.GetContext<TContext>();          conditionBuilder.Append(SanitizeFieldId(context.FieldId));         conditionBuilder.Append(OperatorSymbol);         conditionBuilder.Append(GetValue(context));          return conditionBuilder.ToString();     }      public abstract bool CanHandle(FilterAction filterAction);      public abstract object GetValue(TContext context);      protected virtual string SanitizeFieldId(string fieldId)     {         return fieldId;     } }  public class DateGreaterThanAndLessThanEqualConditionBuilder : IConditionBuilder {     public const string GREATER_THAN = " > ";      public const string LESS_THAN_EQUAL = " <= ";      public string BuildCondition(SearchCondition filterCondition)     {         var conditionBuilder = new StringBuilder();          var context = filterCondition.GetContext<DateContext>();          conditionBuilder.Append(SanitizeFieldId(context.FieldId));         conditionBuilder.Append(GREATER_THAN);         conditionBuilder.Append("'" + context.FromDate + "'");         conditionBuilder.Append(LESS_THAN_EQUAL);         conditionBuilder.Append("'" + context.EndDate + "'");         return conditionBuilder.ToString();     }      public bool CanHandle(FilterAction action) => action == FilterAction.DateGreaterThanLessThan;      protected virtual string SanitizeFieldId(string fieldId)     {         return fieldId;     } }  public class SanitizedFieldConditionBuiler<TContext> : ConditionBuilder<TContext> where TContext : FieldSearchContext {     private ConditionBuilder<TContext> _baseConditionBuilder;     private IColumnSanitizer _columnSanitizer;      public SanitizedFieldConditionBuiler(ConditionBuilder<TContext> baseConditionBuilder, IColumnSanitizer columnSanitizer)     {         _baseConditionBuilder = baseConditionBuilder;         _columnSanitizer = columnSanitizer;     }      public override string OperatorSymbol => _baseConditionBuilder.OperatorSymbol;      public override bool CanHandle(FilterAction filterAction) => _baseConditionBuilder.CanHandle(filterAction);      public override object GetValue(TContext context) => _baseConditionBuilder.GetValue(context);      protected override string SanitizeFieldId(string fieldId)     {         return _columnSanitizer.Sanitize(fieldId);     } }  public class SanitizedDateFieldGreaterThanAndLessThanEqualConditionBuilder : DateGreaterThanAndLessThanEqualConditionBuilder {     private IColumnSanitizer _columnSanitizer;      public SanitizedDateFieldGreaterThanAndLessThanEqualConditionBuilder(IColumnSanitizer columnSanitizer)     {         _columnSanitizer = columnSanitizer;     }      protected override string SanitizeFieldId(string fieldId)     {         return _columnSanitizer.Sanitize(fieldId);     } } 

I use extension methods to initialize SanitizedFieldConditionBuilerand SanitizedDateFieldGreaterThanAndLessThanEqualConditionBuilderas shown below:

public static class Extensions     {         public static SanitizedFieldConditionBuiler<TContext> SanitizeField<TContext>(this ConditionBuilder<TContext> source, IColumnSanitizer columnSanitizer) where TContext : FieldSearchContext         {             return new SanitizedFieldConditionBuiler<TContext>(source, columnSanitizer);         }          public static SanitizedDateFieldGreaterThanAndLessThanEqualConditionBuilder SanitizeField(this IConditionBuilder source, IColumnSanitizer columnSanitizer)         {             return new SanitizedDateFieldGreaterThanAndLessThanEqualConditionBuilder(columnSanitizer);         }      } 

The Sanitization is available by means of an interface IColumnSanitizer and has two different implementations, for Sql Server and Oracle respectively

 public interface IColumnSanitizer     {         string Sanitize(string columnName);     }      public class SqlSanitizer : IColumnSanitizer     {         public string Sanitize(string columnName)         {             return "[" + columnName + "]";         }     }      public class OracleSanitizer : IColumnSanitizer     {         public string Sanitize(string columnName)         {             return "\"" + columnName + "\"";         }     } 

Below is how context classes are implemented:

public abstract class FieldSearchContext {     public virtual string FieldId { get; }      protected FieldSearchContext(string fieldId)     {         FieldId = fieldId;     } }  public class DateContext : FieldSearchContext {     public DateContext(string fieldId, DateTime? fromDate, DateTime? endDate) : base(fieldId)     {         FromDate = fromDate;         EndDate = endDate;     }      public DateTime? FromDate { get; }      public DateTime? EndDate { get; } }  public class TextContext : FieldSearchContext {     public TextContext(string fieldId, string text) : base(fieldId)     {         Text = text;     }      public string Text { get; } }  public class NumericContext : FieldSearchContext {     public NumericContext(string fieldId, decimal number) : base(fieldId)     {         Number = number;     }      public decimal Number { get; } } 

These changes work perfectly fine but I want to find out if this can be achieved in a different and better way.

Use the code below to see it in action:

 class Program     {         static void Main(string[] args)         {             var conditions = new List<SearchCondition>()             {                 new SearchCondition(new NumericContext("Numeric Field", 1234), FilterAction.NumericLessThan),                 new SearchCondition(new TextContext("Text Field", "ASDF"), FilterAction.TextEqual),                 new SearchCondition(new TextContext("Text Field", "QWERTY"), FilterAction.TextLike),                 new SearchCondition(new DateContext("Date Field", DateTime.Now, DateTime.Now.AddYears(1)), FilterAction.DateGreaterThanLessThan)             };              Console.WriteLine(BuildWhereClause(Operation.AND, conditions));             Console.Read();         }          private static string BuildWhereClause(Operation operation, IList<SearchCondition> conditions)         {             var returnValue = new List<string>();             var conditionBuilders = new List<IConditionBuilder>()             {                 new TextEqualsConditionBuilder().SanitizeField(new SqlSanitizer()),                 new NumericLessThanConditionBuilder().SanitizeField(new SqlSanitizer()),                 new TextLikeConditionBuilder().SanitizeField(new SqlSanitizer()),                 new DateGreaterThanAndLessThanEqualConditionBuilder().SanitizeField(new SqlSanitizer())             };              foreach (var condition in conditions)             {                 var context = condition.GetContext<FieldSearchContext>();                 var conditionBuilder = conditionBuilders.FirstOrDefault(u => u.CanHandle(condition.FilterAction));                 returnValue.Add(conditionBuilder.BuildCondition(condition));             }              if (returnValue.Any())                 return string.Join(Convert.ToString(" " + operation + " "), returnValue);              return string.Empty;         }     }      enum Operation : int     {         AND = 1,         OR = 2     } 

Preview Pane style – List view breaking after modifying display columns

I’m having an issue with my list views, when using the preview pane style. I have views that worked perfectly, however if I modify the view to change the selected display columns, the preview pane no longer shows the title field from which to hover and display the list item. Are there required fields that the preview pane needs to work? I’m not removing the title field from display.

I want to keep the title field, and the columns I have removed from display are all empty (i.e. not used in the list form). I can change the preview panel to show list items by hovering over the blank space where the title field used to be, it’s like it’s hidden from view. See below: enter image description here

Breaking down doors – AC or DC?

It is not uncommon for players to encounter a door that resists being opened – the door may be stuck, barred, locked, barricaded, etc. A locked door could be unlocked by finding a key or passing a Difficulty Check to pick the lock, or it could be broken down.

In the D&D 5e Dungeon Master’s Guide page 237, the examples for when a strength ability check might be used are: “Smash down a door, move a boulder, use a spike to wedge a door shut”. Which seems fine – set a DC and see if the player can beat it with Strength check. This seems to be confirmed by the Player’s Handbook page 176, again in reference to when a Strength check may be used: “Force open a stuck, locked, or barred door”.

However, page 246 of the DMG also details object Armour Class and Hit Points. One could argue that a door is considered to be an object (at least, as much as a wall is considered to be an object by the book). Lets say the door is made of wood, its a medium sized object and it is resilient, so it has an AC of 15 and 18 Hit Points. When the door reaches 0 HP, it opens.

When would it be appropriate to use the AC and hit points of a door to determine if it opens versus setting a DC Strength check?

For the purposes of this question, assume there is always a chance for success and a risk of failure, there are no automatic successes or failures. Also assume that the players are determined to break the door, they are not interested in looking for ways around it – the door will be broken and open eventually, it is more a case of what method should be used to determine when the door opens.


Note that although this question is specifically asking about breaking doors, it would apply to any situation where it might be appropriate to use either an AC or a DC to break something. I have simply used doors as my example as they are one of the most likely and most common things a player may try to break.

Breaking up a list of lists

I have a list of values stored in SortedLat, where SortedLat is a list of 74 sublists, and each sublist has its first element be a string. As you can see I am trying to create the first column for a table with these strings.

TableOfValues1 = Prepend[q, {"B1", "B2"}] TableOfValues2 =   MapThread[   Prepend, {TableOfValues1, {"",      Partition[Table[SortedLat[[m]][[1]], {m, 1, 74}], 1]}}] 

B1,B2 are just lists of 74 numbers.

I realize the problem with the code is probably that

Partition[Table[SortedLat[[m]][[1]],{m,1,74}],1]}}] 

gives me a list of 74 strings instead of 74 separate strings. Therefore it gives the error that the dimensions don’t match. Is there a way to break up the list of 74 strings into 74 separate strings to make the table/grid work?

Thanks.

Goodberry house rule – would this be a reasonable non breaking change?


Background:

This is the first time I’ve DM’d 5e (returning from extensive 2e and 3e experience).

I’ve run the group through the official “Lost Mines of Phandelver” adventure and just started the “Hoard of Dragon Queen” adventure. All potions the group has looted/purchased have been used since healing ability is a scarcity in this group (Paladin, Sorcerer, and Ranger/Cleric). I only allow long rests outside of active dungeons (Alarm spell goes off alright!).

When the ranger multi-classed as a cleric, she realized she could cast Goodberry with all available unused slots before a long rest. This way, she would have them for the majority of the next day. We are only level 7 now, but I can see the impact of Goodberry getting out of hand (i.e. expending multiple slots with a lot of healing on tap, effectively negating short rests). (I don’t allow Goodberry to be used to revive unconscious characters.)

Now, I’ve found that small brawls/encounters are trickier since the party effectively has pockets of Cure Light Wound on tap (plus the full reserve of cleric/ranger slots). Even the fact that it takes an action for every HP of healing doesn’t fully counter this.

The Problem With This:

As you can see Goodberry has changed encounter dynamics — the group can start a dungeon with 100+ HPs of targeted easy healing (only gets stronger as they level).

Hoarding spell slots isn’t the problem (wouldn’t be an issue in my eyes, this would mean they’d have to not cast spells in other situations). The problem is the prospect of a safe long rest starting with the previous night’s Goodberry hoard. To solve this problem, I came up with the following house-rule:

Goodberry will last 24 hours or until the caster regains spell slots

This way, you can cast Goodberry before sleeping and it will remain in effect if your sleep is interrupted, but after a long rest it will lose potency (and your spell slots refresh).

Is this a balanced rule change? I cannot find other spells in the PHB that have a similar duration of >8 hours and don’t require concentration or active spell slots to compare it with (perhaps Goodberry is a one-of-a-kind spell?).

By VTM 5e, are the Kindred in the VtMB2 clan reveal trailers breaking any Camarilla laws?

For reference: As of this question being posted, the current released Bloodlines 2 clans are – Brujah, Tremere and Toreador (not counting Thin-blood).

This is prompted by how I saw a theory in the comments of one of the reveal videos, speculating whether the Kindred who appear in these videos might actually be the intended blood-hunt targets for the thin-blood pc.

They cited the following things as why they thought so:

Brujah – Very unsubtle looking cases of arson and murder which could attract some undesired attention

Tremere- Very messy blood ritual

Toreador- Filming herself eating/murdering someone

Whether or not the theory is correct (that not being the topic/question here – just context), the Toreador at least, I do agree is likely doing something they shouldn’t with making what is essentially a snuff video.

I’m not too sure of the severity of that by itself though, if she’s not actually distributing it (I don’t know), or about the others as they seem more of-norm.

So, my question is, with it in mind that the game does actually draw heavily and specifically from VTM 5E (even mentioning the fall of the Pyramid):

By the rules set in the VTM 5e rpg, are any of the kindred in the VtMB2 clan reveal trailers actually committing any violations/breaking any laws of the Camarilla during them?

iptables script breaking internet connection

Looking for some help in where I’m going wrong with an iptables script I’ve been using for a long time.

I was using this on Ubuntu Server 16.04 without any problems, I’ve upgraded to 19.04 (yes it’s a fresh install) and suddenly I have issues I can’t seem to overcome..

script: *filter  :INPUT DROP  :FORWARD DROP  :OUTPUT DROP  -A INPUT -s 192.168.1.1/24 -j ACCEPT  -A OUTPUT -d 192.168.1.1/24 -j ACCEPT  -A INPUT -s 127.0.0.1 -j ACCEPT  -A OUTPUT -d 127.0.0.1 -j ACCEPT  -A OUTPUT -d *VPN IP here* -p udp -j ACCEPT  -A INPUT -s *VPN IP Here* -p udp -j ACCEPT  -A INPUT -i tun0 -j ACCEPT  -A OUTPUT -o tun0 -j ACCEPT  COMMIT 

Without these rules in iptables, the VPN works perfectly on 19.04

As soon as I commit these rules to iptables, the internet shuts off as such, I can’t get a ip readback from curl ipecho.net/plain just says cant resolve hostname, yet however I can ping google (8.8.8.8) and it pings fine. I can’t even get any update list from ubuntu with apt-get update.

I’ve checked that the adapter names are correct and the VPN is tun0 so it’s not that.

The script is designed to kill the internet if something happens to the VPN connection (network cable unplugged, router reset etc downtime on the VPN server), however the VPN works and is connected so I’m not sure why it won’t work as intended.

As I say it worked perfectly on 16.04 however wont on 19.04. Confused.

Any help would be hugely appreciated.

How to compose load balancing and circuit breaking for external data source

So I have this issue. My website uses data, that is scraped from a different site – sports results. This data can update in relatively random intervals, but I do not care if my data is a bit stale – it does not have to be instant, but it should update on some regular basis.

At the same time, I cannot just cache the responses from the external site -> I process them and import into a graph database so that I can do other analytics over them.

I would like to have a system like this:

interface IDataSource {  public function getData(): array; }  class ExternalDataSource implements IDataSource { // gets data from the external website - the ultimate source of truth }  class InternalDataSource implements IDataSource { // gets data from my own graph database }  class InternalImportDecorator implements IDataSource {   private $  external;   public function __contruct(ExternalDataSource $  external) {     $  this->external = $  external   }    public function getData(): array   {     $  data = $  this-external->getData();     // import the data into my internal DB     return $  data;   } }  class CompositeDataSource implements IDataSource {     public function __construct(ExternalDataSource $  external, InternalDataSource $  internal)     {         $  this->external = new InternalImportDecorator($  external);         $  this->internal = $  internal;     }      public function getData(): array //HERE I NEED HELP     {       if(rand(0, 100) > 95) {//in 95% of the cases, go for internal DB for data - like weighted load-balancer somewhat         //here I need something like "chain of responsibility" in case the internal DB is not yet populated       } else { // go for the external data source, so that I can update my internal data         //what if the external data source is not available? I need a circuit breaker with fallback to internal         //what if I fall back to internal and the internal DB has not yet been populated       }     }  }  

I have a general idea about the code and the composition, I just need help with one method implementation. Or maybe just some nomenclature, how is this situation properly called, so that I can google it myself.

Private Message AJAX request is breaking theme by loading JavaScript code twice

I have a strange issue when using private message module together with the bootrap theme. I setup the block to select the conversation/thread on the left region. I noticed when I use this block provided by PR module under the path ../private_messages the chat is loaded without page refresh (via ajax). Thats really cool but: It is changing to many parts from the DOM. It is also appending all javascript files again what is causing setting jquery events a second time. For example: When I now click the bootstrap navbar-toogle it is expanding and immediately collapsing the menu again. So it’s not possible to open the menu anymore. When I now change the current chat by selecting another thread in the private messages block. Then it is loading the chat like expected but also again (3rd time now) the javascript files, so it is setting again all onclick events to different objects. Then the menu is working because all click events running 3 times now (1st expanding, 2nd hiding, 3rd expanding). The next click on another thread in the PR block would start the procedure again and again…

This is the the the request when it’s trying to load another chat: Loading private message chat via ajax

The response what you can see on then picture (on the right) is really long. I can see there is also a command in this json value what is including the following: {"command":"insert","method":"append","selector":"body","data":"\u003Cscript src=\u0022\/core\/assets\/vendor\/domready\/ready.min.js?v=1.0.8 … and so on…

It looks like this is telling drupal to append the js files again at the end of the DOM (before ends). How can I fix that behavior?