Add controller to database
This commit is contained in:
		
							parent
							
								
									9f64075f5a
								
							
						
					
					
						commit
						d193000aec
					
				
					 34 changed files with 1055 additions and 195 deletions
				
			
		
							
								
								
									
										38
									
								
								.sqlx/query-08c517120fcfb4534a3ff540910417afca55278e269f12203f4fc83096944810.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								.sqlx/query-08c517120fcfb4534a3ff540910417afca55278e269f12203f4fc83096944810.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "INSERT INTO junction_tag (tag_id, relay_id) VALUES (?, ?) RETURNING *",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "tag_id",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "relay_id",
 | 
				
			||||||
 | 
					        "ordinal": 2,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "schedule_id",
 | 
				
			||||||
 | 
					        "ordinal": 3,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 2
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      true,
 | 
				
			||||||
 | 
					      true
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "08c517120fcfb4534a3ff540910417afca55278e269f12203f4fc83096944810"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								.sqlx/query-1cb4cc57ff361d6d84a0c8e8f5df1ff46abbb21dfc3eb3f4f38b251f99d10abd.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								.sqlx/query-1cb4cc57ff361d6d84a0c8e8f5df1ff46abbb21dfc3eb3f4f38b251f99d10abd.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "SELECT * FROM controllers WHERE uid = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "uid",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "name",
 | 
				
			||||||
 | 
					        "ordinal": 2,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "relay_count",
 | 
				
			||||||
 | 
					        "ordinal": 3,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "active",
 | 
				
			||||||
 | 
					        "ordinal": 4,
 | 
				
			||||||
 | 
					        "type_info": "Bool"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "1cb4cc57ff361d6d84a0c8e8f5df1ff46abbb21dfc3eb3f4f38b251f99d10abd"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								.sqlx/query-1d658709678f72291d835ef2a4183d24f993442ea05e17910f587a4c92d4e7f5.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.sqlx/query-1d658709678f72291d835ef2a4183d24f993442ea05e17910f587a4c92d4e7f5.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "UPDATE controllers SET name = ?, relay_count = ?, active = ? WHERE id = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 4
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": []
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "1d658709678f72291d835ef2a4183d24f993442ea05e17910f587a4c92d4e7f5"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								.sqlx/query-1eda8cf54e553e8e892ac63a31cb94e91e7851a53ebae17a26b19300b83d7dac.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.sqlx/query-1eda8cf54e553e8e892ac63a31cb94e91e7851a53ebae17a26b19300b83d7dac.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "UPDATE schedules SET name = ?, periods = ? WHERE id = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 3
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": []
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "1eda8cf54e553e8e892ac63a31cb94e91e7851a53ebae17a26b19300b83d7dac"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								.sqlx/query-3fe383ea9ed4965e25d54eea08fb5abbab1b0c8eec7cf11597267de780299d0d.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								.sqlx/query-3fe383ea9ed4965e25d54eea08fb5abbab1b0c8eec7cf11597267de780299d0d.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "SELECT * FROM tags WHERE tag = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "tag",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "3fe383ea9ed4965e25d54eea08fb5abbab1b0c8eec7cf11597267de780299d0d"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								.sqlx/query-457e9d4808332255ed7354a28e6ebc2015558f66dbcd00cb4ce559d80f2bd023.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								.sqlx/query-457e9d4808332255ed7354a28e6ebc2015558f66dbcd00cb4ce559d80f2bd023.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "SELECT * FROM schedules WHERE id = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "uid",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "name",
 | 
				
			||||||
 | 
					        "ordinal": 2,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "periods",
 | 
				
			||||||
 | 
					        "ordinal": 3,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "457e9d4808332255ed7354a28e6ebc2015558f66dbcd00cb4ce559d80f2bd023"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								.sqlx/query-66a141b71041a7827f1932e6e288fdab37cc699720e5484c30697b5566b8d513.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								.sqlx/query-66a141b71041a7827f1932e6e288fdab37cc699720e5484c30697b5566b8d513.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "SELECT * FROM schedules",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "uid",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "name",
 | 
				
			||||||
 | 
					        "ordinal": 2,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "periods",
 | 
				
			||||||
 | 
					        "ordinal": 3,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 0
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "66a141b71041a7827f1932e6e288fdab37cc699720e5484c30697b5566b8d513"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								.sqlx/query-7519da166e2e0b6de4c02559fc173396e85db762d482607e4662e788c5542fea.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								.sqlx/query-7519da166e2e0b6de4c02559fc173396e85db762d482607e4662e788c5542fea.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "SELECT * FROM controllers",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "uid",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "name",
 | 
				
			||||||
 | 
					        "ordinal": 2,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "relay_count",
 | 
				
			||||||
 | 
					        "ordinal": 3,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "active",
 | 
				
			||||||
 | 
					        "ordinal": 4,
 | 
				
			||||||
 | 
					        "type_info": "Bool"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 0
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "7519da166e2e0b6de4c02559fc173396e85db762d482607e4662e788c5542fea"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								.sqlx/query-7b3ee1cad84a146699b9010be6d31665a416687772b95d159e5d3e98cde3511c.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								.sqlx/query-7b3ee1cad84a146699b9010be6d31665a416687772b95d159e5d3e98cde3511c.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "SELECT schedule.* FROM schedules AS schedule INNER JOIN junction_tag ON junction_tag.schedule_id = schedule.id WHERE junction_tag.tag_id = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "uid",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "name",
 | 
				
			||||||
 | 
					        "ordinal": 2,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "periods",
 | 
				
			||||||
 | 
					        "ordinal": 3,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "7b3ee1cad84a146699b9010be6d31665a416687772b95d159e5d3e98cde3511c"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								.sqlx/query-87b7396fb761030e25836cb90ed07a1bdaa1d82ae3d43d107cf8bac3e9ba4c25.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.sqlx/query-87b7396fb761030e25836cb90ed07a1bdaa1d82ae3d43d107cf8bac3e9ba4c25.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "DELETE FROM junction_tag WHERE schedule_id = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": []
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "87b7396fb761030e25836cb90ed07a1bdaa1d82ae3d43d107cf8bac3e9ba4c25"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								.sqlx/query-96f34b8654265ea5ab5210ab5dcad8c0bacd8d9e73e375dc35e759bdb82369a1.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								.sqlx/query-96f34b8654265ea5ab5210ab5dcad8c0bacd8d9e73e375dc35e759bdb82369a1.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "INSERT INTO schedules (uid, name, periods) VALUES (?, ?, ?) RETURNING *",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "uid",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "name",
 | 
				
			||||||
 | 
					        "ordinal": 2,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "periods",
 | 
				
			||||||
 | 
					        "ordinal": 3,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 3
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "96f34b8654265ea5ab5210ab5dcad8c0bacd8d9e73e375dc35e759bdb82369a1"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								.sqlx/query-a69f0bf9b3fefd7914502aa15fa120ecf4e5542011b781d8023bdb422580d97a.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								.sqlx/query-a69f0bf9b3fefd7914502aa15fa120ecf4e5542011b781d8023bdb422580d97a.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "INSERT INTO junction_tag (tag_id, schedule_id) VALUES (?, ?) RETURNING *",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "tag_id",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "relay_id",
 | 
				
			||||||
 | 
					        "ordinal": 2,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "schedule_id",
 | 
				
			||||||
 | 
					        "ordinal": 3,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 2
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      true,
 | 
				
			||||||
 | 
					      true
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "a69f0bf9b3fefd7914502aa15fa120ecf4e5542011b781d8023bdb422580d97a"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								.sqlx/query-a6dc153657cb3fefb5ba5b763dc5b7b4da78ab8acec79c7e7ea51ce5c9414bcb.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.sqlx/query-a6dc153657cb3fefb5ba5b763dc5b7b4da78ab8acec79c7e7ea51ce5c9414bcb.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "SELECT tag FROM tags INNER JOIN junction_tag ON junction_tag.tag_id = tags.id WHERE junction_tag.schedule_id = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "tag",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "a6dc153657cb3fefb5ba5b763dc5b7b4da78ab8acec79c7e7ea51ce5c9414bcb"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								.sqlx/query-a8b2d9cfd386b5f9ad5b76ef08711691dae057a431fffc27417e4f5504dcfb30.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.sqlx/query-a8b2d9cfd386b5f9ad5b76ef08711691dae057a431fffc27417e4f5504dcfb30.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "DELETE FROM schedules WHERE uid = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": []
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "a8b2d9cfd386b5f9ad5b76ef08711691dae057a431fffc27417e4f5504dcfb30"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								.sqlx/query-a94cb95af7e6c13e0e155c74de2febe44c1250f25989034a3f9e4e8bcb39dece.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.sqlx/query-a94cb95af7e6c13e0e155c74de2febe44c1250f25989034a3f9e4e8bcb39dece.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "DELETE FROM controllers WHERE uid = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": []
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "a94cb95af7e6c13e0e155c74de2febe44c1250f25989034a3f9e4e8bcb39dece"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								.sqlx/query-acfc608095768f30a55eb0298dfe86d095af0af9545252cf06f30827e9ca502a.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								.sqlx/query-acfc608095768f30a55eb0298dfe86d095af0af9545252cf06f30827e9ca502a.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "INSERT INTO controllers (uid, name, relay_count, active) VALUES (?, ?, ?, ?) RETURNING *",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "uid",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "name",
 | 
				
			||||||
 | 
					        "ordinal": 2,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "relay_count",
 | 
				
			||||||
 | 
					        "ordinal": 3,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "active",
 | 
				
			||||||
 | 
					        "ordinal": 4,
 | 
				
			||||||
 | 
					        "type_info": "Bool"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 4
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "acfc608095768f30a55eb0298dfe86d095af0af9545252cf06f30827e9ca502a"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								.sqlx/query-b91f6aab0bdb316633b3a0d75303086dd6e4e204e9e063535b19db666476fe88.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								.sqlx/query-b91f6aab0bdb316633b3a0d75303086dd6e4e204e9e063535b19db666476fe88.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "SELECT schedule.* FROM controllers AS schedule INNER JOIN junction_tag ON junction_tag.schedule_id = schedule.id WHERE junction_tag.tag_id = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "uid",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "name",
 | 
				
			||||||
 | 
					        "ordinal": 2,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "relay_count",
 | 
				
			||||||
 | 
					        "ordinal": 3,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "active",
 | 
				
			||||||
 | 
					        "ordinal": 4,
 | 
				
			||||||
 | 
					        "type_info": "Bool"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "b91f6aab0bdb316633b3a0d75303086dd6e4e204e9e063535b19db666476fe88"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								.sqlx/query-c30156fb112fcc28f08fbbec04197c41c9f71f6a4a3f44221f5ec012c99ebf54.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								.sqlx/query-c30156fb112fcc28f08fbbec04197c41c9f71f6a4a3f44221f5ec012c99ebf54.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "SELECT * FROM controllers WHERE id = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "uid",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "name",
 | 
				
			||||||
 | 
					        "ordinal": 2,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "relay_count",
 | 
				
			||||||
 | 
					        "ordinal": 3,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "active",
 | 
				
			||||||
 | 
					        "ordinal": 4,
 | 
				
			||||||
 | 
					        "type_info": "Bool"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "c30156fb112fcc28f08fbbec04197c41c9f71f6a4a3f44221f5ec012c99ebf54"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								.sqlx/query-db48fb93e9f22ee7da0786ae913d962b1da35b5b2b663f759f6af106650951b8.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								.sqlx/query-db48fb93e9f22ee7da0786ae913d962b1da35b5b2b663f759f6af106650951b8.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "SELECT * FROM tags WHERE id = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "tag",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "db48fb93e9f22ee7da0786ae913d962b1da35b5b2b663f759f6af106650951b8"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								.sqlx/query-e9386ab7ecbe4ce13f8ee5ee5852697741fb210ea8bfc3d61f1508106c0b076e.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								.sqlx/query-e9386ab7ecbe4ce13f8ee5ee5852697741fb210ea8bfc3d61f1508106c0b076e.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "SELECT * FROM schedules WHERE uid = ?",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "uid",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "name",
 | 
				
			||||||
 | 
					        "ordinal": 2,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "periods",
 | 
				
			||||||
 | 
					        "ordinal": 3,
 | 
				
			||||||
 | 
					        "type_info": "Blob"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "e9386ab7ecbe4ce13f8ee5ee5852697741fb210ea8bfc3d61f1508106c0b076e"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								.sqlx/query-ea4b06aaad9436096e20a53d81fd36ed21da18ceed5b71e51a1e749bab466422.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								.sqlx/query-ea4b06aaad9436096e20a53d81fd36ed21da18ceed5b71e51a1e749bab466422.json
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "db_name": "SQLite",
 | 
				
			||||||
 | 
					  "query": "INSERT INTO tags (tag) VALUES (?) RETURNING *",
 | 
				
			||||||
 | 
					  "describe": {
 | 
				
			||||||
 | 
					    "columns": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "id",
 | 
				
			||||||
 | 
					        "ordinal": 0,
 | 
				
			||||||
 | 
					        "type_info": "Int64"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "name": "tag",
 | 
				
			||||||
 | 
					        "ordinal": 1,
 | 
				
			||||||
 | 
					        "type_info": "Text"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "parameters": {
 | 
				
			||||||
 | 
					      "Right": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nullable": [
 | 
				
			||||||
 | 
					      false,
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "hash": "ea4b06aaad9436096e20a53d81fd36ed21da18ceed5b71e51a1e749bab466422"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										5
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -2,10 +2,11 @@
 | 
				
			||||||
build:
 | 
					build:
 | 
				
			||||||
	cargo build
 | 
						cargo build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sqlx: build
 | 
					sqlx:
 | 
				
			||||||
 | 
						rm ./emgauwa-dev.sqlite
 | 
				
			||||||
	cargo sqlx database create
 | 
						cargo sqlx database create
 | 
				
			||||||
	cargo sqlx migrate run
 | 
						cargo sqlx migrate run
 | 
				
			||||||
	cargo sqlx prepare
 | 
						cargo sqlx prepare --workspace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
build-rpi:
 | 
					build-rpi:
 | 
				
			||||||
	cross build --target arm-unknown-linux-gnueabihf
 | 
						cross build --target arm-unknown-linux-gnueabihf
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,8 +2,10 @@ use std::str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use futures::{future, pin_mut, StreamExt};
 | 
					use futures::{future, pin_mut, StreamExt};
 | 
				
			||||||
use futures::channel::mpsc;
 | 
					use futures::channel::mpsc;
 | 
				
			||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
 | 
					use tokio::io::AsyncReadExt;
 | 
				
			||||||
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
 | 
					use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
 | 
				
			||||||
 | 
					use tokio_tungstenite::tungstenite::Error;
 | 
				
			||||||
 | 
					use emgauwa_lib::db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod settings;
 | 
					mod settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +13,8 @@ mod settings;
 | 
				
			||||||
async fn main() {
 | 
					async fn main() {
 | 
				
			||||||
	let settings = settings::init();
 | 
						let settings = settings::init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let _pool = db::init(&settings.database).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let url = format!(
 | 
						let url = format!(
 | 
				
			||||||
		"ws://{}:{}/api/v1/ws/controllers",
 | 
							"ws://{}:{}/api/v1/ws/controllers",
 | 
				
			||||||
		settings.core.host,
 | 
							settings.core.host,
 | 
				
			||||||
| 
						 | 
					@ -21,17 +25,11 @@ async fn main() {
 | 
				
			||||||
	tokio::spawn(read_stdin(stdin_tx));
 | 
						tokio::spawn(read_stdin(stdin_tx));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let (ws_stream, _) = connect_async(url).await.expect("Failed to connect");
 | 
						let (ws_stream, _) = connect_async(url).await.expect("Failed to connect");
 | 
				
			||||||
	println!("WebSocket handshake has been successfully completed");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let (write, read) = ws_stream.split();
 | 
						let (write, read) = ws_stream.split();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let stdin_to_ws = stdin_rx.map(Ok).forward(write);
 | 
						let stdin_to_ws = stdin_rx.map(Ok).forward(write);
 | 
				
			||||||
	let ws_to_stdout = {
 | 
						let ws_to_stdout = read.for_each(handle_message);
 | 
				
			||||||
		read.for_each(|message| async {
 | 
					 | 
				
			||||||
			let data = message.unwrap().into_text().unwrap();
 | 
					 | 
				
			||||||
			println!("{}", data);
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pin_mut!(stdin_to_ws, ws_to_stdout);
 | 
						pin_mut!(stdin_to_ws, ws_to_stdout);
 | 
				
			||||||
	future::select(stdin_to_ws, ws_to_stdout).await;
 | 
						future::select(stdin_to_ws, ws_to_stdout).await;
 | 
				
			||||||
| 
						 | 
					@ -50,4 +48,11 @@ async fn read_stdin(tx: mpsc::UnboundedSender<Message>) {
 | 
				
			||||||
		buf.truncate(n);
 | 
							buf.truncate(n);
 | 
				
			||||||
		tx.unbounded_send(Message::text(str::from_utf8(&buf).unwrap())).unwrap();
 | 
							tx.unbounded_send(Message::text(str::from_utf8(&buf).unwrap())).unwrap();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn handle_message(message_result: Result<Message, Error>) {
 | 
				
			||||||
 | 
						match message_result {
 | 
				
			||||||
 | 
							Ok(message) => println!("{}", message.into_text().unwrap()),
 | 
				
			||||||
 | 
							Err(err) => println!("Error: {}", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -14,13 +14,13 @@ async fn main() -> std::io::Result<()> {
 | 
				
			||||||
	let settings = settings::init();
 | 
						let settings = settings::init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let log_level: LevelFilter = LevelFilter::from_str(&settings.logging.level)
 | 
						let log_level: LevelFilter = LevelFilter::from_str(&settings.logging.level)
 | 
				
			||||||
		.unwrap_or_else(|_| panic!("Error parsing log level."));
 | 
							.expect("Error parsing log level.");
 | 
				
			||||||
	trace!("Log level set to {:?}", log_level);
 | 
						trace!("Log level set to {:?}", log_level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SimpleLogger::new()
 | 
						SimpleLogger::new()
 | 
				
			||||||
		.with_level(log_level)
 | 
							.with_level(log_level)
 | 
				
			||||||
		.init()
 | 
							.init()
 | 
				
			||||||
		.unwrap_or_else(|_| panic!("Error initializing logger."));
 | 
							.expect("Error initializing logger.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let pool = emgauwa_lib::db::init(&settings.database).await;
 | 
						let pool = emgauwa_lib::db::init(&settings.database).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										122
									
								
								emgauwa-lib/src/db/controllers.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								emgauwa-lib/src/db/controllers.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,122 @@
 | 
				
			||||||
 | 
					use serde_derive::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					use std::ops::DerefMut;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use sqlx::pool::PoolConnection;
 | 
				
			||||||
 | 
					use sqlx::Sqlite;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::db::errors::DatabaseError;
 | 
				
			||||||
 | 
					use crate::db::model_utils::Period;
 | 
				
			||||||
 | 
					use crate::db::tag::Tag;
 | 
				
			||||||
 | 
					use crate::db::types::ControllerUid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Serialize, Clone)]
 | 
				
			||||||
 | 
					pub struct Controller {
 | 
				
			||||||
 | 
						pub id: i64,
 | 
				
			||||||
 | 
						pub uid: ControllerUid,
 | 
				
			||||||
 | 
						pub name: String,
 | 
				
			||||||
 | 
						pub relay_count: i64,
 | 
				
			||||||
 | 
						pub active: bool,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
 | 
				
			||||||
 | 
					pub struct Periods(pub Vec<Period>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Controller {
 | 
				
			||||||
 | 
						pub async fn get_all(
 | 
				
			||||||
 | 
							conn: &mut PoolConnection<Sqlite>,
 | 
				
			||||||
 | 
						) -> Result<Vec<Controller>, DatabaseError> {
 | 
				
			||||||
 | 
							Ok(sqlx::query_as!(Controller, "SELECT * FROM controllers")
 | 
				
			||||||
 | 
								.fetch_all(conn.deref_mut())
 | 
				
			||||||
 | 
								.await?)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pub async fn get(
 | 
				
			||||||
 | 
							conn: &mut PoolConnection<Sqlite>,
 | 
				
			||||||
 | 
							id: i64,
 | 
				
			||||||
 | 
						) -> Result<Controller, DatabaseError> {
 | 
				
			||||||
 | 
							sqlx::query_as!(
 | 
				
			||||||
 | 
								Controller,
 | 
				
			||||||
 | 
								"SELECT * FROM controllers WHERE id = ?",
 | 
				
			||||||
 | 
								id
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
								.fetch_optional(conn.deref_mut())
 | 
				
			||||||
 | 
								.await
 | 
				
			||||||
 | 
								.map(|s| s.ok_or(DatabaseError::NotFound))?
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pub async fn get_by_uid(
 | 
				
			||||||
 | 
							conn: &mut PoolConnection<Sqlite>,
 | 
				
			||||||
 | 
							filter_uid: &ControllerUid,
 | 
				
			||||||
 | 
						) -> Result<Controller, DatabaseError> {
 | 
				
			||||||
 | 
							sqlx::query_as!(
 | 
				
			||||||
 | 
								Controller,
 | 
				
			||||||
 | 
								"SELECT * FROM controllers WHERE uid = ?",
 | 
				
			||||||
 | 
								filter_uid
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							.fetch_optional(conn.deref_mut())
 | 
				
			||||||
 | 
							.await
 | 
				
			||||||
 | 
							.map(|s| s.ok_or(DatabaseError::NotFound))?
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pub async fn get_by_tag(
 | 
				
			||||||
 | 
							conn: &mut PoolConnection<Sqlite>,
 | 
				
			||||||
 | 
							tag: &Tag,
 | 
				
			||||||
 | 
						) -> Result<Vec<Controller>, DatabaseError> {
 | 
				
			||||||
 | 
							Ok(sqlx::query_as!(Controller, "SELECT schedule.* FROM controllers AS schedule INNER JOIN junction_tag ON junction_tag.schedule_id = schedule.id WHERE junction_tag.tag_id = ?", tag.id)
 | 
				
			||||||
 | 
								.fetch_all(conn.deref_mut())
 | 
				
			||||||
 | 
								.await?)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pub async fn delete_by_uid(
 | 
				
			||||||
 | 
							conn: &mut PoolConnection<Sqlite>,
 | 
				
			||||||
 | 
							filter_uid: ControllerUid,
 | 
				
			||||||
 | 
						) -> Result<(), DatabaseError> {
 | 
				
			||||||
 | 
							sqlx::query!("DELETE FROM controllers WHERE uid = ?", filter_uid)
 | 
				
			||||||
 | 
								.execute(conn.deref_mut())
 | 
				
			||||||
 | 
								.await
 | 
				
			||||||
 | 
								.map(|res| match res.rows_affected() {
 | 
				
			||||||
 | 
									0 => Err(DatabaseError::DeleteError),
 | 
				
			||||||
 | 
									_ => Ok(()),
 | 
				
			||||||
 | 
								})?
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pub async fn create(
 | 
				
			||||||
 | 
							conn: &mut PoolConnection<Sqlite>,
 | 
				
			||||||
 | 
							new_uid: &ControllerUid,
 | 
				
			||||||
 | 
							new_name: &str,
 | 
				
			||||||
 | 
							new_relay_count: i64,
 | 
				
			||||||
 | 
							new_active: bool
 | 
				
			||||||
 | 
						) -> Result<Controller, DatabaseError> {
 | 
				
			||||||
 | 
							sqlx::query_as!(
 | 
				
			||||||
 | 
								Controller,
 | 
				
			||||||
 | 
								"INSERT INTO controllers (uid, name, relay_count, active) VALUES (?, ?, ?, ?) RETURNING *",
 | 
				
			||||||
 | 
								new_uid,
 | 
				
			||||||
 | 
								new_name,
 | 
				
			||||||
 | 
								new_relay_count,
 | 
				
			||||||
 | 
								new_active,
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							.fetch_optional(conn.deref_mut())
 | 
				
			||||||
 | 
							.await?
 | 
				
			||||||
 | 
							.ok_or(DatabaseError::InsertGetError)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pub async fn update(
 | 
				
			||||||
 | 
							&self,
 | 
				
			||||||
 | 
							conn: &mut PoolConnection<Sqlite>,
 | 
				
			||||||
 | 
							new_name: &str,
 | 
				
			||||||
 | 
							new_relay_count: i64,
 | 
				
			||||||
 | 
							new_active: bool
 | 
				
			||||||
 | 
						) -> Result<Controller, DatabaseError> {
 | 
				
			||||||
 | 
							sqlx::query!(
 | 
				
			||||||
 | 
								"UPDATE controllers SET name = ?, relay_count = ?, active = ? WHERE id = ?",
 | 
				
			||||||
 | 
								new_name,
 | 
				
			||||||
 | 
								new_relay_count,
 | 
				
			||||||
 | 
								new_active,
 | 
				
			||||||
 | 
								self.id,
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							.execute(conn.deref_mut())
 | 
				
			||||||
 | 
							.await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Controller::get_by_uid(conn, &self.uid).await
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -6,17 +6,18 @@ use std::str::FromStr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::db::errors::DatabaseError;
 | 
					use crate::db::errors::DatabaseError;
 | 
				
			||||||
use crate::db::model_utils::Period;
 | 
					use crate::db::model_utils::Period;
 | 
				
			||||||
use crate::db::types::EmgauwaUid;
 | 
					use crate::db::types::ScheduleUid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// export for easier/flatter access
 | 
					// export for easier/flatter access
 | 
				
			||||||
pub use crate::db::schedules::{Periods, Schedule};
 | 
					pub use crate::db::schedules::{Periods, Schedule};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) mod errors;
 | 
					pub mod errors;
 | 
				
			||||||
mod model_utils;
 | 
					mod model_utils;
 | 
				
			||||||
mod models;
 | 
					mod models;
 | 
				
			||||||
pub(crate) mod schedules;
 | 
					pub mod schedules;
 | 
				
			||||||
pub(crate) mod tag;
 | 
					pub mod tag;
 | 
				
			||||||
pub mod types;
 | 
					pub mod types;
 | 
				
			||||||
 | 
					pub mod controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static MIGRATOR: Migrator = sqlx::migrate!("../migrations"); // defaults to "./migrations"
 | 
					static MIGRATOR: Migrator = sqlx::migrate!("../migrations"); // defaults to "./migrations"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +28,7 @@ pub async fn run_migrations(pool: &Pool<Sqlite>) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async fn init_schedule(
 | 
					async fn init_schedule(
 | 
				
			||||||
	pool: &Pool<Sqlite>,
 | 
						pool: &Pool<Sqlite>,
 | 
				
			||||||
	uid: &EmgauwaUid,
 | 
						uid: &ScheduleUid,
 | 
				
			||||||
	name: &str,
 | 
						name: &str,
 | 
				
			||||||
	periods: Periods,
 | 
						periods: Periods,
 | 
				
			||||||
) -> Result<(), DatabaseError> {
 | 
					) -> Result<(), DatabaseError> {
 | 
				
			||||||
| 
						 | 
					@ -68,13 +69,13 @@ pub async fn init(db: &str) -> Pool<Sqlite> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	run_migrations(&pool).await;
 | 
						run_migrations(&pool).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	init_schedule(&pool, &EmgauwaUid::Off, "Off", Periods(vec![]))
 | 
						init_schedule(&pool, &ScheduleUid::Off, "Off", Periods(vec![]))
 | 
				
			||||||
		.await
 | 
							.await
 | 
				
			||||||
		.expect("Error initializing schedule Off");
 | 
							.expect("Error initializing schedule Off");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	init_schedule(
 | 
						init_schedule(
 | 
				
			||||||
		&pool,
 | 
							&pool,
 | 
				
			||||||
		&EmgauwaUid::On,
 | 
							&ScheduleUid::On,
 | 
				
			||||||
		"On",
 | 
							"On",
 | 
				
			||||||
		Periods(vec![Period::new_on()]),
 | 
							Periods(vec![Period::new_on()]),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,14 +8,14 @@ use sqlx::Sqlite;
 | 
				
			||||||
use crate::db::errors::DatabaseError;
 | 
					use crate::db::errors::DatabaseError;
 | 
				
			||||||
use crate::db::model_utils::Period;
 | 
					use crate::db::model_utils::Period;
 | 
				
			||||||
use crate::db::tag::Tag;
 | 
					use crate::db::tag::Tag;
 | 
				
			||||||
use crate::db::types::EmgauwaUid;
 | 
					use crate::db::types::ScheduleUid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Serialize, Clone)]
 | 
					#[derive(Debug, Serialize, Clone)]
 | 
				
			||||||
pub struct Schedule {
 | 
					pub struct Schedule {
 | 
				
			||||||
	#[serde(skip)]
 | 
						#[serde(skip)]
 | 
				
			||||||
	pub id: i64,
 | 
						pub id: i64,
 | 
				
			||||||
	#[serde(rename(serialize = "id"))]
 | 
						#[serde(rename(serialize = "id"))]
 | 
				
			||||||
	pub uid: EmgauwaUid,
 | 
						pub uid: ScheduleUid,
 | 
				
			||||||
	pub name: String,
 | 
						pub name: String,
 | 
				
			||||||
	pub periods: Periods,
 | 
						pub periods: Periods,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -32,9 +32,23 @@ impl Schedule {
 | 
				
			||||||
			.await?)
 | 
								.await?)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pub async fn get(
 | 
				
			||||||
 | 
							conn: &mut PoolConnection<Sqlite>,
 | 
				
			||||||
 | 
							id: &i64,
 | 
				
			||||||
 | 
						) -> Result<Schedule, DatabaseError> {
 | 
				
			||||||
 | 
							sqlx::query_as!(
 | 
				
			||||||
 | 
								Schedule,
 | 
				
			||||||
 | 
								"SELECT * FROM schedules WHERE id = ?",
 | 
				
			||||||
 | 
								id
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
								.fetch_optional(conn.deref_mut())
 | 
				
			||||||
 | 
								.await
 | 
				
			||||||
 | 
								.map(|s| s.ok_or(DatabaseError::NotFound))?
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pub async fn get_by_uid(
 | 
						pub async fn get_by_uid(
 | 
				
			||||||
		conn: &mut PoolConnection<Sqlite>,
 | 
							conn: &mut PoolConnection<Sqlite>,
 | 
				
			||||||
		filter_uid: &EmgauwaUid,
 | 
							filter_uid: &ScheduleUid,
 | 
				
			||||||
	) -> Result<Schedule, DatabaseError> {
 | 
						) -> Result<Schedule, DatabaseError> {
 | 
				
			||||||
		sqlx::query_as!(
 | 
							sqlx::query_as!(
 | 
				
			||||||
			Schedule,
 | 
								Schedule,
 | 
				
			||||||
| 
						 | 
					@ -57,12 +71,12 @@ impl Schedule {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pub async fn delete_by_uid(
 | 
						pub async fn delete_by_uid(
 | 
				
			||||||
		conn: &mut PoolConnection<Sqlite>,
 | 
							conn: &mut PoolConnection<Sqlite>,
 | 
				
			||||||
		filter_uid: EmgauwaUid,
 | 
							filter_uid: ScheduleUid,
 | 
				
			||||||
	) -> Result<(), DatabaseError> {
 | 
						) -> Result<(), DatabaseError> {
 | 
				
			||||||
		let filter_uid = match filter_uid {
 | 
							let filter_uid = match filter_uid {
 | 
				
			||||||
			EmgauwaUid::Off => Err(DatabaseError::Protected),
 | 
								ScheduleUid::Off => Err(DatabaseError::Protected),
 | 
				
			||||||
			EmgauwaUid::On => Err(DatabaseError::Protected),
 | 
								ScheduleUid::On => Err(DatabaseError::Protected),
 | 
				
			||||||
			EmgauwaUid::Any(_) => Ok(filter_uid),
 | 
								ScheduleUid::Any(_) => Ok(filter_uid),
 | 
				
			||||||
		}?;
 | 
							}?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sqlx::query!("DELETE FROM schedules WHERE uid = ?", filter_uid)
 | 
							sqlx::query!("DELETE FROM schedules WHERE uid = ?", filter_uid)
 | 
				
			||||||
| 
						 | 
					@ -79,7 +93,7 @@ impl Schedule {
 | 
				
			||||||
		new_name: &str,
 | 
							new_name: &str,
 | 
				
			||||||
		new_periods: &Periods,
 | 
							new_periods: &Periods,
 | 
				
			||||||
	) -> Result<Schedule, DatabaseError> {
 | 
						) -> Result<Schedule, DatabaseError> {
 | 
				
			||||||
		let uid = EmgauwaUid::default();
 | 
							let uid = ScheduleUid::default();
 | 
				
			||||||
		sqlx::query_as!(
 | 
							sqlx::query_as!(
 | 
				
			||||||
			Schedule,
 | 
								Schedule,
 | 
				
			||||||
			"INSERT INTO schedules (uid, name, periods) VALUES (?, ?, ?) RETURNING *",
 | 
								"INSERT INTO schedules (uid, name, periods) VALUES (?, ?, ?) RETURNING *",
 | 
				
			||||||
| 
						 | 
					@ -100,8 +114,8 @@ impl Schedule {
 | 
				
			||||||
	) -> Result<Schedule, DatabaseError> {
 | 
						) -> Result<Schedule, DatabaseError> {
 | 
				
			||||||
		// overwrite periods on protected schedules
 | 
							// overwrite periods on protected schedules
 | 
				
			||||||
		let new_periods = match self.uid {
 | 
							let new_periods = match self.uid {
 | 
				
			||||||
			EmgauwaUid::Off | EmgauwaUid::On => self.periods.borrow(),
 | 
								ScheduleUid::Off | ScheduleUid::On => self.periods.borrow(),
 | 
				
			||||||
			EmgauwaUid::Any(_) => new_periods,
 | 
								ScheduleUid::Any(_) => new_periods,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sqlx::query!(
 | 
							sqlx::query!(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,16 @@ impl Tag {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pub async fn get(
 | 
						pub async fn get(
 | 
				
			||||||
 | 
							conn: &mut PoolConnection<Sqlite>,
 | 
				
			||||||
 | 
							id: i64,
 | 
				
			||||||
 | 
						) -> Result<Tag, DatabaseError> {
 | 
				
			||||||
 | 
							sqlx::query_as!(Tag, "SELECT * FROM tags WHERE id = ?", id)
 | 
				
			||||||
 | 
								.fetch_optional(conn.deref_mut())
 | 
				
			||||||
 | 
								.await
 | 
				
			||||||
 | 
								.map(|t| t.ok_or(DatabaseError::NotFound))?
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pub async fn get_by_tag(
 | 
				
			||||||
		conn: &mut PoolConnection<Sqlite>,
 | 
							conn: &mut PoolConnection<Sqlite>,
 | 
				
			||||||
		target_tag: &str,
 | 
							target_tag: &str,
 | 
				
			||||||
	) -> Result<Tag, DatabaseError> {
 | 
						) -> Result<Tag, DatabaseError> {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										62
									
								
								emgauwa-lib/src/db/types/controller_uid.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								emgauwa-lib/src/db/types/controller_uid.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,62 @@
 | 
				
			||||||
 | 
					use serde::{Serialize, Serializer};
 | 
				
			||||||
 | 
					use sqlx::{Decode, Encode, Sqlite, Type};
 | 
				
			||||||
 | 
					use sqlx::database::HasArguments;
 | 
				
			||||||
 | 
					use sqlx::encode::IsNull;
 | 
				
			||||||
 | 
					use sqlx::error::BoxDynError;
 | 
				
			||||||
 | 
					use sqlx::sqlite::{SqliteTypeInfo, SqliteValueRef};
 | 
				
			||||||
 | 
					use uuid::Uuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone, Debug)]
 | 
				
			||||||
 | 
					pub struct ControllerUid(Uuid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Serialize for ControllerUid {
 | 
				
			||||||
 | 
					    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
 | 
				
			||||||
 | 
					        where
 | 
				
			||||||
 | 
					            S: Serializer,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        String::from(self).serialize(serializer)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<&ControllerUid> for String {
 | 
				
			||||||
 | 
					    fn from(uid: &ControllerUid) -> String {
 | 
				
			||||||
 | 
					        uid.0.as_hyphenated().to_string()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Type<Sqlite> for ControllerUid {
 | 
				
			||||||
 | 
					    fn type_info() -> SqliteTypeInfo {
 | 
				
			||||||
 | 
					        <&[u8] as Type<Sqlite>>::type_info()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn compatible(ty: &SqliteTypeInfo) -> bool {
 | 
				
			||||||
 | 
					        <&[u8] as Type<Sqlite>>::compatible(ty)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'q> Encode<'q, Sqlite> for ControllerUid {
 | 
				
			||||||
 | 
					    //noinspection DuplicatedCode
 | 
				
			||||||
 | 
					    fn encode_by_ref(&self, buf: &mut <Sqlite as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
 | 
				
			||||||
 | 
					        let uuid_val = self.0.as_bytes().to_vec();
 | 
				
			||||||
 | 
					        <&Vec<u8> as Encode<Sqlite>>::encode(&uuid_val, buf)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'r> Decode<'r, Sqlite> for ControllerUid {
 | 
				
			||||||
 | 
					    //noinspection DuplicatedCode
 | 
				
			||||||
 | 
					    fn decode(value: SqliteValueRef<'r>) -> Result<Self, BoxDynError> {
 | 
				
			||||||
 | 
					        Ok(Self::from(<&[u8] as Decode<Sqlite>>::decode(value)?))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<&[u8]> for ControllerUid {
 | 
				
			||||||
 | 
					    fn from(value: &[u8]) -> Self {
 | 
				
			||||||
 | 
					        Self(Uuid::from_slice(&value).unwrap())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<Vec<u8>> for ControllerUid {
 | 
				
			||||||
 | 
					    fn from(value: Vec<u8>) -> Self {
 | 
				
			||||||
 | 
					        Self::from(value.as_slice())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,146 +0,0 @@
 | 
				
			||||||
use std::convert::TryFrom;
 | 
					 | 
				
			||||||
use std::fmt::{Debug, Formatter};
 | 
					 | 
				
			||||||
use std::str::FromStr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use serde::{Serialize, Serializer};
 | 
					 | 
				
			||||||
use sqlx::database::HasArguments;
 | 
					 | 
				
			||||||
use sqlx::encode::IsNull;
 | 
					 | 
				
			||||||
use sqlx::error::BoxDynError;
 | 
					 | 
				
			||||||
use sqlx::sqlite::{SqliteTypeInfo, SqliteValueRef};
 | 
					 | 
				
			||||||
use sqlx::{Decode, Encode, Sqlite, Type};
 | 
					 | 
				
			||||||
use uuid::Uuid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Clone)]
 | 
					 | 
				
			||||||
pub enum EmgauwaUid {
 | 
					 | 
				
			||||||
	Off,
 | 
					 | 
				
			||||||
	On,
 | 
					 | 
				
			||||||
	Any(Uuid),
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl EmgauwaUid {
 | 
					 | 
				
			||||||
	const OFF_STR: &'static str = "off";
 | 
					 | 
				
			||||||
	const ON_STR: &'static str = "on";
 | 
					 | 
				
			||||||
	const OFF_U8: u8 = 0;
 | 
					 | 
				
			||||||
	const ON_U8: u8 = 1;
 | 
					 | 
				
			||||||
	const OFF_U128: u128 = 0;
 | 
					 | 
				
			||||||
	const ON_U128: u128 = 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Default for EmgauwaUid {
 | 
					 | 
				
			||||||
	fn default() -> Self {
 | 
					 | 
				
			||||||
		EmgauwaUid::Any(Uuid::new_v4())
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Debug for EmgauwaUid {
 | 
					 | 
				
			||||||
	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
 | 
					 | 
				
			||||||
		match self {
 | 
					 | 
				
			||||||
			EmgauwaUid::Off => EmgauwaUid::OFF_STR.fmt(f),
 | 
					 | 
				
			||||||
			EmgauwaUid::On => EmgauwaUid::ON_STR.fmt(f),
 | 
					 | 
				
			||||||
			EmgauwaUid::Any(value) => value.fmt(f),
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Type<Sqlite> for EmgauwaUid {
 | 
					 | 
				
			||||||
	fn type_info() -> SqliteTypeInfo {
 | 
					 | 
				
			||||||
		<&[u8] as Type<Sqlite>>::type_info()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fn compatible(ty: &SqliteTypeInfo) -> bool {
 | 
					 | 
				
			||||||
		<&[u8] as Type<Sqlite>>::compatible(ty)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'q> Encode<'q, Sqlite> for EmgauwaUid {
 | 
					 | 
				
			||||||
	//noinspection DuplicatedCode
 | 
					 | 
				
			||||||
	fn encode_by_ref(&self, buf: &mut <Sqlite as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
 | 
					 | 
				
			||||||
		<&Vec<u8> as Encode<Sqlite>>::encode(&Vec::from(self), buf)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'r> Decode<'r, Sqlite> for EmgauwaUid {
 | 
					 | 
				
			||||||
	fn decode(value: SqliteValueRef<'r>) -> Result<Self, BoxDynError> {
 | 
					 | 
				
			||||||
		Ok(EmgauwaUid::from(<&[u8] as Decode<Sqlite>>::decode(value)?))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Serialize for EmgauwaUid {
 | 
					 | 
				
			||||||
	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
 | 
					 | 
				
			||||||
	where
 | 
					 | 
				
			||||||
		S: Serializer,
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		String::from(self).serialize(serializer)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<Uuid> for EmgauwaUid {
 | 
					 | 
				
			||||||
	fn from(uid: Uuid) -> EmgauwaUid {
 | 
					 | 
				
			||||||
		match uid.as_u128() {
 | 
					 | 
				
			||||||
			EmgauwaUid::OFF_U128 => EmgauwaUid::Off,
 | 
					 | 
				
			||||||
			EmgauwaUid::ON_U128 => EmgauwaUid::On,
 | 
					 | 
				
			||||||
			_ => EmgauwaUid::Any(uid),
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl TryFrom<&str> for EmgauwaUid {
 | 
					 | 
				
			||||||
	type Error = uuid::Error;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fn try_from(value: &str) -> Result<Self, Self::Error> {
 | 
					 | 
				
			||||||
		match value {
 | 
					 | 
				
			||||||
			EmgauwaUid::OFF_STR => Ok(EmgauwaUid::Off),
 | 
					 | 
				
			||||||
			EmgauwaUid::ON_STR => Ok(EmgauwaUid::On),
 | 
					 | 
				
			||||||
			any => match Uuid::from_str(any) {
 | 
					 | 
				
			||||||
				Ok(uuid) => Ok(EmgauwaUid::Any(uuid)),
 | 
					 | 
				
			||||||
				Err(err) => Err(err),
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<&EmgauwaUid> for Uuid {
 | 
					 | 
				
			||||||
	fn from(emgauwa_uid: &EmgauwaUid) -> Uuid {
 | 
					 | 
				
			||||||
		match emgauwa_uid {
 | 
					 | 
				
			||||||
			EmgauwaUid::Off => Uuid::from_u128(EmgauwaUid::OFF_U128),
 | 
					 | 
				
			||||||
			EmgauwaUid::On => Uuid::from_u128(EmgauwaUid::ON_U128),
 | 
					 | 
				
			||||||
			EmgauwaUid::Any(value) => *value,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<&EmgauwaUid> for String {
 | 
					 | 
				
			||||||
	fn from(emgauwa_uid: &EmgauwaUid) -> String {
 | 
					 | 
				
			||||||
		match emgauwa_uid {
 | 
					 | 
				
			||||||
			EmgauwaUid::Off => String::from(EmgauwaUid::OFF_STR),
 | 
					 | 
				
			||||||
			EmgauwaUid::On => String::from(EmgauwaUid::ON_STR),
 | 
					 | 
				
			||||||
			EmgauwaUid::Any(value) => value.as_hyphenated().to_string(),
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<&EmgauwaUid> for Vec<u8> {
 | 
					 | 
				
			||||||
	fn from(emgauwa_uid: &EmgauwaUid) -> Vec<u8> {
 | 
					 | 
				
			||||||
		match emgauwa_uid {
 | 
					 | 
				
			||||||
			EmgauwaUid::Off => vec![EmgauwaUid::OFF_U8],
 | 
					 | 
				
			||||||
			EmgauwaUid::On => vec![EmgauwaUid::ON_U8],
 | 
					 | 
				
			||||||
			EmgauwaUid::Any(value) => value.as_bytes().to_vec(),
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<&[u8]> for EmgauwaUid {
 | 
					 | 
				
			||||||
	fn from(value: &[u8]) -> Self {
 | 
					 | 
				
			||||||
		match value {
 | 
					 | 
				
			||||||
			[EmgauwaUid::OFF_U8] => EmgauwaUid::Off,
 | 
					 | 
				
			||||||
			[EmgauwaUid::ON_U8] => EmgauwaUid::On,
 | 
					 | 
				
			||||||
			value_bytes => EmgauwaUid::Any(Uuid::from_slice(value_bytes).unwrap()),
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<Vec<u8>> for EmgauwaUid {
 | 
					 | 
				
			||||||
	fn from(value: Vec<u8>) -> Self {
 | 
					 | 
				
			||||||
		EmgauwaUid::from(value.as_slice())
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,2 +1,5 @@
 | 
				
			||||||
pub mod emgauwa_uid;
 | 
					mod schedule_uid;
 | 
				
			||||||
pub use emgauwa_uid::EmgauwaUid;
 | 
					mod controller_uid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub use schedule_uid::ScheduleUid;
 | 
				
			||||||
 | 
					pub use controller_uid::ControllerUid;
 | 
				
			||||||
							
								
								
									
										147
									
								
								emgauwa-lib/src/db/types/schedule_uid.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								emgauwa-lib/src/db/types/schedule_uid.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,147 @@
 | 
				
			||||||
 | 
					use std::convert::TryFrom;
 | 
				
			||||||
 | 
					use std::fmt::{Debug, Formatter};
 | 
				
			||||||
 | 
					use std::str::FromStr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use serde::{Serialize, Serializer};
 | 
				
			||||||
 | 
					use sqlx::database::HasArguments;
 | 
				
			||||||
 | 
					use sqlx::encode::IsNull;
 | 
				
			||||||
 | 
					use sqlx::error::BoxDynError;
 | 
				
			||||||
 | 
					use sqlx::sqlite::{SqliteTypeInfo, SqliteValueRef};
 | 
				
			||||||
 | 
					use sqlx::{Decode, Encode, Sqlite, Type};
 | 
				
			||||||
 | 
					use uuid::Uuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone)]
 | 
				
			||||||
 | 
					pub enum ScheduleUid {
 | 
				
			||||||
 | 
						Off,
 | 
				
			||||||
 | 
						On,
 | 
				
			||||||
 | 
						Any(Uuid),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl ScheduleUid {
 | 
				
			||||||
 | 
						const OFF_STR: &'static str = "off";
 | 
				
			||||||
 | 
						const ON_STR: &'static str = "on";
 | 
				
			||||||
 | 
						const OFF_U8: u8 = 0;
 | 
				
			||||||
 | 
						const ON_U8: u8 = 1;
 | 
				
			||||||
 | 
						const OFF_U128: u128 = 0;
 | 
				
			||||||
 | 
						const ON_U128: u128 = 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Default for ScheduleUid {
 | 
				
			||||||
 | 
						fn default() -> Self {
 | 
				
			||||||
 | 
							Self::Any(Uuid::new_v4())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Debug for ScheduleUid {
 | 
				
			||||||
 | 
						fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
 | 
				
			||||||
 | 
							match self {
 | 
				
			||||||
 | 
								Self::Off => Self::OFF_STR.fmt(f),
 | 
				
			||||||
 | 
								Self::On => Self::ON_STR.fmt(f),
 | 
				
			||||||
 | 
								Self::Any(value) => value.fmt(f),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Type<Sqlite> for ScheduleUid {
 | 
				
			||||||
 | 
						fn type_info() -> SqliteTypeInfo {
 | 
				
			||||||
 | 
							<&[u8] as Type<Sqlite>>::type_info()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn compatible(ty: &SqliteTypeInfo) -> bool {
 | 
				
			||||||
 | 
							<&[u8] as Type<Sqlite>>::compatible(ty)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'q> Encode<'q, Sqlite> for ScheduleUid {
 | 
				
			||||||
 | 
						//noinspection DuplicatedCode
 | 
				
			||||||
 | 
						fn encode_by_ref(&self, buf: &mut <Sqlite as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
 | 
				
			||||||
 | 
							<&Vec<u8> as Encode<Sqlite>>::encode(&Vec::from(self), buf)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'r> Decode<'r, Sqlite> for ScheduleUid {
 | 
				
			||||||
 | 
						//noinspection DuplicatedCode
 | 
				
			||||||
 | 
						fn decode(value: SqliteValueRef<'r>) -> Result<Self, BoxDynError> {
 | 
				
			||||||
 | 
							Ok(Self::from(<&[u8] as Decode<Sqlite>>::decode(value)?))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Serialize for ScheduleUid {
 | 
				
			||||||
 | 
						fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
 | 
				
			||||||
 | 
						where
 | 
				
			||||||
 | 
							S: Serializer,
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							String::from(self).serialize(serializer)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<Uuid> for ScheduleUid {
 | 
				
			||||||
 | 
						fn from(uid: Uuid) -> Self {
 | 
				
			||||||
 | 
							match uid.as_u128() {
 | 
				
			||||||
 | 
								Self::OFF_U128 => Self::Off,
 | 
				
			||||||
 | 
								Self::ON_U128 => Self::On,
 | 
				
			||||||
 | 
								_ => Self::Any(uid),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl TryFrom<&str> for ScheduleUid {
 | 
				
			||||||
 | 
						type Error = uuid::Error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn try_from(value: &str) -> Result<Self, Self::Error> {
 | 
				
			||||||
 | 
							match value {
 | 
				
			||||||
 | 
								Self::OFF_STR => Ok(Self::Off),
 | 
				
			||||||
 | 
								Self::ON_STR => Ok(Self::On),
 | 
				
			||||||
 | 
								any => match Uuid::from_str(any) {
 | 
				
			||||||
 | 
									Ok(uuid) => Ok(Self::Any(uuid)),
 | 
				
			||||||
 | 
									Err(err) => Err(err),
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<&ScheduleUid> for Uuid {
 | 
				
			||||||
 | 
						fn from(uid: &ScheduleUid) -> Uuid {
 | 
				
			||||||
 | 
							match uid {
 | 
				
			||||||
 | 
								ScheduleUid::Off => Uuid::from_u128(ScheduleUid::OFF_U128),
 | 
				
			||||||
 | 
								ScheduleUid::On => Uuid::from_u128(ScheduleUid::ON_U128),
 | 
				
			||||||
 | 
								ScheduleUid::Any(value) => *value,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<&ScheduleUid> for String {
 | 
				
			||||||
 | 
						fn from(uid: &ScheduleUid) -> String {
 | 
				
			||||||
 | 
							match uid {
 | 
				
			||||||
 | 
								ScheduleUid::Off => String::from(ScheduleUid::OFF_STR),
 | 
				
			||||||
 | 
								ScheduleUid::On => String::from(ScheduleUid::ON_STR),
 | 
				
			||||||
 | 
								ScheduleUid::Any(value) => value.as_hyphenated().to_string(),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<&ScheduleUid> for Vec<u8> {
 | 
				
			||||||
 | 
						fn from(uid: &ScheduleUid) -> Vec<u8> {
 | 
				
			||||||
 | 
							match uid {
 | 
				
			||||||
 | 
								ScheduleUid::Off => vec![ScheduleUid::OFF_U8],
 | 
				
			||||||
 | 
								ScheduleUid::On => vec![ScheduleUid::ON_U8],
 | 
				
			||||||
 | 
								ScheduleUid::Any(value) => value.as_bytes().to_vec(),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<&[u8]> for ScheduleUid {
 | 
				
			||||||
 | 
						fn from(value: &[u8]) -> Self {
 | 
				
			||||||
 | 
							match value {
 | 
				
			||||||
 | 
								[Self::OFF_U8] => Self::Off,
 | 
				
			||||||
 | 
								[Self::ON_U8] => Self::On,
 | 
				
			||||||
 | 
								value_bytes => Self::Any(Uuid::from_slice(value_bytes).unwrap()),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<Vec<u8>> for ScheduleUid {
 | 
				
			||||||
 | 
						fn from(value: Vec<u8>) -> Self {
 | 
				
			||||||
 | 
							Self::from(value.as_slice())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ use sqlx::{Pool, Sqlite};
 | 
				
			||||||
use crate::db::errors::DatabaseError;
 | 
					use crate::db::errors::DatabaseError;
 | 
				
			||||||
use crate::db::{Periods, Schedule};
 | 
					use crate::db::{Periods, Schedule};
 | 
				
			||||||
use crate::db::tag::Tag;
 | 
					use crate::db::tag::Tag;
 | 
				
			||||||
use crate::db::types::EmgauwaUid;
 | 
					use crate::db::types::ScheduleUid;
 | 
				
			||||||
use crate::handlers::errors::ApiError;
 | 
					use crate::handlers::errors::ApiError;
 | 
				
			||||||
use crate::return_models::ReturnSchedule;
 | 
					use crate::return_models::ReturnSchedule;
 | 
				
			||||||
use crate::utils::vec_has_error;
 | 
					use crate::utils::vec_has_error;
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@ pub async fn tagged(
 | 
				
			||||||
	let mut pool_conn = pool.acquire().await?;
 | 
						let mut pool_conn = pool.acquire().await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let (tag,) = path.into_inner();
 | 
						let (tag,) = path.into_inner();
 | 
				
			||||||
	let tag_db = Tag::get(&mut pool_conn, &tag).await?;
 | 
						let tag_db = Tag::get_by_tag(&mut pool_conn, &tag).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let schedules = Schedule::get_by_tag(&mut pool_conn, &tag_db).await?;
 | 
						let schedules = Schedule::get_by_tag(&mut pool_conn, &tag_db).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,9 +61,9 @@ pub async fn show(
 | 
				
			||||||
	let mut pool_conn = pool.acquire().await?;
 | 
						let mut pool_conn = pool.acquire().await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let (schedule_uid,) = path.into_inner();
 | 
						let (schedule_uid,) = path.into_inner();
 | 
				
			||||||
	let emgauwa_uid = EmgauwaUid::try_from(schedule_uid.as_str()).or(Err(ApiError::BadUid))?;
 | 
						let uid = ScheduleUid::try_from(schedule_uid.as_str()).or(Err(ApiError::BadUid))?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let schedule = Schedule::get_by_uid(&mut pool_conn, &emgauwa_uid).await?;
 | 
						let schedule = Schedule::get_by_uid(&mut pool_conn, &uid).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let mut return_schedule = ReturnSchedule::from(schedule);
 | 
						let mut return_schedule = ReturnSchedule::from(schedule);
 | 
				
			||||||
	return_schedule.load_tags(&mut pool_conn);
 | 
						return_schedule.load_tags(&mut pool_conn);
 | 
				
			||||||
| 
						 | 
					@ -148,9 +148,9 @@ pub async fn update(
 | 
				
			||||||
	let mut pool_conn = pool.acquire().await?;
 | 
						let mut pool_conn = pool.acquire().await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let (schedule_uid,) = path.into_inner();
 | 
						let (schedule_uid,) = path.into_inner();
 | 
				
			||||||
	let emgauwa_uid = EmgauwaUid::try_from(schedule_uid.as_str()).or(Err(ApiError::BadUid))?;
 | 
						let uid = ScheduleUid::try_from(schedule_uid.as_str()).or(Err(ApiError::BadUid))?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let schedule = Schedule::get_by_uid(&mut pool_conn, &emgauwa_uid).await?;
 | 
						let schedule = Schedule::get_by_uid(&mut pool_conn, &uid).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let schedule = schedule
 | 
						let schedule = schedule
 | 
				
			||||||
		.update(&mut pool_conn, data.name.as_str(), &data.periods)
 | 
							.update(&mut pool_conn, data.name.as_str(), &data.periods)
 | 
				
			||||||
| 
						 | 
					@ -173,13 +173,13 @@ pub async fn delete(
 | 
				
			||||||
	let mut pool_conn = pool.acquire().await?;
 | 
						let mut pool_conn = pool.acquire().await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let (schedule_uid,) = path.into_inner();
 | 
						let (schedule_uid,) = path.into_inner();
 | 
				
			||||||
	let emgauwa_uid = EmgauwaUid::try_from(schedule_uid.as_str()).or(Err(ApiError::BadUid))?;
 | 
						let uid = ScheduleUid::try_from(schedule_uid.as_str()).or(Err(ApiError::BadUid))?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	match emgauwa_uid {
 | 
						match uid {
 | 
				
			||||||
		EmgauwaUid::Off => Err(ApiError::ProtectedSchedule),
 | 
							ScheduleUid::Off => Err(ApiError::ProtectedSchedule),
 | 
				
			||||||
		EmgauwaUid::On => Err(ApiError::ProtectedSchedule),
 | 
							ScheduleUid::On => Err(ApiError::ProtectedSchedule),
 | 
				
			||||||
		EmgauwaUid::Any(_) => {
 | 
							ScheduleUid::Any(_) => {
 | 
				
			||||||
			Schedule::delete_by_uid(&mut pool_conn, emgauwa_uid).await?;
 | 
								Schedule::delete_by_uid(&mut pool_conn, uid).await?;
 | 
				
			||||||
			Ok(HttpResponse::Ok().json("schedule got deleted"))
 | 
								Ok(HttpResponse::Ok().json("schedule got deleted"))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,18 +6,15 @@ CREATE TABLE controllers
 | 
				
			||||||
        AUTOINCREMENT
 | 
					        AUTOINCREMENT
 | 
				
			||||||
        NOT NULL,
 | 
					        NOT NULL,
 | 
				
			||||||
    uid
 | 
					    uid
 | 
				
			||||||
        VARCHAR(36)
 | 
					        BLOB
 | 
				
			||||||
        NOT NULL
 | 
					        NOT NULL
 | 
				
			||||||
        UNIQUE,
 | 
					        UNIQUE,
 | 
				
			||||||
    name
 | 
					    name
 | 
				
			||||||
        VARCHAR(128)
 | 
					        VARCHAR(128)
 | 
				
			||||||
        NOT NULL,
 | 
					        NOT NULL,
 | 
				
			||||||
    ip
 | 
					 | 
				
			||||||
        VARCHAR(16),
 | 
					 | 
				
			||||||
    port
 | 
					 | 
				
			||||||
        INTEGER,
 | 
					 | 
				
			||||||
    relay_count
 | 
					    relay_count
 | 
				
			||||||
        INTEGER,
 | 
					        INTEGER
 | 
				
			||||||
 | 
					        NOT NULL,
 | 
				
			||||||
    active
 | 
					    active
 | 
				
			||||||
        BOOLEAN
 | 
					        BOOLEAN
 | 
				
			||||||
        NOT NULL
 | 
					        NOT NULL
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue