wsl2のUbuntuにphp7.3をインストール際の「retrieving gpg key timed out.」エラー
を参考にphp7.3をインストールしようとしたが、途中でエラーになるので対応方法をメモ
- エラー内容(インストールが止まるためCtrl+Cで止めた)
sudo add-apt-repository ppa:ondrej/php ~中略~ error: retrieving gpg key timed out.
下記を実行すると「公開鍵を利用できないため、以下の署名は検証できませんでした」というエラーが発生。これがインストールが止まる原因ぽい。
sudo apt update
上記ページを参考に、エラーを回避する
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys <エラーになった公開鍵> sudo apt update
これでインストールできるようになりました。
sudo apt install php7.3 php7.3-common php7.3-cli php7.3-fpm php7.3-mysql php7.3-dev php7.3-mbstring php7.3-zip php7.3-sqlite3 php7.3-curl php7.3-gd php7.3-xml
IEのFormのデータを保存、復元する方法
JavaScriptでFormの値をJavaScriptとして保存し、
再度実行すれば、Formの値を復元するスクリプトです。
(Web Development Helperのスクリプトコンソールを利用します)
長大なFormのテストデータ入力時に役立つかもしれません。
// 準備 // ・以下のページから「Web Development Helper」をダウンロードしてください。 // http://projects.nikhilk.net/Projects/WebDevHelper.aspx // ・ダウンロードしたファイルをインストールしてください。 // ・IEを起動し、「ファイル」メニューの「エクスプローラーバー」から「Web Development Helper」を // 選択してください。 // ・表示されたメニューの「HTTP Logging▼」を選択し、「Script Console」を選択してください。 // ・「Script Console」の右の「Enable Debugging」にチェックを付けてください。 // (「インターネットオプション」の「詳細」タブでスクリプトのデバッグを許可している必要があります。) // // 使い方 // 1:右ペインの「LoadScript」からこのスクリプトファイルを開き、「Execute」をクリックする。 // 2:左ペインに表示された実行結果を全選択し、「Copy」をクリックする。 // (フォームのデータを復元するためのJavaScriptがコピーされます) // 3:再度同じ画面を開き、2でコピーしたスクリプトを実行すればフォームの値が復元されます。 // (select,checkbox,radio,hiddenの項目も復元されます) var scr = ""; var selNm = ""; var selType = ""; var selIdx = 0; var aryIdx = ""; var nameHash = new Array(); dall = "window.document.all['"; var end = ";\r\n"; var forms; if( window.frames.length > 0 ) { // フレームがある場合は最初のフレームからデータを取得する forms = window.frames[0].document.forms; dall = "window.frames[0].document.all['" } else { // フレームがない場合 forms = window.document.forms; } for( i = 0; i < forms.length; i++ ) { frm = forms[i]; for( j = 0; j < frm.all.length; j++ ) { tag = frm.all[j]; if( tag.type != undefined ) { // viewstateは保存しない if( tag.name == "__VIEWSTATE" ) { continue; } if( frm.all[tag.name] != undefined && frm.all[tag.name].length >= 2 && frm.all[tag.name][0].type == tag.type ) // selectのname属性が1つの場合と2つの場合で動作が異なるので回避 { if( nameHash[tag.name] == undefined ) { nameHash[tag.name] = 0; } aryIdx = "[" + nameHash[tag.name] + "]"; nameHash[tag.name] += 1; } else { aryIdx = ""; } // text,textarea,hidden項目を保存 if( tag.type == "text" || tag.type == "textarea" || tag.type == "hidden" ) { scr += dall + tag.name + "']" + aryIdx + ".value = '" + tag.value.replace(/\r\n/g, '\\r\\n') + "'" + end; } else if( tag.type == "checkbox" || tag.type == "radio" ) { scr += dall + tag.name + "']" + aryIdx + ".checked = " + tag.checked + end; } else if( tag.type == "select-one" || tag.type == "select-multiple" ) { selIdx = 0; selNm = tag.name; selType = tag.type; } } else { if( tag.tagName == "OPTION" ) { if( selType == "select-one" && tag.selected ) { scr += dall + selNm + "']" + aryIdx + ".options[" + selIdx + "].selected = " + tag.selected + end; } else if( selType == "select-multiple") { scr += dall + selNm + "']" + aryIdx + ".options[" + selIdx + "].selected = " + tag.selected + end; } selIdx++; } } } } Debug.writeln(scr);
VSマクロ(プロパティー一括生成)をVS2003対応
2008/02/19 (火) VS2005マクロ(プロパティー一括生成)
のマクロをVisualStudio2003、VisualStudio2005両対応に修正。
Continue文がないだけで非常に読みづらい気がする・・・
If文をネストすればもっと単純になるけれど、ネスト深いプログラムは嫌いだし。
気になる点
VS2003でVBのソースからマクロを生成した場合
Private _bar As Integer = 0 ''' <summary> ''' ''' </summary> Public Property Bar() As Int32 〜以下略〜
Integer型が「Int32」として生成される。C#はちゃんと「int」になるのに。
VS2003のバグかも。
' 選択範囲の変数からプロパティーを生成する(VB.NET、C#対応) ' 既に同名のプロパティーがあれば作成しない ' ' プロパティー名の規則 ' 1:変数は"_"(アンダースコア)から始まること ' 2:プロパティー名は変数の先頭1文字を削除し、次の文字を大文字に変換した名前とする ' (ex. 「_foo 」→「Foo」) ' VS2003,VS2005対応 Sub MakeProperty() ' 現在の選択範囲 Dim sel As EnvDTE.TextSelection = DTE.ActiveDocument.Selection Dim selTop As VirtualPoint = sel.TopPoint Dim selBottom As VirtualPoint = sel.BottomPoint ' もし下から上へ選択している場合は、選択範囲を交換する If selTop.Line = DTE.ActiveDocument.Selection.ActivePoint.Line Then sel.SwapAnchor() End If Dim actPoint As TextPoint = DTE.ActiveDocument.Selection.ActivePoint ' 現在キャレットがある場所のクラスを取得 Dim elm As CodeElement = actPoint.CodeElement(vsCMElement.vsCMElementClass) Dim cls As CodeClass = elm Dim typ As CodeType = CType(elm, CodeType) 'クラス内に既に存在するプロパティー一覧を作成する(重複作成しないためのチェック用) Dim lstProp As New System.Collections.Specialized.StringCollection For Each ite As CodeElement In typ.Members If TypeOf ite Is CodeProperty Then lstProp.Add(ite.Name) End If Next ' 編集用オブジェクト Dim editPoint As EditPoint Dim sbProp As New System.Text.StringBuilder Dim blnContinue As Boolean = True Dim newLine As String = System.Environment.NewLine ' クラス内のメンバーに対して For Each ite As CodeElement In typ.Members blnContinue = True sbProp.Length = 0 ' 変数であるかチェック If blnContinue AndAlso Not TypeOf ite Is CodeVariable Then blnContinue = False End If ' 変数が選択範囲内かチェック Dim elmVal As CodeVariable = Nothing If blnContinue Then elmVal = DirectCast(ite, CodeVariable) Dim valLine As Integer = elmVal.StartPoint.Line If Not (selTop.Line <= valLine AndAlso valLine <= selBottom.Line) Then blnContinue = False End If End If ' 変数名の先頭がアンダースコアであるかチェック If blnContinue AndAlso elmVal.Name.Substring(0, 1) <> "_" Then blnContinue = False End If ' 同じ名前のプロパティーが存在している場合は作成しない If blnContinue AndAlso lstProp.Contains(GetPropNm(elmVal.Name)) Then blnContinue = False End If ' プロパティー文字列を生成する If blnContinue Then If DTE.ActiveDocument.Language = "Basic" Then ' 編集中ファイルがVBの場合 sbProp.AppendFormat("''' <summary>").Append(newLine) sbProp.AppendFormat("''' ").Append(newLine) sbProp.AppendFormat("''' </summary>").Append(newLine) sbProp.AppendFormat("Public Property {0}() As {1}", GetPropNm(elmVal.Name), elmVal.Type.AsString).Append(newLine) sbProp.AppendFormat(" Get").Append(newLine) sbProp.AppendFormat(" Return {0}", elmVal.Name).Append(newLine) sbProp.AppendFormat(" End Get").Append(newLine) sbProp.AppendFormat(" Set(ByVal value As {0})", elmVal.Type.AsString).Append(newLine) sbProp.AppendFormat(" {0} = value", elmVal.Name).Append(newLine) sbProp.AppendFormat(" End Set").Append(newLine) sbProp.AppendFormat("End Property").Append(newLine) ElseIf DTE.ActiveDocument.Language = "CSharp" Then ' 編集中ファイルがC#の場合 sbProp.AppendFormat("/// <summary>").Append(newLine) sbProp.AppendFormat("/// ").Append(newLine) sbProp.AppendFormat("/// </summary>").Append(newLine) sbProp.AppendFormat("public {0} {1}", elmVal.Type.AsString, GetPropNm(elmVal.Name)).Append(newLine) sbProp.AppendFormat("{{").Append(newLine) sbProp.AppendFormat(" get {{ return {0}; }}", elmVal.Name).Append(newLine) sbProp.AppendFormat(" set {{ {0} = value; }}", elmVal.Name).Append(newLine) sbProp.AppendFormat("}}").Append(newLine) End If ' 変数の次の行にプロパティーを追加する editPoint = elmVal.EndPoint().CreateEditPoint() editPoint.Insert(System.Environment.NewLine) editPoint.Insert(sbProp.ToString) End If Next ' プロパティーのフォーマットを行う sel.LineDown(True, 12) sel.SmartFormat() sel.LineUp(False) End Sub ' 変数名からプロパティー名を生成して返す Private Function GetPropNm(ByVal varNm As String) As String Dim nm As String = varNm.Substring(1) Return nm.Substring(0, 1).ToUpper() & nm.Substring(1) End Function
VS2005マクロ(プロパティー一括生成)
VS2005マクロ(プロパティー一括生成)を書いてみた。
Eclipseを使っていたときお世話になった機能「GetterおよびSetterの生成」がVisualStudio2005になかったっぽいので作ってみました。
マクロがVC++6の頃とは随分変わってしまい困りましたがなんとかできました。
以下の行を選択してマクロを実行すると
Private _foo As String = "" Private _bar As Integer = 0
以下のようにプロパティーが一括生成されます
Private _foo As String = "" ''' <summary> ''' ''' </summary> Public Property Foo() As String Get Return _foo End Get Set(ByVal value As String) _foo = value End Set End Property Private _bar As Integer = 0 ''' <summary> ''' ''' </summary> Public Property Bar() As Integer Get Return _bar End Get Set(ByVal value As Integer) _bar = value End Set End Property
参考にしたマクロ
- VisualStudio2005のサンプルマクロ(「DevStudio6Editor」がVC++6のマクロを移植したものなので参考になります。)
- VisualStudio2005のサンプルマクロ (Utilitiesの「InsertDocComments」)
C#とBasicに対応しています。(VisualStudio.NET2003は確認してません)
#Region "変数からプロパティーを生成" ' 選択範囲の変数からプロパティーを生成する(VB.NET、C#対応) ' 既に同名のプロパティーがあれば作成しない ' ' プロパティー名の規則 ' 1:変数は"_"(アンダースコア)から始まること ' 2:プロパティー名は変数の先頭1文字を削除し、次の文字を大文字に変換した名前とする ' (ex. 「_foo 」→「Foo」) Sub MakeProperty() ' 現在の選択範囲 Dim sel As EnvDTE.TextSelection = DTE.ActiveDocument.Selection Dim selTop As VirtualPoint = sel.TopPoint Dim selBottom As VirtualPoint = sel.BottomPoint ' もし下から上へ選択している場合は、選択範囲を交換する If selTop.Line = DTE.ActiveDocument.Selection.ActivePoint.Line Then sel.SwapAnchor() End If Dim actPoint As TextPoint = DTE.ActiveDocument.Selection.ActivePoint ' 現在キャレットがある場所のクラスを取得 Dim elm As CodeElement = actPoint.CodeElement(vsCMElement.vsCMElementClass) Dim cls As CodeClass = elm Dim typ As CodeType = CType(elm, CodeType) 'クラス内に既に存在するプロパティー一覧を作成する(重複作成しないためのチェック用) Dim lstProp As New System.Collections.Generic.List(Of String) For Each ite As CodeElement In typ.Members If TypeOf ite Is CodeProperty Then lstProp.Add(ite.Name) End If Next ' 編集用オブジェクト Dim editPoint As EditPoint Dim sbProp As New Text.StringBuilder ' クラス内のメンバーに対して For Each ite As CodeElement In typ.Members sbProp.Length = 0 ' 変数であるかチェック If Not TypeOf ite Is CodeVariable Then Continue For End If ' 変数が選択範囲内かチェック Dim elmVal As CodeVariable = DirectCast(ite, CodeVariable) Dim valLine As Integer = elmVal.StartPoint.Line If Not (selTop.Line <= valLine AndAlso valLine <= selBottom.Line) Then Continue For End If ' 変数名の先頭がアンダースコアであるかチェック If elmVal.Name.Substring(0, 1) <> "_" Then Continue For End If ' 同じ名前のプロパティーが存在している場合は作成しない If lstProp.Contains(GetPropNm(elmVal.Name)) Then Continue For End If ' プロパティー文字列を生成する If DTE.ActiveDocument.Language = "Basic" Then ' 編集中ファイルがVBの場合 sbProp.AppendFormat("''' <summary>").AppendLine() sbProp.AppendFormat("''' ").AppendLine() sbProp.AppendFormat("''' </summary>").AppendLine() sbProp.AppendFormat("Public Property {0}() As {1}", GetPropNm(elmVal.Name), elmVal.Type.AsString).AppendLine() sbProp.AppendFormat(" Get").AppendLine() sbProp.AppendFormat(" Return {0}", elmVal.Name).AppendLine() sbProp.AppendFormat(" End Get").AppendLine() sbProp.AppendFormat(" Set(ByVal value As {0})", elmVal.Type.AsString).AppendLine() sbProp.AppendFormat(" {0} = value", elmVal.Name).AppendLine() sbProp.AppendFormat(" End Set").AppendLine() sbProp.AppendFormat("End Property").AppendLine() ElseIf DTE.ActiveDocument.Language = "CSharp" Then ' 編集中ファイルがC#の場合 sbProp.AppendFormat("/// <summary>").AppendLine() sbProp.AppendFormat("/// ").AppendLine() sbProp.AppendFormat("/// </summary>").AppendLine() sbProp.AppendFormat("public {0} {1}", elmVal.Type.AsString, GetPropNm(elmVal.Name)).AppendLine() sbProp.AppendFormat("{{").AppendLine() sbProp.AppendFormat(" get {{ return {0}; }}", elmVal.Name).AppendLine() sbProp.AppendFormat(" set {{ {0} = value; }}", elmVal.Name).AppendLine() sbProp.AppendFormat("}}").AppendLine() End If ' 変数の次の行にプロパティーを追加する editPoint = elmVal.GetEndPoint().CreateEditPoint() editPoint.Insert(System.Environment.NewLine) editPoint.Insert(sbProp.ToString) Next ' プロパティーのフォーマットを行う sel.LineDown(True, 12) sel.SmartFormat() sel.LineUp(False) End Sub ' 変数名からプロパティー名を生成して返す Private Function GetPropNm(ByVal varNm As String) As String Dim nm As String = varNm.Substring(1) Return nm.Substring(0, 1).ToUpper() & nm.Substring(1) End Function #End Region
英語の技術書が無料で読めるサイト
It Reading for freeで様々な技術系の本が公開されています。
全部で300種類のほどあるようです。All Books
個人的にいい加減Oracleとか勉強したかったので助かります。まだ途中までしか読んでないですが、とても読みやすい!
あとJava系も読んでおきたいです(仕事で使う事はなさそうですが)
日本語版で読んでも理解できないかも・・・(読めるようになりたいなぁ)
TableAdapter親クラスの変更
TableAdapterクラスには親クラスを差し替える機能があるのは知っていたのですが、使い道は全く思いつきませんでした。
(データセットデザイナで TableAdapterにあるBaseClassプロパティを変更することで親を変更できる)
プログラミング MS ADO .NET2.0 (マイクロソフト公式解説書)
- 作者: デビッドセッパ,David Sceppa,日本ユニテック
- 出版社/メーカー: 日経BP社
- 発売日: 2007/07/26
- メディア: 単行本
- 購入: 2人 クリック: 66回
- この商品を含むブログ (13件) を見る
でも有効利用しているサンプルを見つけました。
http://www.codeproject.com/useritems/typed_dataset_transaction.asp
TableAdapterでマニュアルトランザクションを使う簡単な方法はpartialクラスを使いTransactionを公開します。
しかし、TableAdapterごとに書くのは面倒・・・
ということで、親クラスでトランザクションの制御をするクラスを作ったようです。
そのソース
// ---------------------------------------------------------------------------- // // TransactionSupport // // Original author: Mike Pagel // // After ideas given in // http://www.codeproject.com/useritems/typed_dataset_transaction.asp // http://entwickler-forum.de/showpost.php?p=2032&postcount=2 // // ---------------------------------------------------------------------------- using System.Data.SqlClient; using System.Data; using System.Reflection; namespace BizWiz { /// <summary> /// Transaction support for generated table adapters. /// </summary> /// <remarks> /// This class adds transaction support to table adapters. It is used by changing the base /// class of a table adapter from Component to this class. The implementation of this class /// then accesses the derived table adapter's properties through reflection. /// </remarks> public abstract class TransactionSupport : System.ComponentModel.Component { // -------------------------------------------------------------------- #region Reflective access to table adapter properties // -------------------------------------------------------------------- private SqlConnection Connection { // Access to propertis as public and non-public as generated table-adapter // scope seems to be different for different installations: // http://www.codeproject.com/useritems/transactionta.asp?msg=2225021#xx2225021xx get { return (SqlConnection)GetType().GetProperty( "Connection", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ).GetValue( this, null ); } set { GetType().GetProperty( "Connection", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ).SetValue( this, value, null ); } } // -------------------------------------------------------------------- private SqlDataAdapter Adapter { get { return (SqlDataAdapter)GetType().GetProperty( "Adapter", BindingFlags.NonPublic | BindingFlags.Instance ).GetValue( this, null ); } } // -------------------------------------------------------------------- private SqlCommand[] CommandCollection { get { return (SqlCommand[])GetType().GetProperty( "CommandCollection", BindingFlags.NonPublic | BindingFlags.Instance ).GetValue( this, null ); } } #endregion // -------------------------------------------------------------------- #region Properties // -------------------------------------------------------------------- /// <summary> /// Transaction of this table adapter. /// </summary> /// <remarks> /// This property is used to share a transaction and its associated connection /// across multiple table adapters. The typical pattern is shown in the sample /// code below. /// </remarks> /// <example> /// XTableAdapter xta = new XTableAdapter(); /// YTableAdapter yta = new YTableAdapter(); /// /// xta.BeginTransation(); /// yta.Transation = xta.Transaction; /// try /// { /// // perform xta and yta modifications here. /// xta.CommitTransaction(); /// } /// catch( Exception ) /// { /// xta.RollbackTransaction(); /// } /// </example> public SqlTransaction Transaction { get { return transaction; } set { // attach transaction to all commands of this adapter: if( CommandCollection != null ) { foreach( SqlCommand command in CommandCollection ) { command.Transaction = value; } } if( Adapter.InsertCommand != null ) { Adapter.InsertCommand.Transaction = value; } if( Adapter.UpdateCommand != null ) { Adapter.UpdateCommand.Transaction = value; } if( Adapter.DeleteCommand != null ) { Adapter.DeleteCommand.Transaction = value; } // also set connection of this adapter accordingly: if( value != null ) { Connection = value.Connection; } else { // only clear connection if it was attached to // transaction before: if( transaction != null ) Connection = null; } transaction = value; } } #endregion // -------------------------------------------------------------------- #region Operations // -------------------------------------------------------------------- public void BeginTransaction() { // Open the connection, if needed if( Connection.State != ConnectionState.Open ) Connection.Open(); // Create the transaction and assign it to the Transaction property Transaction = Connection.BeginTransaction(); } // -------------------------------------------------------------------- public void CommitTransaction() { // Commit the transaction Transaction.Commit(); // Close the connection Connection.Close(); } // -------------------------------------------------------------------- public void RollbackTransaction() { // Rollback the transaction Transaction.Rollback(); // Close the connection Connection.Close(); } #endregion // -------------------------------------------------------------------- #region Fields // -------------------------------------------------------------------- /// <summary> /// Fields supporting properties. /// </summary> private SqlTransaction transaction; #endregion // -------------------------------------------------------------------- } }
なるほど、リフレクションなら実行時にコネクション取れるわけですね。
なるほど。
使い方
using (TransactionScope transaction = new TransactionScope()) { adapter1.Update(table1); adapter2.Update(table2); transaction.Complete(); }
でも思ったのですがリフレクション使うんだったら、以下のようなstaticメソッド作って
public static void SetTransaction(Component ta, SqlTransaction tx) { // コネクション取得 Type typTA = ta.GetType(); PropertyInfo propCon = typTA.GetProperty("Connection", BindingFlags.NonPublic | BindingFlags.Instance); if (propCon == null) { throw new System.ArgumentException(); } // テーブルアダプターの取得 PropertyInfo propAdapter = typTA.GetProperty("Adapter", BindingFlags.NonPublic | BindingFlags.Instance); if (propAdapter == null) { throw new System.ArgumentException(); } Object objAdapter = propAdapter.GetValue(ta, null); if (objAdapter is SqlDataAdapter) { // コネクションをテーブルアダプターにセットする propCon.SetValue(ta, tx.Connection, null); SqlDataAdapter adapter = (SqlDataAdapter)objAdapter; // 各コマンドにトランザクションをセットする SqlCommand[] CommandCollection = (SqlCommand[])typTA.GetProperty( "CommandCollection", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(ta, null); if (CommandCollection != null) { foreach (SqlCommand command in CommandCollection) { command.Transaction = tx; } } if (adapter.UpdateCommand != null) { adapter.UpdateCommand.Transaction = tx; } if (adapter.InsertCommand != null) { adapter.InsertCommand.Transaction = tx; } if (adapter.DeleteCommand != null) { adapter.DeleteCommand.Transaction = tx; } if (adapter.SelectCommand != null) { adapter.SelectCommand.Transaction = tx; } } }
こんな感じで使う方が簡単じゃないかと。
(結局TableAdapterの親クラスをいちいち変更するのが面倒だと思う)
using (SqlConnection con = new SqlConnection("〜〜〜")) { con.Open(); SqlTransaction tx = con.BeginTransaction(); DBUtil.SetTransaction(ta1, tx); DBUtil.SetTransaction(ta2, tx); ta1.Update(); ta2.Update(); tx.Commit(); }
VS2005買ったw
会社の仕事(.NET2.0)が楽しかったからここ1年ほど家でプログラム書いてなかったけど、
そろそろ飽きてきた。
暇つぶし(否、現実逃避)には最高のソフトだと思う。
というか、仕事中に調べるには気がひける・・・のを家でやるってのもどうかと思うが。