Category Archives: Programming

MySQL and ON DUPLICATE KEY UPDATE

I’ve been working on some MySQL stuff recently, specifically storing a snapshot of the price of bitcoin every 5 minutes from an online exchange.  As you can imagine, the amount of data this can generate is quite large, and becomes more than I need.  I mean, I don’t care what the price for Bitcoin was exactly 3 weeks, 2 days, 11 hours and 20 minutes ago was.  I do care about averages and trends though.

So, I decided to aggregate my data to hourly averages, along with a min/max for each hour.  Then I can delete any of the 5 minute interval data older than a week or so, and use the aggregated data to do my analysis and graphs.

In order to do this I wanted to run a query that would average all the entries within the current hour, and then update a row with these updated averages, along with min/max values.  I also wanted the query to insert a new row if it was a new hour.  After a little research I knew I needed to figure out INSERT INTO… ON DUPLICATE KEY UPDATE as my pattern.

Everything seemed to be going great, until I needed to store calculated fields in an updated row.  I couldn’t get the SQL statement to actually update the row.

It turns out, when you use a SELECT to generate the data to be INSERTed, MySQL creates a temporary table with the data in it, and I couldn’t find the name of the table, so trying to update the values with entries from the SELECT would fail with ‘No such column’ error.

I fixed this by storing the calculated results in specific variables, and in turn using those variables to update the existing row.

INSERT INTO tickerHourly
 (ID, time, product_id, priceAvg, priceMax, priceMin, volumeAvg, counter)
 SELECT
 (select ID from tickerHourly WHERE product_id = ticker.product_id 
 AND hour(time) = hour(UTC_TIMESTAMP()) and date(time) = date(UTC_TIMESTAMP())),
 FROM_UNIXTIME(60*60*ROUND(UNIX_TIMESTAMP(time)/(60*60))),
 product_id,
 @avg := AVG(price),
 @max := MAX(price),
 @min := MIN(price),
 @volumeAvg := AVG(volume),
 @counter := count(*)
 FROM ticker where hour(time) = hour(UTC_TIMESTAMP())
 AND date(time) = date(UTC_TIMESTAMP())
 AND product_id = ?
 group by date(time),hour(time),product_id
 ON DUPLICATE KEY UPDATE
 tickerHourly.counter = @counter,
 tickerHourly.priceAvg = @avg,
 tickerHourly.priceMax = @max,
 tickerHourly.priceMin = @min,
 tickerHourly.volumeAvg = @volumeAvg;

So the line ‘@avg := AVG(price)’ takes the average of all the price entries and stores it in the local variable avg, which I then use as part of the UPDATE clause.  This was my missing information.

Unity 5.6 and Android overlays – Updated

Unity just released 5.6.2f1 which rolls back the change they made to their Android player.  While the method described below works, it’s no longer needed.  There was also some performance issues using the PopupWindow, so it’s better just to go back to using a view added to the Unity view.

I updated the Unity version I’ve been using to 5.6 when it came out of beta, but when I built my android app, I noticed a major problem – the ad banners no longer appeared!  So glad I made sure to test my app before updating in to GPlay 😀

Turns out 5.6 uses a feature in Android to make their view sit on top of all other views for that activity, and when my plugin would create a view to hold both my AdMob view and Amazon adView, it wouldn’t display them on top of the Unity view as before.

I tried a few different methods before seeing that the folks who maintain the AdMob plugin for Android on Unity had  updated their method to use a PopupWindow.  I did some research on this method, and got it to work for both AdMob and Amazon ads.

The one thing that had me stuck for a bit was that you cannot show a PopupWindow right after creating it in the application onCreate method, you need to wait for a bit.  This was also true when I created the PopupWindow during my plugin initialization.

I used the post() method on the rootView to get the delay I needed.

    if (mPopupWindow!=null)
    {
        activity.getWindow().getDecorView().getRootView().post(new Runnable() {
        public void run() {
            if (isDebug)
                Log.i(LOGTAG,"Showing POPUP window...");
            mPopupWindow.showAtLocation(activity.getWindow().getDecorView().getRootView(),
                            Gravity.TOP, 0, 0);
        }
    });
    }

At some point, I’ll update my plugin to allow the PopupWindow to be either at the top or bottom of the display, right now it’s hard-coded to appear at the top.

iOS and App Transport Security Settings

Some time ago, Apple added a security feature to iOS that requires all domains that an app needs to connect to without HTTPS be white-listed in the info.plist file.

It’s pretty simple, you create a Dictionary object with the name of NSAppTransportSecurity and then add a key with the name NSAllowsArbitraryLoads and the bool value of True.  This will basically bypass the security system and allow your app to read from any website.

The problem coming down the pipe, is they are going to turn this ‘temp’ feature off sometime this year.  When they do, an App using this scheme will not be able to read from a non-HTTPS URL.

To get around this you need to explicitly add domains to your white-list.  Not too hard, but it needs to be done.

In the NSAppTransportSecurity, create another dictionary with the name NSExceptionDomains.  Then create another dictionary for each domain you’ll need access to, with the root domain as the name.  Inside that dictionary, add two items – NSTemporaryExceptionAllowsInsecureHTTPLoads with a bool value of TRUE, and NSIncludesSubdomains also with a bool value of TRUE.

That will let you read from those domains in the future, even when Apple kill NSAllowsArbitraryLoads.

The following is an extract from one of our apps which allows the app to read from purplebuttons.com.

<dict>
<key>purplebuttons.com</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>

Custom Inspector: Mixing custom drawer and default property drawers

I’ve been playing around with ScriptableObjects and using them to define parameters for my Dialog display gameobject.  In previous instances, I’d just use constant strings and pass them to the function that creates and displays the dialog.  After reading about ScriptableObjects, I decided to give them a shot to build strings for the dialogs.

Everything was great, except for the inspector displaying long strings.  They just get truncated of the right side of the display.  The behavior exhibited by the NGUI UILabel inspector is much better, as any text to long to be displayed in the inspector is wrapped and the field is extended vertically.

I found the NGUI code in UILabelInspector that handles the displaying of strings across multiple lines, and took a copy to use in my own inspector.  Then I realized, with a custom inspector I have to display all the properties myself, and I didn’t want to (a) write a custom display for each property type, and (b) remember to extend the inspector anytime I modified my ScriptableObject class.

The second problem was solved by iterating over the SerializedProperties contained in the SerializedObject, while the first problem was solved by calling EditorGui.PropertyField on SerializedProperties I didn’t want to display myself.

I then added an exception for the ‘Script’ property, to make it non-editable.

This resulted in the code below:

public override void OnInspectorGUI()
{
	serializedObject.Update();
	SerializedProperty sp = serializedObject.GetIterator();
	if (!sp.NextVisible(true))
		sp = null;
	while (sp!=null)
	{
		if (sp.type == "string")
			DrawMultiLineString(sp.name);
		else
		{
			Rect position = EditorGUILayout.GetControlRect(GUILayout.Height(EditorGUI.GetPropertyHeight(sp)));
			if (sp.name == "m_Script")
			{
				EditorGUI.BeginDisabledGroup(true);
				EditorGUI.PropertyField(position, sp, new GUIContent(sp.displayName), true);
				EditorGUI.EndDisabledGroup();
			}
			else
				EditorGUI.PropertyField(position, sp, new GUIContent(sp.displayName), true);
		}
		if (!sp.NextVisible(true))
			sp = null;
	}
	serializedObject.ApplyModifiedProperties();
}

The call to DrawMultiLineString uses code directly from NGUI’s UILabelInspector, and is not available unless you have NGUI for Unity.

Unity3D and OnValidate

So, I came across MonoBehaviour method earlier today that I’d previously missed:

void OnValidate()

This is called when a script is loaded, or (editor only) when a parameter is changed via the inspector.  I’m using this to allow me to set a property that has a getter/setter via the inspector by using an extra variable.   I set the extra copy in the inspector, and then use code in OnValidate to copy it to the setter method.

I’m also going to use it instead of the Update method for my editor scripts – Update is called every time something changes in the editor, OnValidate, only when something on that script changes – much more effective.