device data decoupled from device

dev
Anton Franzluebbers 2023-07-12 17:15:15 -04:00
parent 85706edab7
commit 9029ed5917
17 changed files with 1034 additions and 103 deletions

View File

@ -24,7 +24,7 @@ export interface DeviceData extends Record {
current_app: string; current_app: string;
data: { [key: string]: string }; data: { [key: string]: string };
} }
export interface RoomData extends HasData {} export interface RoomData extends HasData { }
const device = get(currentDevice); const device = get(currentDevice);
if (device == '' && device.length > 0) { if (device == '' && device.length > 0) {
@ -151,3 +151,34 @@ export function removeDevice(d: string) {
pb.collection('Users').update(user.id, user); pb.collection('Users').update(user.id, user);
} }
} }
export async function pair(pairingCode: string) {
// find the device by pairing code
try {
let device = (await pb
.collection('Device')
.getFirstListItem(`pairing_code="${pairingCode}"`)) as DeviceData;
// add it to the local data
currentDevice.set(device.id);
pairedDevices.set([...get(pairedDevices), device.id]);
// add it to my account if logged in
const u = get(currentUser)
if (u) {
u.devices.push(device.id);
await pb.collection('Users').update(u.id, u);
}
return { error: null }
} catch (e) {
console.error('Not found: ' + e);
if (e == "ClientResponseError 404: The requested resource wasn't found.") {
return {
error: 'Device not found with this pairing code.'
}
}
return {
error: e
}
}
}

View File

@ -19,19 +19,21 @@ namespace VELConnect
public class VELConnectManager : MonoBehaviour public class VELConnectManager : MonoBehaviour
{ {
public string velConnectUrl = "http://localhost"; public string velConnectUrl = "http://localhost";
public static string VelConnectUrl => _instance.velConnectUrl; private static VELConnectManager instance;
private static VELConnectManager _instance;
public class State public class State
{ {
public Device device;
public DataBlock room;
public User user;
public class User public class User
{ {
public string id; public string id;
public string email;
public string username; public string username;
public string date_created; public string created;
public string last_modified; public string updted;
public Dictionary<string, string> data;
} }
public class Device public class Device
@ -47,26 +49,31 @@ namespace VELConnect
[CanBeNull] public string current_room; [CanBeNull] public string current_room;
[CanBeNull] public string pairing_code; [CanBeNull] public string pairing_code;
[CanBeNull] public string last_online; [CanBeNull] public string last_online;
public Dictionary<string, string> data; [CanBeNull] public DeviceExpand expand;
public DataBlock deviceData => expand.data;
public class DeviceExpand
{
public DataBlock data;
}
/// <summary> /// <summary>
/// Returns the value if it exists, otherwise null /// Returns the value if it exists, otherwise null
/// </summary> /// </summary>
public string TryGetData(string key) public string TryGetData(string key)
{ {
string val = null; return deviceData.data?.TryGetValue(key, out string val) == true ? val : null;
return data?.TryGetValue(key, out val) == true ? val : null;
} }
} }
public class RoomState public class DataBlock
{ {
public readonly string id; public readonly string id;
public readonly DateTime created; public readonly DateTime created;
public readonly DateTime updated; public readonly DateTime updated;
public string block_id; public string block_id;
public string owner_id; public string owner;
public string visibility;
public string category; public string category;
public string modified_by; public string modified_by;
public Dictionary<string, string> data; public Dictionary<string, string> data;
@ -80,11 +87,6 @@ namespace VELConnect
return data?.TryGetValue(key, out val) == true ? val : null; return data?.TryGetValue(key, out val) == true ? val : null;
} }
} }
public User user;
public Device device;
public RoomState room;
} }
public class UserCount public class UserCount
@ -162,8 +164,8 @@ namespace VELConnect
private void Awake() private void Awake()
{ {
if (_instance != null) Debug.LogError("VELConnectManager instance already exists", this); if (instance != null) Debug.LogError("VELConnectManager instance already exists", this);
_instance = this; instance = this;
// Compute device id // Compute device id
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
@ -220,10 +222,11 @@ namespace VELConnect
version = Application.version, version = Application.version,
platform = SystemInfo.operatingSystem, platform = SystemInfo.operatingSystem,
}; };
PostRequestCallback(velConnectUrl + "/api/collections/UserCount/records", JsonConvert.SerializeObject(postData, Formatting.None, new JsonSerializerSettings PostRequestCallback(velConnectUrl + "/api/collections/UserCount/records", JsonConvert.SerializeObject(
{ postData, Formatting.None, new JsonSerializerSettings
NullValueHandling = NullValueHandling.Ignore {
})); NullValueHandling = NullValueHandling.Ignore
}));
}); });
} }
@ -233,7 +236,7 @@ namespace VELConnect
{ {
try try
{ {
GetRequestCallback(velConnectUrl + "/state/device/" + deviceId, json => GetRequestCallback(velConnectUrl + "/state/" + deviceId, json =>
{ {
state = JsonConvert.DeserializeObject<State>(json); state = JsonConvert.DeserializeObject<State>(json);
if (state == null) return; if (state == null) return;
@ -305,12 +308,12 @@ namespace VELConnect
} }
} }
if (state.device.data != null) if (state.device.deviceData.data != null)
{ {
foreach (KeyValuePair<string, string> elem in state.device.data) foreach (KeyValuePair<string, string> elem in state.device.deviceData.data)
{ {
string oldValue = null; string oldValue = null;
lastState?.device?.data?.TryGetValue(elem.Key, out oldValue); lastState?.device?.deviceData?.data?.TryGetValue(elem.Key, out oldValue);
if (elem.Value != oldValue) if (elem.Value != oldValue)
{ {
try try
@ -430,10 +433,10 @@ namespace VELConnect
if (sendInitialState) if (sendInitialState)
{ {
if (_instance != null && _instance.lastState?.device != null) if (instance != null && instance.lastState?.device != null)
{ {
if (_instance.lastState.device.GetType().GetField(key) if (instance.lastState.device.GetType().GetField(key)
?.GetValue(_instance.lastState.device) is string val) ?.GetValue(instance.lastState.device) is string val)
{ {
try try
{ {
@ -520,12 +523,12 @@ namespace VELConnect
public static string GetDeviceData(string key) public static string GetDeviceData(string key)
{ {
return _instance != null ? _instance.lastState?.device?.TryGetData(key) : null; return instance != null ? instance.lastState?.device?.TryGetData(key) : null;
} }
public static string GetRoomData(string key) public static string GetRoomData(string key)
{ {
return _instance != null ? _instance.lastState?.room?.TryGetData(key) : null; return instance != null ? instance.lastState?.room?.TryGetData(key) : null;
} }
/// <summary> /// <summary>
@ -536,18 +539,18 @@ namespace VELConnect
{ {
device[DeviceField.last_online] = DateTime.UtcNow.ToLongDateString(); device[DeviceField.last_online] = DateTime.UtcNow.ToLongDateString();
if (_instance.state?.device != null) if (instance.state?.device != null)
{ {
// loop through all the fields in the device // loop through all the fields in the device
foreach (DeviceField key in device.Keys.ToArray()) foreach (DeviceField key in device.Keys.ToArray())
{ {
FieldInfo field = _instance.state.device.GetType().GetField(key.ToString()); FieldInfo field = instance.state.device.GetType().GetField(key.ToString());
if ((string)field.GetValue(_instance.state.device) != device[key]) if ((string)field.GetValue(instance.state.device) != device[key])
{ {
if (_instance.lastState?.device != null) if (instance.lastState?.device != null)
{ {
// update our local state, so we don't get change events on our own updates // update our local state, so we don't get change events on our own updates
field.SetValue(_instance.lastState.device, device[key]); field.SetValue(instance.lastState.device, device[key]);
} }
} }
else else
@ -566,7 +569,7 @@ namespace VELConnect
} }
PostRequestCallback( PostRequestCallback(
_instance.velConnectUrl + "/device/" + deviceId, instance.velConnectUrl + "/device/" + deviceId,
JsonConvert.SerializeObject(device) JsonConvert.SerializeObject(device)
); );
} }
@ -576,21 +579,21 @@ namespace VELConnect
/// </summary> /// </summary>
public static void SetDeviceData(Dictionary<string, string> data) public static void SetDeviceData(Dictionary<string, string> data)
{ {
if (_instance.state?.device != null) if (instance.state?.device != null)
{ {
foreach (string key in data.Keys.ToList()) foreach (string key in data.Keys.ToList())
{ {
// if the value is unchanged from the current state, remove it so we don't double-update // if the value is unchanged from the current state, remove it so we don't double-update
if (_instance.state.device.data.TryGetValue(key, out string val) && val == data[key]) if (instance.state.device.deviceData.data.TryGetValue(key, out string val) && val == data[key])
{ {
data.Remove(key); data.Remove(key);
} }
else else
{ {
// update our local state, so we don't get change events on our own updates // update our local state, so we don't get change events on our own updates
if (_instance.lastState?.device?.data != null) if (instance.lastState?.device?.deviceData?.data != null)
{ {
_instance.lastState.device.data[key] = data[key]; instance.lastState.device.deviceData.data[key] = data[key];
} }
} }
} }
@ -602,7 +605,7 @@ namespace VELConnect
} }
// if we have no data, just set the whole thing // if we have no data, just set the whole thing
if (_instance.lastState?.device != null) _instance.lastState.device.data ??= data; if (instance.lastState?.device?.deviceData != null) instance.lastState.device.deviceData.data ??= data;
} }
@ -613,7 +616,7 @@ namespace VELConnect
}; };
PostRequestCallback( PostRequestCallback(
_instance.velConnectUrl + "/device/" + deviceId, instance.velConnectUrl + "/device/" + deviceId,
JsonConvert.SerializeObject(device, Formatting.None, new JsonSerializerSettings JsonConvert.SerializeObject(device, Formatting.None, new JsonSerializerSettings
{ {
NullValueHandling = NullValueHandling.Ignore NullValueHandling = NullValueHandling.Ignore
@ -634,19 +637,18 @@ namespace VELConnect
return; return;
} }
State.RoomState room = new State.RoomState State.DataBlock room = new State.DataBlock
{ {
category = "room", category = "room",
visibility = "public",
data = data data = data
}; };
// remove keys that already match our current state // remove keys that already match our current state
if (_instance.state?.room != null) if (instance.state?.room != null)
{ {
foreach (string key in data.Keys.ToArray()) foreach (string key in data.Keys.ToArray())
{ {
if (_instance.state.room.data[key] == data[key]) if (instance.state.room.data[key] == data[key])
{ {
data.Remove(key); data.Remove(key);
} }
@ -660,16 +662,16 @@ namespace VELConnect
} }
// update our local state, so we don't get change events on our own updates // update our local state, so we don't get change events on our own updates
if (_instance.lastState?.room != null) if (instance.lastState?.room != null)
{ {
foreach (KeyValuePair<string, string> kvp in data) foreach (KeyValuePair<string, string> kvp in data)
{ {
_instance.lastState.room.data[kvp.Key] = kvp.Value; instance.lastState.room.data[kvp.Key] = kvp.Value;
} }
} }
PostRequestCallback( PostRequestCallback(
_instance.velConnectUrl + "/data_block/" + Application.productName + "_" + VelNetManager.Room, instance.velConnectUrl + "/data_block/" + Application.productName + "_" + VelNetManager.Room,
JsonConvert.SerializeObject(room, Formatting.None, new JsonSerializerSettings JsonConvert.SerializeObject(room, Formatting.None, new JsonSerializerSettings
{ {
NullValueHandling = NullValueHandling.Ignore NullValueHandling = NullValueHandling.Ignore
@ -727,7 +729,7 @@ namespace VELConnect
public static void GetRequestCallback(string url, Action<string> successCallback = null, public static void GetRequestCallback(string url, Action<string> successCallback = null,
Action<string> failureCallback = null) Action<string> failureCallback = null)
{ {
_instance.StartCoroutine(_instance.GetRequestCallbackCo(url, successCallback, failureCallback)); instance.StartCoroutine(instance.GetRequestCallbackCo(url, successCallback, failureCallback));
} }
private IEnumerator GetRequestCallbackCo(string url, Action<string> successCallback = null, private IEnumerator GetRequestCallbackCo(string url, Action<string> successCallback = null,
@ -755,7 +757,7 @@ namespace VELConnect
Action<string> successCallback = null, Action<string> successCallback = null,
Action<string> failureCallback = null) Action<string> failureCallback = null)
{ {
_instance.StartCoroutine(PostRequestCallbackCo(url, postData, headers, successCallback, failureCallback)); instance.StartCoroutine(PostRequestCallbackCo(url, postData, headers, successCallback, failureCallback));
} }

View File

@ -38,40 +38,30 @@ func main() {
// get the old value to do a merge // get the old value to do a merge
record, err := dao.FindFirstRecordByData("DataBlock", "block_id", c.PathParam("block_id")) record, err := dao.FindFirstRecordByData("DataBlock", "block_id", c.PathParam("block_id"))
if err == nil { if err != nil {
mergeDataBlock(requestData, record) // create a new record if needed
} else {
collection, err := dao.FindCollectionByNameOrId("DataBlock") collection, err := dao.FindCollectionByNameOrId("DataBlock")
if err != nil { if err != nil {
return err return err
} }
record = models.NewRecord(collection) record = models.NewRecord(collection)
record.Set("data", "{}")
// we don't have an existing data, so just set the new values
if val, ok := requestData.Data["data"]; ok {
record.Set("data", val)
}
} }
// add the new values // add the new values
record.Set("block_id", c.PathParam("block_id")) record.Set("block_id", c.PathParam("block_id"))
fields := []string{ fields := []string{
"owner_id", "owner",
"visibility",
"category", "category",
"modfied_by",
} }
for _, v := range fields { for _, v := range fields {
if val, ok := requestData.Data[v]; ok { if val, ok := requestData.Data[v]; ok {
record.Set(v, val) record.Set(v, val)
} }
} }
mergeDataBlock(requestData, record)
// double-check that data is not null
if (record.Get("data") == nil) || (record.Get("data") == "") {
record.Set("data", "{}")
}
// apply to the db // apply to the db
if err := dao.SaveRecord(record); err != nil { if err := dao.SaveRecord(record); err != nil {
@ -98,32 +88,46 @@ func main() {
apis.ActivityLogger(app), apis.ActivityLogger(app),
) )
// This is used by Unity itself for device-centric data getting/setting
e.Router.POST("/device/:device_id", func(c echo.Context) error { e.Router.POST("/device/:device_id", func(c echo.Context) error {
dao := app.Dao() dao := app.Dao()
requestData := apis.RequestData(c) requestData := apis.RequestData(c)
// get the old value to do a merge // get the existing device (by device id)
record, err := dao.FindFirstRecordByData("Device", "device_id", c.PathParam("device_id")) deviceRecord, err := dao.FindRecordById("Device", c.PathParam("device_id"))
if err == nil {
mergeDataBlock(requestData, record)
} else {
// if no device, create one
if err != nil {
collection, err := dao.FindCollectionByNameOrId("Device") collection, err := dao.FindCollectionByNameOrId("Device")
if err != nil { if err != nil {
log.Fatalln("Couldn't create device")
return err return err
} }
record = models.NewRecord(collection) deviceRecord = models.NewRecord(collection)
deviceRecord.SetId(c.PathParam("device_id"))
}
log.Println(deviceRecord.PublicExport())
// we don't have an existing data, so just set the new values // get the device data block
if val, ok := requestData.Data["data"]; ok { deviceDataRecord, err := dao.FindRecordById("DataBlock", deviceRecord.GetString("data"))
record.Set("data", val) if err != nil {
collection, err := dao.FindCollectionByNameOrId("DataBlock")
if err != nil {
log.Fatalln("Couldn't create datablock")
return err
} }
deviceDataRecord = models.NewRecord(collection)
deviceDataRecord.RefreshId()
deviceRecord.Set("data", deviceDataRecord.Id)
deviceDataRecord.Set("category", "device")
deviceDataRecord.Set("data", "{}")
} }
// add the new values // add the new device values
record.Set("device_id", c.PathParam("device_id")) deviceRecord.Set("device_id", c.PathParam("device_id"))
fields := []string{ fields := []string{
"os_info", "os_info",
"friendly_name", "friendly_name",
@ -135,51 +139,54 @@ func main() {
} }
for _, v := range fields { for _, v := range fields {
if val, ok := requestData.Data[v]; ok { if val, ok := requestData.Data[v]; ok {
record.Set(v, val) deviceRecord.Set(v, val)
} }
} }
// double-check that data is not null mergeDataBlock(requestData, deviceDataRecord)
if (record.Get("data") == nil) || (record.Get("data") == "") {
record.Set("data", "{}")
}
// apply to the db // apply to the db
if err := dao.SaveRecord(record); err != nil { if err := dao.SaveRecord(deviceRecord); err != nil {
return err
}
if err := dao.SaveRecord(deviceDataRecord); err != nil {
return err return err
} }
return c.JSON(http.StatusOK, record) return c.JSON(http.StatusOK, deviceRecord)
}, },
apis.ActivityLogger(app), apis.ActivityLogger(app),
) )
e.Router.GET("/device/:device_id", func(c echo.Context) error { // e.Router.GET("/device/:device_id", func(c echo.Context) error {
record, err := app.Dao().FindFirstRecordByData("Device", "device_id", c.PathParam("device_id")) // record, err := app.Dao().FindFirstRecordByData("Device", "device_id", c.PathParam("device_id"))
if err != nil { // if err != nil {
return apis.NewNotFoundError("The device does not exist.", err) // return apis.NewNotFoundError("The device does not exist.", err)
} // }
// enable ?expand query param support // // enable ?expand query param support
apis.EnrichRecord(c, app.Dao(), record) // apis.EnrichRecord(c, app.Dao(), record)
return c.JSON(http.StatusOK, record) // return c.JSON(http.StatusOK, record)
}, // },
apis.ActivityLogger(app), // apis.ActivityLogger(app),
) // )
// gets all relevant tables for this device id // gets all relevant tables for this device id
e.Router.GET("/state/device/:device_id", func(c echo.Context) error { e.Router.GET("/state/:device_id", func(c echo.Context) error {
record, err := app.Dao().FindFirstRecordByData("Device", "device_id", c.PathParam("device_id")) deviceRecord, err := app.Dao().FindRecordById("Device", c.PathParam("device_id"))
if err != nil { if err != nil {
return apis.NewNotFoundError("The device does not exist.", err) return apis.NewNotFoundError("The device does not exist.", err)
} }
room, _ := app.Dao().FindFirstRecordByData("DataBlock", "block_id", record.GetString("current_room")) apis.EnrichRecord(c, app.Dao(), deviceRecord, "data")
room, _ := app.Dao().FindFirstRecordByData("DataBlock", "block_id", deviceRecord.GetString("current_room"))
user, _ := app.Dao().FindRecordById("Users", deviceRecord.GetString("owner"))
output := map[string]interface{}{ output := map[string]interface{}{
"device": record, "device": deviceRecord,
"room": room, "room": room,
"user": user,
} }
return c.JSON(http.StatusOK, output) return c.JSON(http.StatusOK, output)

View File

@ -0,0 +1,34 @@
package migrations
import (
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/tools/types"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
collection.ViewRule = types.Pointer("")
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
collection.ViewRule = nil
return dao.SaveCollection(collection)
})
}

View File

@ -0,0 +1,42 @@
package migrations
import (
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/tools/types"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
collection.ListRule = types.Pointer("")
collection.CreateRule = types.Pointer("")
collection.UpdateRule = types.Pointer("")
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
collection.ListRule = nil
collection.CreateRule = nil
collection.UpdateRule = nil
return dao.SaveCollection(collection)
})
}

View File

@ -0,0 +1,38 @@
package migrations
import (
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/tools/types"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("fupstz47c55s69f")
if err != nil {
return err
}
collection.ViewRule = types.Pointer("")
collection.UpdateRule = types.Pointer("")
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("fupstz47c55s69f")
if err != nil {
return err
}
collection.ViewRule = nil
collection.UpdateRule = nil
return dao.SaveCollection(collection)
})
}

View File

@ -0,0 +1,96 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models/schema"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("fupstz47c55s69f")
if err != nil {
return err
}
json.Unmarshal([]byte(`[]`), &collection.Indexes)
// remove
collection.Schema.RemoveField("pphfrekz")
// remove
collection.Schema.RemoveField("vjzi0uvv")
// add
new_data := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "qxsvm1rf",
"name": "data",
"type": "relation",
"required": false,
"unique": false,
"options": {
"collectionId": "3qwwkz4wb0lyi78",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": 1,
"displayFields": []
}
}`), new_data)
collection.Schema.AddField(new_data)
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("fupstz47c55s69f")
if err != nil {
return err
}
json.Unmarshal([]byte(`[
"CREATE UNIQUE INDEX ` + "`" + `idx_jgyX3xA` + "`" + ` ON ` + "`" + `Device` + "`" + ` (` + "`" + `device_id` + "`" + `)"
]`), &collection.Indexes)
// add
del_data := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "pphfrekz",
"name": "data",
"type": "json",
"required": false,
"unique": false,
"options": {}
}`), del_data)
collection.Schema.AddField(del_data)
// add
del_device_id := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "vjzi0uvv",
"name": "device_id",
"type": "text",
"required": true,
"unique": false,
"options": {
"min": null,
"max": null,
"pattern": ""
}
}`), del_device_id)
collection.Schema.AddField(del_device_id)
// remove
collection.Schema.RemoveField("qxsvm1rf")
return dao.SaveCollection(collection)
})
}

View File

@ -0,0 +1,74 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models/schema"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
// remove
collection.Schema.RemoveField("2j8ydmzp")
// add
new_owner := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "a3d7pkoh",
"name": "owner",
"type": "relation",
"required": false,
"unique": false,
"options": {
"collectionId": "_pb_users_auth_",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": 1,
"displayFields": []
}
}`), new_owner)
collection.Schema.AddField(new_owner)
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
// add
del_owner_id := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "2j8ydmzp",
"name": "owner_id",
"type": "text",
"required": false,
"unique": false,
"options": {
"min": null,
"max": null,
"pattern": ""
}
}`), del_owner_id)
collection.Schema.AddField(del_owner_id)
// remove
collection.Schema.RemoveField("a3d7pkoh")
return dao.SaveCollection(collection)
})
}

View File

@ -0,0 +1,78 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("ejjwc6vs7mfpyck")
if err != nil {
return err
}
return dao.DeleteCollection(collection)
}, func(db dbx.Builder) error {
jsonData := `{
"id": "ejjwc6vs7mfpyck",
"created": "2023-07-06 23:16:00.484Z",
"updated": "2023-07-06 23:16:00.484Z",
"name": "UserDevice",
"type": "base",
"system": false,
"schema": [
{
"system": false,
"id": "7qflf3o6",
"name": "user_id",
"type": "relation",
"required": true,
"unique": false,
"options": {
"collectionId": "_pb_users_auth_",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": 1,
"displayFields": []
}
},
{
"system": false,
"id": "l7xsjmop",
"name": "device_id",
"type": "relation",
"required": true,
"unique": false,
"options": {
"collectionId": "fupstz47c55s69f",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": 1,
"displayFields": []
}
}
],
"indexes": [],
"listRule": null,
"viewRule": null,
"createRule": null,
"updateRule": null,
"deleteRule": null,
"options": {}
}`
collection := &models.Collection{}
if err := json.Unmarshal([]byte(jsonData), &collection); err != nil {
return err
}
return daos.New(db).SaveCollection(collection)
})
}

View File

@ -0,0 +1,54 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models/schema"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("fupstz47c55s69f")
if err != nil {
return err
}
// add
new_owner := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "nfernq2q",
"name": "owner",
"type": "relation",
"required": false,
"unique": false,
"options": {
"collectionId": "_pb_users_auth_",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": 1,
"displayFields": []
}
}`), new_owner)
collection.Schema.AddField(new_owner)
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("fupstz47c55s69f")
if err != nil {
return err
}
// remove
collection.Schema.RemoveField("nfernq2q")
return dao.SaveCollection(collection)
})
}

View File

@ -0,0 +1,58 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models/schema"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
// update
edit_data := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "mkzyfsng",
"name": "data",
"type": "json",
"required": true,
"unique": false,
"options": {}
}`), edit_data)
collection.Schema.AddField(edit_data)
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
// update
edit_data := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "mkzyfsng",
"name": "data",
"type": "json",
"required": false,
"unique": false,
"options": {}
}`), edit_data)
collection.Schema.AddField(edit_data)
return dao.SaveCollection(collection)
})
}

View File

@ -0,0 +1,55 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models/schema"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
// remove
collection.Schema.RemoveField("s12duaes")
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
// add
del_visibility := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "s12duaes",
"name": "visibility",
"type": "select",
"required": false,
"unique": false,
"options": {
"maxSelect": 1,
"values": [
"public",
"private",
"unlisted"
]
}
}`), del_visibility)
collection.Schema.AddField(del_visibility)
return dao.SaveCollection(collection)
})
}

View File

@ -0,0 +1,54 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models/schema"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("fupstz47c55s69f")
if err != nil {
return err
}
// add
new_past_owners := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "p1aruqz5",
"name": "past_owners",
"type": "relation",
"required": false,
"unique": false,
"options": {
"collectionId": "_pb_users_auth_",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": null,
"displayFields": []
}
}`), new_past_owners)
collection.Schema.AddField(new_past_owners)
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("fupstz47c55s69f")
if err != nil {
return err
}
// remove
collection.Schema.RemoveField("p1aruqz5")
return dao.SaveCollection(collection)
})
}

View File

@ -0,0 +1,72 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models/schema"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("fupstz47c55s69f")
if err != nil {
return err
}
// update
edit_data := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "qxsvm1rf",
"name": "data",
"type": "relation",
"required": true,
"unique": false,
"options": {
"collectionId": "3qwwkz4wb0lyi78",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": 1,
"displayFields": [
"data"
]
}
}`), edit_data)
collection.Schema.AddField(edit_data)
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("fupstz47c55s69f")
if err != nil {
return err
}
// update
edit_data := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "qxsvm1rf",
"name": "data",
"type": "relation",
"required": false,
"unique": false,
"options": {
"collectionId": "3qwwkz4wb0lyi78",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": 1,
"displayFields": []
}
}`), edit_data)
collection.Schema.AddField(edit_data)
return dao.SaveCollection(collection)
})
}

View File

@ -0,0 +1,52 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models/schema"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
// add
new_block_id := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "vvqemti1",
"name": "block_id",
"type": "text",
"required": true,
"unique": false,
"options": {
"min": null,
"max": null,
"pattern": ""
}
}`), new_block_id)
collection.Schema.AddField(new_block_id)
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
// remove
collection.Schema.RemoveField("vvqemti1")
return dao.SaveCollection(collection)
})
}

View File

@ -0,0 +1,72 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models/schema"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
// update
edit_owner := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "a3d7pkoh",
"name": "owner",
"type": "relation",
"required": false,
"unique": false,
"options": {
"collectionId": "_pb_users_auth_",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": 1,
"displayFields": [
"username"
]
}
}`), edit_owner)
collection.Schema.AddField(edit_owner)
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("3qwwkz4wb0lyi78")
if err != nil {
return err
}
// update
edit_owner := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "a3d7pkoh",
"name": "owner",
"type": "relation",
"required": false,
"unique": false,
"options": {
"collectionId": "_pb_users_auth_",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": 1,
"displayFields": []
}
}`), edit_owner)
collection.Schema.AddField(edit_owner)
return dao.SaveCollection(collection)
})
}

View File

@ -0,0 +1,112 @@
package migrations
import (
"encoding/json"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
"github.com/pocketbase/pocketbase/models/schema"
)
func init() {
m.Register(func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("fupstz47c55s69f")
if err != nil {
return err
}
// update
edit_owner := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "nfernq2q",
"name": "owner",
"type": "relation",
"required": false,
"unique": false,
"options": {
"collectionId": "_pb_users_auth_",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": 1,
"displayFields": [
"username"
]
}
}`), edit_owner)
collection.Schema.AddField(edit_owner)
// update
edit_past_owners := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "p1aruqz5",
"name": "past_owners",
"type": "relation",
"required": false,
"unique": false,
"options": {
"collectionId": "_pb_users_auth_",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": null,
"displayFields": [
"username"
]
}
}`), edit_past_owners)
collection.Schema.AddField(edit_past_owners)
return dao.SaveCollection(collection)
}, func(db dbx.Builder) error {
dao := daos.New(db);
collection, err := dao.FindCollectionByNameOrId("fupstz47c55s69f")
if err != nil {
return err
}
// update
edit_owner := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "nfernq2q",
"name": "owner",
"type": "relation",
"required": false,
"unique": false,
"options": {
"collectionId": "_pb_users_auth_",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": 1,
"displayFields": []
}
}`), edit_owner)
collection.Schema.AddField(edit_owner)
// update
edit_past_owners := &schema.SchemaField{}
json.Unmarshal([]byte(`{
"system": false,
"id": "p1aruqz5",
"name": "past_owners",
"type": "relation",
"required": false,
"unique": false,
"options": {
"collectionId": "_pb_users_auth_",
"cascadeDelete": false,
"minSelect": null,
"maxSelect": null,
"displayFields": []
}
}`), edit_past_owners)
collection.Schema.AddField(edit_past_owners)
return dao.SaveCollection(collection)
})
}